diff --git a/TMessagesProj/build.gradle b/TMessagesProj/build.gradle index 426276d4b..0825caac9 100644 --- a/TMessagesProj/build.gradle +++ b/TMessagesProj/build.gradle @@ -5,8 +5,8 @@ apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions' -def verName = "7.2.1-preview05" -def verCode = 98 +def verName = "7.2.1-preview06" +def verCode = 100 def serviceAccountCredentialsFile = rootProject.file("service_account_credentials.json") diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java index 6af950ba5..d75fa99ec 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java @@ -20996,17 +20996,17 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (!AndroidUtilities.isGoogleMapsInstalled(ChatActivity.this)) { return; } - /*if (message.isLiveLocation()) { + if (message.isLiveLocation()) { LocationActivity fragment = new LocationActivity(currentChat == null || ChatObject.canSendMessages(currentChat) || currentChat.megagroup ? 2 : LocationActivity.LOCATION_TYPE_LIVE_VIEW); fragment.setDelegate(ChatActivity.this); fragment.setMessageObject(message); presentFragment(fragment); - } else {*/ + } else { LocationActivity fragment = new LocationActivity(currentEncryptedChat == null ? 3 : 0); fragment.setDelegate(ChatActivity.this); fragment.setMessageObject(message); presentFragment(fragment); - //} + } } else if (message.type == 9 || message.type == 0) { File locFile = null; if (message.messageOwner.attachPath != null && message.messageOwner.attachPath.length() != 0) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/LocationActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/LocationActivity.java index 34a6d0ee2..6d7850817 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/LocationActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/LocationActivity.java @@ -10,6 +10,8 @@ package org.telegram.ui; import android.Manifest; +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.animation.StateListAnimator; @@ -18,6 +20,7 @@ import android.annotation.SuppressLint; import android.app.Activity; import android.content.Context; import android.content.Intent; +import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.graphics.Bitmap; import android.graphics.BitmapFactory; @@ -70,6 +73,7 @@ import org.osmdroid.views.MapView; import org.osmdroid.util.GeoPoint; import org.osmdroid.views.Projection; import org.osmdroid.views.overlay.Marker; +import org.osmdroid.views.overlay.Polygon; import org.osmdroid.views.overlay.mylocation.GpsMyLocationProvider; import org.osmdroid.views.overlay.mylocation.IMyLocationProvider; import org.osmdroid.views.overlay.mylocation.MyLocationNewOverlay; @@ -83,6 +87,8 @@ import org.telegram.messenger.LocationController; import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.FileLog; import org.telegram.messenger.LocaleController; +import org.telegram.messenger.MessagesController; +import org.telegram.messenger.UserObject; import org.telegram.tgnet.TLRPC; import org.telegram.messenger.MessageObject; import org.telegram.messenger.NotificationCenter; @@ -110,12 +116,16 @@ import org.telegram.ui.Components.BackupImageView; import org.telegram.ui.Components.CombinedDrawable; import org.telegram.ui.Components.CubicBezierInterpolator; import org.telegram.ui.Components.EditTextBoldCursor; +import org.telegram.ui.Components.HintView; import org.telegram.ui.Components.LayoutHelper; import org.telegram.ui.Components.MapPlaceholderDrawable; +import org.telegram.ui.Components.ProximitySheet; import org.telegram.ui.Components.RecyclerListView; +import org.telegram.ui.Components.UndoView; import java.io.File; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Locale; @@ -127,6 +137,7 @@ import androidx.recyclerview.widget.RecyclerView; public class LocationActivity extends BaseFragment implements NotificationCenter.NotificationCenterDelegate { private ImageView locationButton; + private ImageView proximityButton; private ActionBarMenuItem mapTypeButton; private SearchButton searchAreaButton; private LinearLayout emptyView; @@ -137,13 +148,28 @@ public class LocationActivity extends BaseFragment implements NotificationCenter private View shadow; private ActionBarMenuItem searchItem; private MapOverlayView overlayView; + private HintView hintView; + + private UndoView[] undoView = new UndoView[2]; + private boolean canUndo; + + private boolean proximityAnimationInProgress; private MapView mapView; + private BoundingBox moveToBounds; private IGeoPoint forceUpdate; private float yOffset; + private Polygon proximityCircle; + private GeoPoint proximityCircleCenter; + private double proximityCircleRadius; + + private double previousRadius; + private boolean scrolling; + private ProximitySheet proximitySheet; + private FrameLayout mapViewClip; private LocationActivityAdapter adapter; private RecyclerListView listView; @@ -180,6 +206,8 @@ public class LocationActivity extends BaseFragment implements NotificationCenter private FrameLayout lastPressedMarkerView; private boolean checkPermission = true; + private boolean checkBackgroundPermission = true; + private int askWithRadius; private boolean searching; private boolean searchWas; @@ -233,6 +261,8 @@ public class LocationActivity extends BaseFragment implements NotificationCenter public TLRPC.User user; public TLRPC.Chat chat; public Marker marker; + public Marker directionMarker; + public boolean hasRotation; } private static class SearchButton extends TextView { @@ -274,7 +304,7 @@ public class LocationActivity extends BaseFragment implements NotificationCenter } public void addInfoView(Marker marker, VenueLocation location) { - if (lastPressedVenue == location) { + if (location == null || lastPressedVenue == location) { return; } showSearchPlacesButton(false); @@ -292,7 +322,7 @@ public class LocationActivity extends BaseFragment implements NotificationCenter lastPressedMarkerView = new FrameLayout(context); lastPressedMarkerView.setBackgroundResource(R.drawable.venue_tooltip); - lastPressedMarkerView.getBackground().setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_dialogBackground), PorterDuff.Mode.SRC_IN)); + lastPressedMarkerView.getBackground().setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_dialogBackground), PorterDuff.Mode.MULTIPLY)); frameLayout.addView(lastPressedMarkerView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, 71)); lastPressedMarkerView.setAlpha(0.0f); lastPressedMarkerView.setOnClickListener(v -> { @@ -377,7 +407,7 @@ public class LocationActivity extends BaseFragment implements NotificationCenter views.put(marker, frameLayout); final IMapController controller = mapView.getController(); - controller.animateTo(marker.getPosition(),mapView.getZoomLevelDouble(),300L); + controller.animateTo(marker.getPosition(), mapView.getZoomLevelDouble(), 300L); } public void removeInfoView(Marker marker) { @@ -387,6 +417,7 @@ public class LocationActivity extends BaseFragment implements NotificationCenter views.remove(marker); } } + //TODO public void updatePositions() { if (mapView == null) { @@ -396,7 +427,7 @@ public class LocationActivity extends BaseFragment implements NotificationCenter for (HashMap.Entry entry : views.entrySet()) { Marker marker = entry.getKey(); View view = entry.getValue(); - Point point = projection.toPixels(marker.getPosition(),null); + Point point = projection.toPixels(marker.getPosition(), null); view.setTranslationX(point.x - view.getMeasuredWidth() / 2); view.setTranslationY(point.y - view.getMeasuredHeight() + AndroidUtilities.dp(22)); } @@ -418,6 +449,7 @@ public class LocationActivity extends BaseFragment implements NotificationCenter super.onFragmentCreate(); getNotificationCenter().addObserver(this, NotificationCenter.closeChats); NotificationCenter.getGlobalInstance().addObserver(this, NotificationCenter.locationPermissionGranted); + NotificationCenter.getGlobalInstance().addObserver(this, NotificationCenter.liveLocationsChanged); if (messageObject != null && messageObject.isLiveLocation()) { getNotificationCenter().addObserver(this, NotificationCenter.didReceiveNewMessages); getNotificationCenter().addObserver(this, NotificationCenter.replaceMessagesObjects); @@ -429,12 +461,16 @@ public class LocationActivity extends BaseFragment implements NotificationCenter public void onFragmentDestroy() { super.onFragmentDestroy(); NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.locationPermissionGranted); + NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.liveLocationsChanged); getNotificationCenter().removeObserver(this, NotificationCenter.closeChats); getNotificationCenter().removeObserver(this, NotificationCenter.didReceiveNewMessages); getNotificationCenter().removeObserver(this, NotificationCenter.replaceMessagesObjects); // TODO // proper exit, like upstream does with // setMyLocationEnabled(false); + if (undoView[0] != null) { + undoView[0].hide(true, 0); + } if (adapter != null) { adapter.destroy(); } @@ -451,6 +487,18 @@ public class LocationActivity extends BaseFragment implements NotificationCenter } } + private UndoView getUndoView() { + if (undoView[0].getVisibility() == View.VISIBLE) { + UndoView old = undoView[0]; + undoView[0] = undoView[1]; + undoView[1] = old; + old.hide(true, 2); + mapViewClip.removeView(undoView[0]); + mapViewClip.addView(undoView[0]); + } + return undoView[0]; + } + @Override public boolean isSwipeBackEnabled(MotionEvent event) { return false; @@ -502,7 +550,7 @@ public class LocationActivity extends BaseFragment implements NotificationCenter FileLog.e(e); } } else if (id == share_live_location) { - openShareLiveLocation(); + openShareLiveLocation(0); } } }); @@ -520,9 +568,9 @@ public class LocationActivity extends BaseFragment implements NotificationCenter actionBar.setTitle(LocaleController.getString("ChatLocation", R.string.ChatLocation)); } otherItem = menu.addItem(0, R.drawable.ic_ab_other); - otherItem.addSubItem(open_in, R.drawable.baseline_open_in_browser_24, LocaleController.getString("OpenInExternalApp", R.string.OpenInExternalApp)); + otherItem.addSubItem(open_in, R.drawable.msg_openin, LocaleController.getString("OpenInExternalApp", R.string.OpenInExternalApp)); if (!getLocationController().isSharingLocation(dialogId)) { - otherItem.addSubItem(share_live_location, R.drawable.baseline_location_on_24, LocaleController.getString("SendLiveLocationMenu", R.string.SendLiveLocationMenu)); + otherItem.addSubItem(share_live_location, R.drawable.menu_location, LocaleController.getString("SendLiveLocationMenu", R.string.SendLiveLocationMenu)); } otherItem.setContentDescription(LocaleController.getString("AccDescrMoreOptions", R.string.AccDescrMoreOptions)); } @@ -598,6 +646,8 @@ public class LocationActivity extends BaseFragment implements NotificationCenter if (changed) { fixLayoutInternal(first); first = false; + } else { + updateClipView(true); } } @@ -614,7 +664,7 @@ public class LocationActivity extends BaseFragment implements NotificationCenter fragmentView.setBackgroundColor(Theme.getColor(Theme.key_dialogBackground)); shadowDrawable = context.getResources().getDrawable(R.drawable.sheet_shadow_round).mutate(); - shadowDrawable.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_dialogBackground), PorterDuff.Mode.SRC_IN)); + shadowDrawable.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_dialogBackground), PorterDuff.Mode.MULTIPLY)); Rect padding = new Rect(); shadowDrawable.getPadding(padding); @@ -643,7 +693,7 @@ public class LocationActivity extends BaseFragment implements NotificationCenter Drawable drawable = Theme.createSimpleSelectorRoundRectDrawable(AndroidUtilities.dp(40), Theme.getColor(Theme.key_location_actionBackground), Theme.getColor(Theme.key_location_actionPressedBackground)); if (Build.VERSION.SDK_INT < 21) { Drawable shadowDrawable = context.getResources().getDrawable(R.drawable.places_btn).mutate(); - shadowDrawable.setColorFilter(new PorterDuffColorFilter(0xff000000, PorterDuff.Mode.SRC_IN)); + shadowDrawable.setColorFilter(new PorterDuffColorFilter(0xff000000, PorterDuff.Mode.MULTIPLY)); CombinedDrawable combinedDrawable = new CombinedDrawable(shadowDrawable, drawable, AndroidUtilities.dp(2), AndroidUtilities.dp(2)); combinedDrawable.setFullsize(true); drawable = combinedDrawable; @@ -688,7 +738,7 @@ public class LocationActivity extends BaseFragment implements NotificationCenter Drawable drawable = Theme.createSimpleSelectorCircleDrawable(AndroidUtilities.dp(40), Theme.getColor(Theme.key_location_actionBackground), Theme.getColor(Theme.key_location_actionPressedBackground)); if (Build.VERSION.SDK_INT < 21) { Drawable shadowDrawable = context.getResources().getDrawable(R.drawable.floating_shadow_profile).mutate(); - shadowDrawable.setColorFilter(new PorterDuffColorFilter(0xff000000, PorterDuff.Mode.SRC_IN)); + shadowDrawable.setColorFilter(new PorterDuffColorFilter(0xff000000, PorterDuff.Mode.MULTIPLY)); CombinedDrawable combinedDrawable = new CombinedDrawable(shadowDrawable, drawable, 0, 0); combinedDrawable.setIconSize(AndroidUtilities.dp(40), AndroidUtilities.dp(40)); drawable = combinedDrawable; @@ -721,7 +771,7 @@ public class LocationActivity extends BaseFragment implements NotificationCenter ITileSource tileSource = new XYTileSource( "Wikimedia", 0, 19, 256, ".png", - new String[] {"https://maps.wikimedia.org/osm-intl/"}, + new String[]{"https://maps.wikimedia.org/osm-intl/"}, "© OpenStreetMap contributors"); attributionOverlay.setText(Html.fromHtml("© OpenStreetMap contributors")); mapView.setTileSource(tileSource); @@ -730,7 +780,7 @@ public class LocationActivity extends BaseFragment implements NotificationCenter ITileSource tileSource = new XYTileSource( "Carto Dark", 0, 20, 256, ".png", - new String[] { + new String[]{ "https://cartodb-basemaps-a.global.ssl.fastly.net/dark_all/", "https://cartodb-basemaps-b.global.ssl.fastly.net/dark_all/", "https://cartodb-basemaps-c.global.ssl.fastly.net/dark_all/", @@ -745,7 +795,7 @@ public class LocationActivity extends BaseFragment implements NotificationCenter drawable = Theme.createSimpleSelectorCircleDrawable(AndroidUtilities.dp(40), Theme.getColor(Theme.key_location_actionBackground), Theme.getColor(Theme.key_location_actionPressedBackground)); if (Build.VERSION.SDK_INT < 21) { Drawable shadowDrawable = context.getResources().getDrawable(R.drawable.floating_shadow_profile).mutate(); - shadowDrawable.setColorFilter(new PorterDuffColorFilter(0xff000000, PorterDuff.Mode.SRC_IN)); + shadowDrawable.setColorFilter(new PorterDuffColorFilter(0xff000000, PorterDuff.Mode.MULTIPLY)); CombinedDrawable combinedDrawable = new CombinedDrawable(shadowDrawable, drawable, 0, 0); combinedDrawable.setIconSize(AndroidUtilities.dp(40), AndroidUtilities.dp(40)); drawable = combinedDrawable; @@ -765,7 +815,7 @@ public class LocationActivity extends BaseFragment implements NotificationCenter locationButton.setBackgroundDrawable(drawable); locationButton.setImageResource(R.drawable.location_current); locationButton.setScaleType(ImageView.ScaleType.CENTER); - locationButton.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_location_actionActiveIcon), PorterDuff.Mode.SRC_IN)); + locationButton.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_location_actionActiveIcon), PorterDuff.Mode.MULTIPLY)); locationButton.setTag(Theme.key_location_actionActiveIcon); locationButton.setContentDescription(LocaleController.getString("AccDescrMyLocation", R.string.AccDescrMyLocation)); FrameLayout.LayoutParams layoutParams1 = LayoutHelper.createFrame(Build.VERSION.SDK_INT >= 21 ? 40 : 44, Build.VERSION.SDK_INT >= 21 ? 40 : 44, Gravity.RIGHT | Gravity.BOTTOM, 0, 0, 12, 12); @@ -781,14 +831,17 @@ public class LocationActivity extends BaseFragment implements NotificationCenter } } } + if (!checkGpsEnabled()) { + return; + } if (messageObject != null || chatLocation != null) { if (myLocation != null && mapView != null) { final IMapController controller = mapView.getController(); - controller.animateTo(new GeoPoint(myLocation.getLatitude(), myLocation.getLongitude()),mapView.getMaxZoomLevel() -2, null); + controller.animateTo(new GeoPoint(myLocation.getLatitude(), myLocation.getLongitude()), mapView.getMaxZoomLevel() - 2, null); } } else { if (myLocation != null && mapView != null) { - locationButton.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_location_actionActiveIcon), PorterDuff.Mode.SRC_IN)); + locationButton.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_location_actionActiveIcon), PorterDuff.Mode.MULTIPLY)); locationButton.setTag(Theme.key_location_actionActiveIcon); adapter.setCustomLocation(null); userLocationMoved = false; @@ -807,6 +860,92 @@ public class LocationActivity extends BaseFragment implements NotificationCenter removeInfoView(); }); + proximityButton = new ImageView(context); + drawable = Theme.createSimpleSelectorCircleDrawable(AndroidUtilities.dp(40), Theme.getColor(Theme.key_location_actionBackground), Theme.getColor(Theme.key_location_actionPressedBackground)); + if (Build.VERSION.SDK_INT < 21) { + Drawable shadowDrawable = context.getResources().getDrawable(R.drawable.floating_shadow_profile).mutate(); + shadowDrawable.setColorFilter(new PorterDuffColorFilter(0xff000000, PorterDuff.Mode.MULTIPLY)); + CombinedDrawable combinedDrawable = new CombinedDrawable(shadowDrawable, drawable, 0, 0); + combinedDrawable.setIconSize(AndroidUtilities.dp(40), AndroidUtilities.dp(40)); + drawable = combinedDrawable; + } else { + StateListAnimator animator = new StateListAnimator(); + animator.addState(new int[]{android.R.attr.state_pressed}, ObjectAnimator.ofFloat(proximityButton, View.TRANSLATION_Z, AndroidUtilities.dp(2), AndroidUtilities.dp(4)).setDuration(200)); + animator.addState(new int[]{}, ObjectAnimator.ofFloat(proximityButton, View.TRANSLATION_Z, AndroidUtilities.dp(4), AndroidUtilities.dp(2)).setDuration(200)); + proximityButton.setStateListAnimator(animator); + proximityButton.setOutlineProvider(new ViewOutlineProvider() { + @SuppressLint("NewApi") + @Override + public void getOutline(View view, Outline outline) { + outline.setOval(0, 0, AndroidUtilities.dp(40), AndroidUtilities.dp(40)); + } + }); + } + proximityButton.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_location_actionIcon), PorterDuff.Mode.MULTIPLY)); + proximityButton.setBackgroundDrawable(drawable); + proximityButton.setScaleType(ImageView.ScaleType.CENTER); + proximityButton.setContentDescription(LocaleController.getString("AccDescrLocationNotify", R.string.AccDescrLocationNotify)); + mapViewClip.addView(proximityButton, LayoutHelper.createFrame(Build.VERSION.SDK_INT >= 21 ? 40 : 44, Build.VERSION.SDK_INT >= 21 ? 40 : 44, Gravity.RIGHT | Gravity.TOP, 0, 12 + 50, 12, 0)); + proximityButton.setOnClickListener(v -> { + if (getParentActivity() == null || myLocation == null || !checkGpsEnabled() || mapView == null) { + return; + } + if (hintView != null) { + hintView.hide(); + } + SharedPreferences preferences = MessagesController.getGlobalMainSettings(); + preferences.edit().putInt("proximityhint", 3).commit(); + LocationController.SharingLocationInfo info = getLocationController().getSharingLocationInfo(dialogId); + if (canUndo) { + undoView[0].hide(true, 1); + } + if (info != null && info.proximityMeters > 0) { + proximityButton.setImageResource(R.drawable.msg_location_alert); + if (proximityCircle != null) { + mapView.getOverlayManager().remove(proximityCircle); + proximityCircle = null; + } + canUndo = true; + getUndoView().showWithAction(0, UndoView.ACTION_PROXIMITY_REMOVED, 0, null, + () -> { + getLocationController().setProximityLocation(dialogId, 0, true); + canUndo = false; + }, () -> { + proximityButton.setImageResource(R.drawable.msg_location_alert2); + createCircle(info.proximityMeters); + canUndo = false; + }); + return; + } + openProximityAlert(); + }); + TLRPC.Chat chat = null; + if ((int) dialogId < 0) { + chat = getMessagesController().getChat(-(int) dialogId); + } + if (messageObject == null || !messageObject.isLiveLocation() || messageObject.isExpiredLiveLocation(getConnectionsManager().getCurrentTime()) || ChatObject.isChannel(chat) && !chat.megagroup) { + proximityButton.setVisibility(View.GONE); + proximityButton.setImageResource(R.drawable.msg_location_alert); + } else { + LocationController.SharingLocationInfo myInfo = getLocationController().getSharingLocationInfo(dialogId); + if (myInfo != null && myInfo.proximityMeters > 0) { + proximityButton.setImageResource(R.drawable.msg_location_alert2); + } else { + if ((int) dialogId > 0 && messageObject.getFromChatId() == getUserConfig().getClientUserId()) { + proximityButton.setVisibility(View.INVISIBLE); + proximityButton.setAlpha(0.0f); + proximityButton.setScaleX(0.4f); + proximityButton.setScaleY(0.4f); + } + proximityButton.setImageResource(R.drawable.msg_location_alert); + } + } + + hintView = new HintView(context, 6, true); + hintView.setVisibility(View.INVISIBLE); + hintView.setShowingDuration(4000); + mapViewClip.addView(hintView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.TOP, 10, 0, 10, 0)); + emptyView = new LinearLayout(context); emptyView.setOrientation(LinearLayout.VERTICAL); emptyView.setGravity(Gravity.CENTER_HORIZONTAL); @@ -817,7 +956,7 @@ public class LocationActivity extends BaseFragment implements NotificationCenter emptyImageView = new ImageView(context); emptyImageView.setImageResource(R.drawable.location_empty); - emptyImageView.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_dialogEmptyImage), PorterDuff.Mode.SRC_IN)); + emptyImageView.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_dialogEmptyImage), PorterDuff.Mode.MULTIPLY)); emptyView.addView(emptyImageView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT)); emptyTitleTextView = new TextView(context); @@ -863,7 +1002,7 @@ public class LocationActivity extends BaseFragment implements NotificationCenter } } }); - adapter.setUpdateRunnable(this::updateClipView); + adapter.setUpdateRunnable(() -> updateClipView(false)); listView.setVerticalScrollBarEnabled(false); listView.setLayoutManager(layoutManager = new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)); frameLayout.addView(listView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.LEFT | Gravity.TOP)); @@ -879,7 +1018,7 @@ public class LocationActivity extends BaseFragment implements NotificationCenter @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { - updateClipView(); + updateClipView(false); if (forceUpdate != null) { yOffset += dy; } @@ -921,12 +1060,12 @@ public class LocationActivity extends BaseFragment implements NotificationCenter } else if (locationType == LOCATION_TYPE_GROUP_VIEW) { if (mapView != null) { final IMapController controller = mapView.getController(); - controller.animateTo(new GeoPoint(chatLocation.geo_point.lat, chatLocation.geo_point._long),mapView.getMaxZoomLevel() -2, null); + controller.animateTo(new GeoPoint(chatLocation.geo_point.lat, chatLocation.geo_point._long), mapView.getMaxZoomLevel() - 2, null); } - } else if (position == 1 && messageObject != null && !messageObject.isLiveLocation()) { + } else if (position == 1 && messageObject != null && (!messageObject.isLiveLocation() || locationType == LOCATION_TYPE_LIVE_VIEW)) { if (mapView != null) { final IMapController controller = mapView.getController(); - controller.animateTo(new GeoPoint(messageObject.messageOwner.media.geo.lat, messageObject.messageOwner.media.geo._long),mapView.getMaxZoomLevel() -2, null); + controller.animateTo(new GeoPoint(messageObject.messageOwner.media.geo.lat, messageObject.messageOwner.media.geo._long), mapView.getMaxZoomLevel() - 2, null); } } else if (position == 1 && locationType != 2) { if (delegate != null && userLocation != null) { @@ -953,7 +1092,7 @@ public class LocationActivity extends BaseFragment implements NotificationCenter getLocationController().removeSharingLocation(dialogId); finishFragment(); } else { - openShareLiveLocation(); + openShareLiveLocation(0); } } else { Object object = adapter.getItem(position); @@ -970,7 +1109,7 @@ public class LocationActivity extends BaseFragment implements NotificationCenter } else if (object instanceof LiveLocation) { LiveLocation liveLocation = (LiveLocation) object; final IMapController controller = mapView.getController(); - controller.animateTo(liveLocation.marker.getPosition(), mapView.getMaxZoomLevel() -2 ,null); + controller.animateTo(liveLocation.marker.getPosition(), mapView.getMaxZoomLevel() - 2, null); } } }); @@ -1019,7 +1158,7 @@ public class LocationActivity extends BaseFragment implements NotificationCenter } if (ev.getAction() == MotionEvent.ACTION_MOVE) { if (!userLocationMoved) { - locationButton.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_location_actionIcon), PorterDuff.Mode.SRC_IN)); + locationButton.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_location_actionIcon), PorterDuff.Mode.MULTIPLY)); locationButton.setTag(Theme.key_location_actionIcon); userLocationMoved = true; } @@ -1034,6 +1173,17 @@ public class LocationActivity extends BaseFragment implements NotificationCenter } return super.onTouchEvent(ev); } + + @Override + protected void onLayout(boolean changed, int left, int top, int right, int bottom) { + super.onLayout(changed, left, top, right, bottom); + AndroidUtilities.runOnUIThread(() -> { + if (moveToBounds != null) { + mapView.zoomToBoundingBox(moveToBounds, false, AndroidUtilities.dp(80 + 33)); + moveToBounds = null; + } + }); + } }; AndroidUtilities.runOnUIThread(() -> { @@ -1056,21 +1206,18 @@ public class LocationActivity extends BaseFragment implements NotificationCenter if (messageObject == null && chatLocation == null) { - if (locationType == LOCATION_TYPE_GROUP && dialogId != 0) { - TLRPC.Chat chat = getMessagesController().getChat(-(int) dialogId); - if (chat != null) { - FrameLayout frameLayout1 = new FrameLayout(context); - frameLayout1.setBackgroundResource(R.drawable.livepin); - mapViewClip.addView(frameLayout1, LayoutHelper.createFrame(62, 76, Gravity.TOP | Gravity.CENTER_HORIZONTAL)); + if (chat != null && locationType == LOCATION_TYPE_GROUP && dialogId != 0) { + FrameLayout frameLayout1 = new FrameLayout(context); + frameLayout1.setBackgroundResource(R.drawable.livepin); + mapViewClip.addView(frameLayout1, LayoutHelper.createFrame(62, 76, Gravity.TOP | Gravity.CENTER_HORIZONTAL)); - BackupImageView backupImageView = new BackupImageView(context); - backupImageView.setRoundRadius(AndroidUtilities.dp(26)); - backupImageView.setImage(ImageLocation.getForChat(chat, false), "50_50", new AvatarDrawable(chat), chat); - frameLayout1.addView(backupImageView, LayoutHelper.createFrame(52, 52, Gravity.LEFT | Gravity.TOP, 5, 5, 0, 0)); + BackupImageView backupImageView = new BackupImageView(context); + backupImageView.setRoundRadius(AndroidUtilities.dp(26)); + backupImageView.setImage(ImageLocation.getForChat(chat, false), "50_50", new AvatarDrawable(chat), chat); + frameLayout1.addView(backupImageView, LayoutHelper.createFrame(52, 52, Gravity.LEFT | Gravity.TOP, 5, 5, 0, 0)); - markerImageView = frameLayout1; - markerImageView.setTag(1); - } + markerImageView = frameLayout1; + markerImageView.setTag(1); } if (markerImageView == null) { @@ -1129,6 +1276,19 @@ public class LocationActivity extends BaseFragment implements NotificationCenter adapter.setMessageObject(messageObject); } } + if (messageObject != null && locationType == LOCATION_TYPE_LIVE_VIEW) { + adapter.setMessageObject(messageObject); + } + + + for (int a = 0; a < 2; a++) { + undoView[a] = new UndoView(context); + undoView[a].setAdditionalTranslationY(AndroidUtilities.dp(10)); + if (Build.VERSION.SDK_INT >= 21) { + undoView[a].setTranslationZ(AndroidUtilities.dp(5)); + } + mapViewClip.addView(undoView[a], LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.BOTTOM | Gravity.LEFT, 8, 0, 8, 8)); + } shadow = new View(context) { @@ -1150,11 +1310,14 @@ public class LocationActivity extends BaseFragment implements NotificationCenter } } }; + if (Build.VERSION.SDK_INT >= 21) { + shadow.setTranslationZ(AndroidUtilities.dp(6)); + } mapViewClip.addView(shadow, layoutParams); if (messageObject == null && chatLocation == null && initialLocation != null) { userLocationMoved = true; - locationButton.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_location_actionIcon), PorterDuff.Mode.SRC_IN)); + locationButton.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_location_actionIcon), PorterDuff.Mode.MULTIPLY)); locationButton.setTag(Theme.key_location_actionIcon); } @@ -1208,7 +1371,7 @@ public class LocationActivity extends BaseFragment implements NotificationCenter private TextView getAttributionOverlay(Context context) { attributionOverlay = new TextView(context); attributionOverlay.setText(Html.fromHtml("© OpenStreetMap contributors")); - attributionOverlay.setShadowLayer(1,-1,-1, Color.WHITE); + attributionOverlay.setShadowLayer(1, -1, -1, Color.WHITE); attributionOverlay.setLinksClickable(true); attributionOverlay.setMovementMethod(LinkMovementMethod.getInstance()); return attributionOverlay; @@ -1223,11 +1386,11 @@ public class LocationActivity extends BaseFragment implements NotificationCenter } else if (liveLocation.chat != null && liveLocation.chat.photo != null) { photo = liveLocation.chat.photo.photo_small; } - result = Bitmap.createBitmap(AndroidUtilities.dp(62), AndroidUtilities.dp(76), Bitmap.Config.ARGB_8888); + result = Bitmap.createBitmap(AndroidUtilities.dp(62), AndroidUtilities.dp(85), Bitmap.Config.ARGB_8888); result.eraseColor(Color.TRANSPARENT); Canvas canvas = new Canvas(result); - Drawable drawable = ApplicationLoader.applicationContext.getResources().getDrawable(R.drawable.livepin); - drawable.setBounds(0, 0, AndroidUtilities.dp(62), AndroidUtilities.dp(76)); + Drawable drawable = ApplicationLoader.applicationContext.getResources().getDrawable(R.drawable.map_pin_photo); + drawable.setBounds(0, 0, AndroidUtilities.dp(62), AndroidUtilities.dp(85)); drawable.draw(canvas); Paint roundPaint = new Paint(Paint.ANTI_ALIAS_FLAG); @@ -1239,13 +1402,13 @@ public class LocationActivity extends BaseFragment implements NotificationCenter if (bitmap != null) { BitmapShader shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); Matrix matrix = new Matrix(); - float scale = AndroidUtilities.dp(52) / (float) bitmap.getWidth(); - matrix.postTranslate(AndroidUtilities.dp(5), AndroidUtilities.dp(5)); + float scale = AndroidUtilities.dp(50) / (float) bitmap.getWidth(); + matrix.postTranslate(AndroidUtilities.dp(6), AndroidUtilities.dp(6)); matrix.postScale(scale, scale); roundPaint.setShader(shader); shader.setLocalMatrix(matrix); - bitmapRect.set(AndroidUtilities.dp(5), AndroidUtilities.dp(5), AndroidUtilities.dp(52 + 5), AndroidUtilities.dp(52 + 5)); - canvas.drawRoundRect(bitmapRect, AndroidUtilities.dp(26), AndroidUtilities.dp(26), roundPaint); + bitmapRect.set(AndroidUtilities.dp(6), AndroidUtilities.dp(6), AndroidUtilities.dp(50 + 6), AndroidUtilities.dp(50 + 6)); + canvas.drawRoundRect(bitmapRect, AndroidUtilities.dp(25), AndroidUtilities.dp(25), roundPaint); } } else { AvatarDrawable avatarDrawable = new AvatarDrawable(); @@ -1254,8 +1417,8 @@ public class LocationActivity extends BaseFragment implements NotificationCenter } else if (liveLocation.chat != null) { avatarDrawable.setInfo(liveLocation.chat); } - canvas.translate(AndroidUtilities.dp(5), AndroidUtilities.dp(5)); - avatarDrawable.setBounds(0, 0, AndroidUtilities.dp(52.2f), AndroidUtilities.dp(52.2f)); + canvas.translate(AndroidUtilities.dp(6), AndroidUtilities.dp(6)); + avatarDrawable.setBounds(0, 0, AndroidUtilities.dp(50), AndroidUtilities.dp(50)); avatarDrawable.draw(canvas); } canvas.restore(); @@ -1278,26 +1441,133 @@ public class LocationActivity extends BaseFragment implements NotificationCenter } } - private void openShareLiveLocation() { - if (delegate == null || getParentActivity() == null || myLocation == null) { - return; + private void openProximityAlert() { + if (proximityCircle == null) { + createCircle(500); + proximityCircleRadius = 500; + } else { + previousRadius = proximityCircleRadius; } - TLRPC.User user = null; + + TLRPC.User user; if ((int) dialogId > 0) { user = getMessagesController().getUser((int) dialogId); + } else { + user = null; } - showDialog(AlertsCreator.createLocationUpdateDialog(getParentActivity(), user, param -> { - TLRPC.TL_messageMediaGeoLive location = new TLRPC.TL_messageMediaGeoLive(); - location.geo = new TLRPC.TL_geoPoint(); - location.geo.lat = AndroidUtilities.fixLocationCoord(myLocation.getLatitude()); - location.geo._long = AndroidUtilities.fixLocationCoord(myLocation.getLongitude()); - location.period = param; - delegate.didSelectLocation(location, locationType, true, 0); + proximitySheet = new ProximitySheet(getParentActivity(), user, (move, radius) -> { + if (proximityCircle != null) { + proximityCircleRadius = radius; + proximityCircle.setPoints(Polygon.pointsAsCircle(proximityCircleCenter, radius)); + if (move) { + moveToBounds(radius, true, true); + } + } + if ((int) dialogId < 0) { + return true; + } + for (int a = 0, N = markers.size(); a < N; a++) { + LiveLocation location = markers.get(a); + if (location.object == null || UserObject.isUserSelf(location.user)) { + continue; + } + TLRPC.GeoPoint point = location.object.media.geo; + Location loc = new Location("network"); + loc.setLatitude(point.lat); + loc.setLongitude(point._long); + if (myLocation.distanceTo(loc) > radius) { + return true; + } + } + return false; + }, (move, radius) -> { + LocationController.SharingLocationInfo info = getLocationController().getSharingLocationInfo(dialogId); + if (info == null) { + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setTitle(LocaleController.getString("ShareLocationAlertTitle", R.string.ShareLocationAlertTitle)); + builder.setMessage(LocaleController.getString("ShareLocationAlertText", R.string.ShareLocationAlertText)); + builder.setPositiveButton(LocaleController.getString("ShareLocationAlertButton", R.string.ShareLocationAlertButton), (dialog, id) -> shareLiveLocation(user, 900, radius)); + builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); + showDialog(builder.create()); + return false; + } + proximitySheet.setRadiusSet(); + proximityButton.setImageResource(R.drawable.msg_location_alert2); + getUndoView().showWithAction(0, UndoView.ACTION_PROXIMITY_SET, radius, user, null, null); + getLocationController().setProximityLocation(dialogId, radius, true); + return true; + }, () -> { + if (mapView != null) { + mapView.setPadding(AndroidUtilities.dp(70), 0, AndroidUtilities.dp(70), AndroidUtilities.dp(10)); + } + if (!proximitySheet.getRadiusSet()) { + if (previousRadius > 0) { + proximityCircleRadius = previousRadius; + proximityCircle.setPoints(Polygon.pointsAsCircle(proximityCircleCenter, previousRadius)); + } else if (proximityCircle != null) { + mapView.getOverlayManager().remove(proximityCircle); + proximityCircle = null; + } + } + proximitySheet = null; + }); + FrameLayout frameLayout = (FrameLayout) fragmentView; + frameLayout.addView(proximitySheet, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT)); + proximitySheet.show(); + } + + private void openShareLiveLocation(int proximityRadius) { + if (delegate == null || getParentActivity() == null || myLocation == null || !checkGpsEnabled()) { + return; + } + if (checkBackgroundPermission && Build.VERSION.SDK_INT >= 29) { + Activity activity = getParentActivity(); + if (activity != null) { + askWithRadius = proximityRadius; + checkBackgroundPermission = false; + SharedPreferences preferences = MessagesController.getGlobalMainSettings(); + int lastTime = preferences.getInt("backgroundloc", 0); + if (Math.abs(System.currentTimeMillis() / 1000 - lastTime) > 24 * 60 * 60 && activity.checkSelfPermission(Manifest.permission.ACCESS_BACKGROUND_LOCATION) != PackageManager.PERMISSION_GRANTED) { + preferences.edit().putInt("backgroundloc", (int) (System.currentTimeMillis() / 1000)).commit(); + AlertsCreator.createBackgroundLocationPermissionDialog(activity, getMessagesController().getUser(getUserConfig().getClientUserId()), () -> openShareLiveLocation(askWithRadius)).show(); + return; + } + } + } + TLRPC.User user; + if ((int) dialogId > 0) { + user = getMessagesController().getUser((int) dialogId); + } else { + user = null; + } + showDialog(AlertsCreator.createLocationUpdateDialog(getParentActivity(), user, param -> shareLiveLocation(user, param, proximityRadius))); + } + + private void shareLiveLocation(TLRPC.User user, int period, int radius) { + TLRPC.TL_messageMediaGeoLive location = new TLRPC.TL_messageMediaGeoLive(); + location.geo = new TLRPC.TL_geoPoint(); + location.geo.lat = AndroidUtilities.fixLocationCoord(myLocation.getLatitude()); + location.geo._long = AndroidUtilities.fixLocationCoord(myLocation.getLongitude()); + location.heading = LocationController.getHeading(myLocation); + location.flags |= 1; + location.period = period; + location.proximity_notification_radius = radius; + location.flags |= 8; + delegate.didSelectLocation(location, locationType, true, 0); + if (radius > 0) { + proximitySheet.setRadiusSet(); + proximityButton.setImageResource(R.drawable.msg_location_alert2); + if (proximitySheet != null) { + proximitySheet.dismiss(); + } + getUndoView().showWithAction(0, UndoView.ACTION_PROXIMITY_SET, radius, user, null, null); + } else { finishFragment(); - })); + } } private Bitmap[] bitmapCache = new Bitmap[7]; + private Bitmap createPlaceBitmap(int num) { if (bitmapCache[num % 7] != null) { return bitmapCache[num % 7]; @@ -1346,7 +1616,7 @@ public class LocationActivity extends BaseFragment implements NotificationCenter public boolean onMarkerClick(Marker marker, MapView mapView) { markerImageView.setVisibility(View.INVISIBLE); if (!userLocationMoved) { - locationButton.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_location_actionIcon), PorterDuff.Mode.SRC_IN)); + locationButton.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_location_actionIcon), PorterDuff.Mode.MULTIPLY)); locationButton.setTag(Theme.key_location_actionIcon); userLocationMoved = true; } @@ -1395,11 +1665,33 @@ public class LocationActivity extends BaseFragment implements NotificationCenter marker.setAnchor(0.5f, 0.907f); mapView.getOverlays().add(marker); liveLocation.marker = marker; + + if (!UserObject.isUserSelf(liveLocation.user)) { + Marker directionMarker = new Marker(mapView); + + directionMarker.setPosition(latLng); + directionMarker.setFlat(true); + directionMarker.setIcon(getParentActivity().getResources().getDrawable(R.drawable.map_pin_circle)); + directionMarker.setAnchor(0.5f, 0.5f); + mapView.getOverlayManager().add(directionMarker); + liveLocation.directionMarker = directionMarker; + + if (message.media.heading != 0) { + liveLocation.directionMarker.setRotation(message.media.heading); + liveLocation.directionMarker.setIcon(getParentActivity().getResources().getDrawable(R.drawable.map_pin_cone2)); + liveLocation.hasRotation = true; + } else { + liveLocation.directionMarker.setRotation(0); + liveLocation.directionMarker.setIcon(getParentActivity().getResources().getDrawable(R.drawable.map_pin_circle)); + liveLocation.hasRotation = false; + } + } markers.add(liveLocation); markersMap.put(liveLocation.id, liveLocation); LocationController.SharingLocationInfo myInfo = getLocationController().getSharingLocationInfo(dialogId); if (liveLocation.id == getUserConfig().getClientUserId() && myInfo != null && liveLocation.object.id == myInfo.mid && myLocation != null) { - liveLocation.marker.setPosition(new GeoPoint(myLocation.getLatitude(), myLocation.getLongitude())); + GeoPoint latLng1 = new GeoPoint(myLocation.getLatitude(), myLocation.getLongitude()); + liveLocation.marker.setPosition(latLng1); } } } catch (Exception e) { @@ -1409,6 +1701,9 @@ public class LocationActivity extends BaseFragment implements NotificationCenter liveLocation.object = message; liveLocation.marker.setPosition(latLng); } + if (proximitySheet != null) { + proximitySheet.updateText(true, true); + } return liveLocation; } @@ -1439,6 +1734,17 @@ public class LocationActivity extends BaseFragment implements NotificationCenter marker.setAnchor(0.5f, 0.907f); mapView.getOverlays().add(marker); liveLocation.marker = marker; + + if (!UserObject.isUserSelf(liveLocation.user)) { + Marker directionMarker = new Marker(mapView); + ; + directionMarker.setPosition(latLng); + directionMarker.setFlat(true); + directionMarker.setIcon(getParentActivity().getResources().getDrawable(R.drawable.map_pin_circle)); + directionMarker.setAnchor(0.5f, 0.5f); + mapView.getOverlayManager().add(directionMarker); + liveLocation.directionMarker = directionMarker; + } markers.add(liveLocation); markersMap.put(liveLocation.id, liveLocation); } @@ -1455,7 +1761,7 @@ public class LocationActivity extends BaseFragment implements NotificationCenter } //Paris, Tour Eiffel - GeoPoint initLocation = new GeoPoint(48.85825,2.29448); + GeoPoint initLocation = new GeoPoint(48.85825, 2.29448); final IMapController controller = mapView.getController(); mapView.setMaxZoomLevel(20.0); mapView.setMultiTouchControls(true); @@ -1534,6 +1840,7 @@ public class LocationActivity extends BaseFragment implements NotificationCenter }; myLocationOverlay.enableMyLocation(); myLocationOverlay.setDrawAccuracyEnabled(true); + myLocationOverlay.setPersonIcon(BitmapFactory.decodeResource(getParentActivity().getResources(),R.drawable.map_pin_circle)); //TODO mapView.addMapListener(new MapListener() { @@ -1595,34 +1902,72 @@ public class LocationActivity extends BaseFragment implements NotificationCenter attributionOverlay.bringToFront(); if (checkGpsEnabled && getParentActivity() != null) { checkGpsEnabled = false; - if (!getParentActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_LOCATION_GPS)) { - return; - } - try { - LocationManager lm = (LocationManager) ApplicationLoader.applicationContext.getSystemService(Context.LOCATION_SERVICE); - if (!lm.isProviderEnabled(LocationManager.GPS_PROVIDER)) { - AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); - builder.setTitle(LocaleController.getString("GpsDisabledAlertTitle", R.string.GpsDisabledAlertTitle)); - builder.setMessage(LocaleController.getString("GpsDisabledAlertText", R.string.GpsDisabledAlertText)); - builder.setPositiveButton(LocaleController.getString("ConnectingToProxyEnable", R.string.ConnectingToProxyEnable), (dialog, id) -> { - if (getParentActivity() == null) { - return; - } - try { - getParentActivity().startActivity(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS)); - } catch (Exception ignore) { + checkGpsEnabled(); + } - } - }); - builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); - showDialog(builder.create()); - } - } catch (Exception e) { - FileLog.e(e); + if (proximityButton != null && proximityButton.getVisibility() == View.VISIBLE) { + LocationController.SharingLocationInfo myInfo = getLocationController().getSharingLocationInfo(dialogId); + if (myInfo != null && myInfo.proximityMeters > 0) { + createCircle(myInfo.proximityMeters); } } } + private boolean checkGpsEnabled() { + if (!getParentActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_LOCATION_GPS)) { + return true; + } + try { + LocationManager lm = (LocationManager) ApplicationLoader.applicationContext.getSystemService(Context.LOCATION_SERVICE); + if (!lm.isProviderEnabled(LocationManager.GPS_PROVIDER)) { + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setTitle(LocaleController.getString("GpsDisabledAlertTitle", R.string.GpsDisabledAlertTitle)); + builder.setMessage(LocaleController.getString("GpsDisabledAlertText", R.string.GpsDisabledAlertText)); + builder.setPositiveButton(LocaleController.getString("ConnectingToProxyEnable", R.string.ConnectingToProxyEnable), (dialog, id) -> { + if (getParentActivity() == null) { + return; + } + try { + getParentActivity().startActivity(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS)); + } catch (Exception ignore) { + + } + }); + builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); + showDialog(builder.create()); + return false; + } + } catch (Exception e) { + FileLog.e(e); + } + return true; + } + + private void createCircle(int meters) { + if (mapView == null) { + return; + } + + proximityCircleCenter = new GeoPoint(myLocation.getLatitude(), myLocation.getLongitude()); + proximityCircleRadius = meters; + + proximityCircle = new Polygon(); + proximityCircle.setPoints(Polygon.pointsAsCircle(proximityCircleCenter, meters)); + + if (isActiveThemeDark()) { + proximityCircle.getOutlinePaint().setColor(0xffffffff); + proximityCircle.getFillPaint().setColor(0x20ffffff); + } else { + proximityCircle.getOutlinePaint().setColor(0xff000000); + proximityCircle.getOutlinePaint().setColor(0x20000000); + } + + // TODO: set dash /gap + proximityCircle.getOutlinePaint().setStrokeWidth(2); + mapView.getOverlayManager().add(proximityCircle); + + } + private void removeInfoView() { if (lastPressedMarker != null) { markerImageView.setVisibility(View.VISIBLE); @@ -1684,13 +2029,32 @@ public class LocationActivity extends BaseFragment implements NotificationCenter } mapViewClip.addView(overlayView, 1, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, overScrollHeight + AndroidUtilities.dp(10), Gravity.TOP | Gravity.LEFT)); } - updateClipView(); + updateClipView(false); + maybeShowProximityHint(); } else if (fragmentView != null) { ((FrameLayout) fragmentView).addView(mapView, 0, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.TOP | Gravity.LEFT)); } } } + private void maybeShowProximityHint() { + if (proximityButton == null || proximityButton.getVisibility() != View.VISIBLE || proximityAnimationInProgress) { + return; + } + SharedPreferences preferences = MessagesController.getGlobalMainSettings(); + int val = preferences.getInt("proximityhint", 0); + if (val < 3) { + preferences.edit().putInt("proximityhint", ++val).commit(); + if ((int) dialogId > 0) { + TLRPC.User user = getMessagesController().getUser((int) dialogId); + hintView.setOverrideText(LocaleController.formatString("ProximityTooltioUser", R.string.ProximityTooltioUser, UserObject.getFirstName(user))); + } else { + hintView.setOverrideText(LocaleController.getString("ProximityTooltioGroup", R.string.ProximityTooltioGroup)); + } + hintView.showForView(proximityButton, true); + } + } + private void showResults() { if (adapter.getItemCount() == 0) { return; @@ -1707,7 +2071,7 @@ public class LocationActivity extends BaseFragment implements NotificationCenter listView.smoothScrollBy(0, offset); } - private void updateClipView() { + private void updateClipView(boolean fromLayout) { int height = 0; int top; RecyclerView.ViewHolder holder = listView.findViewHolderForAdapterPosition(0); @@ -1744,25 +2108,31 @@ public class LocationActivity extends BaseFragment implements NotificationCenter } float translationY = Math.min(overScrollHeight - mapTypeButton.getMeasuredHeight() - AndroidUtilities.dp(64 + (locationType == LOCATION_TYPE_SEND || locationType == LOCATION_TYPE_SEND_WITH_LIVE ? 30 : 10)), -top); mapTypeButton.setTranslationY(translationY); + proximityButton.setTranslationY(translationY); + if (hintView != null) { + hintView.setExtraTranslationY(translationY); + } if (searchAreaButton != null) { searchAreaButton.setTranslation(translationY); } if (markerImageView != null) { markerImageView.setTranslationY(markerTop = -top - AndroidUtilities.dp(markerImageView.getTag() == null ? 48 : 69) + height / 2); } - layoutParams = (FrameLayout.LayoutParams) mapView.getLayoutParams(); - if (layoutParams != null && layoutParams.height != overScrollHeight + AndroidUtilities.dp(10)) { - layoutParams.height = overScrollHeight + AndroidUtilities.dp(10); - if (mapView != null) { - mapView.setPadding(AndroidUtilities.dp(70), 0, AndroidUtilities.dp(70), AndroidUtilities.dp(10)); - } - mapView.setLayoutParams(layoutParams); - } - if (overlayView != null) { - layoutParams = (FrameLayout.LayoutParams) overlayView.getLayoutParams(); + if (!fromLayout) { + layoutParams = (FrameLayout.LayoutParams) mapView.getLayoutParams(); if (layoutParams != null && layoutParams.height != overScrollHeight + AndroidUtilities.dp(10)) { layoutParams.height = overScrollHeight + AndroidUtilities.dp(10); - overlayView.setLayoutParams(layoutParams); + if (mapView != null) { + mapView.setPadding(AndroidUtilities.dp(70), 0, AndroidUtilities.dp(70), AndroidUtilities.dp(10)); + } + mapView.setLayoutParams(layoutParams); + } + if (overlayView != null) { + layoutParams = (FrameLayout.LayoutParams) overlayView.getLayoutParams(); + if (layoutParams != null && layoutParams.height != overScrollHeight + AndroidUtilities.dp(10)) { + layoutParams.height = overScrollHeight + AndroidUtilities.dp(10); + overlayView.setLayoutParams(layoutParams); + } } } } @@ -1775,7 +2145,9 @@ public class LocationActivity extends BaseFragment implements NotificationCenter if (viewHeight == 0) { return; } - if (locationType == 2) { + if (locationType == LOCATION_TYPE_LIVE_VIEW) { + overScrollHeight = viewHeight - AndroidUtilities.dp(66) - height; + } else if (locationType == 2) { overScrollHeight = viewHeight - AndroidUtilities.dp(66 + 7) - height; } else { overScrollHeight = viewHeight - AndroidUtilities.dp(66) - height; @@ -1822,13 +2194,13 @@ public class LocationActivity extends BaseFragment implements NotificationCenter top = 0; } layoutManager.scrollToPositionWithOffset(0, -AndroidUtilities.dp(top)); - updateClipView(); + updateClipView(false); listView.post(() -> { layoutManager.scrollToPositionWithOffset(0, -AndroidUtilities.dp(top)); - updateClipView(); + updateClipView(false); }); } else { - updateClipView(); + updateClipView(false); } } } @@ -1858,7 +2230,11 @@ public class LocationActivity extends BaseFragment implements NotificationCenter LiveLocation liveLocation = markersMap.get(getUserConfig().getClientUserId()); LocationController.SharingLocationInfo myInfo = getLocationController().getSharingLocationInfo(dialogId); if (liveLocation != null && myInfo != null && liveLocation.object.id == myInfo.mid) { - liveLocation.marker.setPosition(new GeoPoint(location.getLatitude(), location.getLongitude())); + GeoPoint latLng = new GeoPoint(location.getLatitude(), location.getLongitude()); + liveLocation.marker.setPosition(latLng); + if (liveLocation.directionMarker != null) { + liveLocation.directionMarker.setPosition(latLng); + } } if (messageObject == null && chatLocation == null && mapView != null) { GeoPoint latLng = new GeoPoint(location.getLatitude(), location.getLongitude()); @@ -1883,6 +2259,13 @@ public class LocationActivity extends BaseFragment implements NotificationCenter } else { adapter.setGpsLocation(myLocation); } + if (proximitySheet != null) { + proximitySheet.updateText(true, true); + } + if (proximityCircle != null) { + proximityCircleCenter = new GeoPoint(myLocation.getLatitude(), myLocation.getLongitude()); + proximityCircle.setPoints(Polygon.pointsAsCircle(proximityCircleCenter, proximityCircleRadius)); + } } public void setMessageObject(MessageObject message) { @@ -1926,25 +2309,34 @@ public class LocationActivity extends BaseFragment implements NotificationCenter private void fetchRecentLocations(ArrayList messages) { BoundingBox builder = null; - List GeoPoints = new ArrayList<>(); - if (firstFocus) { - builder = null; - } + List geoPoints = new ArrayList<>(); int date = getConnectionsManager().getCurrentTime(); for (int a = 0; a < messages.size(); a++) { TLRPC.Message message = messages.get(a); if (message.date + message.media.period > date) { - if (builder != null) { + if (firstFocus) { GeoPoint latLng = new GeoPoint(message.media.geo.lat, message.media.geo._long); - GeoPoints.add(latLng); + geoPoints.add(latLng); } addUserMarker(message); + if (proximityButton.getVisibility() != View.GONE && MessageObject.getFromChatId(message) != getUserConfig().getClientUserId()) { + proximityButton.setVisibility(View.VISIBLE); + proximityAnimationInProgress = true; + proximityButton.animate().alpha(1.0f).scaleX(1.0f).scaleY(1.0f).setDuration(180).setListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + proximityAnimationInProgress = false; + maybeShowProximityHint(); + } + }).start(); + } } } - if (GeoPoints.size()>0) { - builder = BoundingBox.fromGeoPoints(GeoPoints); + if (geoPoints.size() > 0) { + builder = BoundingBox.fromGeoPoints(geoPoints); } if (firstFocus) { + listView.smoothScrollBy(0, AndroidUtilities.dp(66 * 1.5f)); firstFocus = false; adapter.setLiveLocations(markers); if (messageObject.isLiveLocation()) { @@ -1953,15 +2345,17 @@ public class LocationActivity extends BaseFragment implements NotificationCenter GeoPoint center = bounds.getCenterWithDateLine(); //TODO check GeoPoint northEast = move(center, 100, 100); GeoPoint southWest = move(center, -100, -100); - GeoPoints.add(southWest); - GeoPoints.add(northEast); - if (GeoPoints.size()>0) { - builder = BoundingBox.fromGeoPoints(GeoPoints); + geoPoints.add(southWest); + geoPoints.add(northEast); + if (geoPoints.size() > 0) { + builder = BoundingBox.fromGeoPoints(geoPoints); } bounds = builder; if (messages.size() > 1) { try { - mapView.zoomToBoundingBox(bounds, false,AndroidUtilities.dp(60)); + moveToBounds = bounds; + mapView.zoomToBoundingBox(bounds, false, AndroidUtilities.dp(80 + 33)); + moveToBounds = null; } catch (Exception e) { FileLog.e(e); } @@ -1973,6 +2367,72 @@ public class LocationActivity extends BaseFragment implements NotificationCenter } } + private void moveToBounds(int radius, boolean self, boolean animated) { + BoundingBox builder = null; + List geoPoints = new ArrayList<>(); + geoPoints.add(new GeoPoint(myLocation.getLatitude(), myLocation.getLongitude())); + if (geoPoints.size() > 0) { + builder = BoundingBox.fromGeoPoints(geoPoints); + } + if (self) { + try { + BoundingBox bounds = builder; + GeoPoint center = bounds.getCenterWithDateLine(); //TODO check + GeoPoint northEast = move(center, 100, 100); + GeoPoint southWest = move(center, -100, -100); + geoPoints.add(southWest); + geoPoints.add(northEast); + if (geoPoints.size() > 0) { + builder = BoundingBox.fromGeoPoints(geoPoints); + } + bounds = builder; + try { + int height = (int) (proximitySheet.getCustomView().getMeasuredHeight() - AndroidUtilities.dp(40) + mapViewClip.getTranslationY()); + mapView.setPadding(AndroidUtilities.dp(70), 0, AndroidUtilities.dp(70), height); + if (animated) { + mapView.zoomToBoundingBox(bounds, true, AndroidUtilities.dp(60), mapView.getMaxZoomLevel(), 500L); + } else { + mapView.zoomToBoundingBox(bounds, false, AndroidUtilities.dp(60)); + } + } catch (Exception e) { + FileLog.e(e); + } + } catch (Exception ignore) { + + } + } else { + int date = getConnectionsManager().getCurrentTime(); + for (int a = 0, N = markers.size(); a < N; a++) { + TLRPC.Message message = markers.get(a).object; + if (message.date + message.media.period > date) { + GeoPoint latLng = new GeoPoint(message.media.geo.lat, message.media.geo._long); + geoPoints.add(latLng); + } + } + try { + BoundingBox bounds = builder; + GeoPoint center = bounds.getCenterWithDateLine(); //TODO check + GeoPoint northEast = move(center, 100, 100); + GeoPoint southWest = move(center, -100, -100); + geoPoints.add(southWest); + geoPoints.add(northEast); + if (geoPoints.size() > 0) { + builder = BoundingBox.fromGeoPoints(geoPoints); + } + bounds = builder; + try { + int height = proximitySheet.getCustomView().getMeasuredHeight() - AndroidUtilities.dp(100); + mapView.setPadding(AndroidUtilities.dp(70), 0, AndroidUtilities.dp(70), height); + mapView.zoomToBoundingBox(bounds, false, AndroidUtilities.dp(60)); + } catch (Exception e) { + FileLog.e(e); + } + } catch (Exception ignore) { + + } + } + } + private boolean getRecentLocations() { ArrayList messages = getLocationController().locationsCache.get(messageObject.getDialogId()); if (messages != null && messages.isEmpty()) { @@ -2027,6 +2487,24 @@ public class LocationActivity extends BaseFragment implements NotificationCenter return messages != null; } + private double bearingBetweenLocations(GeoPoint latLng1, GeoPoint latLng2) { + double lat1 = latLng1.getLatitude() * Math.PI / 180; + double long1 = latLng1.getLongitude() * Math.PI / 180; + double lat2 = latLng2.getLatitude() * Math.PI / 180; + double long2 = latLng2.getLongitude() * Math.PI / 180; + double dLon = (long2 - long1); + + double y = Math.sin(dLon) * Math.cos(lat2); + double x = Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(dLon); + + double brng = Math.atan2(y, x); + + brng = Math.toDegrees(brng); + brng = (brng + 360) % 360; + + return brng; + } + @SuppressWarnings("unchecked") @Override public void didReceivedNotification(int id, int account, Object... args) { @@ -2036,6 +2514,10 @@ public class LocationActivity extends BaseFragment implements NotificationCenter if (mapView != null && mapsInitialized) { myLocationOverlay.enableMyLocation(); } + } else if (id == NotificationCenter.liveLocationsChanged) { + if (adapter != null) { + adapter.updateLiveLocationCell(); + } } else if (id == NotificationCenter.didReceiveNewMessages) { boolean scheduled = (Boolean) args[2]; if (scheduled) { @@ -2052,6 +2534,15 @@ public class LocationActivity extends BaseFragment implements NotificationCenter if (messageObject.isLiveLocation()) { addUserMarker(messageObject.messageOwner); added = true; + } else if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionGeoProximityReached) { + int lowerId = (int) messageObject.getDialogId(); + if (lowerId > 0) { + proximityButton.setImageResource(R.drawable.msg_location_alert); + if (proximityCircle != null) { + mapView.getOverlayManager().remove(proximityCircle); + proximityCircle = null; + } + } } } if (added && adapter != null) { @@ -2074,13 +2565,34 @@ public class LocationActivity extends BaseFragment implements NotificationCenter LocationController.SharingLocationInfo myInfo = getLocationController().getSharingLocationInfo(did); if (myInfo == null || myInfo.mid != messageObject.getId()) { liveLocation.object = messageObject.messageOwner; - liveLocation.marker.setPosition(new GeoPoint(messageObject.messageOwner.media.geo.lat, messageObject.messageOwner.media.geo._long)); + GeoPoint latLng = new GeoPoint(messageObject.messageOwner.media.geo.lat, messageObject.messageOwner.media.geo._long); + liveLocation.marker.setPosition(latLng); + if (liveLocation.directionMarker != null) { + GeoPoint oldLocation = liveLocation.directionMarker.getPosition(); + liveLocation.directionMarker.setPosition(latLng); + if (messageObject.messageOwner.media.heading != 0) { + liveLocation.directionMarker.setRotation(messageObject.messageOwner.media.heading); + if (!liveLocation.hasRotation) { + liveLocation.directionMarker.setIcon(getParentActivity().getResources().getDrawable(R.drawable.map_pin_cone2)); + liveLocation.hasRotation = true; + } + } else { + if (liveLocation.hasRotation) { + liveLocation.directionMarker.setRotation(0); + liveLocation.directionMarker.setIcon(getParentActivity().getResources().getDrawable(R.drawable.map_pin_circle)); + liveLocation.hasRotation = false; + } + } + } } updated = true; } } if (updated && adapter != null) { adapter.updateLiveLocations(); + if (proximitySheet != null) { + proximitySheet.updateText(true, true); + } } } } @@ -2094,14 +2606,33 @@ public class LocationActivity extends BaseFragment implements NotificationCenter } catch (Exception e) { FileLog.e(e); } - if(mapView.getOverlays().contains(myLocationOverlay)) { + if (mapView.getOverlays().contains(myLocationOverlay)) { mapView.getOverlays().remove(myLocationOverlay); } myLocationOverlay.disableMyLocation(); } + if (undoView[0] != null) { + undoView[0].hide(true, 0); + } onResumeCalled = false; } + @Override + public boolean onBackPressed() { + if (proximitySheet != null) { + proximitySheet.dismiss(); + return false; + } + return super.onBackPressed(); + } + + @Override + protected void onBecomeFullyHidden() { + if (undoView[0] != null) { + undoView[0].hide(true, 0); + } + } + @Override public void onResume() { super.onResume(); @@ -2133,6 +2664,13 @@ public class LocationActivity extends BaseFragment implements NotificationCenter } } + @Override + public void onRequestPermissionsResultFragment(int requestCode, String[] permissions, int[] grantResults) { + if (requestCode == 30) { + openShareLiveLocation(askWithRadius); + } + } + public void setDelegate(LocationActivityDelegate delegate) { this.delegate = delegate; } @@ -2157,7 +2695,7 @@ public class LocationActivity extends BaseFragment implements NotificationCenter mapTypeButton.setPopupItemsColor(Theme.getColor(Theme.key_actionBarDefaultSubmenuItemIcon), true); mapTypeButton.setPopupItemsColor(Theme.getColor(Theme.key_actionBarDefaultSubmenuItem), false); - shadowDrawable.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_dialogBackground), PorterDuff.Mode.SRC_IN)); + shadowDrawable.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_dialogBackground), PorterDuff.Mode.MULTIPLY)); shadow.invalidate(); if (mapView != null) { @@ -2165,16 +2703,43 @@ public class LocationActivity extends BaseFragment implements NotificationCenter if (!currentMapStyleDark) { currentMapStyleDark = true; // TODO dark + if (proximityCircle != null) { + proximityCircle.getOutlinePaint().setColor(0xffffffff); + proximityCircle.getFillPaint().setColor(0x20ffffff); + } } } else { if (currentMapStyleDark) { currentMapStyleDark = false; // TODO dark + if (proximityCircle != null) { + proximityCircle.getOutlinePaint().setColor(0xff000000); + proximityCircle.getFillPaint().setColor(0x20000000); + } } } } }; + for (int a = 0; a < undoView.length; a++) { + themeDescriptions.add(new ThemeDescription(undoView[a], ThemeDescription.FLAG_BACKGROUNDFILTER, null, null, null, null, Theme.key_undo_background)); + themeDescriptions.add(new ThemeDescription(undoView[a], 0, new Class[]{UndoView.class}, new String[]{"undoImageView"}, null, null, null, Theme.key_undo_cancelColor)); + themeDescriptions.add(new ThemeDescription(undoView[a], 0, new Class[]{UndoView.class}, new String[]{"undoTextView"}, null, null, null, Theme.key_undo_cancelColor)); + themeDescriptions.add(new ThemeDescription(undoView[a], 0, new Class[]{UndoView.class}, new String[]{"infoTextView"}, null, null, null, Theme.key_undo_infoColor)); + themeDescriptions.add(new ThemeDescription(undoView[a], 0, new Class[]{UndoView.class}, new String[]{"subinfoTextView"}, null, null, null, Theme.key_undo_infoColor)); + themeDescriptions.add(new ThemeDescription(undoView[a], 0, new Class[]{UndoView.class}, new String[]{"textPaint"}, null, null, null, Theme.key_undo_infoColor)); + themeDescriptions.add(new ThemeDescription(undoView[a], 0, new Class[]{UndoView.class}, new String[]{"progressPaint"}, null, null, null, Theme.key_undo_infoColor)); + themeDescriptions.add(new ThemeDescription(undoView[a], 0, new Class[]{UndoView.class}, new String[]{"leftImageView"}, "BODY", Theme.key_undo_background)); + themeDescriptions.add(new ThemeDescription(undoView[a], 0, new Class[]{UndoView.class}, new String[]{"leftImageView"}, "Wibe Big", Theme.key_undo_background)); + themeDescriptions.add(new ThemeDescription(undoView[a], 0, new Class[]{UndoView.class}, new String[]{"leftImageView"}, "Wibe Big 3", Theme.key_undo_infoColor)); + themeDescriptions.add(new ThemeDescription(undoView[a], 0, new Class[]{UndoView.class}, new String[]{"leftImageView"}, "Wibe Small", Theme.key_undo_infoColor)); + themeDescriptions.add(new ThemeDescription(undoView[a], 0, new Class[]{UndoView.class}, new String[]{"leftImageView"}, "Body Main.**", Theme.key_undo_infoColor)); + themeDescriptions.add(new ThemeDescription(undoView[a], 0, new Class[]{UndoView.class}, new String[]{"leftImageView"}, "Body Top.**", Theme.key_undo_infoColor)); + themeDescriptions.add(new ThemeDescription(undoView[a], 0, new Class[]{UndoView.class}, new String[]{"leftImageView"}, "Line.**", Theme.key_undo_infoColor)); + themeDescriptions.add(new ThemeDescription(undoView[a], 0, new Class[]{UndoView.class}, new String[]{"leftImageView"}, "Curve Big.**", Theme.key_undo_infoColor)); + themeDescriptions.add(new ThemeDescription(undoView[a], 0, new Class[]{UndoView.class}, new String[]{"leftImageView"}, "Curve Small.**", Theme.key_undo_infoColor)); + } + themeDescriptions.add(new ThemeDescription(fragmentView, ThemeDescription.FLAG_BACKGROUND, null, null, null, cellDelegate, Theme.key_dialogBackground)); themeDescriptions.add(new ThemeDescription(actionBar, ThemeDescription.FLAG_BACKGROUND, null, null, null, null, Theme.key_dialogBackground)); @@ -2207,6 +2772,10 @@ public class LocationActivity extends BaseFragment implements NotificationCenter themeDescriptions.add(new ThemeDescription(mapTypeButton, ThemeDescription.FLAG_BACKGROUNDFILTER, null, null, null, null, Theme.key_location_actionBackground)); themeDescriptions.add(new ThemeDescription(mapTypeButton, ThemeDescription.FLAG_BACKGROUNDFILTER | ThemeDescription.FLAG_DRAWABLESELECTEDSTATE, null, null, null, null, Theme.key_location_actionPressedBackground)); + themeDescriptions.add(new ThemeDescription(proximityButton, 0, null, null, null, cellDelegate, Theme.key_location_actionIcon)); + themeDescriptions.add(new ThemeDescription(proximityButton, ThemeDescription.FLAG_BACKGROUNDFILTER, null, null, null, null, Theme.key_location_actionBackground)); + themeDescriptions.add(new ThemeDescription(proximityButton, ThemeDescription.FLAG_BACKGROUNDFILTER | ThemeDescription.FLAG_DRAWABLESELECTEDSTATE, null, null, null, null, Theme.key_location_actionPressedBackground)); + themeDescriptions.add(new ThemeDescription(searchAreaButton, ThemeDescription.FLAG_TEXTCOLOR, null, null, null, null, Theme.key_location_actionActiveIcon)); themeDescriptions.add(new ThemeDescription(searchAreaButton, ThemeDescription.FLAG_BACKGROUNDFILTER, null, null, null, null, Theme.key_location_actionBackground)); themeDescriptions.add(new ThemeDescription(searchAreaButton, ThemeDescription.FLAG_BACKGROUNDFILTER | ThemeDescription.FLAG_DRAWABLESELECTEDSTATE, null, null, null, null, Theme.key_location_actionPressedBackground)); diff --git a/bin/update_libs.sh b/bin/update_libs.sh index 414aa2417..9891f4962 100755 --- a/bin/update_libs.sh +++ b/bin/update_libs.sh @@ -1,6 +1,6 @@ #!/bin/bash -V2RAY_CORE_VERSION="4.31.3" +V2RAY_CORE_VERSION="4.32.0" if [ ! -x "$(command -v go)" ]; then