diff --git a/TMessagesProj/build.gradle b/TMessagesProj/build.gradle index cfe49741c..d0519d455 100644 --- a/TMessagesProj/build.gradle +++ b/TMessagesProj/build.gradle @@ -22,7 +22,7 @@ dependencies { compileOnly 'org.checkerframework:checker-qual:2.5.2' compileOnly 'org.checkerframework:checker-compat-qual:2.5.0' implementation 'com.google.firebase:firebase-messaging:20.1.0' - implementation 'com.google.firebase:firebase-config:19.1.0' + implementation 'com.google.firebase:firebase-config:19.1.1' implementation 'com.google.android.gms:play-services-maps:17.0.0' implementation 'com.google.android.gms:play-services-auth:17.0.0' implementation 'com.google.android.gms:play-services-vision:16.2.0' @@ -283,7 +283,7 @@ android { } } - defaultConfig.versionCode = 1851 + defaultConfig.versionCode = 1864 applicationVariants.all { variant -> variant.outputs.all { output -> @@ -318,7 +318,7 @@ android { defaultConfig { minSdkVersion 16 targetSdkVersion 28 - versionName "5.14.0" + versionName "5.15.0" vectorDrawables.generatedDensities = ['mdpi', 'hdpi', 'xhdpi', 'xxhdpi'] diff --git a/TMessagesProj/jni/tgnet/ConnectionsManager.cpp b/TMessagesProj/jni/tgnet/ConnectionsManager.cpp index 57d2d77d0..cae167d4c 100644 --- a/TMessagesProj/jni/tgnet/ConnectionsManager.cpp +++ b/TMessagesProj/jni/tgnet/ConnectionsManager.cpp @@ -3301,18 +3301,29 @@ void ConnectionsManager::setSystemLangCode(std::string langCode) { void ConnectionsManager::resumeNetwork(bool partial) { scheduleTask([&, partial] { + if (lastMonotonicPauseTime != 0) { + int64_t diff = (getCurrentTimeMonotonicMillis() - lastMonotonicPauseTime) / 1000; + int64_t systemDiff = getCurrentTime() - lastSystemPauseTime; + if (systemDiff < 0 || abs(systemDiff - diff) > 2) { + timeDifference -= (systemDiff - diff); + } + } if (partial) { if (networkPaused) { - lastPauseTime = getCurrentTimeMonotonicMillis(); + lastMonotonicPauseTime = lastPauseTime = getCurrentTimeMonotonicMillis(); + lastSystemPauseTime = getCurrentTime(); networkPaused = false; if (LOGS_ENABLED) DEBUG_D("wakeup network in background account%u", instanceNum); } else if (lastPauseTime != 0) { - lastPauseTime = getCurrentTimeMonotonicMillis(); + lastMonotonicPauseTime = lastPauseTime = getCurrentTimeMonotonicMillis(); + lastSystemPauseTime = getCurrentTime(); networkPaused = false; if (LOGS_ENABLED) DEBUG_D("reset sleep timeout account%u", instanceNum); } } else { lastPauseTime = 0; + lastMonotonicPauseTime = 0; + lastSystemPauseTime = 0; networkPaused = false; if (LOGS_ENABLED) DEBUG_D("wakeup network account%u", instanceNum); } @@ -3332,7 +3343,8 @@ void ConnectionsManager::pauseNetwork() { if (lastPauseTime != 0) { return; } - lastPauseTime = getCurrentTimeMonotonicMillis(); + lastMonotonicPauseTime = lastPauseTime = getCurrentTimeMonotonicMillis(); + lastSystemPauseTime = getCurrentTime(); } void ConnectionsManager::setNetworkAvailable(bool value, int32_t type, bool slow) { diff --git a/TMessagesProj/jni/tgnet/ConnectionsManager.h b/TMessagesProj/jni/tgnet/ConnectionsManager.h index 7d3724e86..3dc6618c0 100644 --- a/TMessagesProj/jni/tgnet/ConnectionsManager.h +++ b/TMessagesProj/jni/tgnet/ConnectionsManager.h @@ -161,6 +161,8 @@ private: bool networkPaused = false; int32_t nextSleepTimeout = CONNECTION_BACKGROUND_KEEP_TIME; int64_t lastPauseTime = 0; + int64_t lastMonotonicPauseTime = 0; + int32_t lastSystemPauseTime = 0; ConnectionState connectionState = ConnectionStateConnecting; std::unique_ptr movingAuthorization; std::vector sessionsToDestroy; diff --git a/TMessagesProj/src/main/java/androidx/recyclerview/widget/LinearSmoothScrollerMiddle.java b/TMessagesProj/src/main/java/androidx/recyclerview/widget/LinearSmoothScrollerCustom.java similarity index 88% rename from TMessagesProj/src/main/java/androidx/recyclerview/widget/LinearSmoothScrollerMiddle.java rename to TMessagesProj/src/main/java/androidx/recyclerview/widget/LinearSmoothScrollerCustom.java index 9cb8c19f9..50b9ab759 100644 --- a/TMessagesProj/src/main/java/androidx/recyclerview/widget/LinearSmoothScrollerMiddle.java +++ b/TMessagesProj/src/main/java/androidx/recyclerview/widget/LinearSmoothScrollerCustom.java @@ -15,7 +15,9 @@ import android.view.View; import android.view.animation.DecelerateInterpolator; import android.view.animation.LinearInterpolator; -public class LinearSmoothScrollerMiddle extends RecyclerView.SmoothScroller { +import org.telegram.messenger.AndroidUtilities; + +public class LinearSmoothScrollerCustom extends RecyclerView.SmoothScroller { private static final float MILLISECONDS_PER_INCH = 25f; @@ -32,9 +34,14 @@ public class LinearSmoothScrollerMiddle extends RecyclerView.SmoothScroller { private final float MILLISECONDS_PER_PX; protected int mInterimTargetDx = 0, mInterimTargetDy = 0; + private int scrollPosition; - public LinearSmoothScrollerMiddle(Context context) { + public static final int POSITION_MIDDLE = 0; + public static final int POSITION_END = 1; + + public LinearSmoothScrollerCustom(Context context, int position) { MILLISECONDS_PER_PX = MILLISECONDS_PER_INCH / context.getResources().getDisplayMetrics().densityDpi; + scrollPosition = position; } @Override @@ -80,7 +87,6 @@ public class LinearSmoothScrollerMiddle extends RecyclerView.SmoothScroller { } protected void updateActionForInterimTarget(Action action) { - // find an interim target position PointF scrollVector = computeScrollVectorForPosition(getTargetPosition()); if (scrollVector == null || (scrollVector.x == 0 && scrollVector.y == 0)) { final int target = getTargetPosition(); @@ -94,12 +100,7 @@ public class LinearSmoothScrollerMiddle extends RecyclerView.SmoothScroller { mInterimTargetDx = (int) (TARGET_SEEK_SCROLL_DISTANCE_PX * scrollVector.x); mInterimTargetDy = (int) (TARGET_SEEK_SCROLL_DISTANCE_PX * scrollVector.y); final int time = calculateTimeForScrolling(TARGET_SEEK_SCROLL_DISTANCE_PX); - // To avoid UI hiccups, trigger a smooth scroll to a distance little further than the - // interim target. Since we track the distance travelled in onSeekTargetStep callback, it - // won't actually scroll more than what we need. - action.update((int) (mInterimTargetDx * TARGET_SEEK_EXTRA_SCROLL_RATIO) - , (int) (mInterimTargetDy * TARGET_SEEK_EXTRA_SCROLL_RATIO) - , (int) (time * TARGET_SEEK_EXTRA_SCROLL_RATIO), mLinearInterpolator); + action.update((int) (mInterimTargetDx * TARGET_SEEK_EXTRA_SCROLL_RATIO), (int) (mInterimTargetDy * TARGET_SEEK_EXTRA_SCROLL_RATIO), (int) (time * TARGET_SEEK_EXTRA_SCROLL_RATIO), mLinearInterpolator); } private int clampApplyScroll(int tmpDt, int dt) { @@ -126,8 +127,10 @@ public class LinearSmoothScrollerMiddle extends RecyclerView.SmoothScroller { int viewSize = bottom - top; if (viewSize > boxSize) { start = 0; - } else { + } else if (scrollPosition == POSITION_MIDDLE) { start = (boxSize - viewSize) / 2; + } else { + start = (layoutManager.getPaddingTop() - AndroidUtilities.dp(88)); } end = start + viewSize; final int dtStart = start - top; diff --git a/TMessagesProj/src/main/java/androidx/recyclerview/widget/RecyclerView.java b/TMessagesProj/src/main/java/androidx/recyclerview/widget/RecyclerView.java index 6c576c4a5..5ff2a594b 100644 --- a/TMessagesProj/src/main/java/androidx/recyclerview/widget/RecyclerView.java +++ b/TMessagesProj/src/main/java/androidx/recyclerview/widget/RecyclerView.java @@ -575,7 +575,7 @@ public class RecyclerView extends ViewGroup implements ScrollingView, private int topGlowOffset = 0; private int bottomGlowOffset = 0; - private int glowColor = 0; + private Integer glowColor = null; public void setTopGlowOffset(int offset) { topGlowOffset = offset; @@ -620,7 +620,7 @@ public class RecyclerView extends ViewGroup implements ScrollingView, } void applyEdgeEffectColor(EdgeEffect edgeEffect) { - if (edgeEffect != null && Build.VERSION.SDK_INT >= 21 && glowColor != 0) { + if (edgeEffect != null && Build.VERSION.SDK_INT >= 21 && glowColor != null) { edgeEffect.setColor(glowColor); } } @@ -4362,42 +4362,44 @@ public class RecyclerView extends ViewGroup implements ScrollingView, // TODO If padding is not 0 and clipChildrenToPadding is false, to draw glows properly, we // need find children closest to edges. Not sure if it is worth the effort. boolean needsInvalidate = false; - if (mLeftGlow != null && !mLeftGlow.isFinished()) { - final int restore = c.save(); - final int padding = mClipToPadding ? getPaddingBottom() : 0; - c.rotate(270); - c.translate(-getHeight() + padding, 0); - needsInvalidate = mLeftGlow != null && mLeftGlow.draw(c); - c.restoreToCount(restore); - } - if (mTopGlow != null && !mTopGlow.isFinished()) { - final int restore = c.save(); - if (mClipToPadding) { - c.translate(getPaddingLeft(), getPaddingTop()); + if (glowColor == null || glowColor != 0) { + if (mLeftGlow != null && !mLeftGlow.isFinished()) { + final int restore = c.save(); + final int padding = mClipToPadding ? getPaddingBottom() : 0; + c.rotate(270); + c.translate(-getHeight() + padding, 0); + needsInvalidate = mLeftGlow != null && mLeftGlow.draw(c); + c.restoreToCount(restore); } - c.translate(0, topGlowOffset); - needsInvalidate |= mTopGlow != null && mTopGlow.draw(c); - c.restoreToCount(restore); - } - if (mRightGlow != null && !mRightGlow.isFinished()) { - final int restore = c.save(); - final int width = getWidth(); - final int padding = mClipToPadding ? getPaddingTop() : 0; - c.rotate(90); - c.translate(-padding, -width); - needsInvalidate |= mRightGlow != null && mRightGlow.draw(c); - c.restoreToCount(restore); - } - if (mBottomGlow != null && !mBottomGlow.isFinished()) { - final int restore = c.save(); - c.rotate(180); - if (mClipToPadding) { - c.translate(-getWidth() + getPaddingRight(), -getHeight() + getPaddingBottom()); - } else { - c.translate(-getWidth(), -getHeight() + bottomGlowOffset); + if (mTopGlow != null && !mTopGlow.isFinished()) { + final int restore = c.save(); + if (mClipToPadding) { + c.translate(getPaddingLeft(), getPaddingTop()); + } + c.translate(0, topGlowOffset); + needsInvalidate |= mTopGlow != null && mTopGlow.draw(c); + c.restoreToCount(restore); + } + if (mRightGlow != null && !mRightGlow.isFinished()) { + final int restore = c.save(); + final int width = getWidth(); + final int padding = mClipToPadding ? getPaddingTop() : 0; + c.rotate(90); + c.translate(-padding, -width); + needsInvalidate |= mRightGlow != null && mRightGlow.draw(c); + c.restoreToCount(restore); + } + if (mBottomGlow != null && !mBottomGlow.isFinished()) { + final int restore = c.save(); + c.rotate(180); + if (mClipToPadding) { + c.translate(-getWidth() + getPaddingRight(), -getHeight() + getPaddingBottom()); + } else { + c.translate(-getWidth(), -getHeight() + bottomGlowOffset); + } + needsInvalidate |= mBottomGlow != null && mBottomGlow.draw(c); + c.restoreToCount(restore); } - needsInvalidate |= mBottomGlow != null && mBottomGlow.draw(c); - c.restoreToCount(restore); } // If some views are animating, ItemDecorators are likely to move/change with them. diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/AndroidUtilities.java b/TMessagesProj/src/main/java/org/telegram/messenger/AndroidUtilities.java index 0918efbf0..6df984b08 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/AndroidUtilities.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/AndroidUtilities.java @@ -395,21 +395,29 @@ public class AndroidUtilities { return media ? documentMediaIcons[0] : documentIcons[0]; } + public static int calcBitmapColor(Bitmap bitmap) { + try { + Bitmap b = Bitmaps.createScaledBitmap(bitmap, 1, 1, true); + if (b != null) { + int bitmapColor = b.getPixel(0, 0); + if (bitmap != b) { + b.recycle(); + } + return bitmapColor; + } + } catch (Exception e) { + FileLog.e(e); + } + return 0; + } + public static int[] calcDrawableColor(Drawable drawable) { int bitmapColor = 0xff000000; int[] result = new int[4]; try { if (drawable instanceof BitmapDrawable) { Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap(); - if (bitmap != null) { - Bitmap b = Bitmaps.createScaledBitmap(bitmap, 1, 1, true); - if (b != null) { - bitmapColor = b.getPixel(0, 0); - if (bitmap != b) { - b.recycle(); - } - } - } + bitmapColor = calcBitmapColor(bitmap); } else if (drawable instanceof ColorDrawable) { bitmapColor = ((ColorDrawable) drawable).getColor(); } else if (drawable instanceof BackgroundGradientDrawable) { @@ -516,7 +524,7 @@ public class AndroidUtilities { } public static void requestAdjustResize(Activity activity, int classGuid) { - if (activity == null || isTablet()) { + if (activity == null || isTablet() || SharedConfig.smoothKeyboard) { return; } activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); @@ -533,7 +541,7 @@ public class AndroidUtilities { } public static void removeAdjustResize(Activity activity, int classGuid) { - if (activity == null || isTablet()) { + if (activity == null || isTablet() || SharedConfig.smoothKeyboard) { return; } if (adjustOwnerClassGuid == classGuid) { diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/BuildVars.java b/TMessagesProj/src/main/java/org/telegram/messenger/BuildVars.java index caf8b9e15..f03846dd6 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/BuildVars.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/BuildVars.java @@ -19,8 +19,8 @@ public class BuildVars { public static boolean USE_CLOUD_STRINGS = true; public static boolean CHECK_UPDATES = true; public static boolean TON_WALLET_STANDALONE = false; - public static int BUILD_VERSION = 1851; - public static String BUILD_VERSION_STRING = "5.14.0"; + public static int BUILD_VERSION = 1864; + public static String BUILD_VERSION_STRING = "5.15.0"; public static int APP_ID = 4; public static String APP_HASH = "014b35b6184100b085b0d0572f9b5103"; public static String HOCKEY_APP_HASH = "a5b5c4f551dadedc9918d9766a22ca7c"; diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/EmojiData.java b/TMessagesProj/src/main/java/org/telegram/messenger/EmojiData.java index 0dc20fc61..bee8c32a6 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/EmojiData.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/EmojiData.java @@ -793,6 +793,10 @@ public class EmojiData { public static final HashSet emojiBigColoredMap = new HashSet<>(emojiBigColored.length); public static final HashMap emojiAliasMap = new HashMap<>(aliasNew.length); + public static boolean isHeartEmoji(String emoji) { + return "❤".equals(emoji) || "🧡".equals(emoji) || "💛".equals(emoji) || "💚".equals(emoji) || "💙".equals(emoji) || "💜".equals(emoji) || "🖤".equals(emoji) || "🤍".equals(emoji) || "🤎".equals(emoji); + } + static { for (int a = 0; a < emojiToFE0F.length; a++) { emojiToFE0FMap.put(emojiToFE0F[a], true); diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/LocaleController.java b/TMessagesProj/src/main/java/org/telegram/messenger/LocaleController.java index e8239a396..4c416e035 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/LocaleController.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/LocaleController.java @@ -2661,7 +2661,7 @@ public class LocaleController { public int quantityForNumber(int count) { if (count == 0) { return QUANTITY_ZERO; - } else if (count > 0 && count < 2) { + } else if (count == 1) { return QUANTITY_ONE; } else { return QUANTITY_OTHER; diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/LocationController.java b/TMessagesProj/src/main/java/org/telegram/messenger/LocationController.java index f64567145..a69befd7c 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/LocationController.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/LocationController.java @@ -64,6 +64,7 @@ public class LocationController extends BaseController implements NotificationCe private SparseIntArray requests = new SparseIntArray(); private LongSparseArray cacheRequests = new LongSparseArray<>(); private long locationEndWatchTime; + private boolean shareMyCurrentLocation; private boolean lookingForPeopleNearby; @@ -316,7 +317,7 @@ public class LocationController extends BaseController implements NotificationCe if (!permissionsGranted) { playServicesAvailable = false; } - if (lookingForPeopleNearby || !sharingLocations.isEmpty()) { + if (shareMyCurrentLocation || lookingForPeopleNearby || !sharingLocations.isEmpty()) { if (permissionsGranted) { try { setLastKnownLocation(LocationServices.FusedLocationApi.getLastLocation(googleApiClient)); @@ -369,69 +370,86 @@ public class LocationController extends BaseController implements NotificationCe } requests.clear(); } - int date = getConnectionsManager().getCurrentTime(); - float[] result = new float[1]; - for (int a = 0; a < sharingLocations.size(); a++) { - final SharingLocationInfo info = sharingLocations.get(a); - if (info.messageObject.messageOwner.media != null && info.messageObject.messageOwner.media.geo != null) { - int messageDate = info.messageObject.messageOwner.edit_date != 0 ? info.messageObject.messageOwner.edit_date : info.messageObject.messageOwner.date; - TLRPC.GeoPoint point = info.messageObject.messageOwner.media.geo; - if (Math.abs(date - messageDate) < 10) { - Location.distanceBetween(point.lat, point._long, lastKnownLocation.getLatitude(), lastKnownLocation.getLongitude(), result); - if (result[0] < 1.0f) { - continue; + if (!sharingLocations.isEmpty()) { + int date = getConnectionsManager().getCurrentTime(); + float[] result = new float[1]; + for (int a = 0; a < sharingLocations.size(); a++) { + final SharingLocationInfo info = sharingLocations.get(a); + if (info.messageObject.messageOwner.media != null && info.messageObject.messageOwner.media.geo != null) { + int messageDate = info.messageObject.messageOwner.edit_date != 0 ? info.messageObject.messageOwner.edit_date : info.messageObject.messageOwner.date; + TLRPC.GeoPoint point = info.messageObject.messageOwner.media.geo; + if (Math.abs(date - messageDate) < 10) { + Location.distanceBetween(point.lat, point._long, lastKnownLocation.getLatitude(), lastKnownLocation.getLongitude(), result); + if (result[0] < 1.0f) { + continue; + } } } + TLRPC.TL_messages_editMessage req = new TLRPC.TL_messages_editMessage(); + req.peer = getMessagesController().getInputPeer((int) info.did); + req.id = info.mid; + req.flags |= 16384; + req.media = new TLRPC.TL_inputMediaGeoLive(); + req.media.stopped = false; + req.media.geo_point = new TLRPC.TL_inputGeoPoint(); + req.media.geo_point.lat = AndroidUtilities.fixLocationCoord(lastKnownLocation.getLatitude()); + req.media.geo_point._long = AndroidUtilities.fixLocationCoord(lastKnownLocation.getLongitude()); + final int[] reqId = new int[1]; + reqId[0] = getConnectionsManager().sendRequest(req, (response, error) -> { + if (error != null) { + if (error.text.equals("MESSAGE_ID_INVALID")) { + sharingLocations.remove(info); + sharingLocationsMap.remove(info.did); + saveSharingLocation(info, 1); + requests.delete(reqId[0]); + AndroidUtilities.runOnUIThread(() -> { + sharingLocationsUI.remove(info); + sharingLocationsMapUI.remove(info.did); + if (sharingLocationsUI.isEmpty()) { + stopService(); + } + NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.liveLocationsChanged); + }); + } + return; + } + TLRPC.Updates updates = (TLRPC.Updates) response; + boolean updated = false; + for (int a1 = 0; a1 < updates.updates.size(); a1++) { + TLRPC.Update update = updates.updates.get(a1); + if (update instanceof TLRPC.TL_updateEditMessage) { + updated = true; + info.messageObject.messageOwner = ((TLRPC.TL_updateEditMessage) update).message; + } else if (update instanceof TLRPC.TL_updateEditChannelMessage) { + updated = true; + info.messageObject.messageOwner = ((TLRPC.TL_updateEditChannelMessage) update).message; + } + } + if (updated) { + saveSharingLocation(info, 0); + } + getMessagesController().processUpdates(updates, false); + }); + requests.put(reqId[0], 0); } - TLRPC.TL_messages_editMessage req = new TLRPC.TL_messages_editMessage(); - req.peer = getMessagesController().getInputPeer((int) info.did); - req.id = info.mid; - req.flags |= 16384; - req.media = new TLRPC.TL_inputMediaGeoLive(); - req.media.stopped = false; - req.media.geo_point = new TLRPC.TL_inputGeoPoint(); - req.media.geo_point.lat = AndroidUtilities.fixLocationCoord(lastKnownLocation.getLatitude()); - req.media.geo_point._long = AndroidUtilities.fixLocationCoord(lastKnownLocation.getLongitude()); - final int[] reqId = new int[1]; - reqId[0] = getConnectionsManager().sendRequest(req, (response, error) -> { - if (error != null) { - if (error.text.equals("MESSAGE_ID_INVALID")) { - sharingLocations.remove(info); - sharingLocationsMap.remove(info.did); - saveSharingLocation(info, 1); - requests.delete(reqId[0]); - AndroidUtilities.runOnUIThread(() -> { - sharingLocationsUI.remove(info); - sharingLocationsMapUI.remove(info.did); - if (sharingLocationsUI.isEmpty()) { - stopService(); - } - NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.liveLocationsChanged); - }); - } - return; - } - TLRPC.Updates updates = (TLRPC.Updates) response; - boolean updated = false; - for (int a1 = 0; a1 < updates.updates.size(); a1++) { - TLRPC.Update update = updates.updates.get(a1); - if (update instanceof TLRPC.TL_updateEditMessage) { - updated = true; - info.messageObject.messageOwner = ((TLRPC.TL_updateEditMessage) update).message; - } else if (update instanceof TLRPC.TL_updateEditChannelMessage) { - updated = true; - info.messageObject.messageOwner = ((TLRPC.TL_updateEditChannelMessage) update).message; - } - } - if (updated) { - saveSharingLocation(info, 0); - } - getMessagesController().processUpdates(updates, false); + } + if (shareMyCurrentLocation) { + UserConfig userConfig = getUserConfig(); + userConfig.lastMyLocationShareTime = (int) (System.currentTimeMillis() / 1000); + userConfig.saveConfig(false); + + TLRPC.TL_contacts_getLocated req = new TLRPC.TL_contacts_getLocated(); + req.geo_point = new TLRPC.TL_inputGeoPoint(); + req.geo_point.lat = lastKnownLocation.getLatitude(); + req.geo_point._long = lastKnownLocation.getLongitude(); + req.background = true; + getConnectionsManager().sendRequest(req, (response, error) -> { + }); - requests.put(reqId[0], 0); } getConnectionsManager().resumeNetworkMaybe(); - if (shouldStopGps()) { + if (shouldStopGps() || shareMyCurrentLocation) { + shareMyCurrentLocation = false; stop(false); } } @@ -449,25 +467,28 @@ public class LocationController extends BaseController implements NotificationCe } protected void update() { - if (sharingLocations.isEmpty()) { - return; + UserConfig userConfig = getUserConfig(); + if (ApplicationLoader.isScreenOn && !ApplicationLoader.mainInterfacePaused && !shareMyCurrentLocation && userConfig.sharingMyLocationUntil != 0 && Math.abs(System.currentTimeMillis() / 1000 - userConfig.lastMyLocationShareTime) >= 60 * 60) { + shareMyCurrentLocation = true; } - for (int a = 0; a < sharingLocations.size(); a++) { - final SharingLocationInfo info = sharingLocations.get(a); - int currentTime = getConnectionsManager().getCurrentTime(); - if (info.stopTime <= currentTime) { - sharingLocations.remove(a); - sharingLocationsMap.remove(info.did); - saveSharingLocation(info, 1); - AndroidUtilities.runOnUIThread(() -> { - sharingLocationsUI.remove(info); - sharingLocationsMapUI.remove(info.did); - if (sharingLocationsUI.isEmpty()) { - stopService(); - } - NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.liveLocationsChanged); - }); - a--; + if (!sharingLocations.isEmpty()) { + for (int a = 0; a < sharingLocations.size(); a++) { + final SharingLocationInfo info = sharingLocations.get(a); + int currentTime = getConnectionsManager().getCurrentTime(); + if (info.stopTime <= currentTime) { + sharingLocations.remove(a); + sharingLocationsMap.remove(info.did); + saveSharingLocation(info, 1); + AndroidUtilities.runOnUIThread(() -> { + sharingLocationsUI.remove(info); + sharingLocationsMapUI.remove(info.did); + if (sharingLocationsUI.isEmpty()) { + stopService(); + } + NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.liveLocationsChanged); + }); + a--; + } } } if (started) { @@ -480,8 +501,8 @@ public class LocationController extends BaseController implements NotificationCe lastLocationSendTime = SystemClock.elapsedRealtime(); broadcastLastKnownLocation(cancelAll); } - } else { - if (Math.abs(lastLocationSendTime - SystemClock.elapsedRealtime()) > BACKGROUD_UPDATE_TIME) { + } else if (!sharingLocations.isEmpty() || shareMyCurrentLocation) { + if (shareMyCurrentLocation || Math.abs(lastLocationSendTime - SystemClock.elapsedRealtime()) > BACKGROUD_UPDATE_TIME) { lastLocationStartTime = SystemClock.elapsedRealtime(); start(); } @@ -826,7 +847,7 @@ public class LocationController extends BaseController implements NotificationCe } private void stop(boolean empty) { - if (lookingForPeopleNearby) { + if (lookingForPeopleNearby || shareMyCurrentLocation) { return; } started = false; diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/MediaController.java b/TMessagesProj/src/main/java/org/telegram/messenger/MediaController.java index bd2d73047..40114adfe 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/MediaController.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/MediaController.java @@ -2836,20 +2836,9 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener, recordReplyingMessageObject = reply_to_msg; } - private boolean shouldRequestRecordAudioFocus() { - try { - if (/*NotificationsController.audioManager.isWiredHeadsetOn() || */NotificationsController.audioManager.isBluetoothA2dpOn()) { - return false; - } - } catch (Throwable ignore) { - - } - return true; - } - public void requestAudioFocus(boolean request) { if (request) { - if (!hasRecordAudioFocus && shouldRequestRecordAudioFocus()) { + if (!hasRecordAudioFocus && SharedConfig.pauseMusicOnRecord) { int result = NotificationsController.audioManager.requestAudioFocus(audioRecordFocusChangedListener, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT); if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) { hasRecordAudioFocus = true; diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/MessageObject.java b/TMessagesProj/src/main/java/org/telegram/messenger/MessageObject.java index d675de278..6207b2474 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/MessageObject.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/MessageObject.java @@ -3564,6 +3564,9 @@ public class MessageObject { } else { spannable.setSpan(new URLSpanBrowser(url, run), run.start, run.end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); } + } else if (run.urlEntity instanceof TLRPC.TL_messageEntityBankCard) { + hasUrls = true; + spannable.setSpan(new URLSpanNoUnderline("card:" + url, run), run.start, run.end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); } else if (run.urlEntity instanceof TLRPC.TL_messageEntityPhone) { hasUrls = true; String tel = PhoneFormat.stripExceptNumbers(url); diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/MessagesController.java b/TMessagesProj/src/main/java/org/telegram/messenger/MessagesController.java index 0271e1b89..76f39eaca 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/MessagesController.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/MessagesController.java @@ -3043,12 +3043,18 @@ public class MessagesController extends BaseController implements NotificationCe if (first) { boolean isProxyDialog = false; + boolean emptyMax = max_id_delete == 0; + if (emptyMax) { + int max = getMessagesStorage().getDialogMaxMessageId(did); + if (max > 0) { + max_id_delete = Math.max(max, max_id_delete); + } + } getMessagesStorage().deleteDialog(did, onlyHistory); TLRPC.Dialog dialog = dialogs_dict.get(did); if (onlyHistory == 0 || onlyHistory == 3) { getNotificationsController().deleteNotificationChannel(did); } - boolean emptyMax = max_id_delete == 0; if (dialog != null) { if (emptyMax) { max_id_delete = Math.max(0, dialog.top_message); @@ -7211,10 +7217,12 @@ public class MessagesController extends BaseController implements NotificationCe getContactsController().deleteUnknownAppAccounts(); } + private boolean gettingAppChangelog; public void generateUpdateMessage() { - if (BuildVars.DEBUG_VERSION || SharedConfig.lastUpdateVersion == null || SharedConfig.lastUpdateVersion.equals(BuildVars.BUILD_VERSION_STRING)) { + if (gettingAppChangelog || BuildVars.DEBUG_VERSION || SharedConfig.lastUpdateVersion == null || SharedConfig.lastUpdateVersion.equals(BuildVars.BUILD_VERSION_STRING)) { return; } + gettingAppChangelog = true; TLRPC.TL_help_getAppChangelog req = new TLRPC.TL_help_getAppChangelog(); req.prev_app_version = SharedConfig.lastUpdateVersion; getConnectionsManager().sendRequest(req, (response, error) -> { diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/MessagesStorage.java b/TMessagesProj/src/main/java/org/telegram/messenger/MessagesStorage.java index d6a2739e9..1b1cf5446 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/MessagesStorage.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/MessagesStorage.java @@ -2046,7 +2046,7 @@ public class MessagesStorage extends BaseController { } public void putDialogPhotos(final int did, final TLRPC.photos_Photos photos) { - if (photos == null || photos.photos.isEmpty()) { + if (photos == null) { return; } storageQueue.postRunnable(() -> { @@ -8148,6 +8148,33 @@ public class MessagesStorage extends BaseController { }); } + public int getDialogMaxMessageId(final long dialog_id) { + final CountDownLatch countDownLatch = new CountDownLatch(1); + final Integer[] max = new Integer[]{0}; + storageQueue.postRunnable(() -> { + SQLiteCursor cursor = null; + try { + cursor = database.queryFinalized("SELECT MAX(mid) FROM messages WHERE uid = " + dialog_id); + if (cursor.next()) { + max[0] = cursor.intValue(0); + } + } catch (Exception e) { + FileLog.e(e); + } finally { + if (cursor != null) { + cursor.dispose(); + } + } + countDownLatch.countDown(); + }); + try { + countDownLatch.await(); + } catch (Exception e) { + FileLog.e(e); + } + return max[0]; + } + public int getDialogReadMax(final boolean outbox, final long dialog_id) { final CountDownLatch countDownLatch = new CountDownLatch(1); final Integer[] max = new Integer[]{0}; diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/SharedConfig.java b/TMessagesProj/src/main/java/org/telegram/messenger/SharedConfig.java index 741f929f8..54f4694d2 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/SharedConfig.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/SharedConfig.java @@ -84,6 +84,8 @@ public class SharedConfig { public static boolean streamAllVideo = false; public static boolean streamMkv = false; public static boolean saveStreamMedia = true; + public static boolean smoothKeyboard = false; + public static boolean pauseMusicOnRecord = true; public static boolean sortContactsByName; public static boolean sortFilesByName; public static boolean shuffleMusic; @@ -249,6 +251,8 @@ public class SharedConfig { useSystemEmoji = preferences.getBoolean("useSystemEmoji", false); streamMedia = preferences.getBoolean("streamMedia", true); saveStreamMedia = preferences.getBoolean("saveStreamMedia", true); + smoothKeyboard = preferences.getBoolean("smoothKeyboard", false); + pauseMusicOnRecord = preferences.getBoolean("pauseMusicOnRecord", true); streamAllVideo = preferences.getBoolean("streamAllVideo", BuildVars.DEBUG_VERSION); streamMkv = preferences.getBoolean("streamMkv", false); suggestStickers = preferences.getInt("suggestStickers", 0); @@ -671,6 +675,22 @@ public class SharedConfig { editor.commit(); } + public static void toggleSmoothKeyboard() { + smoothKeyboard = !smoothKeyboard; + SharedPreferences preferences = MessagesController.getGlobalMainSettings(); + SharedPreferences.Editor editor = preferences.edit(); + editor.putBoolean("smoothKeyboard", smoothKeyboard); + editor.commit(); + } + + public static void togglePauseMusicOnRecord() { + pauseMusicOnRecord = !pauseMusicOnRecord; + SharedPreferences preferences = MessagesController.getGlobalMainSettings(); + SharedPreferences.Editor editor = preferences.edit(); + editor.putBoolean("pauseMusicOnRecord", pauseMusicOnRecord); + editor.commit(); + } + public static void toggleInappCamera() { inappCamera = !inappCamera; SharedPreferences preferences = MessagesController.getGlobalMainSettings(); diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/UserConfig.java b/TMessagesProj/src/main/java/org/telegram/messenger/UserConfig.java index 18bc6871a..24767d54d 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/UserConfig.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/UserConfig.java @@ -48,6 +48,9 @@ public class UserConfig extends BaseController { public int migrateOffsetChannelId = -1; public long migrateOffsetAccess = -1; + public int sharingMyLocationUntil; + public int lastMyLocationShareTime; + public boolean notificationsSettingsLoaded; public boolean notificationsSignUpSettingsLoaded; public boolean syncContacts = true; @@ -142,6 +145,8 @@ public class UserConfig extends BaseController { editor.putBoolean("notificationsSignUpSettingsLoaded", notificationsSignUpSettingsLoaded); editor.putLong("autoDownloadConfigLoadTime", autoDownloadConfigLoadTime); editor.putBoolean("hasValidDialogLoadIds", hasValidDialogLoadIds); + editor.putInt("sharingMyLocationUntil", sharingMyLocationUntil); + editor.putInt("lastMyLocationShareTime", lastMyLocationShareTime); if (tonEncryptedData != null) { editor.putString("tonEncryptedData", tonEncryptedData); editor.putString("tonPublicKey", tonPublicKey); @@ -296,6 +301,8 @@ public class UserConfig extends BaseController { tonPublicKey = preferences.getString("tonPublicKey", null); tonKeyName = preferences.getString("tonKeyName", "walletKey" + currentAccount); tonCreationFinished = preferences.getBoolean("tonCreationFinished", true); + sharingMyLocationUntil = preferences.getInt("sharingMyLocationUntil", 0); + lastMyLocationShareTime = preferences.getInt("lastMyLocationShareTime", 0); String salt = preferences.getString("tonPasscodeSalt", null); if (salt != null) { try { @@ -443,6 +450,8 @@ public class UserConfig extends BaseController { getPreferences().edit().clear().commit(); clearTonConfig(); + sharingMyLocationUntil = 0; + lastMyLocationShareTime = 0; currentUser = null; clientUserId = 0; registeredForPush = false; diff --git a/TMessagesProj/src/main/java/org/telegram/tgnet/TLRPC.java b/TMessagesProj/src/main/java/org/telegram/tgnet/TLRPC.java index 50a655c95..fab92a558 100644 --- a/TMessagesProj/src/main/java/org/telegram/tgnet/TLRPC.java +++ b/TMessagesProj/src/main/java/org/telegram/tgnet/TLRPC.java @@ -61,7 +61,7 @@ public class TLRPC { public static final int MESSAGE_FLAG_EDITED = 0x00008000; public static final int MESSAGE_FLAG_MEGAGROUP = 0x80000000; - public static final int LAYER = 109; + public static final int LAYER = 110; public static class TL_chatBannedRights extends TLObject { public static int constructor = 0x9f120418; @@ -12837,6 +12837,86 @@ public class TLRPC { } } + public static class TL_dialogFilter extends TLObject { + public static int constructor = 0x14f9162c; + + public int flags; + public boolean pm; + public boolean secret_chats; + public boolean private_groups; + public boolean public_groups; + public boolean broadcasts; + public boolean bots; + public boolean exclude_muted; + public boolean exclude_read; + public int id; + public String title; + public ArrayList include_peers = new ArrayList<>(); + + public static TL_dialogFilter TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) { + if (TL_dialogFilter.constructor != constructor) { + if (exception) { + throw new RuntimeException(String.format("can't parse magic %x in TL_dialogFilter", constructor)); + } else { + return null; + } + } + TL_dialogFilter result = new TL_dialogFilter(); + result.readParams(stream, exception); + return result; + } + + public void readParams(AbstractSerializedData stream, boolean exception) { + flags = stream.readInt32(exception); + pm = (flags & 1) != 0; + secret_chats = (flags & 2) != 0; + private_groups = (flags & 4) != 0; + public_groups = (flags & 8) != 0; + broadcasts = (flags & 16) != 0; + bots = (flags & 32) != 0; + exclude_muted = (flags & 2048) != 0; + exclude_read = (flags & 4096) != 0; + id = stream.readInt32(exception); + title = stream.readString(exception); + int magic = stream.readInt32(exception); + if (magic != 0x1cb5c415) { + if (exception) { + throw new RuntimeException(String.format("wrong Vector magic, got %x", magic)); + } + return; + } + int count = stream.readInt32(exception); + for (int a = 0; a < count; a++) { + InputPeer object = InputPeer.TLdeserialize(stream, stream.readInt32(exception), exception); + if (object == null) { + return; + } + include_peers.add(object); + } + } + + public void serializeToStream(AbstractSerializedData stream) { + stream.writeInt32(constructor); + flags = pm ? (flags | 1) : (flags &~ 1); + flags = secret_chats ? (flags | 2) : (flags &~ 2); + flags = private_groups ? (flags | 4) : (flags &~ 4); + flags = public_groups ? (flags | 8) : (flags &~ 8); + flags = broadcasts ? (flags | 16) : (flags &~ 16); + flags = bots ? (flags | 32) : (flags &~ 32); + flags = exclude_muted ? (flags | 2048) : (flags &~ 2048); + flags = exclude_read ? (flags | 4096) : (flags &~ 4096); + stream.writeInt32(flags); + stream.writeInt32(id); + stream.writeString(title); + stream.writeInt32(0x1cb5c415); + int count = include_peers.size(); + stream.writeInt32(count); + for (int a = 0; a < count; a++) { + include_peers.get(a).serializeToStream(stream); + } + } + } + public static class TL_auth_passwordRecovery extends TLObject { public static int constructor = 0x137948a5; @@ -14415,6 +14495,56 @@ public class TLRPC { } } + public static class TL_payments_bankCardData extends TLObject { + public static int constructor = 0x3e24e573; + + public String title; + public ArrayList open_urls = new ArrayList<>(); + + public static TL_payments_bankCardData TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) { + if (TL_payments_bankCardData.constructor != constructor) { + if (exception) { + throw new RuntimeException(String.format("can't parse magic %x in TL_payments_bankCardData", constructor)); + } else { + return null; + } + } + TL_payments_bankCardData result = new TL_payments_bankCardData(); + result.readParams(stream, exception); + return result; + } + + public void readParams(AbstractSerializedData stream, boolean exception) { + title = stream.readString(exception); + int magic = stream.readInt32(exception); + if (magic != 0x1cb5c415) { + if (exception) { + throw new RuntimeException(String.format("wrong Vector magic, got %x", magic)); + } + return; + } + int count = stream.readInt32(exception); + for (int a = 0; a < count; a++) { + TL_bankCardOpenUrl object = TL_bankCardOpenUrl.TLdeserialize(stream, stream.readInt32(exception), exception); + if (object == null) { + return; + } + open_urls.add(object); + } + } + + public void serializeToStream(AbstractSerializedData stream) { + stream.writeInt32(constructor); + stream.writeString(title); + stream.writeInt32(0x1cb5c415); + int count = open_urls.size(); + stream.writeInt32(count); + for (int a = 0; a < count; a++) { + open_urls.get(a).serializeToStream(stream); + } + } + } + public static class TL_messages_highScores extends TLObject { public static int constructor = 0x9a3bfd99; @@ -20008,6 +20138,9 @@ public class TLRPC { case 0x154798c3: result = new TL_updateMessageReactions(); break; + case 0x26ffde7d: + result = new TL_updateDialogFilter(); + break; case 0xfa0f3ca2: result = new TL_updatePinnedDialogs(); break; @@ -20017,6 +20150,9 @@ public class TLRPC { case 0x9c974fdf: result = new TL_updateReadHistoryInbox(); break; + case 0xa5d72105: + result = new TL_updateDialogFilterOrder(); + break; case 0x9375341e: result = new TL_updateSavedGifs(); break; @@ -20038,6 +20174,9 @@ public class TLRPC { case 0x95313b0c: result = new TL_updateUserPhoto(); break; + case 0x3504914f: + result = new TL_updateDialogFilters(); + break; case 0x8e5e9873: result = new TL_updateDcOptions(); break; @@ -20600,7 +20739,7 @@ public class TLRPC { public static class TL_updatePeerLocated extends Update { public static int constructor = 0xb4afcfb0; - public ArrayList peers = new ArrayList<>(); + public ArrayList peers = new ArrayList<>(); public void readParams(AbstractSerializedData stream, boolean exception) { int magic = stream.readInt32(exception); @@ -20612,7 +20751,7 @@ public class TLRPC { } int count = stream.readInt32(exception); for (int a = 0; a < count; a++) { - TL_peerLocated object = TL_peerLocated.TLdeserialize(stream, stream.readInt32(exception), exception); + PeerLocated object = PeerLocated.TLdeserialize(stream, stream.readInt32(exception), exception); if (object == null) { return; } @@ -21101,6 +21240,31 @@ public class TLRPC { } } + public static class TL_updateDialogFilter extends Update { + public static int constructor = 0x26ffde7d; + + public int flags; + public int id; + public TL_dialogFilter filter; + + public void readParams(AbstractSerializedData stream, boolean exception) { + flags = stream.readInt32(exception); + id = stream.readInt32(exception); + if ((flags & 1) != 0) { + filter = TL_dialogFilter.TLdeserialize(stream, stream.readInt32(exception), exception); + } + } + + public void serializeToStream(AbstractSerializedData stream) { + stream.writeInt32(constructor); + stream.writeInt32(flags); + stream.writeInt32(id); + if ((flags & 1) != 0) { + filter.serializeToStream(stream); + } + } + } + public static class TL_updatePinnedDialogs extends Update { public static int constructor = 0xfa0f3ca2; @@ -21195,6 +21359,36 @@ public class TLRPC { } } + public static class TL_updateDialogFilterOrder extends Update { + public static int constructor = 0xa5d72105; + + public ArrayList order = new ArrayList<>(); + + public void readParams(AbstractSerializedData stream, boolean exception) { + int magic = stream.readInt32(exception); + if (magic != 0x1cb5c415) { + if (exception) { + throw new RuntimeException(String.format("wrong Vector magic, got %x", magic)); + } + return; + } + int count = stream.readInt32(exception); + for (int a = 0; a < count; a++) { + order.add(stream.readInt32(exception)); + } + } + + public void serializeToStream(AbstractSerializedData stream) { + stream.writeInt32(constructor); + stream.writeInt32(0x1cb5c415); + int count = order.size(); + stream.writeInt32(count); + for (int a = 0; a < count; a++) { + stream.writeInt32(order.get(a)); + } + } + } + public static class TL_updateSavedGifs extends Update { public static int constructor = 0x9375341e; @@ -21348,6 +21542,15 @@ public class TLRPC { } } + public static class TL_updateDialogFilters extends Update { + public static int constructor = 0x3504914f; + + + public void serializeToStream(AbstractSerializedData stream) { + stream.writeInt32(constructor); + } + } + public static class TL_updateDcOptions extends Update { public static int constructor = 0x8e5e9873; @@ -22407,6 +22610,9 @@ public class TLRPC { break; case 0x9c4e7e8b: result = new TL_messageEntityUnderline(); + break; + case 0x761e6af4: + result = new TL_messageEntityBankCard(); break; case 0x9b69e34b: result = new TL_messageEntityPhone(); @@ -22691,6 +22897,22 @@ public class TLRPC { public static int constructor = 0x9c4e7e8b; + public void readParams(AbstractSerializedData stream, boolean exception) { + offset = stream.readInt32(exception); + length = stream.readInt32(exception); + } + + public void serializeToStream(AbstractSerializedData stream) { + stream.writeInt32(constructor); + stream.writeInt32(offset); + stream.writeInt32(length); + } + } + + public static class TL_messageEntityBankCard extends MessageEntity { + public static int constructor = 0x761e6af4; + + public void readParams(AbstractSerializedData stream, boolean exception) { offset = stream.readInt32(exception); length = stream.readInt32(exception); @@ -25184,6 +25406,37 @@ public class TLRPC { } } + public static class TL_bankCardOpenUrl extends TLObject { + public static int constructor = 0xf568028a; + + public String url; + public String name; + + public static TL_bankCardOpenUrl TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) { + if (TL_bankCardOpenUrl.constructor != constructor) { + if (exception) { + throw new RuntimeException(String.format("can't parse magic %x in TL_bankCardOpenUrl", constructor)); + } else { + return null; + } + } + TL_bankCardOpenUrl result = new TL_bankCardOpenUrl(); + result.readParams(stream, exception); + return result; + } + + public void readParams(AbstractSerializedData stream, boolean exception) { + url = stream.readString(exception); + name = stream.readString(exception); + } + + public void serializeToStream(AbstractSerializedData stream) { + stream.writeInt32(constructor); + stream.writeString(url); + stream.writeString(name); + } + } + public static class TL_contacts_resolvedPeer extends TLObject { public static int constructor = 0x7f077ad9; @@ -27713,26 +27966,50 @@ public class TLRPC { } } - public static class TL_peerLocated extends TLObject { + public static abstract class PeerLocated extends TLObject { + + public static PeerLocated TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) { + PeerLocated result = null; + switch (constructor) { + case 0xf8ec284b: + result = new TL_peerSelfLocated(); + break; + case 0xca461b5d: + result = new TL_peerLocated(); + break; + } + if (result == null && exception) { + throw new RuntimeException(String.format("can't parse magic %x in PeerLocated", constructor)); + } + if (result != null) { + result.readParams(stream, exception); + } + return result; + } + } + + public static class TL_peerSelfLocated extends PeerLocated { + public static int constructor = 0xf8ec284b; + + public int expires; + + public void readParams(AbstractSerializedData stream, boolean exception) { + expires = stream.readInt32(exception); + } + + public void serializeToStream(AbstractSerializedData stream) { + stream.writeInt32(constructor); + stream.writeInt32(expires); + } + } + + public static class TL_peerLocated extends PeerLocated { public static int constructor = 0xca461b5d; public Peer peer; public int expires; public int distance; - public static TL_peerLocated TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) { - if (TL_peerLocated.constructor != constructor) { - if (exception) { - throw new RuntimeException(String.format("can't parse magic %x in TL_peerLocated", constructor)); - } else { - return null; - } - } - TL_peerLocated result = new TL_peerLocated(); - result.readParams(stream, exception); - return result; - } - public void readParams(AbstractSerializedData stream, boolean exception) { peer = Peer.TLdeserialize(stream, stream.readInt32(exception), exception); expires = stream.readInt32(exception); @@ -33740,9 +34017,12 @@ public class TLRPC { } public static class TL_contacts_getLocated extends TLObject { - public static int constructor = 0xa356056; + public static int constructor = 0xd348bc44; + public int flags; + public boolean background; public InputGeoPoint geo_point; + public int self_expires; public TLObject deserializeResponse(AbstractSerializedData stream, int constructor, boolean exception) { return Updates.TLdeserialize(stream, constructor, exception); @@ -33750,7 +34030,12 @@ public class TLRPC { public void serializeToStream(AbstractSerializedData stream) { stream.writeInt32(constructor); + flags = background ? (flags | 2) : (flags &~ 2); + stream.writeInt32(flags); geo_point.serializeToStream(stream); + if ((flags & 1) != 0) { + stream.writeInt32(self_expires); + } } } @@ -37637,6 +37922,69 @@ public class TLRPC { } } + public static class TL_messages_getDialogFilters extends TLObject { + public static int constructor = 0xf19ed96d; + + + public TLObject deserializeResponse(AbstractSerializedData stream, int constructor, boolean exception) { + Vector vector = new Vector(); + int size = stream.readInt32(exception); + for (int a = 0; a < size; a++) { + TL_dialogFilter object = TL_dialogFilter.TLdeserialize(stream, stream.readInt32(exception), exception); + if (object == null) { + return vector; + } + vector.objects.add(object); + } + return vector; + } + + public void serializeToStream(AbstractSerializedData stream) { + stream.writeInt32(constructor); + } + } + + public static class TL_messages_updateDialogFilter extends TLObject { + public static int constructor = 0x1ad4a04a; + + public int flags; + public int id; + public TL_dialogFilter filter; + + public TLObject deserializeResponse(AbstractSerializedData stream, int constructor, boolean exception) { + return Bool.TLdeserialize(stream, constructor, exception); + } + + public void serializeToStream(AbstractSerializedData stream) { + stream.writeInt32(constructor); + stream.writeInt32(flags); + stream.writeInt32(id); + if ((flags & 1) != 0) { + filter.serializeToStream(stream); + } + } + } + + public static class TL_messages_updateDialogFiltersOrder extends TLObject { + public static int constructor = 0xc563c1e4; + + public ArrayList order = new ArrayList<>(); + + public TLObject deserializeResponse(AbstractSerializedData stream, int constructor, boolean exception) { + return Bool.TLdeserialize(stream, constructor, exception); + } + + public void serializeToStream(AbstractSerializedData stream) { + stream.writeInt32(constructor); + stream.writeInt32(0x1cb5c415); + int count = order.size(); + stream.writeInt32(count); + for (int a = 0; a < count; a++) { + stream.writeInt32(order.get(a)); + } + } + } + public static class TL_help_getAppChangelog extends TLObject { public static int constructor = 0x9010ef6f; @@ -39017,6 +39365,21 @@ public class TLRPC { } } + public static class TL_payments_getBankCardData extends TLObject { + public static int constructor = 0x2e79d779; + + public String number; + + public TLObject deserializeResponse(AbstractSerializedData stream, int constructor, boolean exception) { + return TL_payments_bankCardData.TLdeserialize(stream, constructor, exception); + } + + public void serializeToStream(AbstractSerializedData stream) { + stream.writeInt32(constructor); + stream.writeString(number); + } + } + public static class TL_langpack_getLangPack extends TLObject { public static int constructor = 0x9ab5c58e; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBar.java b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBar.java index cb4e71381..158cdc5dc 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBar.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBar.java @@ -253,7 +253,7 @@ public class ActionBar extends FrameLayout { addToContainer = value; } - public boolean getAddToContainer() { + public boolean shouldAddToContainer() { return addToContainer; } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarLayout.java b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarLayout.java index 19b37c29f..2fc4cd657 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarLayout.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarLayout.java @@ -37,7 +37,6 @@ import android.view.ViewOutlineProvider; import android.view.animation.AccelerateDecelerateInterpolator; import android.view.animation.DecelerateInterpolator; import android.widget.FrameLayout; -import android.widget.LinearLayout; import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.FileLog; @@ -58,14 +57,13 @@ public class ActionBarLayout extends FrameLayout { void onRebuildAllFragments(ActionBarLayout layout, boolean last); } - public class LinearLayoutContainer extends LinearLayout { + public class LayoutContainer extends AdjustPanFrameLayout { private Rect rect = new Rect(); private boolean isKeyboardVisible; - public LinearLayoutContainer(Context context) { + public LayoutContainer(Context context) { super(context); - setOrientation(VERTICAL); } @Override @@ -74,6 +72,7 @@ public class ActionBarLayout extends FrameLayout { return super.drawChild(canvas, child, drawingTime); } else { int actionBarHeight = 0; + int actionBarY = 0; int childCount = getChildCount(); for (int a = 0; a < childCount; a++) { View view = getChildAt(a); @@ -83,13 +82,14 @@ public class ActionBarLayout extends FrameLayout { if (view instanceof ActionBar && view.getVisibility() == VISIBLE) { if (((ActionBar) view).getCastShadows()) { actionBarHeight = view.getMeasuredHeight(); + actionBarY = (int) view.getY(); } break; } } boolean result = super.drawChild(canvas, child, drawingTime); if (actionBarHeight != 0 && headerShadowDrawable != null) { - headerShadowDrawable.setBounds(0, actionBarHeight, getMeasuredWidth(), actionBarHeight + headerShadowDrawable.getIntrinsicHeight()); + headerShadowDrawable.setBounds(0, actionBarY + actionBarHeight, getMeasuredWidth(), actionBarY + actionBarHeight + headerShadowDrawable.getIntrinsicHeight()); headerShadowDrawable.draw(canvas); } return result; @@ -104,9 +104,48 @@ public class ActionBarLayout extends FrameLayout { return false; } + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + int width = MeasureSpec.getSize(widthMeasureSpec); + int height = MeasureSpec.getSize(heightMeasureSpec); + int count = getChildCount(); + int actionBarHeight = 0; + for (int a = 0; a < count; a++) { + View child = getChildAt(a); + if (child instanceof ActionBar) { + child.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(height, MeasureSpec.UNSPECIFIED)); + actionBarHeight = child.getMeasuredHeight(); + break; + } + } + for (int a = 0; a < count; a++) { + View child = getChildAt(a); + if (!(child instanceof ActionBar)) { + measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, actionBarHeight); + } + } + setMeasuredDimension(width, height); + } + @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { - super.onLayout(changed, l, t, r, b); + int count = getChildCount(); + int actionBarHeight = 0; + for (int a = 0; a < count; a++) { + View child = getChildAt(a); + if (child instanceof ActionBar) { + actionBarHeight = child.getMeasuredHeight(); + child.layout(0, 0, child.getMeasuredWidth(), actionBarHeight); + break; + } + } + for (int a = 0; a < count; a++) { + View child = getChildAt(a); + if (!(child instanceof ActionBar)) { + FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) child.getLayoutParams(); + child.layout(layoutParams.leftMargin, layoutParams.topMargin + actionBarHeight, layoutParams.leftMargin + child.getMeasuredWidth(), layoutParams.topMargin + actionBarHeight + child.getMeasuredHeight()); + } + } View rootView = getRootView(); getWindowVisibleDisplayFrame(rect); @@ -132,6 +171,40 @@ public class ActionBarLayout extends FrameLayout { } return false; } + + @Override + protected void onPanTranslationUpdate(int y) { + currentPanTranslationY = y; + int count = getChildCount(); + for (int a = 0; a < count; a++) { + View child = getChildAt(a); + if (child instanceof ActionBar) { + child.setTranslationY(y); + } else { + if (this == layoutToIgnore) { + child.setTranslationY(y); + } else { + child.setTranslationY(0); + } + } + } + if (layoutToIgnore == null && !fragmentsStack.isEmpty()) { + fragmentsStack.get(fragmentsStack.size() - 1).onPanTranslationUpdate(y); + } + } + + @Override + protected void onTransitionStart() { + fragmentsStack.get(fragmentsStack.size() - 1).onPanTransitionStart(); + } + + @Override + protected void onTransitionEnd() { + fragmentsStack.get(fragmentsStack.size() - 1).onPanTransitionEnd(); + if (layoutToIgnore != null && !transitionAnimationInProgress && !startedTracking) { + layoutToIgnore = null; + } + } } private static Drawable headerShadowDrawable; @@ -142,10 +215,11 @@ public class ActionBarLayout extends FrameLayout { private Runnable delayedOpenAnimationRunnable; private boolean inPreviewMode; + private boolean previewOpenAnimationInProgress; private ColorDrawable previewBackgroundDrawable; - private LinearLayoutContainer containerView; - private LinearLayoutContainer containerViewBack; + private LayoutContainer containerView; + private LayoutContainer containerViewBack; private DrawerLayoutContainer drawerLayoutContainer; private ActionBar currentActionBar; @@ -155,12 +229,15 @@ public class ActionBarLayout extends FrameLayout { public float innerTranslationX; + private int currentPanTranslationY; + private boolean maybeStartTracking; protected boolean startedTracking; private int startedTrackingX; private int startedTrackingY; protected boolean animationInProgress; private VelocityTracker velocityTracker; + private View layoutToIgnore; private boolean beginTrackingSent; private boolean transitionAnimationInProgress; private boolean transitionAnimationPreviewMode; @@ -213,7 +290,7 @@ public class ActionBarLayout extends FrameLayout { public void init(ArrayList stack) { fragmentsStack = stack; - containerViewBack = new LinearLayoutContainer(parentActivity); + containerViewBack = new LayoutContainer(parentActivity); addView(containerViewBack); FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) containerViewBack.getLayoutParams(); layoutParams.width = LayoutHelper.MATCH_PARENT; @@ -221,7 +298,7 @@ public class ActionBarLayout extends FrameLayout { layoutParams.gravity = Gravity.TOP | Gravity.LEFT; containerViewBack.setLayoutParams(layoutParams); - containerView = new LinearLayoutContainer(parentActivity); + containerView = new LayoutContainer(parentActivity); addView(containerView); layoutParams = (FrameLayout.LayoutParams) containerView.getLayoutParams(); layoutParams.width = LayoutHelper.MATCH_PARENT; @@ -249,7 +326,12 @@ public class ActionBarLayout extends FrameLayout { } public void drawHeaderShadow(Canvas canvas, int y) { + drawHeaderShadow(canvas, 255, y); + } + + public void drawHeaderShadow(Canvas canvas, int alpha, int y) { if (headerShadowDrawable != null) { + headerShadowDrawable.setAlpha(alpha); headerShadowDrawable.setBounds(0, y, getMeasuredWidth(), y + headerShadowDrawable.getIntrinsicHeight()); headerShadowDrawable.draw(canvas); } @@ -273,6 +355,10 @@ public class ActionBarLayout extends FrameLayout { } } + public int getCurrentPanTranslationY() { + return currentPanTranslationY; + } + public void onResume() { if (transitionAnimationInProgress) { if (currentAnimation != null) { @@ -382,7 +468,7 @@ public class ActionBarLayout extends FrameLayout { lastFragment.setParentLayout(null); fragmentsStack.remove(fragmentsStack.size() - 1); - LinearLayoutContainer temp = containerView; + LayoutContainer temp = containerView; containerView = containerViewBack; containerViewBack = temp; bringChildToFront(containerView); @@ -391,6 +477,8 @@ public class ActionBarLayout extends FrameLayout { currentActionBar = lastFragment.actionBar; lastFragment.onResume(); lastFragment.onBecomeFullyVisible(); + + layoutToIgnore = containerView; } else { if (fragmentsStack.size() >= 2) { BaseFragment lastFragment = fragmentsStack.get(fragmentsStack.size() - 2); @@ -402,13 +490,14 @@ public class ActionBarLayout extends FrameLayout { parent.removeViewInLayout(lastFragment.fragmentView); } } - if (lastFragment.actionBar != null && lastFragment.actionBar.getAddToContainer()) { + if (lastFragment.actionBar != null && lastFragment.actionBar.shouldAddToContainer()) { ViewGroup parent = (ViewGroup) lastFragment.actionBar.getParent(); if (parent != null) { parent.removeViewInLayout(lastFragment.actionBar); } } } + layoutToIgnore = null; } containerViewBack.setVisibility(View.INVISIBLE); startedTracking = false; @@ -421,6 +510,7 @@ public class ActionBarLayout extends FrameLayout { private void prepareForMoving(MotionEvent ev) { maybeStartTracking = false; startedTracking = true; + layoutToIgnore = containerViewBack; startedTrackingX = (int) ev.getX(); containerViewBack.setVisibility(View.VISIBLE); beginTrackingSent = false; @@ -435,7 +525,13 @@ public class ActionBarLayout extends FrameLayout { lastFragment.onRemoveFromParent(); parent.removeView(fragmentView); } - if (lastFragment.actionBar != null && lastFragment.actionBar.getAddToContainer()) { + containerViewBack.addView(fragmentView); + FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) fragmentView.getLayoutParams(); + layoutParams.width = LayoutHelper.MATCH_PARENT; + layoutParams.height = LayoutHelper.MATCH_PARENT; + layoutParams.topMargin = layoutParams.bottomMargin = layoutParams.rightMargin = layoutParams.leftMargin = 0; + fragmentView.setLayoutParams(layoutParams); + if (lastFragment.actionBar != null && lastFragment.actionBar.shouldAddToContainer()) { parent = (ViewGroup) lastFragment.actionBar.getParent(); if (parent != null) { parent.removeView(lastFragment.actionBar); @@ -446,12 +542,6 @@ public class ActionBarLayout extends FrameLayout { containerViewBack.addView(lastFragment.actionBar); lastFragment.actionBar.setTitleOverlayText(titleOverlayText, titleOverlayTextId, overlayAction); } - containerViewBack.addView(fragmentView); - LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) fragmentView.getLayoutParams(); - layoutParams.width = LayoutHelper.MATCH_PARENT; - layoutParams.height = LayoutHelper.MATCH_PARENT; - layoutParams.topMargin = layoutParams.bottomMargin = layoutParams.rightMargin = layoutParams.leftMargin = 0; - fragmentView.setLayoutParams(layoutParams); if (!lastFragment.hasOwnBackground && fragmentView.getBackground() == null) { fragmentView.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite)); } @@ -466,7 +556,7 @@ public class ActionBarLayout extends FrameLayout { if (fragmentsStack.size() > 1) { if (ev != null && ev.getAction() == MotionEvent.ACTION_DOWN && !startedTracking && !maybeStartTracking) { BaseFragment currentFragment = fragmentsStack.get(fragmentsStack.size() - 1); - if (!currentFragment.swipeBackEnabled) { + if (!currentFragment.isSwipeBackEnabled(ev)) { return false; } startedTrackingPointerId = ev.getPointerId(0); @@ -508,7 +598,7 @@ public class ActionBarLayout extends FrameLayout { } velocityTracker.computeCurrentVelocity(1000); BaseFragment currentFragment = fragmentsStack.get(fragmentsStack.size() - 1); - if (!inPreviewMode && !transitionAnimationPreviewMode && !startedTracking && currentFragment.swipeBackEnabled) { + if (!inPreviewMode && !transitionAnimationPreviewMode && !startedTracking && currentFragment.isSwipeBackEnabled(ev)) { float velX = velocityTracker.getXVelocity(); float velY = velocityTracker.getYVelocity(); if (velX >= 3500 && velX > Math.abs(velY) && currentFragment.canBeginSlide()) { @@ -551,9 +641,11 @@ public class ActionBarLayout extends FrameLayout { }); animatorSet.start(); animationInProgress = true; + layoutToIgnore = containerViewBack; } else { maybeStartTracking = false; startedTracking = false; + layoutToIgnore = null; } if (velocityTracker != null) { velocityTracker.recycle(); @@ -562,6 +654,7 @@ public class ActionBarLayout extends FrameLayout { } else if (ev == null) { maybeStartTracking = false; startedTracking = false; + layoutToIgnore = null; if (velocityTracker != null) { velocityTracker.recycle(); velocityTracker = null; @@ -638,6 +731,10 @@ public class ActionBarLayout extends FrameLayout { return transitionAnimationInProgress; } + public boolean isPreviewOpenAnimationInProgress() { + return previewOpenAnimationInProgress; + } + private void presentFragmentInternalRemoveOld(boolean removeLast, final BaseFragment fragment) { if (fragment == null) { return; @@ -656,7 +753,7 @@ public class ActionBarLayout extends FrameLayout { parent.removeViewInLayout(fragment.fragmentView); } } - if (fragment.actionBar != null && fragment.actionBar.getAddToContainer()) { + if (fragment.actionBar != null && fragment.actionBar.shouldAddToContainer()) { ViewGroup parent = (ViewGroup) fragment.actionBar.getParent(); if (parent != null) { parent.removeViewInLayout(fragment.actionBar); @@ -774,20 +871,8 @@ public class ActionBarLayout extends FrameLayout { parent.removeView(fragmentView); } } - if (fragment.actionBar != null && fragment.actionBar.getAddToContainer()) { - if (removeActionBarExtraHeight) { - fragment.actionBar.setOccupyStatusBar(false); - } - ViewGroup parent = (ViewGroup) fragment.actionBar.getParent(); - if (parent != null) { - parent.removeView(fragment.actionBar); - } - containerViewBack.addView(fragment.actionBar); - fragment.actionBar.setTitleOverlayText(titleOverlayText, titleOverlayTextId, overlayAction); - } - containerViewBack.addView(fragmentView); - LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) fragmentView.getLayoutParams(); + FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) fragmentView.getLayoutParams(); layoutParams.width = LayoutHelper.MATCH_PARENT; layoutParams.height = LayoutHelper.MATCH_PARENT; if (preview) { @@ -798,6 +883,17 @@ public class ActionBarLayout extends FrameLayout { layoutParams.topMargin = layoutParams.bottomMargin = layoutParams.rightMargin = layoutParams.leftMargin = 0; } fragmentView.setLayoutParams(layoutParams); + if (fragment.actionBar != null && fragment.actionBar.shouldAddToContainer()) { + if (removeActionBarExtraHeight) { + fragment.actionBar.setOccupyStatusBar(false); + } + ViewGroup parent = (ViewGroup) fragment.actionBar.getParent(); + if (parent != null) { + parent.removeView(fragment.actionBar); + } + containerViewBack.addView(fragment.actionBar); + fragment.actionBar.setTitleOverlayText(titleOverlayText, titleOverlayTextId, overlayAction); + } fragmentsStack.add(fragment); fragment.onResume(); currentActionBar = fragment.actionBar; @@ -805,7 +901,7 @@ public class ActionBarLayout extends FrameLayout { fragmentView.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite)); } - LinearLayoutContainer temp = containerView; + LayoutContainer temp = containerView; containerView = containerViewBack; containerViewBack = temp; containerView.setVisibility(View.VISIBLE); @@ -849,6 +945,7 @@ public class ActionBarLayout extends FrameLayout { transitionAnimationStartTime = System.currentTimeMillis(); transitionAnimationInProgress = true; + layoutToIgnore = containerView; onOpenAnimationEndRunnable = () -> { if (currentFragment != null) { currentFragment.onTransitionAnimationEnd(false, false); @@ -857,10 +954,10 @@ public class ActionBarLayout extends FrameLayout { fragment.onBecomeFullyVisible(); }; ArrayList animators = new ArrayList<>(); - animators.add(ObjectAnimator.ofFloat(this, "alpha", 0.0f, 1.0f)); + animators.add(ObjectAnimator.ofFloat(this, View.ALPHA, 0.0f, 1.0f)); if (backgroundView != null) { backgroundView.setVisibility(VISIBLE); - animators.add(ObjectAnimator.ofFloat(backgroundView, "alpha", 0.0f, 1.0f)); + animators.add(ObjectAnimator.ofFloat(backgroundView, View.ALPHA, 0.0f, 1.0f)); } if (currentFragment != null) { currentFragment.onTransitionAnimationStart(false, false); @@ -881,6 +978,7 @@ public class ActionBarLayout extends FrameLayout { transitionAnimationPreviewMode = preview; transitionAnimationStartTime = System.currentTimeMillis(); transitionAnimationInProgress = true; + layoutToIgnore = containerView; onOpenAnimationEndRunnable = () -> { if (preview) { inPreviewMode = true; @@ -978,7 +1076,7 @@ public class ActionBarLayout extends FrameLayout { if (!fragmentsStack.isEmpty()) { BaseFragment previousFragment = fragmentsStack.get(fragmentsStack.size() - 1); previousFragment.onPause(); - if (previousFragment.actionBar != null && previousFragment.actionBar.getAddToContainer()) { + if (previousFragment.actionBar != null && previousFragment.actionBar.shouldAddToContainer()) { ViewGroup parent = (ViewGroup) previousFragment.actionBar.getParent(); if (parent != null) { parent.removeView(previousFragment.actionBar); @@ -1017,6 +1115,7 @@ public class ActionBarLayout extends FrameLayout { if (nextTranslation > 0) { nextTranslation = 0; } else if (nextTranslation < -AndroidUtilities.dp(60)) { + previewOpenAnimationInProgress = true; inPreviewMode = false; nextTranslation = 0; @@ -1027,7 +1126,7 @@ public class ActionBarLayout extends FrameLayout { fragment.fragmentView.setOutlineProvider(null); fragment.fragmentView.setClipToOutline(false); } - LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) fragment.fragmentView.getLayoutParams(); + FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) fragment.fragmentView.getLayoutParams(); layoutParams.topMargin = layoutParams.bottomMargin = layoutParams.rightMargin = layoutParams.leftMargin = 0; fragment.fragmentView.setLayoutParams(layoutParams); @@ -1035,11 +1134,16 @@ public class ActionBarLayout extends FrameLayout { AnimatorSet animatorSet = new AnimatorSet(); animatorSet.playTogether( - ObjectAnimator.ofFloat(fragment.fragmentView, "scaleX", 1.0f, 1.05f, 1.0f), - ObjectAnimator.ofFloat(fragment.fragmentView, "scaleY", 1.0f, 1.05f, 1.0f)); + ObjectAnimator.ofFloat(fragment.fragmentView, View.SCALE_X, 1.0f, 1.05f, 1.0f), + ObjectAnimator.ofFloat(fragment.fragmentView, View.SCALE_Y, 1.0f, 1.05f, 1.0f)); animatorSet.setDuration(200); animatorSet.setInterpolator(new CubicBezierInterpolator(0.42, 0.0, 0.58, 1.0)); - + animatorSet.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + previewOpenAnimationInProgress = false; + } + }); animatorSet.start(); performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP); @@ -1055,6 +1159,10 @@ public class ActionBarLayout extends FrameLayout { if (!inPreviewMode && !transitionAnimationPreviewMode) { return; } + if (delayedOpenAnimationRunnable != null) { + AndroidUtilities.cancelRunOnUIThread(delayedOpenAnimationRunnable); + delayedOpenAnimationRunnable = null; + } closeLastFragment(true); } @@ -1074,7 +1182,7 @@ public class ActionBarLayout extends FrameLayout { } if (previousFragment != null) { - LinearLayoutContainer temp = containerView; + LayoutContainer temp = containerView; containerView = containerViewBack; containerViewBack = temp; @@ -1086,17 +1194,6 @@ public class ActionBarLayout extends FrameLayout { if (!inPreviewMode) { containerView.setVisibility(View.VISIBLE); - if (previousFragment.actionBar != null && previousFragment.actionBar.getAddToContainer()) { - if (removeActionBarExtraHeight) { - previousFragment.actionBar.setOccupyStatusBar(false); - } - ViewGroup parent = (ViewGroup) previousFragment.actionBar.getParent(); - if (parent != null) { - parent.removeView(previousFragment.actionBar); - } - containerView.addView(previousFragment.actionBar); - previousFragment.actionBar.setTitleOverlayText(titleOverlayText, titleOverlayTextId, overlayAction); - } ViewGroup parent = (ViewGroup) fragmentView.getParent(); if (parent != null) { previousFragment.onRemoveFromParent(); @@ -1107,11 +1204,22 @@ public class ActionBarLayout extends FrameLayout { } } containerView.addView(fragmentView); - LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) fragmentView.getLayoutParams(); + FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) fragmentView.getLayoutParams(); layoutParams.width = LayoutHelper.MATCH_PARENT; layoutParams.height = LayoutHelper.MATCH_PARENT; layoutParams.topMargin = layoutParams.bottomMargin = layoutParams.rightMargin = layoutParams.leftMargin = 0; fragmentView.setLayoutParams(layoutParams); + if (previousFragment.actionBar != null && previousFragment.actionBar.shouldAddToContainer()) { + if (removeActionBarExtraHeight) { + previousFragment.actionBar.setOccupyStatusBar(false); + } + parent = (ViewGroup) previousFragment.actionBar.getParent(); + if (parent != null) { + parent.removeView(previousFragment.actionBar); + } + containerView.addView(previousFragment.actionBar); + previousFragment.actionBar.setTitleOverlayText(titleOverlayText, titleOverlayTextId, overlayAction); + } } previousFragment.onTransitionAnimationStart(true, true); @@ -1132,6 +1240,7 @@ public class ActionBarLayout extends FrameLayout { if (needAnimation) { transitionAnimationStartTime = System.currentTimeMillis(); transitionAnimationInProgress = true; + layoutToIgnore = containerView; final BaseFragment previousFragmentFinal = previousFragment; onCloseAnimationEndRunnable = () -> { if (inPreviewMode || transitionAnimationPreviewMode) { @@ -1179,6 +1288,7 @@ public class ActionBarLayout extends FrameLayout { if (useAlphaAnimations) { transitionAnimationStartTime = System.currentTimeMillis(); transitionAnimationInProgress = true; + layoutToIgnore = containerView; onCloseAnimationEndRunnable = () -> { removeFragmentFromStackInternal(currentFragment); @@ -1192,9 +1302,9 @@ public class ActionBarLayout extends FrameLayout { }; ArrayList animators = new ArrayList<>(); - animators.add(ObjectAnimator.ofFloat(this, "alpha", 1.0f, 0.0f)); + animators.add(ObjectAnimator.ofFloat(this, View.ALPHA, 1.0f, 0.0f)); if (backgroundView != null) { - animators.add(ObjectAnimator.ofFloat(backgroundView, "alpha", 1.0f, 0.0f)); + animators.add(ObjectAnimator.ofFloat(backgroundView, View.ALPHA, 1.0f, 0.0f)); } currentAnimation = new AnimatorSet(); @@ -1229,7 +1339,7 @@ public class ActionBarLayout extends FrameLayout { } for (int a = 0; a < fragmentsStack.size() - 1; a++) { BaseFragment previousFragment = fragmentsStack.get(a); - if (previousFragment.actionBar != null && previousFragment.actionBar.getAddToContainer()) { + if (previousFragment.actionBar != null && previousFragment.actionBar.shouldAddToContainer()) { ViewGroup parent = (ViewGroup) previousFragment.actionBar.getParent(); if (parent != null) { parent.removeView(previousFragment.actionBar); @@ -1256,7 +1366,8 @@ public class ActionBarLayout extends FrameLayout { parent.removeView(fragmentView); } } - if (previousFragment.actionBar != null && previousFragment.actionBar.getAddToContainer()) { + containerView.addView(fragmentView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT)); + if (previousFragment.actionBar != null && previousFragment.actionBar.shouldAddToContainer()) { if (removeActionBarExtraHeight) { previousFragment.actionBar.setOccupyStatusBar(false); } @@ -1267,7 +1378,6 @@ public class ActionBarLayout extends FrameLayout { containerView.addView(previousFragment.actionBar); previousFragment.actionBar.setTitleOverlayText(titleOverlayText, titleOverlayTextId, overlayAction); } - containerView.addView(fragmentView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT)); previousFragment.onResume(); currentActionBar = previousFragment.actionBar; if (!previousFragment.hasOwnBackground && fragmentView.getBackground() == null) { @@ -1528,6 +1638,9 @@ public class ActionBarLayout extends FrameLayout { private void onCloseAnimationEnd() { if (transitionAnimationInProgress && onCloseAnimationEndRunnable != null) { transitionAnimationInProgress = false; + if (currentPanTranslationY == 0) { + layoutToIgnore = null; + } transitionAnimationPreviewMode = false; transitionAnimationStartTime = 0; onCloseAnimationEndRunnable.run(); @@ -1550,6 +1663,9 @@ public class ActionBarLayout extends FrameLayout { private void onOpenAnimationEnd() { if (transitionAnimationInProgress && onOpenAnimationEndRunnable != null) { transitionAnimationInProgress = false; + if (currentPanTranslationY == 0) { + layoutToIgnore = null; + } transitionAnimationPreviewMode = false; transitionAnimationStartTime = 0; onOpenAnimationEndRunnable.run(); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarMenuItem.java b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarMenuItem.java index 37100791a..bc4dbfed9 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarMenuItem.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarMenuItem.java @@ -39,6 +39,7 @@ import android.widget.TextView; import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.LocaleController; import org.telegram.messenger.R; +import org.telegram.messenger.SharedConfig; import org.telegram.ui.Components.CloseProgressDrawable2; import org.telegram.ui.Components.EditTextBoldCursor; import org.telegram.ui.Components.LayoutHelper; @@ -73,6 +74,10 @@ public class ActionBarMenuItem extends FrameLayout { public Animator getCustomToggleTransition() { return null; } + + public void onLayout(int l, int t, int r, int b) { + + } } public interface ActionBarSumMenuItemDelegate { @@ -111,7 +116,7 @@ public class ActionBarMenuItem extends FrameLayout { private CloseProgressDrawable2 progressDrawable; private int additionalYOffset; private int additionalXOffset; - private boolean longClickEnabled = true; + private boolean longClickEnabled; private boolean animateClear = true; private boolean clearsTextOnSearchCollapse = true; private boolean measurePopup = true; @@ -564,6 +569,10 @@ public class ActionBarMenuItem extends FrameLayout { iconView.setImageDrawable(drawable); } + public ImageView getIconView() { + return iconView; + } + public void setIcon(int resId) { if (iconView == null) { return; @@ -898,6 +907,9 @@ public class ActionBarMenuItem extends FrameLayout { if (popupWindow != null && popupWindow.isShowing()) { updateOrShowPopup(false, true); } + if (listener != null) { + listener.onLayout(left, top, right, bottom); + } } public void setAdditionalYOffset(int value) { @@ -912,7 +924,7 @@ public class ActionBarMenuItem extends FrameLayout { int offsetY; if (parentMenu != null) { - offsetY = -parentMenu.parentActionBar.getMeasuredHeight() + parentMenu.getTop() + parentMenu.getPaddingTop(); + offsetY = -parentMenu.parentActionBar.getMeasuredHeight() + parentMenu.getTop() + parentMenu.getPaddingTop() - (int) parentMenu.parentActionBar.getTranslationY(); } else { float scaleY = getScaleY(); offsetY = -(int) (getMeasuredHeight() * scaleY - (subMenuOpenSide != 2 ? getTranslationY() : 0) / scaleY) + additionalYOffset; @@ -926,11 +938,21 @@ public class ActionBarMenuItem extends FrameLayout { if (parentMenu != null) { View parent = parentMenu.parentActionBar; if (subMenuOpenSide == 0) { - if (show) { - popupWindow.showAsDropDown(parent, getLeft() + parentMenu.getLeft() + getMeasuredWidth() - popupLayout.getMeasuredWidth() + (int) getTranslationX(), offsetY); - } - if (update) { - popupWindow.update(parent, getLeft() + parentMenu.getLeft() + getMeasuredWidth() - popupLayout.getMeasuredWidth() + (int) getTranslationX(), offsetY, -1, -1); + if (SharedConfig.smoothKeyboard) { + getLocationOnScreen(location); + if (show) { + popupWindow.showAtLocation(parent, Gravity.LEFT | Gravity.TOP, location[0] + getMeasuredWidth() - popupLayout.getMeasuredWidth() + (int) getTranslationX(), offsetY); + } + if (update) { + popupWindow.update(location[0] + getMeasuredWidth() - popupLayout.getMeasuredWidth() + (int) getTranslationX(), offsetY, -1, -1); + } + } else { + if (show) { + popupWindow.showAsDropDown(parent, getLeft() + parentMenu.getLeft() + getMeasuredWidth() - popupLayout.getMeasuredWidth() + (int) getTranslationX(), offsetY); + } + if (update) { + popupWindow.update(parent, getLeft() + parentMenu.getLeft() + getMeasuredWidth() - popupLayout.getMeasuredWidth() + (int) getTranslationX(), offsetY, -1, -1); + } } } else { if (show) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/AdjustPanFrameLayout.java b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/AdjustPanFrameLayout.java new file mode 100644 index 000000000..8f62d82be --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/AdjustPanFrameLayout.java @@ -0,0 +1,48 @@ +package org.telegram.ui.ActionBar; + +import android.content.Context; +import android.graphics.Canvas; +import android.widget.FrameLayout; + +public class AdjustPanFrameLayout extends FrameLayout { + + private AdjustPanLayoutHelper adjustPanLayoutHelper; + + public AdjustPanFrameLayout(Context context) { + super(context); + adjustPanLayoutHelper = new AdjustPanLayoutHelper(this) { + @Override + protected void onPanTranslationUpdate(int y) { + AdjustPanFrameLayout.this.onPanTranslationUpdate(y); + } + + @Override + protected void onTransitionStart() { + AdjustPanFrameLayout.this.onTransitionStart(); + } + + @Override + protected void onTransitionEnd() { + AdjustPanFrameLayout.this.onTransitionEnd(); + } + }; + } + + @Override + protected void dispatchDraw(Canvas canvas) { + adjustPanLayoutHelper.update(); + super.dispatchDraw(canvas); + } + + protected void onPanTranslationUpdate(int y) { + + } + + protected void onTransitionStart() { + + } + + protected void onTransitionEnd() { + + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/AdjustPanLayoutHelper.java b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/AdjustPanLayoutHelper.java new file mode 100644 index 000000000..316711a44 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/AdjustPanLayoutHelper.java @@ -0,0 +1,79 @@ +package org.telegram.ui.ActionBar; + +import android.os.Build; +import android.view.View; + +import org.telegram.messenger.AndroidUtilities; +import org.telegram.messenger.SharedConfig; + +public class AdjustPanLayoutHelper { + + private int[] loc = new int[2]; + private final static int FRAMES_WITHOUT_MOVE_LIMIT = 5; + private View parentView; + private int framesWithoutMovement; + private int prevMovement; + private boolean wasMovement; + + public AdjustPanLayoutHelper(View parent) { + parentView = parent; + parentView.getViewTreeObserver().addOnGlobalLayoutListener(this::onUpdate); + parentView.getViewTreeObserver().addOnScrollChangedListener(this::onUpdate); + parentView.getViewTreeObserver().addOnGlobalFocusChangeListener((oldFocus, newFocus) -> onUpdate()); + } + + private void onUpdate() { + if (!SharedConfig.smoothKeyboard) { + return; + } + //prevMovement = Integer.MAX_VALUE; + framesWithoutMovement = 0; + wasMovement = false; + parentView.invalidate(); + } + + public void update() { + if (parentView.getVisibility() != View.VISIBLE || parentView.getParent() == null) { + return; + } + if (!AndroidUtilities.usingHardwareInput && SharedConfig.smoothKeyboard) { + parentView.getLocationInWindow(loc); + if (loc[1] <= 0) { + loc[1] -= parentView.getTranslationY(); + if (Build.VERSION.SDK_INT < 21) { + loc[1] -= AndroidUtilities.statusBarHeight; + } + } else { + loc[1] = 0; + } + if (loc[1] != prevMovement) { + if (!wasMovement) { + onTransitionStart(); + } + wasMovement = true; + onPanTranslationUpdate(-loc[1]); + framesWithoutMovement = 0; + prevMovement = loc[1]; + } else { + framesWithoutMovement++; + } + if (framesWithoutMovement < FRAMES_WITHOUT_MOVE_LIMIT) { + parentView.invalidate(); + } else if (wasMovement) { + onTransitionEnd(); + } + } + } + + protected void onPanTranslationUpdate(int y) { + + } + + protected void onTransitionStart() { + + } + + protected void onTransitionEnd() { + + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/AdjustPanLinearLayout.java b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/AdjustPanLinearLayout.java new file mode 100644 index 000000000..d5fcf8280 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/AdjustPanLinearLayout.java @@ -0,0 +1,30 @@ +package org.telegram.ui.ActionBar; + +import android.content.Context; +import android.graphics.Canvas; +import android.widget.LinearLayout; + +public class AdjustPanLinearLayout extends LinearLayout { + + private AdjustPanLayoutHelper adjustPanLayoutHelper; + + public AdjustPanLinearLayout(Context context) { + super(context); + adjustPanLayoutHelper = new AdjustPanLayoutHelper(this) { + @Override + protected void onPanTranslationUpdate(int y) { + AdjustPanLinearLayout.this.onPanTranslationUpdate(y); + } + }; + } + + @Override + protected void dispatchDraw(Canvas canvas) { + adjustPanLayoutHelper.update(); + super.dispatchDraw(canvas); + } + + protected void onPanTranslationUpdate(int y) { + + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/BaseFragment.java b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/BaseFragment.java index c89526573..12f0b21ac 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/BaseFragment.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/BaseFragment.java @@ -18,6 +18,7 @@ import android.os.Build; import android.os.Bundle; import android.text.TextUtils; import android.view.Menu; +import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.accessibility.AccessibilityManager; @@ -53,7 +54,6 @@ public class BaseFragment { protected boolean inPreviewMode; protected int classGuid; protected Bundle arguments; - protected boolean swipeBackEnabled = true; protected boolean hasOwnBackground = false; protected boolean isPaused = true; @@ -97,6 +97,10 @@ public class BaseFragment { return classGuid; } + public boolean isSwipeBackEnabled(MotionEvent event) { + return true; + } + protected void setInPreviewMode(boolean value) { inPreviewMode = value; if (actionBar != null) { @@ -163,7 +167,7 @@ public class BaseFragment { } if (actionBar != null) { boolean differentParent = parentLayout != null && parentLayout.getContext() != actionBar.getContext(); - if (actionBar.getAddToContainer() || differentParent) { + if (actionBar.shouldAddToContainer() || differentParent) { ViewGroup parent = (ViewGroup) actionBar.getParent(); if (parent != null) { try { @@ -445,6 +449,22 @@ public class BaseFragment { } + protected void onPanTranslationUpdate(int y) { + + } + + protected void onPanTransitionStart() { + + } + + protected void onPanTransitionEnd() { + + } + + public int getCurrentPanTranslationY() { + return parentLayout != null ? parentLayout.getCurrentPanTranslationY() : 0; + } + public Dialog getVisibleDialog() { return visibleDialog; } @@ -473,7 +493,7 @@ public class BaseFragment { return getAccountInstance().getContactsController(); } - protected MediaDataController getMediaDataController() { + public MediaDataController getMediaDataController() { return getAccountInstance().getMediaDataController(); } @@ -493,11 +513,11 @@ public class BaseFragment { return getAccountInstance().getMessagesStorage(); } - protected SendMessagesHelper getSendMessagesHelper() { + public SendMessagesHelper getSendMessagesHelper() { return getAccountInstance().getSendMessagesHelper(); } - protected FileLoader getFileLoader() { + public FileLoader getFileLoader() { return getAccountInstance().getFileLoader(); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/BottomSheet.java b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/BottomSheet.java index 8738d2cd3..bc5e1f7c1 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/BottomSheet.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/BottomSheet.java @@ -61,6 +61,8 @@ public class BottomSheet extends Dialog { protected ContainerView container; private WindowInsets lastInsets; + protected boolean useSmoothKeyboard; + protected Runnable startAnimationRunnable; private int layoutCount; @@ -695,7 +697,7 @@ public class BottomSheet extends Dialog { params.dimAmount = 0; params.flags &= ~WindowManager.LayoutParams.FLAG_DIM_BEHIND; if (focusable) { - params.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; + params.softInputMode = useSmoothKeyboard ? WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN : WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; } else { params.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; } @@ -727,7 +729,7 @@ public class BottomSheet extends Dialog { Window window = getWindow(); WindowManager.LayoutParams params = window.getAttributes(); if (focusable) { - params.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; + params.softInputMode = (useSmoothKeyboard ? WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN : WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); params.flags &=~ WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; } else { params.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING; @@ -748,7 +750,7 @@ public class BottomSheet extends Dialog { public void show() { super.show(); if (focusable) { - getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); + getWindow().setSoftInputMode(useSmoothKeyboard ? WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN : WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); } dismissed = false; cancelSheetAnimation(); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/DrawerLayoutContainer.java b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/DrawerLayoutContainer.java index 70166ca66..75ffd685b 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/DrawerLayoutContainer.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/DrawerLayoutContainer.java @@ -37,6 +37,7 @@ import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.BuildVars; import org.telegram.messenger.FileLog; import org.telegram.messenger.R; +import org.telegram.messenger.SharedConfig; public class DrawerLayoutContainer extends FrameLayout { @@ -76,9 +77,13 @@ public class DrawerLayoutContainer extends FrameLayout { private boolean drawerOpened; private boolean allowDrawContent = true; + private AdjustPanLayoutHelper adjustPanLayoutHelper; + public DrawerLayoutContainer(Context context) { super(context); + adjustPanLayoutHelper = new AdjustPanLayoutHelper(this); + minDrawerMargin = (int) (MIN_DRAWER_MARGIN * AndroidUtilities.density + 0.5f); setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS); setFocusableInTouchMode(true); @@ -488,6 +493,12 @@ public class DrawerLayoutContainer extends FrameLayout { invalidate(); } + @Override + protected void dispatchDraw(Canvas canvas) { + adjustPanLayoutHelper.update(); + super.dispatchDraw(canvas); + } + @Override protected boolean drawChild(Canvas canvas, View child, long drawingTime) { if (!allowDrawContent) { @@ -543,10 +554,12 @@ public class DrawerLayoutContainer extends FrameLayout { if (Build.VERSION.SDK_INT >= 21 && lastInsets != null) { WindowInsets insets = (WindowInsets) lastInsets; - int bottomInset = insets.getSystemWindowInsetBottom(); - if (bottomInset > 0) { - backgroundPaint.setColor(behindKeyboardColor); - canvas.drawRect(0, getMeasuredHeight() - bottomInset, getMeasuredWidth(), getMeasuredHeight(), backgroundPaint); + if (!SharedConfig.smoothKeyboard) { + int bottomInset = insets.getSystemWindowInsetBottom(); + if (bottomInset > 0) { + backgroundPaint.setColor(behindKeyboardColor); + canvas.drawRect(0, getMeasuredHeight() - bottomInset, getMeasuredWidth(), getMeasuredHeight(), backgroundPaint); + } } if (hasCutout) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/SimpleTextView.java b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/SimpleTextView.java index 919c2c002..1d18a714c 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/SimpleTextView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/SimpleTextView.java @@ -10,12 +10,13 @@ package org.telegram.ui.ActionBar; import android.content.Context; import android.graphics.Canvas; +import android.graphics.LinearGradient; import android.graphics.Paint; import android.graphics.PorterDuff; -import android.graphics.PorterDuffColorFilter; +import android.graphics.PorterDuffXfermode; +import android.graphics.Shader; import android.graphics.Typeface; import android.graphics.drawable.Drawable; -import android.graphics.drawable.GradientDrawable; import android.os.SystemClock; import android.text.Layout; import android.text.SpannableStringBuilder; @@ -49,8 +50,8 @@ public class SimpleTextView extends View implements Drawable.Callback { private float scrollingOffset; private long lastUpdateTime; private int currentScrollDelay; - private GradientDrawable fadeDrawable; - private GradientDrawable fadeDrawableBack; + private Paint fadePaint; + private Paint fadePaintBack; private int lastWidth; private int offsetX; @@ -107,8 +108,15 @@ public class SimpleTextView extends View implements Drawable.Callback { } scrollNonFitText = value; if (scrollNonFitText) { - fadeDrawable = new GradientDrawable(GradientDrawable.Orientation.LEFT_RIGHT, new int[]{0xffffffff, 0}); - fadeDrawableBack = new GradientDrawable(GradientDrawable.Orientation.LEFT_RIGHT, new int[]{0, 0xffffffff}); + fadePaint = new Paint(); + LinearGradient gradient = new LinearGradient(0, 0, AndroidUtilities.dp(6), 0, new int[]{0xffffffff, 0}, new float[]{0f, 1f}, Shader.TileMode.CLAMP); + fadePaint.setShader(gradient); + fadePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT)); + + fadePaintBack = new Paint(); + gradient = new LinearGradient(0, 0, AndroidUtilities.dp(6), 0, new int[]{0, 0xffffffff}, new float[]{0f, 1f}, Shader.TileMode.CLAMP); + fadePaintBack.setShader(gradient); + fadePaintBack.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT)); } requestLayout(); } @@ -383,6 +391,12 @@ public class SimpleTextView extends View implements Drawable.Callback { @Override protected void onDraw(Canvas canvas) { int textOffsetX = 0; + + boolean fade = scrollNonFitText && (textDoesNotFit || scrollingOffset != 0); + if (fade) { + canvas.saveLayerAlpha(0, 0, getMeasuredWidth(), getMeasuredHeight(), 255, Canvas.ALL_SAVE_FLAG); + } + totalWidth = textWidth; if (leftDrawable != null) { int x = (int) -scrollingOffset; @@ -456,37 +470,25 @@ public class SimpleTextView extends View implements Drawable.Callback { if (offsetX + textOffsetX != 0 || offsetY != 0 || scrollingOffset != 0) { canvas.restore(); } - if (scrollNonFitText && (textDoesNotFit || scrollingOffset != 0)) { + if (fade) { if (scrollingOffset < AndroidUtilities.dp(10)) { - fadeDrawable.setAlpha((int) (255 * (scrollingOffset / AndroidUtilities.dp(10)))); + fadePaint.setAlpha((int) (255 * (scrollingOffset / AndroidUtilities.dp(10)))); } else if (scrollingOffset > totalWidth + AndroidUtilities.dp(DIST_BETWEEN_SCROLLING_TEXT) - AndroidUtilities.dp(10)) { float dist = scrollingOffset - (totalWidth + AndroidUtilities.dp(DIST_BETWEEN_SCROLLING_TEXT) - AndroidUtilities.dp(10)); - fadeDrawable.setAlpha((int) (255 * (1.0f - dist / AndroidUtilities.dp(10)))); + fadePaint.setAlpha((int) (255 * (1.0f - dist / AndroidUtilities.dp(10)))); } else { - fadeDrawable.setAlpha(255); + fadePaint.setAlpha(255); } - fadeDrawable.setBounds(0, 0, AndroidUtilities.dp(6), getMeasuredHeight()); - fadeDrawable.draw(canvas); - - fadeDrawableBack.setBounds(getMeasuredWidth() - AndroidUtilities.dp(6), 0, getMeasuredWidth(), getMeasuredHeight()); - fadeDrawableBack.draw(canvas); + canvas.drawRect(0, 0, AndroidUtilities.dp(6), getMeasuredHeight(), fadePaint); + canvas.save(); + canvas.translate(getMeasuredWidth() - AndroidUtilities.dp(6), 0); + canvas.drawRect(0, 0, AndroidUtilities.dp(6), getMeasuredHeight(), fadePaintBack); + canvas.restore(); } updateScrollAnimation(); } } - @Override - public void setBackgroundColor(int color) { - if (scrollNonFitText) { - if (fadeDrawable != null) { - fadeDrawable.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.MULTIPLY)); - fadeDrawableBack.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.MULTIPLY)); - } - } else { - super.setBackgroundColor(color); - } - } - private void updateScrollAnimation() { if (!scrollNonFitText || !textDoesNotFit && scrollingOffset == 0) { return; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/Theme.java b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/Theme.java index 70a232e83..7abe892e6 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/Theme.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/Theme.java @@ -125,15 +125,25 @@ public class Theme { private boolean isSelected; private Path path; + private Rect backupRect = new Rect(); + private boolean isOut; private int topY; private boolean isTopNear; private boolean isBottomNear; - private int[] currentShadowDrawableRadius = new int[4]; + private int[] currentShadowDrawableRadius = new int[]{-1, -1, -1, -1}; private Drawable[] shadowDrawable = new Drawable[4]; - private int shadowDrawableColor = 0xffffffff; + private int[] shadowDrawableColor = new int[]{0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff}; + + private int[][] currentBackgroundDrawableRadius = new int[][]{ + {-1, -1, -1, -1}, + {-1, -1, -1, -1}}; + private Drawable[][] backgroundDrawable = new Drawable[2][4]; + private int[][] backgroundDrawableColor = new int[][]{ + {0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff}, + {0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff}}; public static final int TYPE_TEXT = 0; public static final int TYPE_MEDIA = 1; @@ -216,6 +226,55 @@ public class Theme { return paint; } + public Drawable[] getShadowDrawables() { + return shadowDrawable; + } + + public Drawable getBackgroundDrawable() { + int newRad = AndroidUtilities.dp(SharedConfig.bubbleRadius); + int idx; + if (isTopNear && isBottomNear) { + idx = 3; + } else if (isTopNear) { + idx = 2; + } else if (isBottomNear) { + idx = 1; + } else { + idx = 0; + } + int idx2 = isSelected ? 1 : 0; + if (currentBackgroundDrawableRadius[idx2][idx] != newRad) { + currentBackgroundDrawableRadius[idx2][idx] = newRad; + try { + Bitmap bitmap = Bitmap.createBitmap(dp(50), dp(40), Bitmap.Config.ARGB_8888); + Canvas canvas = new Canvas(bitmap); + + Paint shadowPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + shadowPaint.setColor(0xffffffff); + backupRect.set(getBounds()); + setBounds(0, 0, bitmap.getWidth(), bitmap.getHeight()); + draw(canvas, shadowPaint); + + backgroundDrawable[idx2][idx] = new NinePatchDrawable(bitmap, getByteBuffer(bitmap.getWidth() / 2 - 1, bitmap.getWidth() / 2 + 1, bitmap.getHeight() / 2 - 1, bitmap.getHeight() / 2 + 1).array(), new Rect(), null); + backgroundDrawableColor[idx2][idx] = 0; + setBounds(backupRect); + } catch (Throwable ignore) { + + } + } + int color; + if (isSelected) { + color = getColor(isOut ? key_chat_outBubbleSelected : key_chat_inBubbleSelected); + } else { + color = getColor(isOut ? key_chat_outBubble : key_chat_inBubble); + } + if (backgroundDrawable[idx2][idx] != null && backgroundDrawableColor[idx2][idx] != color) { + backgroundDrawable[idx2][idx].setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.MULTIPLY)); + backgroundDrawableColor[idx2][idx] = color; + } + return backgroundDrawable[idx2][idx]; + } + public Drawable getShadowDrawable() { int newRad = AndroidUtilities.dp(SharedConfig.bubbleRadius); int idx; @@ -235,7 +294,10 @@ public class Theme { Canvas canvas = new Canvas(bitmap); Paint shadowPaint = new Paint(Paint.ANTI_ALIAS_FLAG); - shadowPaint.setColor(0x155F6569); + + LinearGradient gradientShader = new LinearGradient(0, 0, 0, dp(40), new int[]{0x155F6569, 0x295F6569}, null, Shader.TileMode.CLAMP); + shadowPaint.setShader(gradientShader); + shadowPaint.setShadowLayer(2, 0, 1, 0xffffffff); if (AndroidUtilities.density > 1) { setBounds(-1, -1, bitmap.getWidth() + 1, bitmap.getHeight() + 1); @@ -253,15 +315,15 @@ public class Theme { } shadowDrawable[idx] = new NinePatchDrawable(bitmap, getByteBuffer(bitmap.getWidth() / 2 - 1, bitmap.getWidth() / 2 + 1, bitmap.getHeight() / 2 - 1, bitmap.getHeight() / 2 + 1).array(), new Rect(), null); - shadowDrawableColor = 0; + shadowDrawableColor[idx] = 0; } catch (Throwable ignore) { } } int color = getColor(isOut ? key_chat_outBubbleShadow : key_chat_inBubbleShadow); - if (shadowDrawable[idx] != null && shadowDrawableColor != color) { + if (shadowDrawable[idx] != null && shadowDrawableColor[idx] != color) { shadowDrawable[idx].setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.MULTIPLY)); - shadowDrawableColor = color; + shadowDrawableColor[idx] = color; } return shadowDrawable[idx]; } @@ -309,6 +371,14 @@ public class Theme { public void draw(Canvas canvas, Paint paintToUse) { Rect bounds = getBounds(); + if (paintToUse == null && gradientShader == null) { + Drawable background = getBackgroundDrawable(); + if (background != null) { + background.setBounds(bounds); + background.draw(canvas); + return; + } + } int padding = dp(2); int rad; int nearRad; @@ -1825,7 +1895,7 @@ public class Theme { public static int serviceSelectedMessageColorBackup; private static int serviceMessage2Color; private static int serviceSelectedMessage2Color; - private static int currentColor; + public static int currentColor; private static int currentSelectedColor; private static Drawable wallpaper; private static Drawable themedWallpaper; @@ -2602,6 +2672,11 @@ public class Theme { public static final String key_profile_verifiedCheck = "profile_verifiedCheck"; public static final String key_profile_status = "profile_status"; + public static final String key_profile_tabText = "profile_tabText"; + public static final String key_profile_tabSelectedText = "profile_tabSelectedText"; + public static final String key_profile_tabSelectedLine = "profile_tabSelectedLine"; + public static final String key_profile_tabSelector = "profile_tabSelector"; + public static final String key_sharedMedia_startStopLoadIcon = "sharedMedia_startStopLoadIcon"; public static final String key_sharedMedia_linkPlaceholder = "sharedMedia_linkPlaceholder"; public static final String key_sharedMedia_linkPlaceholderText = "sharedMedia_linkPlaceholderText"; @@ -3271,6 +3346,11 @@ public class Theme { defaultColors.put(key_profile_title, 0xffffffff); defaultColors.put(key_profile_status, 0xffd7eafa); + defaultColors.put(key_profile_tabText, 0xff878c90); + defaultColors.put(key_profile_tabSelectedText, 0xff3a95d5); + defaultColors.put(key_profile_tabSelectedLine, 0xff4fa6e9); + defaultColors.put(key_profile_tabSelector, 0x0f000000); + defaultColors.put(key_player_actionBar, 0xffffffff); defaultColors.put(key_player_actionBarSelector, 0x0f000000); defaultColors.put(key_player_actionBarTitle, 0xff2f3438); @@ -3517,6 +3597,11 @@ public class Theme { fallbackKeys.put(key_chat_inPollWrongAnswer, key_chat_attachAudioBackground); fallbackKeys.put(key_chat_outPollWrongAnswer, key_chat_attachAudioBackground); + fallbackKeys.put(key_profile_tabText, key_windowBackgroundWhiteGrayText); + fallbackKeys.put(key_profile_tabSelectedText, key_windowBackgroundWhiteBlueHeader); + fallbackKeys.put(key_profile_tabSelectedLine, key_windowBackgroundWhiteBlueHeader); + fallbackKeys.put(key_profile_tabSelector, key_listSelector); + themeAccentExclusionKeys.addAll(Arrays.asList(keys_avatar_background)); themeAccentExclusionKeys.addAll(Arrays.asList(keys_avatar_nameInMessage)); themeAccentExclusionKeys.add(key_chat_attachFileBackground); @@ -4124,6 +4209,8 @@ public class Theme { int eventType = -1; if (monthOfYear == 11 && dayOfMonth >= 24 && dayOfMonth <= 31 || monthOfYear == 0 && dayOfMonth == 1) { eventType = 0; + } else if (monthOfYear == 1 && dayOfMonth == 14) { + eventType = 1; } return eventType; } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ThemeDescription.java b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ThemeDescription.java index aaba88bd5..32f541862 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ThemeDescription.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ThemeDescription.java @@ -237,7 +237,9 @@ public class ThemeDescription { if (drawablesToUpdate[a] == null) { continue; } - if (drawablesToUpdate[a] instanceof ScamDrawable) { + if (drawablesToUpdate[a] instanceof BackDrawable) { + ((BackDrawable) drawablesToUpdate[a]).setColor(color); + } else if (drawablesToUpdate[a] instanceof ScamDrawable) { ((ScamDrawable) drawablesToUpdate[a]).setColor(color); } else if (drawablesToUpdate[a] instanceof RLottieDrawable) { if (lottieLayerName != null) { @@ -699,6 +701,7 @@ public class ThemeDescription { ((RadialProgressView) object).setProgressColor(color); } else if (object instanceof Paint) { ((Paint) object).setColor(color); + child.invalidate(); } else if (object instanceof SeekBarView) { if ((changeFlags & FLAG_PROGRESSBAR) != 0) { ((SeekBarView) object).setOuterColor(color); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ActionIntroActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ActionIntroActivity.java index 71292137a..0cd598888 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ActionIntroActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ActionIntroActivity.java @@ -249,20 +249,29 @@ public class ActionIntroActivity extends BaseFragment implements LocationControl int y = (height - imageView.getMeasuredHeight()) / 2; imageView.layout(0, y, imageView.getMeasuredWidth(), y + imageView.getMeasuredHeight()); int x = (int) (width * 0.4f); - y = (int) (height * 0.22f); + y = (int) (height * 0.08f); titleTextView.layout(x, y, x + titleTextView.getMeasuredWidth(), y + titleTextView.getMeasuredHeight()); x = (int) (width * 0.4f + (width * 0.6f - descriptionLayout.getMeasuredWidth()) / 2); - y = (int) (height * 0.39f); + y = (int) (height * 0.25f); descriptionLayout.layout(x, y, x + descriptionLayout.getMeasuredWidth(), y + descriptionLayout.getMeasuredHeight()); x = (int) (width * 0.4f + (width * 0.6f - buttonTextView.getMeasuredWidth()) / 2); - y = (int) (height * 0.74f); + y = (int) (height * 0.78f); buttonTextView.layout(x, y, x + buttonTextView.getMeasuredWidth(), y + buttonTextView.getMeasuredHeight()); } else { - int y = (int) (height * 0.148f); - imageView.layout(0, y, imageView.getMeasuredWidth(), y + imageView.getMeasuredHeight()); - y = (int) (height * 0.551f); - titleTextView.layout(0, y, titleTextView.getMeasuredWidth(), y + titleTextView.getMeasuredHeight()); - y = (int) (height * 0.631f); + int y; + if (AndroidUtilities.displaySize.y < 1800) { + y = (int) (height * 0.06f); + imageView.layout(0, y, imageView.getMeasuredWidth(), y + imageView.getMeasuredHeight()); + y = (int) (height * 0.463f); + titleTextView.layout(0, y, titleTextView.getMeasuredWidth(), y + titleTextView.getMeasuredHeight()); + y = (int) (height * 0.543f); + } else { + y = (int) (height * 0.148f); + imageView.layout(0, y, imageView.getMeasuredWidth(), y + imageView.getMeasuredHeight()); + y = (int) (height * 0.551f); + titleTextView.layout(0, y, titleTextView.getMeasuredWidth(), y + titleTextView.getMeasuredHeight()); + y = (int) (height * 0.631f); + } int x = (getMeasuredWidth() - descriptionLayout.getMeasuredWidth()) / 2; descriptionLayout.layout(x, y, x + descriptionLayout.getMeasuredWidth(), y + descriptionLayout.getMeasuredHeight()); x = (width - buttonTextView.getMeasuredWidth()) / 2; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Adapters/DrawerLayoutAdapter.java b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/DrawerLayoutAdapter.java index 8b9de9a0a..15181ca2c 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Adapters/DrawerLayoutAdapter.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/DrawerLayoutAdapter.java @@ -221,6 +221,17 @@ public class DrawerLayoutAdapter extends RecyclerListView.SelectionAdapter { items.add(null); // divider items.add(new Item(7, LocaleController.getString("InviteFriends", R.string.InviteFriends), R.drawable.menu_invite_ny)); items.add(new Item(9, LocaleController.getString("TelegramFAQ", R.string.TelegramFAQ), R.drawable.menu_help_ny)); + } else if (eventType == 1) { + items.add(new Item(2, LocaleController.getString("NewGroup", R.string.NewGroup), R.drawable.menu_groups_14)); + items.add(new Item(3, LocaleController.getString("NewSecretChat", R.string.NewSecretChat), R.drawable.menu_secret_14)); + items.add(new Item(4, LocaleController.getString("NewChannel", R.string.NewChannel), R.drawable.menu_broadcast_14)); + items.add(new Item(6, LocaleController.getString("Contacts", R.string.Contacts), R.drawable.menu_contacts_14)); + items.add(new Item(10, LocaleController.getString("Calls", R.string.Calls), R.drawable.menu_calls_14)); + items.add(new Item(11, LocaleController.getString("SavedMessages", R.string.SavedMessages), R.drawable.menu_bookmarks_14)); + items.add(new Item(8, LocaleController.getString("Settings", R.string.Settings), R.drawable.menu_settings_14)); + items.add(null); // divider + items.add(new Item(7, LocaleController.getString("InviteFriends", R.string.InviteFriends), R.drawable.menu_secret_ny)); + items.add(new Item(9, LocaleController.getString("TelegramFAQ", R.string.TelegramFAQ), R.drawable.menu_help)); } else { items.add(new Item(2, LocaleController.getString("NewGroup", R.string.NewGroup), R.drawable.menu_groups)); items.add(new Item(3, LocaleController.getString("NewSecretChat", R.string.NewSecretChat), R.drawable.menu_secret)); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ArticleViewer.java b/TMessagesProj/src/main/java/org/telegram/ui/ArticleViewer.java index f9479353e..5b7d03e97 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ArticleViewer.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ArticleViewer.java @@ -3761,7 +3761,7 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg windowLayoutParams.width = WindowManager.LayoutParams.MATCH_PARENT; windowLayoutParams.gravity = Gravity.TOP | Gravity.LEFT; windowLayoutParams.type = WindowManager.LayoutParams.LAST_APPLICATION_WINDOW; - windowLayoutParams.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; + windowLayoutParams.softInputMode = SharedConfig.smoothKeyboard ? WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN : WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; windowLayoutParams.flags = WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; if (Build.VERSION.SDK_INT >= 21) { windowLayoutParams.flags |= WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | diff --git a/TMessagesProj/src/main/java/org/telegram/ui/AudioSelectActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/AudioSelectActivity.java index c22b80448..25f4f3d48 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/AudioSelectActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/AudioSelectActivity.java @@ -55,6 +55,7 @@ import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.FileLoader; import org.telegram.messenger.FileLog; import org.telegram.messenger.R; +import org.telegram.messenger.SharedConfig; import org.telegram.messenger.UserObject; import org.telegram.tgnet.TLRPC; import org.telegram.messenger.UserConfig; @@ -212,7 +213,7 @@ public class AudioSelectActivity extends BaseFragment implements NotificationCen editText.setCursorColor(Theme.getColor(Theme.key_dialogTextBlack)); editText.setHintTextColor(Theme.getColor(Theme.key_chat_messagePanelHint)); - sizeNotifierFrameLayout = new SizeNotifierFrameLayout(context) { + sizeNotifierFrameLayout = new SizeNotifierFrameLayout(context, SharedConfig.smoothKeyboard) { private int lastNotifyWidth; private boolean ignoreLayout; @@ -225,18 +226,27 @@ public class AudioSelectActivity extends BaseFragment implements NotificationCen setMeasuredDimension(widthSize, heightSize); - int keyboardSize = getKeyboardHeight(); + int kbHeight = getKeyboardHeight(); + int keyboardSize = SharedConfig.smoothKeyboard ? 0 : kbHeight; if (keyboardSize <= AndroidUtilities.dp(20)) { if (!AndroidUtilities.isInMultiwindow && commentTextView != null && frameLayout2.getParent() == this) { heightSize -= commentTextView.getEmojiPadding(); heightMeasureSpec = MeasureSpec.makeMeasureSpec(heightSize, MeasureSpec.EXACTLY); } - } else if (commentTextView != null) { + } + + if (kbHeight > AndroidUtilities.dp(20) && commentTextView != null) { ignoreLayout = true; commentTextView.hideEmojiView(); ignoreLayout = false; } + if (SharedConfig.smoothKeyboard && commentTextView != null && commentTextView.isPopupShowing()) { + fragmentView.setTranslationY(getCurrentPanTranslationY()); + listView.setTranslationY(0); + emptyView.setTranslationY(0); + } + int childCount = getChildCount(); for (int i = 0; i < childCount; i++) { View child = getChildAt(i); @@ -269,7 +279,8 @@ public class AudioSelectActivity extends BaseFragment implements NotificationCen } final int count = getChildCount(); - int paddingBottom = commentTextView != null && frameLayout2.getParent() == this && getKeyboardHeight() <= AndroidUtilities.dp(20) && !AndroidUtilities.isInMultiwindow && !AndroidUtilities.isTablet() ? commentTextView.getEmojiPadding() : 0; + int keyboardSize = SharedConfig.smoothKeyboard ? 0 : getKeyboardHeight(); + int paddingBottom = commentTextView != null && frameLayout2.getParent() == this && keyboardSize <= AndroidUtilities.dp(20) && !AndroidUtilities.isInMultiwindow && !AndroidUtilities.isTablet() ? commentTextView.getEmojiPadding() : 0; setBottomClip(paddingBottom); for (int i = 0; i < count; i++) { @@ -323,7 +334,7 @@ public class AudioSelectActivity extends BaseFragment implements NotificationCen if (AndroidUtilities.isTablet()) { childTop = getMeasuredHeight() - child.getMeasuredHeight(); } else { - childTop = getMeasuredHeight() + getKeyboardHeight() - child.getMeasuredHeight(); + childTop = getMeasuredHeight() + keyboardSize - child.getMeasuredHeight(); } } child.layout(childLeft, childTop, childLeft + width, childTop + height); @@ -390,7 +401,7 @@ public class AudioSelectActivity extends BaseFragment implements NotificationCen listView.setOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { - if (newState == RecyclerView.SCROLL_STATE_DRAGGING && searching && searchWas) { + if (newState == RecyclerView.SCROLL_STATE_DRAGGING) { AndroidUtilities.hideKeyboard(getParentActivity().getCurrentFocus()); } } @@ -583,6 +594,21 @@ public class AudioSelectActivity extends BaseFragment implements NotificationCen return fragmentView; } + @Override + protected void onPanTranslationUpdate(int y) { + if (listView == null) { + return; + } + if (commentTextView.isPopupShowing()) { + fragmentView.setTranslationY(y); + listView.setTranslationY(0); + emptyView.setTranslationY(0); + } else { + listView.setTranslationY(y); + emptyView.setTranslationY(y); + } + } + private void updateEmptyView() { if (loadingAudio) { listView.setEmptyView(progressView); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatActionCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatActionCell.java index 9b39ae40c..214e759d2 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatActionCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatActionCell.java @@ -11,6 +11,9 @@ package org.telegram.ui.Cells; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; +import android.graphics.ColorFilter; +import android.graphics.PorterDuff; +import android.graphics.PorterDuffColorFilter; import android.text.Layout; import android.text.Spannable; import android.text.StaticLayout; @@ -78,6 +81,11 @@ public class ChatActionCell extends BaseCell { private int customDate; private CharSequence customText; + private String overrideBackground; + private String overrideText; + private ColorFilter overrideColorFilter; + private int overrideColor; + private ChatActionCellDelegate delegate; public ChatActionCell(Context context) { @@ -125,6 +133,11 @@ public class ChatActionCell extends BaseCell { } } + public void setOverrideColor(String background, String text) { + overrideBackground = background; + overrideText = text; + } + public void setMessageObject(MessageObject messageObject) { if (currentMessageObject == messageObject && (hasReplyMessage || messageObject.replyMessageObject == null)) { return; @@ -407,197 +420,222 @@ public class ChatActionCell extends BaseCell { imageReceiver.draw(canvas); } - if (textLayout != null) { - final int count = textLayout.getLineCount(); - final int corner = AndroidUtilities.dp(11); - final int cornerOffset = AndroidUtilities.dp(6); - final int cornerRest = corner - cornerOffset; - final int cornerIn = AndroidUtilities.dp(8); - int y = AndroidUtilities.dp(7); - int previousLineBottom = 0; - int previousLineHeight = 0; - int dx; - int dx2; - int dy; - for (int a = 0; a < count; a++) { - int width = findMaxWidthAroundLine(a); - int x = (getMeasuredWidth() - width - cornerRest) / 2; - width += cornerRest; - int lineBottom = textLayout.getLineBottom(a); - int height = lineBottom - previousLineBottom; - int additionalHeight = 0; - previousLineBottom = lineBottom; + if (textLayout == null) { + return; + } - boolean drawBottomCorners = a == count - 1; - boolean drawTopCorners = a == 0; + if (overrideBackground != null) { + int color = Theme.getColor(overrideBackground); + if (color != overrideColor) { + overrideColor = color; + overrideColorFilter = new PorterDuffColorFilter(overrideColor, PorterDuff.Mode.MULTIPLY); + } + for (int a = 0; a < 4; a++) { + Theme.chat_cornerOuter[a].setColorFilter(overrideColorFilter); + Theme.chat_cornerInner[a].setColorFilter(overrideColorFilter); + } + Theme.chat_actionBackgroundPaint.setColor(overrideColor); + Theme.chat_actionTextPaint.setColor(Theme.getColor(overrideText)); + } - if (drawTopCorners) { - y -= AndroidUtilities.dp(3); - height += AndroidUtilities.dp(3); - } - if (drawBottomCorners) { - height += AndroidUtilities.dp(3); - } + final int count = textLayout.getLineCount(); + final int corner = AndroidUtilities.dp(11); + final int cornerOffset = AndroidUtilities.dp(6); + final int cornerRest = corner - cornerOffset; + final int cornerIn = AndroidUtilities.dp(8); + int y = AndroidUtilities.dp(7); + int previousLineBottom = 0; + int previousLineHeight = 0; + int dx; + int dx2; + int dy; + for (int a = 0; a < count; a++) { + int width = findMaxWidthAroundLine(a); + int x = (getMeasuredWidth() - width - cornerRest) / 2; + width += cornerRest; + int lineBottom = textLayout.getLineBottom(a); + int height = lineBottom - previousLineBottom; + int additionalHeight = 0; + previousLineBottom = lineBottom; - int yOld = y; - int hOld = height; + boolean drawBottomCorners = a == count - 1; + boolean drawTopCorners = a == 0; - int drawInnerBottom = 0; - int drawInnerTop = 0; - int nextLineWidth = 0; - int prevLineWidth = 0; - if (!drawBottomCorners && a + 1 < count) { - nextLineWidth = findMaxWidthAroundLine(a + 1) + cornerRest; - if (nextLineWidth + cornerRest * 2 < width) { - drawInnerBottom = 1; - drawBottomCorners = true; - } else if (width + cornerRest * 2 < nextLineWidth) { - drawInnerBottom = 2; - } else { - drawInnerBottom = 3; - } - } - if (!drawTopCorners && a > 0) { - prevLineWidth = findMaxWidthAroundLine(a - 1) + cornerRest; - if (prevLineWidth + cornerRest * 2 < width) { - drawInnerTop = 1; - drawTopCorners = true; - } else if (width + cornerRest * 2 < prevLineWidth) { - drawInnerTop = 2; - } else { - drawInnerTop = 3; - } - } - - if (drawInnerBottom != 0) { - if (drawInnerBottom == 1) { - int nextX = (getMeasuredWidth() - nextLineWidth) / 2; - additionalHeight = AndroidUtilities.dp(3); - - if (isLineBottom(nextLineWidth, width, a + 1, count, cornerRest)) { - canvas.drawRect(x + cornerOffset, y + height, nextX - cornerRest, y + height + AndroidUtilities.dp(3), Theme.chat_actionBackgroundPaint); - canvas.drawRect(nextX + nextLineWidth + cornerRest, y + height, x + width - cornerOffset, y + height + AndroidUtilities.dp(3), Theme.chat_actionBackgroundPaint); - } else { - canvas.drawRect(x + cornerOffset, y + height, nextX, y + height + AndroidUtilities.dp(3), Theme.chat_actionBackgroundPaint); - canvas.drawRect(nextX + nextLineWidth, y + height, x + width - cornerOffset, y + height + AndroidUtilities.dp(3), Theme.chat_actionBackgroundPaint); - } - } else if (drawInnerBottom == 2) { - additionalHeight = AndroidUtilities.dp(3); - - dy = y + height - AndroidUtilities.dp(11); - - dx = x - cornerIn; - if (drawInnerTop != 2 && drawInnerTop != 3) { - dx -= cornerRest; - } - if (drawTopCorners || drawBottomCorners) { - canvas.drawRect(dx + cornerIn, dy + AndroidUtilities.dp(3), dx + cornerIn + corner, dy + corner, Theme.chat_actionBackgroundPaint); - } - Theme.chat_cornerInner[2].setBounds(dx, dy, dx + cornerIn, dy + cornerIn); - Theme.chat_cornerInner[2].draw(canvas); - - dx = x + width; - if (drawInnerTop != 2 && drawInnerTop != 3) { - dx += cornerRest; - } - if (drawTopCorners || drawBottomCorners) { - canvas.drawRect(dx - corner, dy + AndroidUtilities.dp(3), dx, dy + corner, Theme.chat_actionBackgroundPaint); - } - Theme.chat_cornerInner[3].setBounds(dx, dy, dx + cornerIn, dy + cornerIn); - Theme.chat_cornerInner[3].draw(canvas); - } else { - additionalHeight = AndroidUtilities.dp(6); - } - } - if (drawInnerTop != 0) { - if (drawInnerTop == 1) { - int prevX = (getMeasuredWidth() - prevLineWidth) / 2; - - y -= AndroidUtilities.dp(3); - height += AndroidUtilities.dp(3); - - if (isLineTop(prevLineWidth, width, a - 1, count, cornerRest)) { - canvas.drawRect(x + cornerOffset, y, prevX - cornerRest, y + AndroidUtilities.dp(3), Theme.chat_actionBackgroundPaint); - canvas.drawRect(prevX + prevLineWidth + cornerRest, y, x + width - cornerOffset, y + AndroidUtilities.dp(3), Theme.chat_actionBackgroundPaint); - } else { - canvas.drawRect(x + cornerOffset, y, prevX, y + AndroidUtilities.dp(3), Theme.chat_actionBackgroundPaint); - canvas.drawRect(prevX + prevLineWidth, y, x + width - cornerOffset, y + AndroidUtilities.dp(3), Theme.chat_actionBackgroundPaint); - } - } else if (drawInnerTop == 2) { - y -= AndroidUtilities.dp(3); - height += AndroidUtilities.dp(3); - - dy = previousLineHeight; - - dx = x - cornerIn; - if (drawInnerBottom != 2 && drawInnerBottom != 3) { - dx -= cornerRest; - } - if (drawTopCorners || drawBottomCorners) { - canvas.drawRect(dx + cornerIn, y + AndroidUtilities.dp(3), dx + cornerIn + corner, y + AndroidUtilities.dp(11), Theme.chat_actionBackgroundPaint); - } - Theme.chat_cornerInner[0].setBounds(dx, dy, dx + cornerIn, dy + cornerIn); - Theme.chat_cornerInner[0].draw(canvas); - - dx = x + width; - if (drawInnerBottom != 2 && drawInnerBottom != 3) { - dx += cornerRest; - } - if (drawTopCorners || drawBottomCorners) { - canvas.drawRect(dx - corner, y + AndroidUtilities.dp(3), dx, y + AndroidUtilities.dp(11), Theme.chat_actionBackgroundPaint); - } - Theme.chat_cornerInner[1].setBounds(dx, dy, dx + cornerIn, dy + cornerIn); - Theme.chat_cornerInner[1].draw(canvas); - } else { - y -= AndroidUtilities.dp(6); - height += AndroidUtilities.dp(6); - } - } - - if (drawTopCorners || drawBottomCorners) { - canvas.drawRect(x + cornerOffset, yOld, x + width - cornerOffset, yOld + hOld, Theme.chat_actionBackgroundPaint); - } else { - canvas.drawRect(x, yOld, x + width, yOld + hOld, Theme.chat_actionBackgroundPaint); - } - - dx = x - cornerRest; - dx2 = x + width - cornerOffset; - if (drawTopCorners && !drawBottomCorners && drawInnerBottom != 2) { - canvas.drawRect(dx, y + corner, dx + corner, y + height + additionalHeight - AndroidUtilities.dp(6), Theme.chat_actionBackgroundPaint); - canvas.drawRect(dx2, y + corner, dx2 + corner, y + height + additionalHeight - AndroidUtilities.dp(6), Theme.chat_actionBackgroundPaint); - } else if (drawBottomCorners && !drawTopCorners && drawInnerTop != 2) { - canvas.drawRect(dx, y + corner - AndroidUtilities.dp(5), dx + corner, y + height + additionalHeight - corner, Theme.chat_actionBackgroundPaint); - canvas.drawRect(dx2, y + corner - AndroidUtilities.dp(5), dx2 + corner, y + height + additionalHeight - corner, Theme.chat_actionBackgroundPaint); - } else if (drawTopCorners || drawBottomCorners) { - canvas.drawRect(dx, y + corner, dx + corner, y + height + additionalHeight - corner, Theme.chat_actionBackgroundPaint); - canvas.drawRect(dx2, y + corner, dx2 + corner, y + height + additionalHeight - corner, Theme.chat_actionBackgroundPaint); - } - - if (drawTopCorners) { - Theme.chat_cornerOuter[0].setBounds(dx, y, dx + corner, y + corner); - Theme.chat_cornerOuter[0].draw(canvas); - Theme.chat_cornerOuter[1].setBounds(dx2, y, dx2 + corner, y + corner); - Theme.chat_cornerOuter[1].draw(canvas); - } - - if (drawBottomCorners) { - dy = y + height + additionalHeight - corner; - - Theme.chat_cornerOuter[2].setBounds(dx2, dy, dx2 + corner, dy + corner); - Theme.chat_cornerOuter[2].draw(canvas); - Theme.chat_cornerOuter[3].setBounds(dx, dy, dx + corner, dy + corner); - Theme.chat_cornerOuter[3].draw(canvas); - } - - y += height; - - previousLineHeight = y + additionalHeight; + if (drawTopCorners) { + y -= AndroidUtilities.dp(3); + height += AndroidUtilities.dp(3); + } + if (drawBottomCorners) { + height += AndroidUtilities.dp(3); } - canvas.save(); - canvas.translate(textXLeft, textY); - textLayout.draw(canvas); - canvas.restore(); + int yOld = y; + int hOld = height; + + int drawInnerBottom = 0; + int drawInnerTop = 0; + int nextLineWidth = 0; + int prevLineWidth = 0; + if (!drawBottomCorners && a + 1 < count) { + nextLineWidth = findMaxWidthAroundLine(a + 1) + cornerRest; + if (nextLineWidth + cornerRest * 2 < width) { + drawInnerBottom = 1; + drawBottomCorners = true; + } else if (width + cornerRest * 2 < nextLineWidth) { + drawInnerBottom = 2; + } else { + drawInnerBottom = 3; + } + } + if (!drawTopCorners && a > 0) { + prevLineWidth = findMaxWidthAroundLine(a - 1) + cornerRest; + if (prevLineWidth + cornerRest * 2 < width) { + drawInnerTop = 1; + drawTopCorners = true; + } else if (width + cornerRest * 2 < prevLineWidth) { + drawInnerTop = 2; + } else { + drawInnerTop = 3; + } + } + + if (drawInnerBottom != 0) { + if (drawInnerBottom == 1) { + int nextX = (getMeasuredWidth() - nextLineWidth) / 2; + additionalHeight = AndroidUtilities.dp(3); + + if (isLineBottom(nextLineWidth, width, a + 1, count, cornerRest)) { + canvas.drawRect(x + cornerOffset, y + height, nextX - cornerRest, y + height + AndroidUtilities.dp(3), Theme.chat_actionBackgroundPaint); + canvas.drawRect(nextX + nextLineWidth + cornerRest, y + height, x + width - cornerOffset, y + height + AndroidUtilities.dp(3), Theme.chat_actionBackgroundPaint); + } else { + canvas.drawRect(x + cornerOffset, y + height, nextX, y + height + AndroidUtilities.dp(3), Theme.chat_actionBackgroundPaint); + canvas.drawRect(nextX + nextLineWidth, y + height, x + width - cornerOffset, y + height + AndroidUtilities.dp(3), Theme.chat_actionBackgroundPaint); + } + } else if (drawInnerBottom == 2) { + additionalHeight = AndroidUtilities.dp(3); + + dy = y + height - AndroidUtilities.dp(11); + + dx = x - cornerIn; + if (drawInnerTop != 2 && drawInnerTop != 3) { + dx -= cornerRest; + } + if (drawTopCorners || drawBottomCorners) { + canvas.drawRect(dx + cornerIn, dy + AndroidUtilities.dp(3), dx + cornerIn + corner, dy + corner, Theme.chat_actionBackgroundPaint); + } + Theme.chat_cornerInner[2].setBounds(dx, dy, dx + cornerIn, dy + cornerIn); + Theme.chat_cornerInner[2].draw(canvas); + + dx = x + width; + if (drawInnerTop != 2 && drawInnerTop != 3) { + dx += cornerRest; + } + if (drawTopCorners || drawBottomCorners) { + canvas.drawRect(dx - corner, dy + AndroidUtilities.dp(3), dx, dy + corner, Theme.chat_actionBackgroundPaint); + } + Theme.chat_cornerInner[3].setBounds(dx, dy, dx + cornerIn, dy + cornerIn); + Theme.chat_cornerInner[3].draw(canvas); + } else { + additionalHeight = AndroidUtilities.dp(6); + } + } + if (drawInnerTop != 0) { + if (drawInnerTop == 1) { + int prevX = (getMeasuredWidth() - prevLineWidth) / 2; + + y -= AndroidUtilities.dp(3); + height += AndroidUtilities.dp(3); + + if (isLineTop(prevLineWidth, width, a - 1, count, cornerRest)) { + canvas.drawRect(x + cornerOffset, y, prevX - cornerRest, y + AndroidUtilities.dp(3), Theme.chat_actionBackgroundPaint); + canvas.drawRect(prevX + prevLineWidth + cornerRest, y, x + width - cornerOffset, y + AndroidUtilities.dp(3), Theme.chat_actionBackgroundPaint); + } else { + canvas.drawRect(x + cornerOffset, y, prevX, y + AndroidUtilities.dp(3), Theme.chat_actionBackgroundPaint); + canvas.drawRect(prevX + prevLineWidth, y, x + width - cornerOffset, y + AndroidUtilities.dp(3), Theme.chat_actionBackgroundPaint); + } + } else if (drawInnerTop == 2) { + y -= AndroidUtilities.dp(3); + height += AndroidUtilities.dp(3); + + dy = previousLineHeight; + + dx = x - cornerIn; + if (drawInnerBottom != 2 && drawInnerBottom != 3) { + dx -= cornerRest; + } + if (drawTopCorners || drawBottomCorners) { + canvas.drawRect(dx + cornerIn, y + AndroidUtilities.dp(3), dx + cornerIn + corner, y + AndroidUtilities.dp(11), Theme.chat_actionBackgroundPaint); + } + Theme.chat_cornerInner[0].setBounds(dx, dy, dx + cornerIn, dy + cornerIn); + Theme.chat_cornerInner[0].draw(canvas); + + dx = x + width; + if (drawInnerBottom != 2 && drawInnerBottom != 3) { + dx += cornerRest; + } + if (drawTopCorners || drawBottomCorners) { + canvas.drawRect(dx - corner, y + AndroidUtilities.dp(3), dx, y + AndroidUtilities.dp(11), Theme.chat_actionBackgroundPaint); + } + Theme.chat_cornerInner[1].setBounds(dx, dy, dx + cornerIn, dy + cornerIn); + Theme.chat_cornerInner[1].draw(canvas); + } else { + y -= AndroidUtilities.dp(6); + height += AndroidUtilities.dp(6); + } + } + + if (drawTopCorners || drawBottomCorners) { + canvas.drawRect(x + cornerOffset, yOld, x + width - cornerOffset, yOld + hOld, Theme.chat_actionBackgroundPaint); + } else { + canvas.drawRect(x, yOld, x + width, yOld + hOld, Theme.chat_actionBackgroundPaint); + } + + dx = x - cornerRest; + dx2 = x + width - cornerOffset; + if (drawTopCorners && !drawBottomCorners && drawInnerBottom != 2) { + canvas.drawRect(dx, y + corner, dx + corner, y + height + additionalHeight - AndroidUtilities.dp(6), Theme.chat_actionBackgroundPaint); + canvas.drawRect(dx2, y + corner, dx2 + corner, y + height + additionalHeight - AndroidUtilities.dp(6), Theme.chat_actionBackgroundPaint); + } else if (drawBottomCorners && !drawTopCorners && drawInnerTop != 2) { + canvas.drawRect(dx, y + corner - AndroidUtilities.dp(5), dx + corner, y + height + additionalHeight - corner, Theme.chat_actionBackgroundPaint); + canvas.drawRect(dx2, y + corner - AndroidUtilities.dp(5), dx2 + corner, y + height + additionalHeight - corner, Theme.chat_actionBackgroundPaint); + } else if (drawTopCorners || drawBottomCorners) { + canvas.drawRect(dx, y + corner, dx + corner, y + height + additionalHeight - corner, Theme.chat_actionBackgroundPaint); + canvas.drawRect(dx2, y + corner, dx2 + corner, y + height + additionalHeight - corner, Theme.chat_actionBackgroundPaint); + } + + if (drawTopCorners) { + Theme.chat_cornerOuter[0].setBounds(dx, y, dx + corner, y + corner); + Theme.chat_cornerOuter[0].draw(canvas); + Theme.chat_cornerOuter[1].setBounds(dx2, y, dx2 + corner, y + corner); + Theme.chat_cornerOuter[1].draw(canvas); + } + + if (drawBottomCorners) { + dy = y + height + additionalHeight - corner; + + Theme.chat_cornerOuter[2].setBounds(dx2, dy, dx2 + corner, dy + corner); + Theme.chat_cornerOuter[2].draw(canvas); + Theme.chat_cornerOuter[3].setBounds(dx, dy, dx + corner, dy + corner); + Theme.chat_cornerOuter[3].draw(canvas); + } + + y += height; + + previousLineHeight = y + additionalHeight; + } + + canvas.save(); + canvas.translate(textXLeft, textY); + textLayout.draw(canvas); + canvas.restore(); + + if (overrideColorFilter != null) { + for (int a = 0; a < 4; a++) { + Theme.chat_cornerOuter[a].setColorFilter(Theme.colorFilter); + Theme.chat_cornerInner[a].setColorFilter(Theme.colorFilter); + } + Theme.chat_actionBackgroundPaint.setColor(Theme.currentColor); + Theme.chat_actionTextPaint.setColor(Theme.getColor(Theme.key_chat_serviceText)); } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMessageCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMessageCell.java index e2189e99e..8a3f25ff1 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMessageCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMessageCell.java @@ -4187,6 +4187,8 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate currentPhotoObjectThumb = FileLoader.getClosestPhotoSizeWithSize(messageObject.photoThumbs, 40); photoParentObject = messageObject.photoThumbsObject; + photoImage.setRoundRadius(0); + canChangeRadius = false; if (messageObject.attachPathExists) { photoImage.setImage(ImageLocation.getForPath(messageObject.messageOwner.attachPath), filter, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), "b1", @@ -4365,9 +4367,6 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate } else { w = h = (int) (Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y) * 0.5f); } - } else if (messageObject.isAnyKindOfSticker()) { - photoImage.setRoundRadius(0); - canChangeRadius = false; } int widthForCaption = 0; @@ -5753,7 +5752,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate timeX += AndroidUtilities.dp(4); } } - if (SharedConfig.bubbleRadius >= 10 && captionLayout == null) { + if (SharedConfig.bubbleRadius >= 10 && captionLayout == null && documentAttachType != DOCUMENT_ATTACH_TYPE_ROUND && documentAttachType != DOCUMENT_ATTACH_TYPE_STICKER) { timeX -= AndroidUtilities.dp(2); } } else { @@ -7934,7 +7933,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate viaWidth = (int) Math.ceil(Theme.chat_replyNamePaint.measureText(viaString, 0, viaString.length())); } - boolean authorName = !pinnedTop && drawName && isChat && !currentMessageObject.isOutOwner(); + boolean authorName = (!pinnedTop || ChatObject.isChannel(currentChat) && !currentChat.megagroup) && drawName && isChat && !currentMessageObject.isOutOwner(); boolean viaBot = (messageObject.messageOwner.fwd_from == null || messageObject.type == 14) && viaUsername != null; if (authorName || viaBot) { drawNameLayout = true; @@ -8945,6 +8944,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate if (drawPinnedBottom) { canvas.translate(0, AndroidUtilities.dp(2)); } + boolean bigRadius = false; if (mediaBackground && captionLayout == null) { Paint paint; if (currentMessageObject.shouldDrawWithoutBackground()) { @@ -8955,16 +8955,19 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate int oldAlpha = paint.getAlpha(); paint.setAlpha((int) (oldAlpha * timeAlpha)); Theme.chat_timePaint.setAlpha((int) (255 * timeAlpha)); - int x1 = timeX - AndroidUtilities.dp(SharedConfig.bubbleRadius >= 10 ? 6 : 4); - int y1 = layoutHeight - AndroidUtilities.dp(28); - rect.set(x1, y1, x1 + timeWidth + AndroidUtilities.dp((SharedConfig.bubbleRadius >= 10 ? 12 : 8) + (currentMessageObject.isOutOwner() ? 20 : 0)), y1 + AndroidUtilities.dp(17)); + int r; - if (documentAttachType != DOCUMENT_ATTACH_TYPE_ROUND) { + if (documentAttachType != DOCUMENT_ATTACH_TYPE_ROUND && documentAttachType != DOCUMENT_ATTACH_TYPE_STICKER) { int[] rad = photoImage.getRoundRadius(); r = Math.min(AndroidUtilities.dp(8), Math.max(rad[2], rad[3])); + bigRadius = SharedConfig.bubbleRadius >= 10; } else { r = AndroidUtilities.dp(4); } + int x1 = timeX - AndroidUtilities.dp(bigRadius ? 6 : 4); + int y1 = layoutHeight - AndroidUtilities.dp(28); + rect.set(x1, y1, x1 + timeWidth + AndroidUtilities.dp((bigRadius ? 12 : 8) + (currentMessageObject.isOutOwner() ? 20 : 0)), y1 + AndroidUtilities.dp(17)); + canvas.drawRoundRect(rect, r, r, paint); paint.setAlpha(oldAlpha); @@ -9088,11 +9091,11 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate if (mediaBackground && captionLayout == null) { if (currentMessageObject.shouldDrawWithoutBackground()) { Theme.chat_msgStickerClockDrawable.setAlpha((int) (255 * timeAlpha)); - setDrawableBounds(Theme.chat_msgStickerClockDrawable, layoutWidth - AndroidUtilities.dp(22.0f) - Theme.chat_msgStickerClockDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(13.5f) - Theme.chat_msgStickerClockDrawable.getIntrinsicHeight()); + setDrawableBounds(Theme.chat_msgStickerClockDrawable, layoutWidth - AndroidUtilities.dp(bigRadius ? 24 : 22) - Theme.chat_msgStickerClockDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(13.5f) - Theme.chat_msgStickerClockDrawable.getIntrinsicHeight()); Theme.chat_msgStickerClockDrawable.draw(canvas); Theme.chat_msgStickerClockDrawable.setAlpha(255); } else { - setDrawableBounds(Theme.chat_msgMediaClockDrawable, layoutWidth - AndroidUtilities.dp(22.0f) - Theme.chat_msgMediaClockDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(13.5f) - Theme.chat_msgMediaClockDrawable.getIntrinsicHeight()); + setDrawableBounds(Theme.chat_msgMediaClockDrawable, layoutWidth - AndroidUtilities.dp(bigRadius ? 24 : 22) - Theme.chat_msgMediaClockDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(13.5f) - Theme.chat_msgMediaClockDrawable.getIntrinsicHeight()); Theme.chat_msgMediaClockDrawable.draw(canvas); } } else { @@ -9104,7 +9107,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate if (isBroadcast) { if (drawCheck1 || drawCheck2) { if (mediaBackground && captionLayout == null) { - setDrawableBounds(Theme.chat_msgBroadcastMediaDrawable, layoutWidth - AndroidUtilities.dp(24.0f) - Theme.chat_msgBroadcastMediaDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(14.0f) - Theme.chat_msgBroadcastMediaDrawable.getIntrinsicHeight()); + setDrawableBounds(Theme.chat_msgBroadcastMediaDrawable, layoutWidth - AndroidUtilities.dp(bigRadius ? 26 : 24) - Theme.chat_msgBroadcastMediaDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(14.0f) - Theme.chat_msgBroadcastMediaDrawable.getIntrinsicHeight()); Theme.chat_msgBroadcastMediaDrawable.draw(canvas); } else { setDrawableBounds(Theme.chat_msgBroadcastDrawable, layoutWidth - AndroidUtilities.dp(20.5f) - Theme.chat_msgBroadcastDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(8.0f) - Theme.chat_msgBroadcastDrawable.getIntrinsicHeight()); @@ -9116,16 +9119,16 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate if (mediaBackground && captionLayout == null) { if (currentMessageObject.shouldDrawWithoutBackground()) { if (drawCheck1) { - setDrawableBounds(Theme.chat_msgStickerCheckDrawable, layoutWidth - AndroidUtilities.dp(26.3f) - Theme.chat_msgStickerCheckDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(13.5f) - Theme.chat_msgStickerCheckDrawable.getIntrinsicHeight()); + setDrawableBounds(Theme.chat_msgStickerCheckDrawable, layoutWidth - AndroidUtilities.dp(bigRadius ? 28.3f : 26.3f) - Theme.chat_msgStickerCheckDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(13.5f) - Theme.chat_msgStickerCheckDrawable.getIntrinsicHeight()); } else { - setDrawableBounds(Theme.chat_msgStickerCheckDrawable, layoutWidth - AndroidUtilities.dp(21.5f) - Theme.chat_msgStickerCheckDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(13.5f) - Theme.chat_msgStickerCheckDrawable.getIntrinsicHeight()); + setDrawableBounds(Theme.chat_msgStickerCheckDrawable, layoutWidth - AndroidUtilities.dp(bigRadius ? 23.5f : 21.5f) - Theme.chat_msgStickerCheckDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(13.5f) - Theme.chat_msgStickerCheckDrawable.getIntrinsicHeight()); } Theme.chat_msgStickerCheckDrawable.draw(canvas); } else { if (drawCheck1) { - setDrawableBounds(Theme.chat_msgMediaCheckDrawable, layoutWidth - AndroidUtilities.dp(26.3f) - Theme.chat_msgMediaCheckDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(13.5f) - Theme.chat_msgMediaCheckDrawable.getIntrinsicHeight()); + setDrawableBounds(Theme.chat_msgMediaCheckDrawable, layoutWidth - AndroidUtilities.dp(bigRadius ? 28.3f : 26.3f) - Theme.chat_msgMediaCheckDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(13.5f) - Theme.chat_msgMediaCheckDrawable.getIntrinsicHeight()); } else { - setDrawableBounds(Theme.chat_msgMediaCheckDrawable, layoutWidth - AndroidUtilities.dp(21.5f) - Theme.chat_msgMediaCheckDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(13.5f) - Theme.chat_msgMediaCheckDrawable.getIntrinsicHeight()); + setDrawableBounds(Theme.chat_msgMediaCheckDrawable, layoutWidth - AndroidUtilities.dp(bigRadius ? 23.5f : 21.5f) - Theme.chat_msgMediaCheckDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(13.5f) - Theme.chat_msgMediaCheckDrawable.getIntrinsicHeight()); } Theme.chat_msgMediaCheckDrawable.setAlpha((int) (255 * timeAlpha)); Theme.chat_msgMediaCheckDrawable.draw(canvas); @@ -9135,10 +9138,10 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate Drawable drawable; if (drawCheck1) { drawable = isDrawSelectionBackground() ? Theme.chat_msgOutCheckReadSelectedDrawable : Theme.chat_msgOutCheckReadDrawable; - setDrawableBounds(drawable, layoutWidth - AndroidUtilities.dp(22.5f) - drawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(8.0f) - drawable.getIntrinsicHeight()); + setDrawableBounds(drawable, layoutWidth - AndroidUtilities.dp(22.5f) - drawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(pinnedBottom || pinnedTop ? 9 : 8) - drawable.getIntrinsicHeight()); } else { drawable = isDrawSelectionBackground() ? Theme.chat_msgOutCheckSelectedDrawable : Theme.chat_msgOutCheckDrawable; - setDrawableBounds(drawable, layoutWidth - AndroidUtilities.dp(18.5f) - drawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(8.0f) - drawable.getIntrinsicHeight()); + setDrawableBounds(drawable, layoutWidth - AndroidUtilities.dp(18.5f) - drawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(pinnedBottom || pinnedTop ? 9 : 8) - drawable.getIntrinsicHeight()); } drawable.draw(canvas); } @@ -9146,17 +9149,17 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate if (drawCheck1) { if (mediaBackground && captionLayout == null) { if (currentMessageObject.shouldDrawWithoutBackground()) { - setDrawableBounds(Theme.chat_msgStickerHalfCheckDrawable, layoutWidth - AndroidUtilities.dp(21.5f) - Theme.chat_msgStickerHalfCheckDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(13.5f) - Theme.chat_msgStickerHalfCheckDrawable.getIntrinsicHeight()); + setDrawableBounds(Theme.chat_msgStickerHalfCheckDrawable, layoutWidth - AndroidUtilities.dp(bigRadius ? 23.5f : 21.5f) - Theme.chat_msgStickerHalfCheckDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(13.5f) - Theme.chat_msgStickerHalfCheckDrawable.getIntrinsicHeight()); Theme.chat_msgStickerHalfCheckDrawable.draw(canvas); } else { - setDrawableBounds(Theme.chat_msgMediaHalfCheckDrawable, layoutWidth - AndroidUtilities.dp(21.5f) - Theme.chat_msgMediaHalfCheckDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(13.5f) - Theme.chat_msgMediaHalfCheckDrawable.getIntrinsicHeight()); + setDrawableBounds(Theme.chat_msgMediaHalfCheckDrawable, layoutWidth - AndroidUtilities.dp(bigRadius ? 23.5f : 21.5f) - Theme.chat_msgMediaHalfCheckDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(13.5f) - Theme.chat_msgMediaHalfCheckDrawable.getIntrinsicHeight()); Theme.chat_msgMediaHalfCheckDrawable.setAlpha((int) (255 * timeAlpha)); Theme.chat_msgMediaHalfCheckDrawable.draw(canvas); Theme.chat_msgMediaHalfCheckDrawable.setAlpha(255); } } else { Drawable drawable = isDrawSelectionBackground() ? Theme.chat_msgOutHalfCheckSelectedDrawable : Theme.chat_msgOutHalfCheckDrawable; - setDrawableBounds(drawable, layoutWidth - AndroidUtilities.dp(18) - drawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(8.0f) - drawable.getIntrinsicHeight()); + setDrawableBounds(drawable, layoutWidth - AndroidUtilities.dp(18) - drawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(pinnedBottom || pinnedTop ? 9 : 8) - drawable.getIntrinsicHeight()); drawable.draw(canvas); } } @@ -9169,7 +9172,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate y = layoutHeight - AndroidUtilities.dp(26.5f); } else { x = layoutWidth - AndroidUtilities.dp(32); - y = layoutHeight - AndroidUtilities.dp(21); + y = layoutHeight - AndroidUtilities.dp(pinnedBottom || pinnedTop ? 22 : 21); } rect.set(x, y, x + AndroidUtilities.dp(14), y + AndroidUtilities.dp(14)); canvas.drawRoundRect(rect, AndroidUtilities.dp(1), AndroidUtilities.dp(1), Theme.chat_msgErrorPaint); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ManageChatUserCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ManageChatUserCell.java index 66155cdd9..ed97b8617 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ManageChatUserCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ManageChatUserCell.java @@ -134,6 +134,13 @@ public class ManageChatUserCell extends FrameLayout { super.onMeasure(MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(64) + (needDivider ? 1 : 0), MeasureSpec.EXACTLY)); } + public int getUserId() { + if (currentObject instanceof TLRPC.User) { + return ((TLRPC.User) currentObject).id; + } + return 0; + } + public void setStatusColors(int color, int onlineColor) { statusColor = color; statusOnlineColor = onlineColor; @@ -143,6 +150,10 @@ public class ManageChatUserCell extends FrameLayout { isAdmin = value; } + public boolean hasAvatarSet() { + return avatarImageView.getImageReceiver().hasNotThumb(); + } + public void update(int mask) { if (currentObject == null) { return; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ProfileSearchCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ProfileSearchCell.java index 1bd6b16d3..3921cc6e1 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ProfileSearchCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ProfileSearchCell.java @@ -204,6 +204,14 @@ public class ProfileSearchCell extends BaseCell { } } + public TLRPC.User getUser() { + return user; + } + + public TLRPC.Chat getChat() { + return chat; + } + public void setSublabelOffset(int x, int y) { sublabelOffsetX = x; sublabelOffsetY = y; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/SharedPhotoVideoCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/SharedPhotoVideoCell.java index c9e924740..224210fc1 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/SharedPhotoVideoCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/SharedPhotoVideoCell.java @@ -271,6 +271,24 @@ public class SharedPhotoVideoCell extends FrameLayout { } } + @Override + public void invalidate() { + for (int a = 0; a < 6; a++) { + photoVideoViews[a].invalidate(); + } + super.invalidate(); + } + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + } + + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + } + public void setDelegate(SharedPhotoVideoCellDelegate delegate) { this.delegate = delegate; } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ChangePhoneActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ChangePhoneActivity.java index b4dc1bfc3..a1bfa8b84 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ChangePhoneActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ChangePhoneActivity.java @@ -838,7 +838,6 @@ public class ChangePhoneActivity extends BaseFragment { private Timer timeTimer; private Timer codeTimer; - private int openTime; private final Object timerSync = new Object(); private int time = 60000; private int codeTime = 15000; @@ -1100,7 +1099,6 @@ public class ChangePhoneActivity extends BaseFragment { requestPhone = params.getString("phoneFormated"); phoneHash = params.getString("phoneHash"); timeout = time = params.getInt("timeout"); - openTime = (int) (System.currentTimeMillis() / 1000); nextType = params.getInt("nextType"); pattern = params.getString("pattern"); length = params.getInt("length"); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ChannelAdminLogActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ChannelAdminLogActivity.java index 4f720cb13..b95bc740f 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ChannelAdminLogActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ChannelAdminLogActivity.java @@ -32,7 +32,7 @@ import android.os.Build; import android.os.Bundle; import androidx.core.content.FileProvider; import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.LinearSmoothScrollerMiddle; +import androidx.recyclerview.widget.LinearSmoothScrollerCustom; import androidx.recyclerview.widget.RecyclerView; import android.text.TextUtils; @@ -73,6 +73,7 @@ import org.telegram.messenger.MessageObject; import org.telegram.messenger.MessagesController; import org.telegram.messenger.NotificationCenter; import org.telegram.messenger.R; +import org.telegram.messenger.SharedConfig; import org.telegram.messenger.UserConfig; import org.telegram.messenger.Utilities; import org.telegram.messenger.browser.Browser; @@ -556,7 +557,7 @@ public class ChannelAdminLogActivity extends BaseFragment implements Notificatio avatarContainer.setSubtitle(LocaleController.getString("EventLogAllEvents", R.string.EventLogAllEvents)); avatarContainer.setChatAvatar(currentChat); - fragmentView = new SizeNotifierFrameLayout(context) { + fragmentView = new SizeNotifierFrameLayout(context, SharedConfig.smoothKeyboard) { @Override protected void onAttachedToWindow() { @@ -596,8 +597,6 @@ public class ChannelAdminLogActivity extends BaseFragment implements Notificatio heightSize -= actionBarHeight; } - int keyboardSize = getKeyboardHeight(); - int childCount = getChildCount(); for (int i = 0; i < childCount; i++) { @@ -773,7 +772,7 @@ public class ChannelAdminLogActivity extends BaseFragment implements Notificatio @Override public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) { - LinearSmoothScrollerMiddle linearSmoothScroller = new LinearSmoothScrollerMiddle(recyclerView.getContext()); + LinearSmoothScrollerCustom linearSmoothScroller = new LinearSmoothScrollerCustom(recyclerView.getContext(), LinearSmoothScrollerCustom.POSITION_MIDDLE); linearSmoothScroller.setTargetPosition(position); startSmoothScroll(linearSmoothScroller); } @@ -1958,7 +1957,7 @@ public class ChannelAdminLogActivity extends BaseFragment implements Notificatio args.putInt("user_id", user.id); addCanBanUser(args, user.id); ProfileActivity fragment = new ProfileActivity(args); - fragment.setPlayProfileAnimation(false); + fragment.setPlayProfileAnimation(0); presentFragment(fragment); } } @@ -2188,7 +2187,7 @@ public class ChannelAdminLogActivity extends BaseFragment implements Notificatio args.putInt("user_id", uid); addCanBanUser(args, uid); ProfileActivity fragment = new ProfileActivity(args); - fragment.setPlayProfileAnimation(false); + fragment.setPlayProfileAnimation(0); presentFragment(fragment); } } @@ -2429,11 +2428,13 @@ public class ChannelAdminLogActivity extends BaseFragment implements Notificatio new ThemeDescription(chatListView, 0, new Class[]{ChatMessageCell.class}, null, null, null, Theme.key_avatar_nameInMessagePink), new ThemeDescription(chatListView, 0, new Class[]{ChatMessageCell.class}, null, new Drawable[]{Theme.chat_msgInDrawable, Theme.chat_msgInMediaDrawable}, null, Theme.key_chat_inBubble), new ThemeDescription(chatListView, 0, new Class[]{ChatMessageCell.class}, null, new Drawable[]{Theme.chat_msgInSelectedDrawable, Theme.chat_msgInMediaSelectedDrawable}, null, Theme.key_chat_inBubbleSelected), - new ThemeDescription(chatListView, 0, new Class[]{ChatMessageCell.class}, null, new Drawable[]{Theme.chat_msgInDrawable.getShadowDrawable(), Theme.chat_msgInMediaDrawable.getShadowDrawable()}, null, Theme.key_chat_inBubbleShadow), + new ThemeDescription(chatListView, 0, new Class[]{ChatMessageCell.class}, null, Theme.chat_msgInDrawable.getShadowDrawables(), null, Theme.key_chat_inBubbleShadow), + new ThemeDescription(chatListView, 0, new Class[]{ChatMessageCell.class}, null, Theme.chat_msgInMediaDrawable.getShadowDrawables(), null, Theme.key_chat_inBubbleShadow), + new ThemeDescription(chatListView, 0, new Class[]{ChatMessageCell.class}, null, Theme.chat_msgOutDrawable.getShadowDrawables(), null, Theme.key_chat_outBubbleShadow), + new ThemeDescription(chatListView, 0, new Class[]{ChatMessageCell.class}, null, Theme.chat_msgOutMediaDrawable.getShadowDrawables(), null, Theme.key_chat_outBubbleShadow), new ThemeDescription(chatListView, 0, new Class[]{ChatMessageCell.class}, null, new Drawable[]{Theme.chat_msgOutDrawable, Theme.chat_msgOutMediaDrawable}, null, Theme.key_chat_outBubble), new ThemeDescription(chatListView, 0, new Class[]{ChatMessageCell.class}, null, new Drawable[]{Theme.chat_msgOutDrawable, Theme.chat_msgOutMediaDrawable}, null, Theme.key_chat_outBubbleGradient), new ThemeDescription(chatListView, 0, new Class[]{ChatMessageCell.class}, null, new Drawable[]{Theme.chat_msgOutSelectedDrawable, Theme.chat_msgOutMediaSelectedDrawable}, null, Theme.key_chat_outBubbleSelected), - new ThemeDescription(chatListView, 0, new Class[]{ChatMessageCell.class}, null, new Drawable[]{Theme.chat_msgOutDrawable.getShadowDrawable(), Theme.chat_msgOutMediaDrawable.getShadowDrawable()}, null, Theme.key_chat_outBubbleShadow), new ThemeDescription(chatListView, ThemeDescription.FLAG_TEXTCOLOR, new Class[]{ChatActionCell.class}, Theme.chat_actionTextPaint, null, null, Theme.key_chat_serviceText), new ThemeDescription(chatListView, ThemeDescription.FLAG_LINKCOLOR, new Class[]{ChatActionCell.class}, Theme.chat_actionTextPaint, null, null, Theme.key_chat_serviceLink), diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ChannelCreateActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ChannelCreateActivity.java index 84ad9b767..d85fac948 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ChannelCreateActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ChannelCreateActivity.java @@ -44,6 +44,7 @@ import org.telegram.messenger.LocaleController; import org.telegram.messenger.MessagesController; import org.telegram.messenger.NotificationCenter; import org.telegram.messenger.R; +import org.telegram.messenger.SharedConfig; import org.telegram.tgnet.ConnectionsManager; import org.telegram.tgnet.TLRPC; import org.telegram.ui.ActionBar.ActionBar; @@ -286,7 +287,7 @@ public class ChannelCreateActivity extends BaseFragment implements NotificationC if (currentStep == 0) { actionBar.setTitle(LocaleController.getString("NewChannel", R.string.NewChannel)); - SizeNotifierFrameLayout sizeNotifierFrameLayout = new SizeNotifierFrameLayout(context) { + SizeNotifierFrameLayout sizeNotifierFrameLayout = new SizeNotifierFrameLayout(context, SharedConfig.smoothKeyboard) { private boolean ignoreLayout; @@ -300,7 +301,7 @@ public class ChannelCreateActivity extends BaseFragment implements NotificationC measureChildWithMargins(actionBar, widthMeasureSpec, 0, heightMeasureSpec, 0); - int keyboardSize = getKeyboardHeight(); + int keyboardSize = SharedConfig.smoothKeyboard ? 0 : getKeyboardHeight(); if (keyboardSize > AndroidUtilities.dp(20)) { ignoreLayout = true; nameTextView.hideEmojiView(); @@ -333,7 +334,8 @@ public class ChannelCreateActivity extends BaseFragment implements NotificationC protected void onLayout(boolean changed, int l, int t, int r, int b) { final int count = getChildCount(); - int paddingBottom = getKeyboardHeight() <= AndroidUtilities.dp(20) && !AndroidUtilities.isInMultiwindow && !AndroidUtilities.isTablet() ? nameTextView.getEmojiPadding() : 0; + int keyboardSize = SharedConfig.smoothKeyboard ? 0 : getKeyboardHeight(); + int paddingBottom = keyboardSize <= AndroidUtilities.dp(20) && !AndroidUtilities.isInMultiwindow && !AndroidUtilities.isTablet() ? nameTextView.getEmojiPadding() : 0; setBottomClip(paddingBottom); for (int i = 0; i < count; i++) { @@ -387,7 +389,7 @@ public class ChannelCreateActivity extends BaseFragment implements NotificationC if (AndroidUtilities.isTablet()) { childTop = getMeasuredHeight() - child.getMeasuredHeight(); } else { - childTop = getMeasuredHeight() + getKeyboardHeight() - child.getMeasuredHeight(); + childTop = getMeasuredHeight() + keyboardSize - child.getMeasuredHeight(); } } child.layout(childLeft, childTop, childLeft + width, childTop + height); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java index d81fa1d7c..3dc47aa57 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java @@ -48,7 +48,7 @@ import android.provider.MediaStore; import androidx.core.content.FileProvider; import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.LinearSmoothScrollerMiddle; +import androidx.recyclerview.widget.LinearSmoothScrollerCustom; import androidx.recyclerview.widget.RecyclerView; import android.text.Layout; @@ -97,6 +97,7 @@ import org.telegram.PhoneFormat.PhoneFormat; import org.telegram.messenger.BuildConfig; import org.telegram.messenger.BuildVars; import org.telegram.messenger.ChatObject; +import org.telegram.messenger.EmojiData; import org.telegram.messenger.MediaDataController; import org.telegram.messenger.Emoji; import org.telegram.messenger.ImageLocation; @@ -286,6 +287,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not private TextView reportSpamButton; private ImageView closeReportSpam; private FragmentContextView fragmentContextView; + private FragmentContextView fragmentLocationContextView; private View replyLineView; private TextView emptyView; private TextView gifHintTextView; @@ -537,6 +539,8 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not private FireworksOverlay fireworksOverlay; + private boolean swipeBackEnabled = true; + public static Pattern publicMsgUrlPattern; public static Pattern privateMsgUrlPattern; @@ -660,7 +664,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not object.viewX = coords[0]; object.viewY = coords[1] - (Build.VERSION.SDK_INT >= 21 ? 0 : AndroidUtilities.statusBarHeight); object.parentView = chatListView; - object.animatingImageView = pagedownButton != null && pagedownButton.getTag() != null ? animatingImageView : null; + object.animatingImageView = !SharedConfig.smoothKeyboard && pagedownButton != null && pagedownButton.getTag() != null ? animatingImageView : null; object.imageReceiver = imageReceiver; if (needPreview) { object.thumb = imageReceiver.getBitmapSafe(); @@ -672,7 +676,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (pinnedMessageView != null && pinnedMessageView.getTag() == null || topChatPanelView != null && topChatPanelView.getTag() == null) { object.clipTopAddition = AndroidUtilities.dp(48); } - object.clipTopAddition += chatListViewClipTop; + object.clipTopAddition += chatListViewClipTop + getCurrentPanTranslationY(); return object; } } @@ -1099,6 +1103,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (chatActivityEnterView != null) { chatActivityEnterView.onDestroy(); } + if (avatarContainer != null) { + avatarContainer.onDestroy(); + } if (mentionsAdapter != null) { mentionsAdapter.onDestroy(); } @@ -1468,6 +1475,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } }); + if (avatarContainer != null) { + avatarContainer.onDestroy(); + } avatarContainer = new ChatAvatarContainer(context, this, currentEncryptedChat != null); if (inPreviewMode) { avatarContainer.setOccupyStatusBar(false); @@ -1741,7 +1751,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } }; - fragmentView = new SizeNotifierFrameLayout(context, parentLayout) { + fragmentView = new SizeNotifierFrameLayout(context, SharedConfig.smoothKeyboard, parentLayout) { int inputFieldHeight = 0; @@ -1838,7 +1848,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } } if (child == actionBar && parentLayout != null) { - parentLayout.drawHeaderShadow(canvas, actionBar.getVisibility() == VISIBLE ? actionBar.getMeasuredHeight() + (inPreviewMode && Build.VERSION.SDK_INT >= 21 ? AndroidUtilities.statusBarHeight : 0) : 0); + parentLayout.drawHeaderShadow(canvas, actionBar.getVisibility() == VISIBLE ? (int) actionBar.getTranslationY() + actionBar.getMeasuredHeight() + (inPreviewMode && Build.VERSION.SDK_INT >= 21 ? AndroidUtilities.statusBarHeight : 0) : 0); } return result; } @@ -1869,7 +1879,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), scrimPaint); int chatListViewTop = (int) chatListView.getY(); int chatListViewBottom = chatListViewTop + chatListView.getMeasuredHeight(); - int listTop = chatListView.getTop() + chatListView.getPaddingTop() - AndroidUtilities.dp(4) + (chatActivityEnterView.getMeasuredHeight() - AndroidUtilities.dp(51)); + int listTop = chatListView.getTop() + chatListView.getPaddingTop() - AndroidUtilities.dp(4) + (chatActivityEnterView.getMeasuredHeight() - AndroidUtilities.dp(51)) + getCurrentPanTranslationY(); MessageObject.GroupedMessages scrimGroup; if (scrimView instanceof ChatMessageCell) { scrimGroup = ((ChatMessageCell) scrimView).getCurrentMessagesGroup(); @@ -2003,13 +2013,17 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not setMeasuredDimension(widthSize, heightSize); heightSize -= getPaddingTop(); + if (SharedConfig.smoothKeyboard && chatActivityEnterView.isPopupShowing()) { + setNonNoveTranslation(getCurrentPanTranslationY()); + } + measureChildWithMargins(actionBar, widthMeasureSpec, 0, heightMeasureSpec, 0); int actionBarHeight = actionBar.getMeasuredHeight(); if (actionBar.getVisibility() == VISIBLE) { heightSize -= actionBarHeight; } - int keyboardSize = getKeyboardHeight(); + int keyboardSize = SharedConfig.smoothKeyboard ? 0 : getKeyboardHeight(); if (keyboardSize <= AndroidUtilities.dp(20)) { if (!AndroidUtilities.isInMultiwindow) { @@ -2160,7 +2174,8 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { final int count = getChildCount(); - int paddingBottom = getKeyboardHeight() <= AndroidUtilities.dp(20) && !AndroidUtilities.isInMultiwindow ? chatActivityEnterView.getEmojiPadding() : 0; + int keyboardSize = SharedConfig.smoothKeyboard ? 0 : getKeyboardHeight(); + int paddingBottom = keyboardSize <= AndroidUtilities.dp(20) && !AndroidUtilities.isInMultiwindow ? chatActivityEnterView.getEmojiPadding() : 0; setBottomClip(paddingBottom); for (int i = 0; i < count; i++) { @@ -2266,6 +2281,45 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } notifyHeightChanged(); } + + private void setNonNoveTranslation(int y) { + contentView.setTranslationY(y); + actionBar.setTranslationY(0); + contentView.setBackgroundTranslation(0); + if (pinnedMessageView != null) { + pinnedMessageView.setTranslationY(0); + } + if (fragmentContextView != null) { + fragmentContextView.setTranslationY(0); + } + if (fragmentLocationContextView != null) { + fragmentLocationContextView.setTranslationY(0); + } + topChatPanelView.setTranslationY(0); + } + + @Override + protected void onPanTranslationUpdate(int y) { + if (getParentLayout() != null && getParentLayout().isPreviewOpenAnimationInProgress()) { + return; + } + if (chatAttachAlert != null && chatAttachAlert.isShowing() || chatActivityEnterView.isPopupShowing()) { + setNonNoveTranslation(y); + } else { + actionBar.setTranslationY(y); + contentView.setBackgroundTranslation(y); + if (pinnedMessageView != null) { + pinnedMessageView.setTranslationY(y); + } + if (fragmentContextView != null) { + fragmentContextView.setTranslationY(y); + } + if (fragmentLocationContextView != null) { + fragmentLocationContextView.setTranslationY(y); + } + topChatPanelView.setTranslationY(y); + } + } }; contentView = (SizeNotifierFrameLayout) fragmentView; @@ -3041,7 +3095,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not @Override public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) { - LinearSmoothScrollerMiddle linearSmoothScroller = new LinearSmoothScrollerMiddle(recyclerView.getContext()); + LinearSmoothScrollerCustom linearSmoothScroller = new LinearSmoothScrollerCustom(recyclerView.getContext(), LinearSmoothScrollerCustom.POSITION_MIDDLE); linearSmoothScroller.setTargetPosition(position); startSmoothScroll(linearSmoothScroller); } @@ -4132,8 +4186,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not mentiondownButton.setContentDescription(LocaleController.getString("AccDescrMentionDown", R.string.AccDescrMentionDown)); if (!AndroidUtilities.isTablet() || AndroidUtilities.isSmallTablet()) { - FragmentContextView fragmentLocationContextView = new FragmentContextView(context, this, true); - contentView.addView(fragmentLocationContextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 39, Gravity.TOP | Gravity.LEFT, 0, -36, 0, 0)); + contentView.addView(fragmentLocationContextView = new FragmentContextView(context, this, true), LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 39, Gravity.TOP | Gravity.LEFT, 0, -36, 0, 0)); contentView.addView(fragmentContextView = new FragmentContextView(context, this, false), LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 39, Gravity.TOP | Gravity.LEFT, 0, -36, 0, 0)); fragmentContextView.setAdditionalContextView(fragmentLocationContextView); fragmentLocationContextView.setAdditionalContextView(fragmentContextView); @@ -4147,7 +4200,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not messagesSearchListView.setVisibility(View.GONE); messagesSearchListView.setAlpha(0.0f); messagesSearchListView.setAdapter(messagesSearchAdapter = new MessagesSearchAdapter(context)); - contentView.addView(messagesSearchListView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.LEFT | Gravity.TOP)); + contentView.addView(messagesSearchListView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.LEFT | Gravity.TOP, 0, 0, 0, 48)); messagesSearchListView.setOnItemClickListener((view, position) -> { getMediaDataController().jumpToSearchedMessage(classGuid, position); showMessagesSearchListView(false); @@ -5590,6 +5643,10 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not return dialog_id; } + public long getMergeDialogId() { + return mergeDialogId; + } + public boolean hasReportSpam() { return topChatPanelView != null && topChatPanelView.getTag() == null && reportSpamButton.getVisibility() != View.GONE; } @@ -8406,7 +8463,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } } if (canSave) { - if (messageObject.getDocument() != null) { + if (messageObject.getDocument() != null && !messageObject.isMusic()) { String mime = messageObject.getDocument().mime_type; if (mime != null) { if (messageObject.getDocumentName().toLowerCase().endsWith("attheme")) { @@ -14036,7 +14093,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } else { popupY = AndroidUtilities.statusBarHeight; } - scrimPopupWindow.showAtLocation(chatListView, Gravity.LEFT | Gravity.TOP, popupX, popupY); + scrimPopupWindow.showAtLocation(chatListView, Gravity.LEFT | Gravity.TOP, popupX, popupY - getCurrentPanTranslationY()); chatListView.stopScroll(); chatLayoutManager.setCanScrollVertically(false); scrimView = v; @@ -14188,7 +14245,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not drawable.restart(); if (message.isAnimatedEmoji()) { String emoji = message.getStickerEmoji(); - if ("❤".equals(emoji)) { + if (EmojiData.isHeartEmoji(emoji)) { HashMap pattern = new HashMap<>(); pattern.put(1, 1); pattern.put(13, 0); @@ -15301,6 +15358,11 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not return swipeBackEnabled; } + @Override + public boolean isSwipeBackEnabled(MotionEvent event) { + return swipeBackEnabled; + } + public class ChatActivityAdapter extends RecyclerAnimationScrollHelper.AnimatableAdapter { private Context mContext; @@ -15487,7 +15549,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not Bundle args = new Bundle(); args.putInt("user_id", user.id); ProfileActivity fragment = new ProfileActivity(args); - fragment.setPlayProfileAnimation(currentUser != null && currentUser.id == user.id); + fragment.setPlayProfileAnimation(currentUser != null && currentUser.id == user.id ? 1 : 0); presentFragment(fragment); } } @@ -15644,6 +15706,45 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not messageObject.forceSeekTo = seekTime / (float) messageObject.getDuration(); mediaController.playMessage(messageObject); } + } else if (str.startsWith("card:")) { + String number = str.substring(5); + final AlertDialog[] progressDialog = new AlertDialog[]{new AlertDialog(getParentActivity(), 3)}; + TLRPC.TL_payments_getBankCardData req = new TLRPC.TL_payments_getBankCardData(); + req.number = number; + int requestId = getConnectionsManager().sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> { + try { + progressDialog[0].dismiss(); + } catch (Throwable ignore) { + + } + progressDialog[0] = null; + if (response instanceof TLRPC.TL_payments_bankCardData) { + TLRPC.TL_payments_bankCardData data = (TLRPC.TL_payments_bankCardData) response; + BottomSheet.Builder builder = new BottomSheet.Builder(getParentActivity()); + ArrayList arrayList = new ArrayList<>(); + for (int a = 0, N = data.open_urls.size(); a < N; a++) { + arrayList.add(data.open_urls.get(a).name); + } + arrayList.add(LocaleController.getString("CopyCardNumber", R.string.CopyCardNumber)); + builder.setTitle(data.title); + builder.setItems(arrayList.toArray(new CharSequence[0]), (dialog, which) -> { + if (which < data.open_urls.size()) { + Browser.openUrl(getParentActivity(), data.open_urls.get(which).url, inlineReturn == 0, false); + } else { + AndroidUtilities.addToClipboard(number); + Toast.makeText(ApplicationLoader.applicationContext, LocaleController.getString("CardNumberCopied", R.string.CardNumberCopied), Toast.LENGTH_SHORT).show(); + } + }); + showDialog(builder.create()); + } + }), null, null, 0, getMessagesController().webFileDatacenterId, ConnectionsManager.ConnectionTypeGeneric, true); + AndroidUtilities.runOnUIThread(() -> { + if (progressDialog[0] == null) { + return; + } + progressDialog[0].setOnCancelListener(dialog -> getConnectionsManager().cancelRequest(requestId, true)); + showDialog(progressDialog[0]); + }, 500); } } else { final String urlFinal = ((URLSpan) url).getURL(); @@ -15706,7 +15807,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } } ProfileActivity fragment = new ProfileActivity(args); - fragment.setPlayProfileAnimation(true); + fragment.setPlayProfileAnimation(1); fragment.setChatInfo(chatInfo); fragment.setUserInfo(userInfo); presentFragment(fragment); @@ -16015,7 +16116,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not args.putLong("dialog_id", dialog_id); } ProfileActivity fragment = new ProfileActivity(args); - fragment.setPlayProfileAnimation(currentUser != null && currentUser.id == uid); + fragment.setPlayProfileAnimation(currentUser != null && currentUser.id == uid ? 1 : 0); presentFragment(fragment); } } @@ -16440,6 +16541,16 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not @Override public void notifyItemRangeInserted(int positionStart, int itemCount) { updateRows(); + if (positionStart == 1 && itemCount > 0) { + int lastPosition = positionStart + itemCount; + if (lastPosition >= messagesStartRow && lastPosition < messagesEndRow) { + MessageObject m1 = messages.get(lastPosition - messagesStartRow); + MessageObject m2 = messages.get(lastPosition - messagesStartRow - 1); + if (currentChat != null && m1.messageOwner.from_id == m2.messageOwner.from_id || currentUser != null && m1.isOutOwner() == m2.isOutOwner()) { + notifyItemChanged(positionStart); + } + } + } try { super.notifyItemRangeInserted(positionStart, itemCount); } catch (Exception e) { @@ -16644,12 +16755,14 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not new ThemeDescription(chatListView, 0, new Class[]{ChatMessageCell.class}, null, null, null, Theme.key_avatar_nameInMessagePink), new ThemeDescription(chatListView, 0, new Class[]{ChatMessageCell.class, BotHelpCell.class}, null, new Drawable[]{Theme.chat_msgInDrawable, Theme.chat_msgInMediaDrawable}, null, Theme.key_chat_inBubble), new ThemeDescription(chatListView, 0, new Class[]{ChatMessageCell.class}, null, new Drawable[]{Theme.chat_msgInSelectedDrawable, Theme.chat_msgInMediaSelectedDrawable}, null, Theme.key_chat_inBubbleSelected), - new ThemeDescription(chatListView, 0, new Class[]{ChatMessageCell.class, BotHelpCell.class}, null, new Drawable[]{Theme.chat_msgInDrawable.getShadowDrawable(), Theme.chat_msgInMediaDrawable.getShadowDrawable()}, null, Theme.key_chat_inBubbleShadow), + new ThemeDescription(chatListView, 0, new Class[]{ChatMessageCell.class}, null, Theme.chat_msgInDrawable.getShadowDrawables(), null, Theme.key_chat_inBubbleShadow), + new ThemeDescription(chatListView, 0, new Class[]{ChatMessageCell.class}, null, Theme.chat_msgInMediaDrawable.getShadowDrawables(), null, Theme.key_chat_inBubbleShadow), + new ThemeDescription(chatListView, 0, new Class[]{ChatMessageCell.class}, null, Theme.chat_msgOutDrawable.getShadowDrawables(), null, Theme.key_chat_outBubbleShadow), + new ThemeDescription(chatListView, 0, new Class[]{ChatMessageCell.class}, null, Theme.chat_msgOutMediaDrawable.getShadowDrawables(), null, Theme.key_chat_outBubbleShadow), new ThemeDescription(chatListView, 0, new Class[]{ChatMessageCell.class}, null, new Drawable[]{Theme.chat_msgOutDrawable, Theme.chat_msgOutMediaDrawable}, null, Theme.key_chat_outBubble), new ThemeDescription(chatListView, 0, new Class[]{ChatMessageCell.class}, null, new Drawable[]{Theme.chat_msgOutDrawable, Theme.chat_msgOutMediaDrawable}, null, Theme.key_chat_outBubbleGradient), new ThemeDescription(chatListView, 0, new Class[]{ChatMessageCell.class}, null, new Drawable[]{Theme.chat_msgOutSelectedDrawable, Theme.chat_msgOutMediaSelectedDrawable}, null, Theme.key_chat_outBubbleSelected), new ThemeDescription(chatListView, 0, new Class[]{ChatMessageCell.class}, null, new Drawable[]{Theme.chat_msgOutSelectedDrawable, Theme.chat_msgOutSelectedDrawable}, null, Theme.key_chat_outBubbleGradientSelectedOverlay), - new ThemeDescription(chatListView, 0, new Class[]{ChatMessageCell.class}, null, new Drawable[]{Theme.chat_msgOutDrawable.getShadowDrawable(), Theme.chat_msgOutMediaDrawable.getShadowDrawable()}, null, Theme.key_chat_outBubbleShadow), new ThemeDescription(chatListView, ThemeDescription.FLAG_TEXTCOLOR, new Class[]{ChatActionCell.class}, Theme.chat_actionTextPaint, null, null, Theme.key_chat_serviceText), new ThemeDescription(chatListView, ThemeDescription.FLAG_LINKCOLOR, new Class[]{ChatActionCell.class}, Theme.chat_actionTextPaint, null, null, Theme.key_chat_serviceLink), diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ChatEditActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ChatEditActivity.java index 520dd0a02..666105b03 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ChatEditActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ChatEditActivity.java @@ -43,6 +43,7 @@ import org.telegram.messenger.MessagesController; import org.telegram.messenger.MessagesStorage; import org.telegram.messenger.NotificationCenter; import org.telegram.messenger.R; +import org.telegram.messenger.SharedConfig; import org.telegram.messenger.UserConfig; import org.telegram.tgnet.TLRPC; import org.telegram.ui.ActionBar.ActionBar; @@ -229,7 +230,7 @@ public class ChatEditActivity extends BaseFragment implements ImageUpdater.Image } }); - SizeNotifierFrameLayout sizeNotifierFrameLayout = new SizeNotifierFrameLayout(context) { + SizeNotifierFrameLayout sizeNotifierFrameLayout = new SizeNotifierFrameLayout(context, SharedConfig.smoothKeyboard) { private boolean ignoreLayout; @@ -243,7 +244,7 @@ public class ChatEditActivity extends BaseFragment implements ImageUpdater.Image measureChildWithMargins(actionBar, widthMeasureSpec, 0, heightMeasureSpec, 0); - int keyboardSize = getKeyboardHeight(); + int keyboardSize = SharedConfig.smoothKeyboard ? 0 : getKeyboardHeight(); if (keyboardSize > AndroidUtilities.dp(20)) { ignoreLayout = true; nameTextView.hideEmojiView(); @@ -276,7 +277,8 @@ public class ChatEditActivity extends BaseFragment implements ImageUpdater.Image protected void onLayout(boolean changed, int l, int t, int r, int b) { final int count = getChildCount(); - int paddingBottom = getKeyboardHeight() <= AndroidUtilities.dp(20) && !AndroidUtilities.isInMultiwindow && !AndroidUtilities.isTablet() ? nameTextView.getEmojiPadding() : 0; + int keyboardSize = SharedConfig.smoothKeyboard ? 0 : getKeyboardHeight(); + int paddingBottom = keyboardSize <= AndroidUtilities.dp(20) && !AndroidUtilities.isInMultiwindow && !AndroidUtilities.isTablet() ? nameTextView.getEmojiPadding() : 0; setBottomClip(paddingBottom); for (int i = 0; i < count; i++) { @@ -330,7 +332,7 @@ public class ChatEditActivity extends BaseFragment implements ImageUpdater.Image if (AndroidUtilities.isTablet()) { childTop = getMeasuredHeight() - child.getMeasuredHeight(); } else { - childTop = getMeasuredHeight() + getKeyboardHeight() - child.getMeasuredHeight(); + childTop = getMeasuredHeight() + keyboardSize - child.getMeasuredHeight(); } } child.layout(childLeft, childTop, childLeft + width, childTop + height); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ChatEditTypeActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ChatEditTypeActivity.java index 6f9679980..9656c99d4 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ChatEditTypeActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ChatEditTypeActivity.java @@ -21,7 +21,6 @@ import android.util.TypedValue; import android.view.View; import android.view.ViewGroup; import android.view.inputmethod.EditorInfo; -import android.widget.EditText; import android.widget.LinearLayout; import android.widget.ScrollView; import android.widget.Toast; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ChatRightsEditActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ChatRightsEditActivity.java index c9e9f531f..babb6c58f 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ChatRightsEditActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ChatRightsEditActivity.java @@ -294,6 +294,15 @@ public class ChatRightsEditActivity extends BaseFragment { listView.setVerticalScrollbarPosition(LocaleController.isRTL ? RecyclerListView.SCROLLBAR_POSITION_LEFT : RecyclerListView.SCROLLBAR_POSITION_RIGHT); frameLayout.addView(listView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT)); + listView.setOnScrollListener(new RecyclerView.OnScrollListener() { + @Override + public void onScrollStateChanged(RecyclerView recyclerView, int newState) { + if (newState == RecyclerView.SCROLL_STATE_DRAGGING) { + AndroidUtilities.hideKeyboard(getParentActivity().getCurrentFocus()); + } + } + }); + listView.setOnItemClickListener((view, position) -> { if (!canEdit) { return; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ChatUsersActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ChatUsersActivity.java index 706dd6fee..1760cbc24 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ChatUsersActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ChatUsersActivity.java @@ -960,6 +960,11 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente emptyView.showTextView(); } updateRows(); + + if (needOpenSearch) { + searchItem.openSearch(false); + } + return fragmentView; } @@ -1941,7 +1946,6 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente public void onResume() { super.onResume(); AndroidUtilities.requestAdjustResize(getParentActivity(), classGuid); - //AndroidUtilities.removeAdjustResize(getParentActivity(), classGuid); if (listViewAdapter != null) { listViewAdapter.notifyDataSetChanged(); } @@ -1965,7 +1969,8 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente @Override protected void onTransitionAnimationEnd(boolean isOpen, boolean backward) { if (isOpen && !backward && needOpenSearch) { - searchItem.openSearch(true); + searchItem.getSearchField().requestFocus(); + AndroidUtilities.showKeyboard(searchItem.getSearchField()); } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/CommonGroupsActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/CommonGroupsActivity.java deleted file mode 100644 index 0ef59a3c6..000000000 --- a/TMessagesProj/src/main/java/org/telegram/ui/CommonGroupsActivity.java +++ /dev/null @@ -1,291 +0,0 @@ -/* - * This is the source code of Telegram for Android v. 5.x.x. - * It is licensed under GNU GPL v. 2 or later. - * You should have received a copy of the license in this archive (see LICENSE). - * - * Copyright Nikolai Kudashov, 2013-2018. - */ - -package org.telegram.ui; - -import android.content.Context; -import android.graphics.Paint; -import android.graphics.drawable.Drawable; -import android.os.Bundle; -import android.view.View; -import android.view.ViewGroup; -import android.widget.FrameLayout; - -import org.telegram.messenger.AndroidUtilities; -import org.telegram.messenger.LocaleController; -import org.telegram.messenger.MessagesController; -import org.telegram.messenger.NotificationCenter; -import org.telegram.messenger.R; -import org.telegram.tgnet.ConnectionsManager; -import org.telegram.tgnet.TLRPC; -import org.telegram.ui.ActionBar.ActionBar; -import org.telegram.ui.ActionBar.BaseFragment; -import org.telegram.ui.ActionBar.Theme; -import org.telegram.ui.ActionBar.ThemeDescription; -import org.telegram.ui.Cells.LoadingCell; -import org.telegram.ui.Cells.ProfileSearchCell; -import org.telegram.ui.Cells.TextInfoPrivacyCell; -import org.telegram.ui.Components.EmptyTextProgressView; -import org.telegram.ui.Components.LayoutHelper; -import org.telegram.ui.Components.RecyclerListView; - -import java.util.ArrayList; - -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; - -public class CommonGroupsActivity extends BaseFragment { - - private ListAdapter listViewAdapter; - private EmptyTextProgressView emptyView; - private RecyclerListView listView; - private LinearLayoutManager layoutManager; - - private ArrayList chats = new ArrayList<>(); - private int userId; - private boolean loading; - private boolean firstLoaded; - private boolean endReached; - - public CommonGroupsActivity(int uid) { - super(); - userId = uid; - } - - @Override - public boolean onFragmentCreate() { - super.onFragmentCreate(); - getChats(0, 50); - return true; - } - - @Override - public View createView(Context context) { - actionBar.setBackButtonImage(R.drawable.ic_ab_back); - actionBar.setAllowOverlayTitle(true); - actionBar.setTitle(LocaleController.getString("GroupsInCommonTitle", R.string.GroupsInCommonTitle)); - actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { - @Override - public void onItemClick(int id) { - if (id == -1) { - finishFragment(); - } - } - }); - - fragmentView = new FrameLayout(context); - fragmentView.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundGray)); - FrameLayout frameLayout = (FrameLayout) fragmentView; - - emptyView = new EmptyTextProgressView(context); - emptyView.setText(LocaleController.getString("NoGroupsInCommon", R.string.NoGroupsInCommon)); - frameLayout.addView(emptyView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT)); - - listView = new RecyclerListView(context); - listView.setEmptyView(emptyView); - listView.setLayoutManager(layoutManager = new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)); - listView.setAdapter(listViewAdapter = new ListAdapter(context)); - listView.setVerticalScrollbarPosition(LocaleController.isRTL ? RecyclerListView.SCROLLBAR_POSITION_LEFT : RecyclerListView.SCROLLBAR_POSITION_RIGHT); - frameLayout.addView(listView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT)); - - listView.setOnItemClickListener((view, position) -> { - if (position < 0 || position >= chats.size()) { - return; - } - TLRPC.Chat chat = chats.get(position); - Bundle args = new Bundle(); - args.putInt("chat_id", chat.id); - if (!MessagesController.getInstance(currentAccount).checkCanOpenChat(args, CommonGroupsActivity.this)) { - return; - } - NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.closeChats); - presentFragment(new ChatActivity(args), true); - }); - listView.setOnScrollListener(new RecyclerView.OnScrollListener() { - @Override - public void onScrolled(RecyclerView recyclerView, int dx, int dy) { - int firstVisibleItem = layoutManager.findFirstVisibleItemPosition(); - int visibleItemCount = firstVisibleItem == RecyclerView.NO_POSITION ? 0 : Math.abs(layoutManager.findLastVisibleItemPosition() - firstVisibleItem) + 1; - if (visibleItemCount > 0) { - int totalItemCount = listViewAdapter.getItemCount(); - if (!endReached && !loading && !chats.isEmpty() && firstVisibleItem + visibleItemCount >= totalItemCount - 5) { - getChats(chats.get(chats.size() - 1).id, 100); - } - } - } - }); - - if (loading) { - emptyView.showProgress(); - } else { - emptyView.showTextView(); - } - return fragmentView; - } - - private void getChats(int max_id, final int count) { - if (loading) { - return; - } - loading = true; - if (emptyView != null && !firstLoaded) { - emptyView.showProgress(); - } - if (listViewAdapter != null) { - listViewAdapter.notifyDataSetChanged(); - } - TLRPC.TL_messages_getCommonChats req = new TLRPC.TL_messages_getCommonChats(); - req.user_id = MessagesController.getInstance(currentAccount).getInputUser(userId); - if (req.user_id instanceof TLRPC.TL_inputUserEmpty) { - return; - } - req.limit = count; - req.max_id = max_id; - int reqId = ConnectionsManager.getInstance(currentAccount).sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> { - if (error == null) { - TLRPC.messages_Chats res = (TLRPC.messages_Chats) response; - MessagesController.getInstance(currentAccount).putChats(res.chats, false); - endReached = res.chats.isEmpty() || res.chats.size() != count; - chats.addAll(res.chats); - } else { - endReached = true; - } - loading = false; - firstLoaded = true; - if (emptyView != null) { - emptyView.showTextView(); - } - if (listViewAdapter != null) { - listViewAdapter.notifyDataSetChanged(); - } - })); - ConnectionsManager.getInstance(currentAccount).bindRequestToGuid(reqId, classGuid); - } - - @Override - public void onResume() { - super.onResume(); - if (listViewAdapter != null) { - listViewAdapter.notifyDataSetChanged(); - } - } - - private class ListAdapter extends RecyclerListView.SelectionAdapter { - private Context mContext; - - public ListAdapter(Context context) { - mContext = context; - } - - @Override - public boolean isEnabled(RecyclerView.ViewHolder holder) { - return holder.getAdapterPosition() != chats.size(); - } - - @Override - public int getItemCount() { - int count = chats.size(); - if (!chats.isEmpty()) { - count++; - if (!endReached) { - count++; - } - } - return count; - } - - @Override - public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - View view; - switch (viewType) { - case 0: - view = new ProfileSearchCell(mContext); - view.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite)); - break; - case 1: - view = new LoadingCell(mContext); - view.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite)); - break; - case 2: - default: - view = new TextInfoPrivacyCell(mContext); - view.setBackgroundDrawable(Theme.getThemedDrawable(mContext, R.drawable.greydivider_bottom, Theme.key_windowBackgroundGrayShadow)); - break; - } - return new RecyclerListView.Holder(view); - } - - @Override - public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { - if (holder.getItemViewType() == 0) { - ProfileSearchCell cell = (ProfileSearchCell) holder.itemView; - TLRPC.Chat chat = chats.get(position); - cell.setData(chat, null, null, null, false, false); - cell.useSeparator = position != chats.size() - 1 || !endReached; - } - } - - @Override - public int getItemViewType(int i) { - if (i < chats.size()) { - return 0; - } else if (!endReached && i == chats.size()) { - return 1; - } - return 2; - } - } - - @Override - public ThemeDescription[] getThemeDescriptions() { - ThemeDescription.ThemeDescriptionDelegate cellDelegate = () -> { - if (listView != null) { - int count = listView.getChildCount(); - for (int a = 0; a < count; a++) { - View child = listView.getChildAt(a); - if (child instanceof ProfileSearchCell) { - ((ProfileSearchCell) child).update(0); - } - } - } - }; - return new ThemeDescription[]{ - new ThemeDescription(listView, ThemeDescription.FLAG_CELLBACKGROUNDCOLOR, new Class[]{LoadingCell.class, ProfileSearchCell.class}, null, null, null, Theme.key_windowBackgroundWhite), - new ThemeDescription(fragmentView, ThemeDescription.FLAG_BACKGROUND, null, null, null, null, Theme.key_windowBackgroundGray), - - new ThemeDescription(actionBar, ThemeDescription.FLAG_BACKGROUND, null, null, null, null, Theme.key_actionBarDefault), - new ThemeDescription(listView, ThemeDescription.FLAG_LISTGLOWCOLOR, null, null, null, null, Theme.key_actionBarDefault), - new ThemeDescription(actionBar, ThemeDescription.FLAG_AB_ITEMSCOLOR, null, null, null, null, Theme.key_actionBarDefaultIcon), - new ThemeDescription(actionBar, ThemeDescription.FLAG_AB_TITLECOLOR, null, null, null, null, Theme.key_actionBarDefaultTitle), - new ThemeDescription(actionBar, ThemeDescription.FLAG_AB_SELECTORCOLOR, null, null, null, null, Theme.key_actionBarDefaultSelector), - - new ThemeDescription(listView, ThemeDescription.FLAG_SELECTOR, null, null, null, null, Theme.key_listSelector), - - new ThemeDescription(listView, 0, new Class[]{View.class}, Theme.dividerPaint, null, null, Theme.key_divider), - - new ThemeDescription(emptyView, ThemeDescription.FLAG_TEXTCOLOR, null, null, null, null, Theme.key_emptyListPlaceholder), - new ThemeDescription(emptyView, ThemeDescription.FLAG_PROGRESSBAR, null, null, null, null, Theme.key_progressCircle), - - new ThemeDescription(listView, ThemeDescription.FLAG_BACKGROUNDFILTER, new Class[]{TextInfoPrivacyCell.class}, null, null, null, Theme.key_windowBackgroundGrayShadow), - new ThemeDescription(listView, 0, new Class[]{TextInfoPrivacyCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteGrayText4), - - new ThemeDescription(listView, 0, new Class[]{LoadingCell.class}, new String[]{"progressBar"}, null, null, null, Theme.key_progressCircle), - - new ThemeDescription(listView, 0, new Class[]{ProfileSearchCell.class}, null, new Paint[]{Theme.dialogs_namePaint[0], Theme.dialogs_namePaint[1], Theme.dialogs_searchNamePaint}, null, null, Theme.key_chats_name), - new ThemeDescription(listView, 0, new Class[]{ProfileSearchCell.class}, null, new Paint[]{Theme.dialogs_nameEncryptedPaint[0], Theme.dialogs_nameEncryptedPaint[1], Theme.dialogs_searchNameEncryptedPaint}, null, null, Theme.key_chats_secretName), - new ThemeDescription(listView, 0, new Class[]{ProfileSearchCell.class}, null, new Drawable[]{Theme.avatar_savedDrawable}, null, Theme.key_avatar_text), - new ThemeDescription(null, 0, null, null, null, cellDelegate, Theme.key_avatar_backgroundRed), - new ThemeDescription(null, 0, null, null, null, cellDelegate, Theme.key_avatar_backgroundOrange), - new ThemeDescription(null, 0, null, null, null, cellDelegate, Theme.key_avatar_backgroundViolet), - new ThemeDescription(null, 0, null, null, null, cellDelegate, Theme.key_avatar_backgroundGreen), - new ThemeDescription(null, 0, null, null, null, cellDelegate, Theme.key_avatar_backgroundCyan), - new ThemeDescription(null, 0, null, null, null, cellDelegate, Theme.key_avatar_backgroundBlue), - new ThemeDescription(null, 0, null, null, null, cellDelegate, Theme.key_avatar_backgroundPink), - }; - } -} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/AlertsCreator.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/AlertsCreator.java index c752b4470..c2d36106f 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/AlertsCreator.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/AlertsCreator.java @@ -1159,6 +1159,68 @@ public class AlertsCreator { } } + public interface BlockDialogCallback { + void run(boolean report, boolean delete); + } + + public static void createBlockDialogAlert(BaseFragment fragment, int count, boolean reportSpam, TLRPC.User user, BlockDialogCallback onProcessRunnable) { + if (fragment == null || fragment.getParentActivity() == null || count == 1 && user == null) { + return; + } + Context context = fragment.getParentActivity(); + AlertDialog.Builder builder = new AlertDialog.Builder(context); + + CheckBoxCell[] cell = new CheckBoxCell[2]; + + LinearLayout linearLayout = new LinearLayout(context); + linearLayout.setOrientation(LinearLayout.VERTICAL); + builder.setView(linearLayout); + + String actionText; + if (count == 1) { + String name = ContactsController.formatName(user.first_name, user.last_name); + builder.setTitle(LocaleController.formatString("BlockUserTitle", R.string.BlockUserTitle, name)); + actionText = LocaleController.getString("BlockUser", R.string.BlockUser); + builder.setMessage(AndroidUtilities.replaceTags(LocaleController.formatString("BlockUserMessage", R.string.BlockUserMessage, name))); + } else { + builder.setTitle(LocaleController.formatString("BlockUserTitle", R.string.BlockUserTitle, LocaleController.formatPluralString("UsersCountTitle", count))); + actionText = LocaleController.getString("BlockUsers", R.string.BlockUsers); + builder.setMessage(AndroidUtilities.replaceTags(LocaleController.formatString("BlockUsersMessage", R.string.BlockUsersMessage, LocaleController.formatPluralString("UsersCount", count)))); + } + + final boolean[] checks = new boolean[]{true, true}; + + for (int a = 0; a < cell.length; a++) { + if (a == 0 && !reportSpam) { + continue; + } + int num = a; + cell[a] = new CheckBoxCell(context, 1); + cell[a].setBackgroundDrawable(Theme.getSelectorDrawable(false)); + if (a == 0) { + cell[a].setText(LocaleController.getString("ReportSpamTitle", R.string.ReportSpamTitle), "", true, false); + } else { + cell[a].setText(count == 1 ? LocaleController.getString("DeleteThisChat", R.string.DeleteThisChat) : LocaleController.getString("DeleteTheseChats", R.string.DeleteTheseChats), "", true, false); + } + cell[a].setPadding(LocaleController.isRTL ? AndroidUtilities.dp(16) : AndroidUtilities.dp(8), 0, LocaleController.isRTL ? AndroidUtilities.dp(8) : AndroidUtilities.dp(16), 0); + linearLayout.addView(cell[a], LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 48)); + cell[a].setOnClickListener(v -> { + CheckBoxCell cell1 = (CheckBoxCell) v; + checks[num] = !checks[num]; + cell1.setChecked(checks[num], true); + }); + } + + builder.setPositiveButton(actionText, (dialogInterface, i) -> onProcessRunnable.run(checks[0], checks[1])); + builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); + AlertDialog alertDialog = builder.create(); + fragment.showDialog(alertDialog); + TextView button = (TextView) alertDialog.getButton(DialogInterface.BUTTON_POSITIVE); + if (button != null) { + button.setTextColor(Theme.getColor(Theme.key_dialogTextRed2)); + } + } + public interface DatePickerDelegate { void didSelectDate(int year, int month, int dayOfMonth); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/AudioPlayerAlert.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/AudioPlayerAlert.java index 05c69a380..5e3da88a6 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/AudioPlayerAlert.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/AudioPlayerAlert.java @@ -715,7 +715,7 @@ public class AudioPlayerAlert extends BottomSheet implements NotificationCenter. listView.setOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { - if (newState == RecyclerView.SCROLL_STATE_DRAGGING && searching && searchWas) { + if (newState == RecyclerView.SCROLL_STATE_DRAGGING) { AndroidUtilities.hideKeyboard(getCurrentFocus()); } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/BackupImageView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/BackupImageView.java index 5b93e5aed..ad5b2d7be 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/BackupImageView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/BackupImageView.java @@ -56,8 +56,12 @@ public class BackupImageView extends View { setImage(imageLocation, imageFilter, null, null, thumb, null, null, size, parentObject); } - public void setImage(ImageLocation imageLocation, String imageFilter, Bitmap thumb, int size, Object parentObject) { - setImage(imageLocation, imageFilter, null, null, null, thumb, null, size, parentObject); + public void setImage(ImageLocation imageLocation, String imageFilter, Bitmap thumbBitmap, int size, int cacheType, Object parentObject) { + Drawable thumb = null; + if (thumbBitmap != null) { + thumb = new BitmapDrawable(null, thumbBitmap); + } + imageReceiver.setImage(imageLocation, imageFilter, null, null, thumb, size, null, parentObject, cacheType); } public void setImage(ImageLocation imageLocation, String imageFilter, ImageLocation thumbLocation, String thumbFilter, int size, Object parentObject) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatActivityEnterView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatActivityEnterView.java index cc1171894..7b1a91a8b 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatActivityEnterView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatActivityEnterView.java @@ -26,6 +26,7 @@ import android.graphics.Paint; import android.graphics.PixelFormat; import android.graphics.PorterDuff; import android.graphics.PorterDuffColorFilter; +import android.graphics.Rect; import android.graphics.RectF; import android.graphics.drawable.Drawable; import android.media.AudioManager; @@ -1015,6 +1016,12 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe parentFragment.extendActionMode(menu); } } + + @Override + public boolean requestRectangleOnScreen(Rect rectangle) { + rectangle.bottom += AndroidUtilities.dp(1000); + return super.requestRectangleOnScreen(rectangle); + } }; messageEditText.setDelegate(() -> { if (delegate != null) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatAttachAlert.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatAttachAlert.java index bcab7b9e5..64d888642 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatAttachAlert.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatAttachAlert.java @@ -132,6 +132,8 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N private View shadow; + private int currentPanTranslationY; + private FrameLayout frameLayout2; private EditTextEmoji commentTextView; private FrameLayout writeButtonContainer; @@ -610,7 +612,7 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N cameraDrawable = context.getResources().getDrawable(R.drawable.instant_camera).mutate(); - sizeNotifierFrameLayout = new SizeNotifierFrameLayout(context) { + sizeNotifierFrameLayout = new SizeNotifierFrameLayout(context, false) { private int lastNotifyWidth; private RectF rect = new RectF(); @@ -649,7 +651,7 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N ignoreLayout = false; } int availableHeight = totalHeight - getPaddingTop(); - int keyboardSize = getKeyboardHeight(); + int keyboardSize = useSmoothKeyboard ? 0 : getKeyboardHeight(); if (!AndroidUtilities.isInMultiwindow && keyboardSize <= AndroidUtilities.dp(20)) { availableHeight -= commentTextView.getEmojiPadding(); } @@ -710,7 +712,7 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N setMeasuredDimension(widthSize, heightSize); widthSize -= backgroundPaddingLeft * 2; - int keyboardSize = getKeyboardHeight(); + int keyboardSize = useSmoothKeyboard ? 0 : getKeyboardHeight(); if (keyboardSize <= AndroidUtilities.dp(20)) { if (!AndroidUtilities.isInMultiwindow) { heightSize -= commentTextView.getEmojiPadding(); @@ -757,7 +759,8 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N } final int count = getChildCount(); - int paddingBottom = getKeyboardHeight() <= AndroidUtilities.dp(20) && !AndroidUtilities.isInMultiwindow && !AndroidUtilities.isTablet() ? commentTextView.getEmojiPadding() : 0; + int keyboardSize = useSmoothKeyboard ? 0 : getKeyboardHeight(); + int paddingBottom = keyboardSize <= AndroidUtilities.dp(20) && !AndroidUtilities.isInMultiwindow && !AndroidUtilities.isTablet() ? commentTextView.getEmojiPadding() : 0; setBottomClip(paddingBottom); for (int i = 0; i < count; i++) { @@ -811,7 +814,7 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N if (AndroidUtilities.isTablet()) { childTop = getMeasuredHeight() - child.getMeasuredHeight(); } else { - childTop = getMeasuredHeight() + getKeyboardHeight() - child.getMeasuredHeight(); + childTop = getMeasuredHeight() + keyboardSize - child.getMeasuredHeight(); } } child.layout(childLeft, childTop, childLeft + width, childTop + height); @@ -917,6 +920,17 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N super.setTranslationY(translationY); checkCameraViewPosition(); } + + @Override + protected void onPanTranslationUpdate(int y) { + currentPanTranslationY = y; + if (commentTextView.isPopupShowing()) { + containerView.setTranslationY(y); + actionBar.setTranslationY(0); + } else { + actionBar.setTranslationY(y); + } + } }; containerView = sizeNotifierFrameLayout; containerView.setWillNotDraw(false); @@ -2996,7 +3010,7 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N cameraViewOffsetY = 0; } int containerHeight = containerView.getMeasuredHeight(); - int keyboardSize = sizeNotifierFrameLayout.getKeyboardHeight(); + int keyboardSize = useSmoothKeyboard ? 0 : sizeNotifierFrameLayout.getKeyboardHeight(); if (!AndroidUtilities.isInMultiwindow && keyboardSize <= AndroidUtilities.dp(20)) { containerHeight -= commentTextView.getEmojiPadding(); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatAvatarContainer.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatAvatarContainer.java index 1e9a1420c..771658318 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatAvatarContainer.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatAvatarContainer.java @@ -22,6 +22,7 @@ import org.telegram.messenger.ChatObject; import org.telegram.messenger.FileLog; import org.telegram.messenger.ImageLocation; import org.telegram.messenger.LocaleController; +import org.telegram.messenger.MediaDataController; import org.telegram.messenger.MessagesController; import org.telegram.messenger.NotificationCenter; import org.telegram.messenger.R; @@ -56,13 +57,22 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent private CharSequence lastSubtitle; private String lastSubtitleColorKey; + private SharedMediaLayout.SharedMediaPreloader sharedMediaPreloader; + public ChatAvatarContainer(Context context, ChatActivity chatActivity, boolean needTime) { super(context); parentFragment = chatActivity; + if (parentFragment != null) { + sharedMediaPreloader = new SharedMediaLayout.SharedMediaPreloader(chatActivity); + } + avatarImageView = new BackupImageView(context); avatarImageView.setRoundRadius(AndroidUtilities.dp(21)); addView(avatarImageView); + if (parentFragment != null && !parentFragment.isInScheduleMode()) { + avatarImageView.setOnClickListener(v -> openProfile(true)); + } titleTextView = new SimpleTextView(context); titleTextView.setTextColor(Theme.getColor(Theme.key_actionBarDefaultTitle)); @@ -90,36 +100,7 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent } if (parentFragment != null && !parentFragment.isInScheduleMode()) { - setOnClickListener(v -> { - TLRPC.User user = parentFragment.getCurrentUser(); - TLRPC.Chat chat = parentFragment.getCurrentChat(); - if (user != null) { - Bundle args = new Bundle(); - if (UserObject.isUserSelf(user)) { - args.putLong("dialog_id", parentFragment.getDialogId()); - MediaActivity fragment = new MediaActivity(args, new int[]{-1, -1, -1, -1, -1}); - fragment.setChatInfo(parentFragment.getCurrentChatInfo()); - parentFragment.presentFragment(fragment); - } else { - args.putInt("user_id", user.id); - args.putBoolean("reportSpam", parentFragment.hasReportSpam()); - if (timeItem != null) { - args.putLong("dialog_id", parentFragment.getDialogId()); - } - ProfileActivity fragment = new ProfileActivity(args); - fragment.setUserInfo(parentFragment.getCurrentUserInfo()); - fragment.setPlayProfileAnimation(true); - parentFragment.presentFragment(fragment); - } - } else if (chat != null) { - Bundle args = new Bundle(); - args.putInt("chat_id", chat.id); - ProfileActivity fragment = new ProfileActivity(args); - fragment.setChatInfo(parentFragment.getCurrentChatInfo()); - fragment.setPlayProfileAnimation(true); - parentFragment.presentFragment(fragment); - } - }); + setOnClickListener(v -> openProfile(false)); TLRPC.Chat chat = parentFragment.getCurrentChat(); statusDrawables[0] = new TypingDotsDrawable(); @@ -133,6 +114,42 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent } } + private void openProfile(boolean byAvatar) { + if (byAvatar && (AndroidUtilities.isTablet() || AndroidUtilities.displaySize.x > AndroidUtilities.displaySize.y || !avatarImageView.getImageReceiver().hasNotThumb())) { + byAvatar = false; + } + TLRPC.User user = parentFragment.getCurrentUser(); + TLRPC.Chat chat = parentFragment.getCurrentChat(); + if (user != null) { + Bundle args = new Bundle(); + if (UserObject.isUserSelf(user)) { + args.putLong("dialog_id", parentFragment.getDialogId()); + int[] media = new int[MediaDataController.MEDIA_TYPES_COUNT]; + System.arraycopy(sharedMediaPreloader.getLastMediaCount(), 0, media, 0, media.length); + MediaActivity fragment = new MediaActivity(args, media, sharedMediaPreloader.getSharedMediaData(), -1); + fragment.setChatInfo(parentFragment.getCurrentChatInfo()); + parentFragment.presentFragment(fragment); + } else { + args.putInt("user_id", user.id); + args.putBoolean("reportSpam", parentFragment.hasReportSpam()); + if (timeItem != null) { + args.putLong("dialog_id", parentFragment.getDialogId()); + } + ProfileActivity fragment = new ProfileActivity(args, sharedMediaPreloader); + fragment.setUserInfo(parentFragment.getCurrentUserInfo()); + fragment.setPlayProfileAnimation(byAvatar ? 2 : 1); + parentFragment.presentFragment(fragment); + } + } else if (chat != null) { + Bundle args = new Bundle(); + args.putInt("chat_id", chat.id); + ProfileActivity fragment = new ProfileActivity(args, sharedMediaPreloader); + fragment.setChatInfo(parentFragment.getCurrentChatInfo()); + fragment.setPlayProfileAnimation(byAvatar ? 2 : 1); + parentFragment.presentFragment(fragment); + } + } + public void setOccupyStatusBar(boolean value) { occupyStatusBar = value; } @@ -237,6 +254,12 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent return subtitleTextView; } + public void onDestroy() { + if (sharedMediaPreloader != null) { + sharedMediaPreloader.onDestroy(parentFragment); + } + } + private void setTypingAnimation(boolean start) { if (start) { try { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/ClippingImageView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/ClippingImageView.java index ded4d611a..b67421b88 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/ClippingImageView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/ClippingImageView.java @@ -51,6 +51,8 @@ public class ClippingImageView extends View { private float animationProgress; private float[][] animationValues; + private float additionalTranslationY; + public ClippingImageView(Context context) { super(context); paint = new Paint(Paint.FILTER_BITMAP_FLAG); @@ -68,6 +70,20 @@ public class ClippingImageView extends View { animationValues = values; } + public void setAdditionalTranslationY(float value) { + additionalTranslationY = value; + } + + @Override + public void setTranslationY(float translationY) { + super.setTranslationY(translationY + additionalTranslationY); + } + + @Override + public float getTranslationY() { + return super.getTranslationY() - additionalTranslationY; + } + @Keep public float getAnimationProgress() { return animationProgress; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/EditTextEmoji.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/EditTextEmoji.java index a145a1113..51b8176f4 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/EditTextEmoji.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/EditTextEmoji.java @@ -3,6 +3,7 @@ package org.telegram.ui.Components; import android.content.Context; import android.graphics.PorterDuff; import android.graphics.PorterDuffColorFilter; +import android.graphics.Rect; import android.os.Build; import android.text.Editable; import android.text.InputFilter; @@ -100,6 +101,12 @@ public class EditTextEmoji extends FrameLayout implements NotificationCenter.Not } return false; } + + @Override + public boolean requestRectangleOnScreen(Rect rectangle) { + rectangle.bottom += AndroidUtilities.dp(1000); + return super.requestRectangleOnScreen(rectangle); + } }; editText.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16); editText.setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/FireworksOverlay.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/FireworksOverlay.java index 153611879..b6d809f48 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/FireworksOverlay.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/FireworksOverlay.java @@ -3,28 +3,38 @@ package org.telegram.ui.Components; import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; +import android.graphics.PorterDuff; +import android.graphics.PorterDuffColorFilter; import android.graphics.RectF; +import android.graphics.drawable.Drawable; import android.os.Build; import android.os.SystemClock; import android.view.View; import org.telegram.messenger.AndroidUtilities; +import org.telegram.messenger.ApplicationLoader; +import org.telegram.messenger.BuildVars; +import org.telegram.messenger.R; import org.telegram.messenger.SharedConfig; import org.telegram.messenger.Utilities; import java.util.ArrayList; +import java.util.Calendar; public class FireworksOverlay extends View { private static Paint[] paint; + private static Paint[] heartPaint; private RectF rect = new RectF(); private long lastUpdateTime; private boolean started; private boolean startedFall; private float speedCoef = 1.0f; private int fallingDownCount; + private static Drawable[] heartDrawable; private static final int particlesCount = SharedConfig.getDevicePerfomanceClass() == SharedConfig.PERFORMANCE_CLASS_LOW ? 50 : 60; private static final int fallParticlesCount = SharedConfig.getDevicePerfomanceClass() == SharedConfig.PERFORMANCE_CLASS_LOW ? 20 : 30; + private boolean isFebruary14; private static int[] colors = new int[] { 0xff2CBCE8, @@ -35,6 +45,14 @@ public class FireworksOverlay extends View { 0xff59B86C }; + private static int[] heartColors = new int[] { + 0xffE2557B, + 0xff5FCDF2, + 0xffFFDA69, + 0xffDB6363, + 0xffE376B0 + }; + static { paint = new Paint[colors.length]; for (int a = 0; a < paint.length; a++) { @@ -60,12 +78,22 @@ public class FireworksOverlay extends View { private void draw(Canvas canvas) { if (type == 0) { canvas.drawCircle(x, y, AndroidUtilities.dp(typeSize), paint[colorType]); - } else { + } else if (type == 1) { rect.set(x - AndroidUtilities.dp(typeSize), y - AndroidUtilities.dp(2), x + AndroidUtilities.dp(typeSize), y + AndroidUtilities.dp(2)); canvas.save(); canvas.rotate(rotation, rect.centerX(), rect.centerY()); canvas.drawRoundRect(rect, AndroidUtilities.dp(2), AndroidUtilities.dp(2), paint[colorType]); canvas.restore(); + } else if (type == 2) { + Drawable drawable = heartDrawable[colorType]; + int w = drawable.getIntrinsicWidth() / 2; + int h = drawable.getIntrinsicHeight() / 2; + drawable.setBounds((int) x - w, (int) y - h, (int) x + w, (int) y + h); + canvas.save(); + canvas.rotate(rotation, x, y); + canvas.scale(typeSize / 6.0f, typeSize / 6.0f, x, y); + drawable.draw(canvas); + canvas.restore(); } } @@ -115,7 +143,7 @@ public class FireworksOverlay extends View { if (wasNegative && moveY > yEdge) { fallingDownCount++; } - if (type == 1) { + if (type == 1 || type == 2) { rotation += moveCoef * 10; if (rotation > 360) { rotation -= 360; @@ -131,13 +159,29 @@ public class FireworksOverlay extends View { super(context); } + private void loadHeartDrawables() { + if (heartDrawable != null) { + return; + } + heartDrawable = new Drawable[heartColors.length]; + for (int a = 0; a < heartDrawable.length; a++) { + heartDrawable[a] = ApplicationLoader.applicationContext.getResources().getDrawable(R.drawable.heart_confetti).mutate(); + heartDrawable[a].setColorFilter(new PorterDuffColorFilter(heartColors[a], PorterDuff.Mode.MULTIPLY)); + } + } + private Particle createParticle(boolean fall) { Particle particle = new Particle(); - particle.colorType = (byte) Utilities.random.nextInt(paint.length); particle.type = (byte) Utilities.random.nextInt(2); + if (isFebruary14 && particle.type == 0) { + particle.type = 2; + particle.colorType = (byte) Utilities.random.nextInt(heartColors.length); + } else { + particle.colorType = (byte) Utilities.random.nextInt(colors.length); + } particle.side = (byte) Utilities.random.nextInt(2); particle.finishedStart = (byte) (1 + Utilities.random.nextInt(2)); - if (particle.type == 0) { + if (particle.type == 0 || particle.type == 2) { particle.typeSize = (byte) (4 + Utilities.random.nextFloat() * 2); } else { particle.typeSize = (byte) (4 + Utilities.random.nextFloat() * 4); @@ -170,6 +214,14 @@ public class FireworksOverlay extends View { startedFall = false; fallingDownCount = 0; speedCoef = 1.0f; + Calendar calendar = Calendar.getInstance(); + calendar.setTimeInMillis(System.currentTimeMillis()); + int day = calendar.get(Calendar.DAY_OF_MONTH); + int month = calendar.get(Calendar.MONTH); + isFebruary14 = month == 1 && (BuildVars.DEBUG_PRIVATE_VERSION || day == 14); + if (isFebruary14) { + loadHeartDrawables(); + } for (int a = 0; a < particlesCount; a++) { particles.add(createParticle(false)); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/GestureDetector2.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/GestureDetector2.java new file mode 100644 index 000000000..18bad2c81 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/GestureDetector2.java @@ -0,0 +1,550 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.telegram.ui.Components; + +import android.content.Context; +import android.os.Build; +import android.os.Handler; +import android.os.Message; +import android.view.MotionEvent; +import android.view.VelocityTracker; +import android.view.ViewConfiguration; + +public class GestureDetector2 { + + public interface OnGestureListener { + boolean onDown(MotionEvent e); + void onUp(MotionEvent e); + void onShowPress(MotionEvent e); + boolean onSingleTapUp(MotionEvent e); + boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY); + void onLongPress(MotionEvent e); + boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY); + } + + /** + * The listener that is used to notify when a double-tap or a confirmed + * single-tap occur. + */ + public interface OnDoubleTapListener { + /** + * Notified when a single-tap occurs. + *

+ * Unlike {@link OnGestureListener#onSingleTapUp(MotionEvent)}, this + * will only be called after the detector is confident that the user's + * first tap is not followed by a second tap leading to a double-tap + * gesture. + * + * @param e The down motion event of the single-tap. + * @return true if the event is consumed, else false + */ + boolean onSingleTapConfirmed(MotionEvent e); + + /** + * Notified when a double-tap occurs. + * + * @param e The down motion event of the first tap of the double-tap. + * @return true if the event is consumed, else false + */ + boolean onDoubleTap(MotionEvent e); + + /** + * Notified when an event within a double-tap gesture occurs, including + * the down, move, and up events. + * + * @param e The motion event that occurred during the double-tap gesture. + * @return true if the event is consumed, else false + */ + boolean onDoubleTapEvent(MotionEvent e); + } + + public interface OnContextClickListener { + /** + * Notified when a context click occurs. + * + * @param e The motion event that occurred during the context click. + * @return true if the event is consumed, else false + */ + boolean onContextClick(MotionEvent e); + } + + /** + * A convenience class to extend when you only want to listen for a subset + * of all the gestures. This implements all methods in the + * {@link OnGestureListener}, {@link OnDoubleTapListener}, and {@link OnContextClickListener} + * but does nothing and return {@code false} for all applicable methods. + */ + public static class SimpleOnGestureListener implements OnGestureListener, OnDoubleTapListener, + OnContextClickListener { + + public boolean onSingleTapUp(MotionEvent e) { + return false; + } + + public void onLongPress(MotionEvent e) { + } + + public boolean onScroll(MotionEvent e1, MotionEvent e2, + float distanceX, float distanceY) { + return false; + } + + public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, + float velocityY) { + return false; + } + + public void onShowPress(MotionEvent e) { + } + + public boolean onDown(MotionEvent e) { + return false; + } + + public void onUp(MotionEvent e) { + + } + + public boolean onDoubleTap(MotionEvent e) { + return false; + } + + public boolean onDoubleTapEvent(MotionEvent e) { + return false; + } + + public boolean onSingleTapConfirmed(MotionEvent e) { + return false; + } + + public boolean onContextClick(MotionEvent e) { + return false; + } + } + + private int mTouchSlopSquare; + private int mDoubleTapTouchSlopSquare; + private int mDoubleTapSlopSquare; + + private int mMinimumFlingVelocity; + private int mMaximumFlingVelocity; + + private static final int LONGPRESS_TIMEOUT = ViewConfiguration.getLongPressTimeout(); + private static final int TAP_TIMEOUT = ViewConfiguration.getTapTimeout(); + private static final int DOUBLE_TAP_TIMEOUT = 150; + private static final int DOUBLE_TAP_MIN_TIME = 40; + + private static final int SHOW_PRESS = 1; + private static final int LONG_PRESS = 2; + private static final int TAP = 3; + + private final Handler mHandler; + private final OnGestureListener mListener; + private OnDoubleTapListener mDoubleTapListener; + + private boolean mStillDown; + private boolean mDeferConfirmSingleTap; + private boolean mInLongPress; + private boolean mInContextClick; + private boolean mAlwaysInTapRegion; + private boolean mAlwaysInBiggerTapRegion; + private boolean mIgnoreNextUpEvent; + + private MotionEvent mCurrentDownEvent; + private MotionEvent mCurrentMotionEvent; + private MotionEvent mPreviousUpEvent; + + private boolean mIsDoubleTapping; + + private float mLastFocusX; + private float mLastFocusY; + private float mDownFocusX; + private float mDownFocusY; + + private boolean mIsLongpressEnabled; + + private VelocityTracker mVelocityTracker; + + private class GestureHandler extends Handler { + GestureHandler() { + super(); + } + + GestureHandler(Handler handler) { + super(handler.getLooper()); + } + + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case SHOW_PRESS: + mListener.onShowPress(mCurrentDownEvent); + break; + + case LONG_PRESS: + dispatchLongPress(); + break; + + case TAP: + if (mDoubleTapListener != null) { + if (!mStillDown) { + mDoubleTapListener.onSingleTapConfirmed(mCurrentDownEvent); + } else { + mDeferConfirmSingleTap = true; + } + } + break; + + default: + throw new RuntimeException("Unknown message " + msg); //never + } + } + } + + @Deprecated + public GestureDetector2(OnGestureListener listener, Handler handler) { + this(null, listener, handler); + } + + @Deprecated + public GestureDetector2(OnGestureListener listener) { + this(null, listener, null); + } + + public GestureDetector2(Context context, OnGestureListener listener) { + this(context, listener, null); + } + + public GestureDetector2(Context context, OnGestureListener listener, Handler handler) { + if (handler != null) { + mHandler = new GestureHandler(handler); + } else { + mHandler = new GestureHandler(); + } + mListener = listener; + if (listener instanceof OnDoubleTapListener) { + setOnDoubleTapListener((OnDoubleTapListener) listener); + } + init(context); + } + + public GestureDetector2(Context context, OnGestureListener listener, Handler handler, boolean unused) { + this(context, listener, handler); + } + + private void init(Context context) { + if (mListener == null) { + throw new NullPointerException("OnGestureListener must not be null"); + } + mIsLongpressEnabled = true; + + int touchSlop, doubleTapSlop, doubleTapTouchSlop; + if (context == null) { + touchSlop = ViewConfiguration.getTouchSlop(); + doubleTapTouchSlop = touchSlop; + doubleTapSlop = 100; + mMinimumFlingVelocity = ViewConfiguration.getMinimumFlingVelocity(); + mMaximumFlingVelocity = ViewConfiguration.getMaximumFlingVelocity(); + } else { + final ViewConfiguration configuration = ViewConfiguration.get(context); + touchSlop = configuration.getScaledTouchSlop(); + doubleTapTouchSlop = configuration.getScaledTouchSlop(); + doubleTapSlop = configuration.getScaledDoubleTapSlop(); + mMinimumFlingVelocity = configuration.getScaledMinimumFlingVelocity(); + mMaximumFlingVelocity = configuration.getScaledMaximumFlingVelocity(); + } + mTouchSlopSquare = touchSlop * touchSlop; + mDoubleTapTouchSlopSquare = doubleTapTouchSlop * doubleTapTouchSlop; + mDoubleTapSlopSquare = doubleTapSlop * doubleTapSlop; + } + + public void setOnDoubleTapListener(OnDoubleTapListener onDoubleTapListener) { + mDoubleTapListener = onDoubleTapListener; + } + + public void setIsLongpressEnabled(boolean isLongpressEnabled) { + mIsLongpressEnabled = isLongpressEnabled; + } + + public boolean isLongpressEnabled() { + return mIsLongpressEnabled; + } + + + public boolean onTouchEvent(MotionEvent ev) { + final int action = ev.getAction(); + + if (mCurrentMotionEvent != null) { + mCurrentMotionEvent.recycle(); + } + mCurrentMotionEvent = MotionEvent.obtain(ev); + + if (mVelocityTracker == null) { + mVelocityTracker = VelocityTracker.obtain(); + } + mVelocityTracker.addMovement(ev); + + final boolean pointerUp = (action & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_UP; + final int skipIndex = pointerUp ? ev.getActionIndex() : -1; + + // Determine focal point + float sumX = 0, sumY = 0; + final int count = ev.getPointerCount(); + for (int i = 0; i < count; i++) { + if (skipIndex == i) continue; + sumX += ev.getX(i); + sumY += ev.getY(i); + } + final int div = pointerUp ? count - 1 : count; + final float focusX = sumX / div; + final float focusY = sumY / div; + + boolean handled = false; + + switch (action & MotionEvent.ACTION_MASK) { + case MotionEvent.ACTION_POINTER_DOWN: + mDownFocusX = mLastFocusX = focusX; + mDownFocusY = mLastFocusY = focusY; + // Cancel long press and taps + cancelTaps(); + break; + + case MotionEvent.ACTION_POINTER_UP: + mDownFocusX = mLastFocusX = focusX; + mDownFocusY = mLastFocusY = focusY; + + // Check the dot product of current velocities. + // If the pointer that left was opposing another velocity vector, clear. + mVelocityTracker.computeCurrentVelocity(1000, mMaximumFlingVelocity); + final int upIndex = ev.getActionIndex(); + final int id1 = ev.getPointerId(upIndex); + final float x1 = mVelocityTracker.getXVelocity(id1); + final float y1 = mVelocityTracker.getYVelocity(id1); + for (int i = 0; i < count; i++) { + if (i == upIndex) continue; + + final int id2 = ev.getPointerId(i); + final float x = x1 * mVelocityTracker.getXVelocity(id2); + final float y = y1 * mVelocityTracker.getYVelocity(id2); + + final float dot = x + y; + if (dot < 0) { + mVelocityTracker.clear(); + break; + } + } + break; + + case MotionEvent.ACTION_DOWN: + if (mDoubleTapListener != null) { + boolean hadTapMessage = mHandler.hasMessages(TAP); + if (hadTapMessage) mHandler.removeMessages(TAP); + if ((mCurrentDownEvent != null) && (mPreviousUpEvent != null) + && hadTapMessage + && isConsideredDoubleTap(mCurrentDownEvent, mPreviousUpEvent, ev)) { + // This is a second tap + mIsDoubleTapping = true; + // Give a callback with the first tap of the double-tap + handled |= mDoubleTapListener.onDoubleTap(mCurrentDownEvent); + // Give a callback with down event of the double-tap + handled |= mDoubleTapListener.onDoubleTapEvent(ev); + } else { + // This is a first tap + mHandler.sendEmptyMessageDelayed(TAP, DOUBLE_TAP_TIMEOUT); + } + } + + mDownFocusX = mLastFocusX = focusX; + mDownFocusY = mLastFocusY = focusY; + if (mCurrentDownEvent != null) { + mCurrentDownEvent.recycle(); + } + mCurrentDownEvent = MotionEvent.obtain(ev); + mAlwaysInTapRegion = true; + mAlwaysInBiggerTapRegion = true; + mStillDown = true; + mInLongPress = false; + mDeferConfirmSingleTap = false; + + if (mIsLongpressEnabled) { + mHandler.removeMessages(LONG_PRESS); + mHandler.sendMessageAtTime( + mHandler.obtainMessage(LONG_PRESS, 0, 0), mCurrentDownEvent.getDownTime() + + ViewConfiguration.getLongPressTimeout()); + } + mHandler.sendEmptyMessageAtTime(SHOW_PRESS, + mCurrentDownEvent.getDownTime() + TAP_TIMEOUT); + handled |= mListener.onDown(ev); + break; + + case MotionEvent.ACTION_MOVE: + if (mInLongPress || mInContextClick) { + break; + } + + final int motionClassification = Build.VERSION.SDK_INT >= 29 ? ev.getClassification() : 0; + final boolean hasPendingLongPress = mHandler.hasMessages(LONG_PRESS); + + final float scrollX = mLastFocusX - focusX; + final float scrollY = mLastFocusY - focusY; + if (mIsDoubleTapping) { + handled |= mDoubleTapListener.onDoubleTapEvent(ev); + } else if (mAlwaysInTapRegion) { + final int deltaX = (int) (focusX - mDownFocusX); + final int deltaY = (int) (focusY - mDownFocusY); + int distance = (deltaX * deltaX) + (deltaY * deltaY); + int slopSquare = mTouchSlopSquare; + + final boolean ambiguousGesture = Build.VERSION.SDK_INT >= 29 && motionClassification == MotionEvent.CLASSIFICATION_AMBIGUOUS_GESTURE; + final boolean shouldInhibitDefaultAction = hasPendingLongPress && ambiguousGesture; + if (shouldInhibitDefaultAction) { + final float multiplier = 2f; + if (distance > slopSquare) { + mHandler.removeMessages(LONG_PRESS); + final long longPressTimeout = ViewConfiguration.getLongPressTimeout(); + mHandler.sendMessageAtTime(mHandler.obtainMessage(LONG_PRESS, 0, 0), ev.getDownTime() + (long) (longPressTimeout * multiplier)); + } + slopSquare *= multiplier * multiplier; + } + + if (distance > slopSquare) { + handled = mListener.onScroll(mCurrentDownEvent, ev, scrollX, scrollY); + mLastFocusX = focusX; + mLastFocusY = focusY; + mAlwaysInTapRegion = false; + mHandler.removeMessages(TAP); + mHandler.removeMessages(SHOW_PRESS); + mHandler.removeMessages(LONG_PRESS); + } + int doubleTapSlopSquare = mDoubleTapTouchSlopSquare; + if (distance > doubleTapSlopSquare) { + mAlwaysInBiggerTapRegion = false; + } + } else if ((Math.abs(scrollX) >= 1) || (Math.abs(scrollY) >= 1)) { + handled = mListener.onScroll(mCurrentDownEvent, ev, scrollX, scrollY); + mLastFocusX = focusX; + mLastFocusY = focusY; + } + if (Build.VERSION.SDK_INT >= 29) { + final boolean deepPress = motionClassification == MotionEvent.CLASSIFICATION_DEEP_PRESS; + if (deepPress && hasPendingLongPress) { + mHandler.removeMessages(LONG_PRESS); + mHandler.sendMessage(mHandler.obtainMessage(LONG_PRESS, 0, 0)); + } + } + break; + + case MotionEvent.ACTION_UP: + mStillDown = false; + mListener.onUp(ev); + MotionEvent currentUpEvent = MotionEvent.obtain(ev); + if (mIsDoubleTapping) { + handled |= mDoubleTapListener.onDoubleTapEvent(ev); + } else if (mInLongPress) { + mHandler.removeMessages(TAP); + mInLongPress = false; + } else if (mAlwaysInTapRegion && !mIgnoreNextUpEvent) { + handled = mListener.onSingleTapUp(ev); + if (mDeferConfirmSingleTap && mDoubleTapListener != null) { + mDoubleTapListener.onSingleTapConfirmed(ev); + } + } else if (!mIgnoreNextUpEvent) { + final VelocityTracker velocityTracker = mVelocityTracker; + final int pointerId = ev.getPointerId(0); + velocityTracker.computeCurrentVelocity(1000, mMaximumFlingVelocity); + final float velocityY = velocityTracker.getYVelocity(pointerId); + final float velocityX = velocityTracker.getXVelocity(pointerId); + + if ((Math.abs(velocityY) > mMinimumFlingVelocity) + || (Math.abs(velocityX) > mMinimumFlingVelocity)) { + handled = mListener.onFling(mCurrentDownEvent, ev, velocityX, velocityY); + } + } + if (mPreviousUpEvent != null) { + mPreviousUpEvent.recycle(); + } + mPreviousUpEvent = currentUpEvent; + if (mVelocityTracker != null) { + mVelocityTracker.recycle(); + mVelocityTracker = null; + } + mIsDoubleTapping = false; + mDeferConfirmSingleTap = false; + mIgnoreNextUpEvent = false; + mHandler.removeMessages(SHOW_PRESS); + mHandler.removeMessages(LONG_PRESS); + break; + + case MotionEvent.ACTION_CANCEL: + cancel(); + break; + } + return handled; + } + + private void cancel() { + mHandler.removeMessages(SHOW_PRESS); + mHandler.removeMessages(LONG_PRESS); + mHandler.removeMessages(TAP); + mVelocityTracker.recycle(); + mVelocityTracker = null; + mIsDoubleTapping = false; + mStillDown = false; + mAlwaysInTapRegion = false; + mAlwaysInBiggerTapRegion = false; + mDeferConfirmSingleTap = false; + mInLongPress = false; + mInContextClick = false; + mIgnoreNextUpEvent = false; + } + + private void cancelTaps() { + mHandler.removeMessages(SHOW_PRESS); + mHandler.removeMessages(LONG_PRESS); + mHandler.removeMessages(TAP); + mIsDoubleTapping = false; + mAlwaysInTapRegion = false; + mAlwaysInBiggerTapRegion = false; + mDeferConfirmSingleTap = false; + mInLongPress = false; + mInContextClick = false; + mIgnoreNextUpEvent = false; + } + + private boolean isConsideredDoubleTap(MotionEvent firstDown, MotionEvent firstUp, MotionEvent secondDown) { + if (!mAlwaysInBiggerTapRegion) { + return false; + } + + final long deltaTime = secondDown.getEventTime() - firstUp.getEventTime(); + if (deltaTime > DOUBLE_TAP_TIMEOUT || deltaTime < DOUBLE_TAP_MIN_TIME) { + return false; + } + + int deltaX = (int) firstDown.getX() - (int) secondDown.getX(); + int deltaY = (int) firstDown.getY() - (int) secondDown.getY(); + int slopSquare = mDoubleTapSlopSquare; + return (deltaX * deltaX + deltaY * deltaY < slopSquare); + } + + private void dispatchLongPress() { + mHandler.removeMessages(TAP); + mDeferConfirmSingleTap = false; + mInLongPress = true; + mListener.onLongPress(mCurrentDownEvent); + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/PhotoViewerCaptionEnterView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/PhotoViewerCaptionEnterView.java index 3a88bf2e0..346829d32 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/PhotoViewerCaptionEnterView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/PhotoViewerCaptionEnterView.java @@ -12,6 +12,7 @@ import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.content.Context; import android.graphics.Canvas; +import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.text.Editable; import android.text.InputFilter; @@ -151,6 +152,12 @@ public class PhotoViewerCaptionEnterView extends FrameLayout implements Notifica protected int getActionModeStyle() { return FloatingToolbar.STYLE_BLACK; } + + @Override + public boolean requestRectangleOnScreen(Rect rectangle) { + rectangle.bottom += AndroidUtilities.dp(1000); + return super.requestRectangleOnScreen(rectangle); + } }; messageEditText.setWindowView(windowView); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/PollVotesAlert.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/PollVotesAlert.java index 2c8cb9856..82e330077 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/PollVotesAlert.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/PollVotesAlert.java @@ -808,7 +808,7 @@ public class PollVotesAlert extends BottomSheet { args.putInt("user_id", userCell.currentUser.id); dismiss(); ProfileActivity fragment = new ProfileActivity(args); - fragment.setPlayProfileAnimation(currentUser != null && currentUser.id == userCell.currentUser.id); + fragment.setPlayProfileAnimation(currentUser != null && currentUser.id == userCell.currentUser.id ? 1 : 0); parentFragment.presentFragment(fragment); } }); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/ProfileGalleryView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/ProfileGalleryView.java index b92053c75..a7eca219f 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/ProfileGalleryView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/ProfileGalleryView.java @@ -42,6 +42,7 @@ public class ProfileGalleryView extends CircularViewPager implements Notificatio private final ViewPagerAdapter adapter; private final int parentClassGuid; private final long dialogId; + private boolean scrolledByUser; private int currentAccount = UserConfig.selectedAccount; @@ -145,6 +146,7 @@ public class ProfileGalleryView extends CircularViewPager implements Notificatio if (action == MotionEvent.ACTION_DOWN) { isScrollingListView = true; isSwipingViewPager = true; + scrolledByUser = true; downPoint.set(ev.getX(), ev.getY()); } else if (action == MotionEvent.ACTION_MOVE) { final float dx = ev.getX() - downPoint.x; @@ -226,7 +228,7 @@ public class ProfileGalleryView extends CircularViewPager implements Notificatio } public BackupImageView getCurrentItemView() { - if (adapter != null) { + if (adapter != null && !adapter.objects.isEmpty()) { return adapter.objects.get(getCurrentItem()).imageView; } else { return null; @@ -237,6 +239,14 @@ public class ProfileGalleryView extends CircularViewPager implements Notificatio setCurrentItem(adapter.getExtraCount(), false); } + public int getRealCount() { + return adapter.getCount() - adapter.getExtraCount() * 2; + } + + public int getRealPosition() { + return adapter.getRealPosition(getCurrentItem()); + } + @Override public boolean onInterceptTouchEvent(MotionEvent e) { if (parentListView.getScrollState() != RecyclerView.SCROLL_STATE_IDLE) { @@ -318,6 +328,9 @@ public class ProfileGalleryView extends CircularViewPager implements Notificatio } loadNeighboringThumbs(); getAdapter().notifyDataSetChanged(); + if (!scrolledByUser) { + resetCurrentItem(); + } if (fromCache) { MessagesController.getInstance(currentAccount).loadDialogPhotos(did, 80, 0, false, parentClassGuid); } @@ -398,9 +411,9 @@ public class ProfileGalleryView extends CircularViewPager implements Notificatio { final int realPosition = getRealPosition(position); if (realPosition == 0) { - setImage(imagesLocations.get(realPosition), null, parentAvatarImageView.getImageReceiver().getBitmap(), imagesLocationsSizes.get(realPosition), null); + setImage(imagesLocations.get(realPosition), null, parentAvatarImageView.getImageReceiver().getBitmap(), imagesLocationsSizes.get(realPosition), 1, null); } else { - setImage(imagesLocations.get(realPosition), null, thumbsLocations.get(realPosition), null, null, null, null, imagesLocationsSizes.get(realPosition), null); + setImage(imagesLocations.get(realPosition), null, thumbsLocations.get(realPosition), null, null, 0, 1, imagesLocationsSizes.get(realPosition)); radialProgress = new RadialProgress2(this); radialProgress.setOverrideAlpha(0.0f); radialProgress.setIcon(MediaActionDrawable.ICON_EMPTY, false, false); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/RecyclerAnimationScrollHelper.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/RecyclerAnimationScrollHelper.java index d3a05b65d..c651a8f53 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/RecyclerAnimationScrollHelper.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/RecyclerAnimationScrollHelper.java @@ -8,8 +8,6 @@ import android.view.View; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; -import com.google.android.exoplayer2.util.Log; - import org.telegram.ui.Cells.ChatMessageCell; import java.util.ArrayList; @@ -24,11 +22,11 @@ public class RecyclerAnimationScrollHelper { private LinearLayoutManager layoutManager; private int scrollDirection; - ValueAnimator animator; + private ValueAnimator animator; - ScrollListener scrollListener; + private ScrollListener scrollListener; - AnimationCallback animationCallback; + private AnimationCallback animationCallback; public RecyclerAnimationScrollHelper(RecyclerListView recyclerView, LinearLayoutManager layoutManager) { this.recyclerView = recyclerView; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/ScrollSlidingTextTabStrip.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/ScrollSlidingTextTabStrip.java index c65c1905e..62a29033f 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/ScrollSlidingTextTabStrip.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/ScrollSlidingTextTabStrip.java @@ -32,6 +32,9 @@ public class ScrollSlidingTextTabStrip extends HorizontalScrollView { public interface ScrollSlidingTabStripDelegate { void onPageSelected(int page, boolean forward); void onPageScrolled(float progress); + default void onSamePageSelected() { + + } } private LinearLayout tabsContainer; @@ -56,6 +59,8 @@ public class ScrollSlidingTextTabStrip extends HorizontalScrollView { private boolean animatingIndicator; private float animationIdicatorProgress; + private int scrollingToChild = -1; + private GradientDrawable selectorDrawable; private String tabLineColorKey = Theme.key_actionBarTabLine; @@ -115,6 +120,7 @@ public class ScrollSlidingTextTabStrip extends HorizontalScrollView { setHorizontalScrollBarEnabled(false); tabsContainer = new LinearLayout(context); tabsContainer.setOrientation(LinearLayout.HORIZONTAL); + tabsContainer.setPadding(AndroidUtilities.dp(7), 0, AndroidUtilities.dp(7), 0); tabsContainer.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutHelper.MATCH_PARENT)); addView(tabsContainer); } @@ -128,6 +134,9 @@ public class ScrollSlidingTextTabStrip extends HorizontalScrollView { } private void setAnimationProgressInernal(TextView newTab, TextView prevTab, float value) { + if (newTab == null || prevTab == null) { + return; + } int newColor = Theme.getColor(activeTextColorKey); int prevColor = Theme.getColor(unactiveTextColorKey); @@ -154,6 +163,9 @@ public class ScrollSlidingTextTabStrip extends HorizontalScrollView { TextView newTab = (TextView) tabsContainer.getChildAt(currentPosition); TextView prevTab = (TextView) tabsContainer.getChildAt(previousPosition); + if (prevTab == null || newTab == null) { + return; + } setAnimationProgressInernal(newTab, prevTab, value); if (value >= 1f) { @@ -218,16 +230,21 @@ public class ScrollSlidingTextTabStrip extends HorizontalScrollView { tab.setGravity(Gravity.CENTER); tab.setText(text); tab.setBackgroundDrawable(Theme.createSelectorDrawable(Theme.getColor(selectorColorKey), 3)); - tab.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); + tab.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15); tab.setSingleLine(true); tab.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); - tab.setPadding(AndroidUtilities.dp(8), 0, AndroidUtilities.dp(8), 0); + tab.setPadding(AndroidUtilities.dp(16), 0, AndroidUtilities.dp(16), 0); tab.setOnClickListener(v -> { int position1 = tabsContainer.indexOfChild(v); - if (position1 < 0 || position1 == currentPosition) { + if (position1 < 0) { + return; + } + if (position1 == currentPosition && delegate != null) { + delegate.onSamePageSelected(); return; } boolean scrollingForward = currentPosition < position1; + scrollingToChild = -1; previousPosition = currentPosition; currentPosition = position1; selectedTabId = id; @@ -254,7 +271,7 @@ public class ScrollSlidingTextTabStrip extends HorizontalScrollView { } scrollToChild(position1); }); - int tabWidth = (int) Math.ceil(tab.getPaint().measureText(text, 0, text.length())) + AndroidUtilities.dp(16); + int tabWidth = (int) Math.ceil(tab.getPaint().measureText(text, 0, text.length())) + tab.getPaddingLeft() + tab.getPaddingRight(); allTextWidth += tabWidth; positionToWidth.put(position, tabWidth); tabsContainer.addView(tab, LayoutHelper.createLinear(0, LayoutHelper.MATCH_PARENT)); @@ -266,6 +283,9 @@ public class ScrollSlidingTextTabStrip extends HorizontalScrollView { TextView tab = (TextView) tabsContainer.getChildAt(a); tab.setTag(currentPosition == a ? activeTextColorKey : unactiveTextColorKey); tab.setTextColor(Theme.getColor(currentPosition == a ? activeTextColorKey : unactiveTextColorKey)); + if (a == 0) { + tab.getLayoutParams().width = count == 1 ? LayoutHelper.WRAP_CONTENT : 0; + } } } @@ -283,6 +303,14 @@ public class ScrollSlidingTextTabStrip extends HorizontalScrollView { public void setInitialTabId(int id) { selectedTabId = id; + int pos = idToPosition.get(id); + TextView child = (TextView) tabsContainer.getChildAt(pos); + if (child != null) { + currentPosition = pos; + prevLayoutWidth = 0; + finishAddingTabs(); + requestLayout(); + } } public int getFirstTabId() { @@ -302,7 +330,7 @@ public class ScrollSlidingTextTabStrip extends HorizontalScrollView { @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - int width = MeasureSpec.getSize(widthMeasureSpec); + int width = MeasureSpec.getSize(widthMeasureSpec) - AndroidUtilities.dp(22); int count = tabsContainer.getChildCount(); for (int a = 0; a < count; a++) { View child = tabsContainer.getChildAt(a); @@ -314,11 +342,16 @@ public class ScrollSlidingTextTabStrip extends HorizontalScrollView { layoutParams.weight = 1.0f / count; layoutParams.width = 0; } else { - layoutParams.weight = 1.0f / allTextWidth * positionToWidth.get(a); - layoutParams.width = 0; + if (a == 0 && count == 1) { + layoutParams.weight = 0.0f; + layoutParams.width = LayoutHelper.WRAP_CONTENT; + } else { + layoutParams.weight = 1.0f / allTextWidth * positionToWidth.get(a); + layoutParams.width = 0; + } } } - if (allTextWidth > width) { + if (count == 1 || allTextWidth > width) { tabsContainer.setWeightSum(0.0f); } else { tabsContainer.setWeightSum(1.0f); @@ -328,9 +361,10 @@ public class ScrollSlidingTextTabStrip extends HorizontalScrollView { } private void scrollToChild(int position) { - if (tabCount == 0) { + if (tabCount == 0 || scrollingToChild == position) { return; } + scrollingToChild = position; TextView child = (TextView) tabsContainer.getChildAt(position); if (child == null) { return; @@ -351,6 +385,7 @@ public class ScrollSlidingTextTabStrip extends HorizontalScrollView { if (prevLayoutWidth != r - l) { prevLayoutWidth = r - l; + scrollingToChild = -1; if (animatingIndicator) { AndroidUtilities.cancelRunOnUIThread(animationRunnable); animatingIndicator = false; @@ -403,6 +438,7 @@ public class ScrollSlidingTextTabStrip extends HorizontalScrollView { child.setTag(unactiveTextColorKey); nextChild.setTag(activeTextColorKey); } + scrollToChild(tabsContainer.indexOfChild(nextChild)); } if (progress >= 1.0f) { currentPosition = position; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/ShareAlert.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/ShareAlert.java index e88a4dbe9..4013a274d 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/ShareAlert.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/ShareAlert.java @@ -56,6 +56,7 @@ import org.telegram.messenger.MessagesStorage; import org.telegram.messenger.NotificationCenter; import org.telegram.messenger.R; import org.telegram.messenger.SendMessagesHelper; +import org.telegram.messenger.SharedConfig; import org.telegram.messenger.UserConfig; import org.telegram.messenger.Utilities; import org.telegram.tgnet.ConnectionsManager; @@ -294,7 +295,7 @@ public class ShareAlert extends BottomSheet implements NotificationCenter.Notifi } - SizeNotifierFrameLayout sizeNotifierFrameLayout = new SizeNotifierFrameLayout(context) { + SizeNotifierFrameLayout sizeNotifierFrameLayout = new SizeNotifierFrameLayout(context, false) { private boolean ignoreLayout = false; private RectF rect1 = new RectF(); @@ -309,7 +310,7 @@ public class ShareAlert extends BottomSheet implements NotificationCenter.Notifi ignoreLayout = false; } int availableHeight = totalHeight - getPaddingTop(); - int keyboardSize = getKeyboardHeight(); + int keyboardSize = SharedConfig.smoothKeyboard ? 0 : getKeyboardHeight(); if (!AndroidUtilities.isInMultiwindow && keyboardSize <= AndroidUtilities.dp(20)) { availableHeight -= commentTextView.getEmojiPadding(); } @@ -333,7 +334,7 @@ public class ShareAlert extends BottomSheet implements NotificationCenter.Notifi setMeasuredDimension(widthSize, heightSize); widthSize -= backgroundPaddingLeft * 2; - int keyboardSize = getKeyboardHeight(); + int keyboardSize = SharedConfig.smoothKeyboard ? 0 : getKeyboardHeight(); if (keyboardSize <= AndroidUtilities.dp(20)) { if (!AndroidUtilities.isInMultiwindow) { heightSize -= commentTextView.getEmojiPadding(); @@ -382,7 +383,8 @@ public class ShareAlert extends BottomSheet implements NotificationCenter.Notifi protected void onLayout(boolean changed, int l, int t, int r, int b) { final int count = getChildCount(); - int paddingBottom = getKeyboardHeight() <= AndroidUtilities.dp(20) && !AndroidUtilities.isInMultiwindow && !AndroidUtilities.isTablet() ? commentTextView.getEmojiPadding() : 0; + int keyboardSize = SharedConfig.smoothKeyboard ? 0 : getKeyboardHeight(); + int paddingBottom = keyboardSize <= AndroidUtilities.dp(20) && !AndroidUtilities.isInMultiwindow && !AndroidUtilities.isTablet() ? commentTextView.getEmojiPadding() : 0; setBottomClip(paddingBottom); for (int i = 0; i < count; i++) { @@ -436,7 +438,7 @@ public class ShareAlert extends BottomSheet implements NotificationCenter.Notifi if (AndroidUtilities.isTablet()) { childTop = getMeasuredHeight() - child.getMeasuredHeight(); } else { - childTop = getMeasuredHeight() + getKeyboardHeight() - child.getMeasuredHeight(); + childTop = getMeasuredHeight() + keyboardSize - child.getMeasuredHeight(); } } child.layout(childLeft, childTop, childLeft + width, childTop + height); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/SharedMediaLayout.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/SharedMediaLayout.java new file mode 100644 index 000000000..9ead739da --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/SharedMediaLayout.java @@ -0,0 +1,3584 @@ +package org.telegram.ui.Components; + +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.AnimatorSet; +import android.animation.ObjectAnimator; +import android.app.Activity; +import android.content.Context; +import android.content.res.Configuration; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.PorterDuff; +import android.graphics.PorterDuffColorFilter; +import android.graphics.drawable.Drawable; +import android.os.Build; +import android.os.Bundle; +import android.text.TextUtils; +import android.util.SparseArray; +import android.util.TypedValue; +import android.view.Gravity; +import android.view.MotionEvent; +import android.view.Surface; +import android.view.VelocityTracker; +import android.view.View; +import android.view.ViewConfiguration; +import android.view.ViewGroup; +import android.view.ViewTreeObserver; +import android.view.WindowManager; +import android.view.animation.Interpolator; +import android.widget.EditText; +import android.widget.FrameLayout; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; + +import org.telegram.messenger.AndroidUtilities; +import org.telegram.messenger.ApplicationLoader; +import org.telegram.messenger.ChatObject; +import org.telegram.messenger.FileLog; +import org.telegram.messenger.LocaleController; +import org.telegram.messenger.MediaController; +import org.telegram.messenger.MediaDataController; +import org.telegram.messenger.MessageObject; +import org.telegram.messenger.NotificationCenter; +import org.telegram.messenger.R; +import org.telegram.messenger.Utilities; +import org.telegram.messenger.browser.Browser; +import org.telegram.tgnet.ConnectionsManager; +import org.telegram.tgnet.TLRPC; +import org.telegram.ui.ActionBar.ActionBar; +import org.telegram.ui.ActionBar.ActionBarMenu; +import org.telegram.ui.ActionBar.ActionBarMenuItem; +import org.telegram.ui.ActionBar.BackDrawable; +import org.telegram.ui.ActionBar.BaseFragment; +import org.telegram.ui.ActionBar.BottomSheet; +import org.telegram.ui.ActionBar.Theme; +import org.telegram.ui.ActionBar.ThemeDescription; +import org.telegram.ui.ArticleViewer; +import org.telegram.ui.Cells.ChatActionCell; +import org.telegram.ui.Cells.GraySectionCell; +import org.telegram.ui.Cells.LoadingCell; +import org.telegram.ui.Cells.ProfileSearchCell; +import org.telegram.ui.Cells.SharedAudioCell; +import org.telegram.ui.Cells.SharedDocumentCell; +import org.telegram.ui.Cells.SharedLinkCell; +import org.telegram.ui.Cells.SharedMediaSectionCell; +import org.telegram.ui.Cells.SharedPhotoVideoCell; +import org.telegram.ui.Cells.UserCell; +import org.telegram.ui.ChatActivity; +import org.telegram.ui.DialogsActivity; +import org.telegram.ui.PhotoViewer; +import org.telegram.ui.ProfileActivity; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; + +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +@SuppressWarnings("unchecked") +public class SharedMediaLayout extends FrameLayout implements NotificationCenter.NotificationCenterDelegate { + + private class MediaPage extends FrameLayout { + private RecyclerListView listView; + private LinearLayout progressView; + private TextView emptyTextView; + private LinearLayoutManager layoutManager; + private ImageView emptyImageView; + private LinearLayout emptyView; + private RadialProgressView progressBar; + private ClippingImageView animatingImageView; + private RecyclerAnimationScrollHelper scrollHelper; + private int selectedType; + + public MediaPage(Context context) { + super(context); + } + } + + private ActionBar actionBar; + + private SharedPhotoVideoAdapter photoVideoAdapter; + private SharedLinksAdapter linksAdapter; + private SharedDocumentsAdapter documentsAdapter; + private SharedDocumentsAdapter voiceAdapter; + private SharedDocumentsAdapter audioAdapter; + private CommonGroupsAdapter commonGroupsAdapter; + private ChatUsersAdapter chatUsersAdapter; + private MediaSearchAdapter documentsSearchAdapter; + private MediaSearchAdapter audioSearchAdapter; + private MediaSearchAdapter linksSearchAdapter; + private MediaPage[] mediaPages = new MediaPage[2]; + private ActionBarMenuItem deleteItem; + private ActionBarMenuItem searchItem; + private ActionBarMenuItem forwardItem; + private ActionBarMenuItem gotoItem; + private int searchItemState; + private Drawable pinnedHeaderShadowDrawable; + private boolean ignoreSearchCollapse; + private NumberTextView selectedMessagesCountTextView; + private LinearLayout actionModeLayout; + private ImageView closeButton; + private BackDrawable backDrawable; + private ArrayList cellCache = new ArrayList<>(10); + private ArrayList cache = new ArrayList<>(10); + private ArrayList audioCellCache = new ArrayList<>(10); + private ArrayList audioCache = new ArrayList<>(10); + private ScrollSlidingTextTabStrip scrollSlidingTextTabStrip; + private View shadowLine; + private ChatActionCell floatingDateView; + private AnimatorSet floatingDateAnimation; + private Runnable hideFloatingDateRunnable = () -> hideFloatingDateView(true); + private ArrayList actionModeViews = new ArrayList<>(); + + private int maximumVelocity; + + private Paint backgroundPaint = new Paint(); + + private boolean searchWas; + private boolean searching; + + private int[] hasMedia; + private int initialTab; + + private SparseArray[] selectedFiles = new SparseArray[]{new SparseArray<>(), new SparseArray<>()}; + private int cantDeleteMessagesCount; + private boolean scrolling; + private long mergeDialogId; + private TLRPC.ChatFull info; + + private AnimatorSet tabsAnimation; + private boolean tabsAnimationInProgress; + private boolean animatingForward; + private boolean backAnimation; + + private long dialog_id; + private int columnsCount = 3; + + private static final Interpolator interpolator = t -> { + --t; + return t * t * t * t * t + 1.0F; + }; + + public interface SharedMediaPreloaderDelegate { + void mediaCountUpdated(); + } + + public static class SharedMediaPreloader implements NotificationCenter.NotificationCenterDelegate { + + private int[] mediaCount = new int[]{-1, -1, -1, -1, -1}; + private int[] mediaMergeCount = new int[]{-1, -1, -1, -1, -1}; + private int[] lastMediaCount = new int[]{-1, -1, -1, -1, -1}; + private SharedMediaData[] sharedMediaData; + private long dialogId; + private long mergeDialogId; + private BaseFragment parentFragment; + private ArrayList delegates = new ArrayList<>(); + + public SharedMediaPreloader(BaseFragment fragment) { + parentFragment = fragment; + if (fragment instanceof ChatActivity) { + ChatActivity chatActivity = (ChatActivity) fragment; + dialogId = chatActivity.getDialogId(); + mergeDialogId = chatActivity.getMergeDialogId(); + } else if (fragment instanceof ProfileActivity) { + ProfileActivity profileActivity = (ProfileActivity) fragment; + dialogId = profileActivity.getDialogId(); + } + + sharedMediaData = new SharedMediaData[5]; + for (int a = 0; a < sharedMediaData.length; a++) { + sharedMediaData[a] = new SharedMediaData(); + sharedMediaData[a].setMaxId(0, (int) dialogId == 0 ? Integer.MIN_VALUE : Integer.MAX_VALUE); + } + loadMediaCounts(); + + NotificationCenter notificationCenter = parentFragment.getNotificationCenter(); + notificationCenter.addObserver(this, NotificationCenter.mediaCountsDidLoad); + notificationCenter.addObserver(this, NotificationCenter.mediaCountDidLoad); + notificationCenter.addObserver(this, NotificationCenter.didReceiveNewMessages); + notificationCenter.addObserver(this, NotificationCenter.messageReceivedByServer); + notificationCenter.addObserver(this, NotificationCenter.mediaDidLoad); + notificationCenter.addObserver(this, NotificationCenter.messagesDeleted); + } + + public void addDelegate(SharedMediaPreloaderDelegate delegate) { + delegates.add(delegate); + } + + public void removeDelegate(SharedMediaPreloaderDelegate delegate) { + delegates.remove(delegate); + } + + public void onDestroy(BaseFragment fragment) { + if (fragment != parentFragment) { + return; + } + delegates.clear(); + NotificationCenter notificationCenter = parentFragment.getNotificationCenter(); + notificationCenter.removeObserver(this, NotificationCenter.mediaCountsDidLoad); + notificationCenter.removeObserver(this, NotificationCenter.mediaCountDidLoad); + notificationCenter.removeObserver(this, NotificationCenter.didReceiveNewMessages); + notificationCenter.removeObserver(this, NotificationCenter.messageReceivedByServer); + notificationCenter.removeObserver(this, NotificationCenter.mediaDidLoad); + notificationCenter.removeObserver(this, NotificationCenter.messagesDeleted); + } + + public int[] getLastMediaCount() { + return lastMediaCount; + } + + public SharedMediaData[] getSharedMediaData() { + return sharedMediaData; + } + + @Override + public void didReceivedNotification(int id, int account, Object... args) { + if (id == NotificationCenter.mediaCountsDidLoad) { + long did = (Long) args[0]; + if (did == dialogId || did == mergeDialogId) { + int[] counts = (int[]) args[1]; + if (did == dialogId) { + mediaCount = counts; + } else { + mediaMergeCount = counts; + } + for (int a = 0; a < counts.length; a++) { + if (mediaCount[a] >= 0 && mediaMergeCount[a] >= 0) { + lastMediaCount[a] = mediaCount[a] + mediaMergeCount[a]; + } else if (mediaCount[a] >= 0) { + lastMediaCount[a] = mediaCount[a]; + } else if (mediaMergeCount[a] >= 0) { + lastMediaCount[a] = mediaMergeCount[a]; + } else { + lastMediaCount[a] = 0; + } + if (did == dialogId && lastMediaCount[a] != 0) { + parentFragment.getMediaDataController().loadMedia(did, 50, 0, a, 2, parentFragment.getClassGuid()); + } + } + for (int a = 0, N = delegates.size(); a < N; a++) { + delegates.get(a).mediaCountUpdated(); + } + } + } else if (id == NotificationCenter.mediaCountDidLoad) { + long did = (Long) args[0]; + if (did == dialogId || did == mergeDialogId) { + int type = (Integer) args[3]; + int mCount = (Integer) args[1]; + if (did == dialogId) { + mediaCount[type] = mCount; + } else { + mediaMergeCount[type] = mCount; + } + if (mediaCount[type] >= 0 && mediaMergeCount[type] >= 0) { + lastMediaCount[type] = mediaCount[type] + mediaMergeCount[type]; + } else if (mediaCount[type] >= 0) { + lastMediaCount[type] = mediaCount[type]; + } else if (mediaMergeCount[type] >= 0) { + lastMediaCount[type] = mediaMergeCount[type]; + } else { + lastMediaCount[type] = 0; + } + for (int a = 0, N = delegates.size(); a < N; a++) { + delegates.get(a).mediaCountUpdated(); + } + } + } else if (id == NotificationCenter.didReceiveNewMessages) { + boolean scheduled = (Boolean) args[2]; + if (scheduled) { + return; + } + if (dialogId == (Long) args[0]) { + boolean enc = ((int) dialogId) == 0; + ArrayList arr = (ArrayList) args[1]; + for (int a = 0; a < arr.size(); a++) { + MessageObject obj = arr.get(a); + if (obj.messageOwner.media == null || obj.needDrawBluredPreview()) { + continue; + } + int type = MediaDataController.getMediaType(obj.messageOwner); + if (type == -1) { + continue; + } + sharedMediaData[type].addMessage(obj, 0, true, enc); + } + loadMediaCounts(); + } + } else if (id == NotificationCenter.messageReceivedByServer) { + Boolean scheduled = (Boolean) args[6]; + if (scheduled) { + return; + } + Integer msgId = (Integer) args[0]; + Integer newMsgId = (Integer) args[1]; + for (int a = 0; a < sharedMediaData.length; a++) { + sharedMediaData[a].replaceMid(msgId, newMsgId); + } + } else if (id == NotificationCenter.mediaDidLoad) { + long did = (Long) args[0]; + int guid = (Integer) args[3]; + if (guid == parentFragment.getClassGuid()) { + int type = (Integer) args[4]; + sharedMediaData[type].setTotalCount((Integer) args[1]); + ArrayList arr = (ArrayList) args[2]; + boolean enc = ((int) did) == 0; + int loadIndex = did == dialogId ? 0 : 1; + if (!arr.isEmpty()) { + sharedMediaData[type].setEndReached(loadIndex, (Boolean) args[5]); + } + for (int a = 0; a < arr.size(); a++) { + MessageObject message = arr.get(a); + sharedMediaData[type].addMessage(message, loadIndex, false, enc); + } + } + } else if (id == NotificationCenter.messagesDeleted) { + boolean scheduled = (Boolean) args[2]; + if (scheduled) { + return; + } + int channelId = (Integer) args[1]; + TLRPC.Chat currentChat; + int lowerId = (int) dialogId; + if (lowerId < 0) { + currentChat = parentFragment.getMessagesController().getChat(-lowerId); + } else { + currentChat = null; + } + if (ChatObject.isChannel(currentChat)) { + if (!(channelId == 0 && mergeDialogId != 0 || channelId == currentChat.id)) { + return; + } + } else if (channelId != 0) { + return; + } + + boolean changed = false; + ArrayList markAsDeletedMessages = (ArrayList) args[0]; + for (int a = 0, N = markAsDeletedMessages.size(); a < N; a++) { + for (int b = 0; b < sharedMediaData.length; b++) { + MessageObject messageObject = sharedMediaData[b].deleteMessage(markAsDeletedMessages.get(a), 0); + if (messageObject != null) { + if (messageObject.getDialogId() == dialogId) { + if (mediaCount[b] > 0) { + mediaCount[b]--; + } + } else { + if (mediaMergeCount[b] > 0) { + mediaMergeCount[b]--; + } + } + changed = true; + } + } + } + if (changed) { + for (int a = 0; a < mediaCount.length; a++) { + if (mediaCount[a] >= 0 && mediaMergeCount[a] >= 0) { + lastMediaCount[a] = mediaCount[a] + mediaMergeCount[a]; + } else if (mediaCount[a] >= 0) { + lastMediaCount[a] = mediaCount[a]; + } else if (mediaMergeCount[a] >= 0) { + lastMediaCount[a] = mediaMergeCount[a]; + } else { + lastMediaCount[a] = 0; + } + } + for (int a = 0, N = delegates.size(); a < N; a++) { + delegates.get(a).mediaCountUpdated(); + } + } + loadMediaCounts(); + } + } + + private void loadMediaCounts() { + parentFragment.getMediaDataController().getMediaCounts(dialogId, parentFragment.getClassGuid()); + if (mergeDialogId != 0) { + parentFragment.getMediaDataController().getMediaCounts(mergeDialogId, parentFragment.getClassGuid()); + } + } + } + + private PhotoViewer.PhotoViewerProvider provider = new PhotoViewer.EmptyPhotoViewerProvider() { + + @Override + public PhotoViewer.PlaceProviderObject getPlaceForPhoto(MessageObject messageObject, TLRPC.FileLocation fileLocation, int index, boolean needPreview) { + if (messageObject == null || mediaPages[0].selectedType != 0 && mediaPages[0].selectedType != 1) { + return null; + } + final RecyclerListView listView = mediaPages[0].listView; + for (int a = 0, count = listView.getChildCount(); a < count; a++) { + View view = listView.getChildAt(a); + BackupImageView imageView = null; + if (view instanceof SharedPhotoVideoCell) { + SharedPhotoVideoCell cell = (SharedPhotoVideoCell) view; + for (int i = 0; i < 6; i++) { + MessageObject message = cell.getMessageObject(i); + if (message == null) { + break; + } + if (message.getId() == messageObject.getId()) { + imageView = cell.getImageView(i); + } + } + } else if (view instanceof SharedDocumentCell) { + SharedDocumentCell cell = (SharedDocumentCell) view; + MessageObject message = cell.getMessage(); + if (message.getId() == messageObject.getId()) { + imageView = cell.getImageView(); + } + } + if (imageView != null) { + int[] coords = new int[2]; + imageView.getLocationInWindow(coords); + PhotoViewer.PlaceProviderObject object = new PhotoViewer.PlaceProviderObject(); + object.viewX = coords[0]; + object.viewY = coords[1] - (Build.VERSION.SDK_INT >= 21 ? 0 : AndroidUtilities.statusBarHeight); + object.parentView = listView; + object.animatingImageView = mediaPages[0].animatingImageView; + mediaPages[0].listView.getLocationInWindow(coords); + object.animatingImageViewYOffset = -coords[1]; + object.imageReceiver = imageView.getImageReceiver(); + object.radius = object.imageReceiver.getRoundRadius(); + object.thumb = object.imageReceiver.getBitmapSafe(); + object.parentView.getLocationInWindow(coords); + object.clipTopAddition = 0; + + if (PhotoViewer.isShowingImage(messageObject)) { + final View pinnedHeader = listView.getPinnedHeader(); + if (pinnedHeader != null) { + int top = 0; + if (view instanceof SharedDocumentCell) { + top += AndroidUtilities.dp(8f); + } + final int topOffset = top - object.viewY; + if (topOffset > view.getHeight()) { + listView.scrollBy(0, -(topOffset + pinnedHeader.getHeight())); + } else { + int bottomOffset = object.viewY - listView.getHeight(); + if (view instanceof SharedDocumentCell) { + bottomOffset -= AndroidUtilities.dp(8f); + } + if (bottomOffset >= 0) { + listView.scrollBy(0, bottomOffset + view.getHeight()); + } + } + } + } + + return object; + } + } + return null; + } + }; + + public static class SharedMediaData { + public ArrayList messages = new ArrayList<>(); + public SparseArray[] messagesDict = new SparseArray[]{new SparseArray<>(), new SparseArray<>()}; + public ArrayList sections = new ArrayList<>(); + public HashMap> sectionArrays = new HashMap<>(); + public int totalCount; + public boolean loading; + public boolean[] endReached = new boolean[]{false, true}; + public int[] max_id = new int[]{0, 0}; + + public void setTotalCount(int count) { + totalCount = count; + } + + public void setMaxId(int num, int value) { + max_id[num] = value; + } + + public void setEndReached(int num, boolean value) { + endReached[num] = value; + } + + public boolean addMessage(MessageObject messageObject, int loadIndex, boolean isNew, boolean enc) { + if (messagesDict[loadIndex].indexOfKey(messageObject.getId()) >= 0) { + return false; + } + ArrayList messageObjects = sectionArrays.get(messageObject.monthKey); + if (messageObjects == null) { + messageObjects = new ArrayList<>(); + sectionArrays.put(messageObject.monthKey, messageObjects); + if (isNew) { + sections.add(0, messageObject.monthKey); + } else { + sections.add(messageObject.monthKey); + } + } + if (isNew) { + messageObjects.add(0, messageObject); + messages.add(0, messageObject); + } else { + messageObjects.add(messageObject); + messages.add(messageObject); + } + messagesDict[loadIndex].put(messageObject.getId(), messageObject); + if (!enc) { + if (messageObject.getId() > 0) { + max_id[loadIndex] = Math.min(messageObject.getId(), max_id[loadIndex]); + } + } else { + max_id[loadIndex] = Math.max(messageObject.getId(), max_id[loadIndex]); + } + return true; + } + + public MessageObject deleteMessage(int mid, int loadIndex) { + MessageObject messageObject = messagesDict[loadIndex].get(mid); + if (messageObject == null) { + return null; + } + ArrayList messageObjects = sectionArrays.get(messageObject.monthKey); + if (messageObjects == null) { + return null; + } + messageObjects.remove(messageObject); + messages.remove(messageObject); + messagesDict[loadIndex].remove(messageObject.getId()); + if (messageObjects.isEmpty()) { + sectionArrays.remove(messageObject.monthKey); + sections.remove(messageObject.monthKey); + } + totalCount--; + return messageObject; + } + + public void replaceMid(int oldMid, int newMid) { + MessageObject obj = messagesDict[0].get(oldMid); + if (obj != null) { + messagesDict[0].remove(oldMid); + messagesDict[0].put(newMid, obj); + obj.messageOwner.id = newMid; + } + } + } + + private SharedMediaData[] sharedMediaData = new SharedMediaData[5]; + + private final static int forward = 100; + private final static int delete = 101; + private final static int gotochat = 102; + + private ProfileActivity profileActivity; + + private int startedTrackingPointerId; + private boolean startedTracking; + private boolean maybeStartTracking; + private int startedTrackingX; + private int startedTrackingY; + private VelocityTracker velocityTracker; + + private boolean isActionModeShowed; + + public SharedMediaLayout(Context context, long did, int[] mediaCount, SharedMediaData[] mediaData, int commonGroupsCount, ArrayList sortedUsers, TLRPC.ChatFull chatInfo, ProfileActivity parent) { + super(context); + + hasMedia = new int[]{mediaCount[0], mediaCount[1], mediaCount[2], mediaCount[3], mediaCount[4], commonGroupsCount}; + if (chatInfo != null) { + initialTab = 6; + } else { + for (int a = 0; a < hasMedia.length; a++) { + if (hasMedia[a] == -1 || hasMedia[a] > 0) { + initialTab = a; + break; + } + } + } + info = chatInfo; + if (info != null) { + mergeDialogId = -info.migrated_from_chat_id; + } + dialog_id = did; + for (int a = 0; a < sharedMediaData.length; a++) { + sharedMediaData[a] = new SharedMediaData(); + sharedMediaData[a].max_id[0] = ((int) dialog_id) == 0 ? Integer.MIN_VALUE : Integer.MAX_VALUE; + if (mediaData != null) { + sharedMediaData[a].totalCount = mediaData[a].totalCount; + sharedMediaData[a].messages.addAll(mediaData[a].messages); + sharedMediaData[a].sections.addAll(mediaData[a].sections); + for (HashMap.Entry> entry : mediaData[a].sectionArrays.entrySet()) { + sharedMediaData[a].sectionArrays.put(entry.getKey(), new ArrayList<>(entry.getValue())); + } + for (int i = 0; i < 2; i++) { + sharedMediaData[a].messagesDict[i] = mediaData[a].messagesDict[i].clone(); + sharedMediaData[a].max_id[i] = mediaData[a].max_id[i]; + sharedMediaData[a].endReached[i] = mediaData[a].endReached[i]; + } + } + if (mergeDialogId != 0 && info != null) { + sharedMediaData[a].max_id[1] = info.migrated_from_max_id; + sharedMediaData[a].endReached[1] = false; + } + } + + profileActivity = parent; + actionBar = profileActivity.getActionBar(); + + profileActivity.getNotificationCenter().addObserver(this, NotificationCenter.mediaDidLoad); + profileActivity.getNotificationCenter().addObserver(this, NotificationCenter.messagesDeleted); + profileActivity.getNotificationCenter().addObserver(this, NotificationCenter.didReceiveNewMessages); + profileActivity.getNotificationCenter().addObserver(this, NotificationCenter.messageReceivedByServer); + profileActivity.getNotificationCenter().addObserver(this, NotificationCenter.messagePlayingDidReset); + profileActivity.getNotificationCenter().addObserver(this, NotificationCenter.messagePlayingPlayStateChanged); + profileActivity.getNotificationCenter().addObserver(this, NotificationCenter.messagePlayingDidStart); + + for (int a = 0; a < 10; a++) { + cellCache.add(new SharedPhotoVideoCell(context)); + if (initialTab == MediaDataController.MEDIA_MUSIC) { + SharedAudioCell cell = new SharedAudioCell(context) { + @Override + public boolean needPlayMessage(MessageObject messageObject) { + if (messageObject.isVoice() || messageObject.isRoundVideo()) { + boolean result = MediaController.getInstance().playMessage(messageObject); + MediaController.getInstance().setVoiceMessagesPlaylist(result ? sharedMediaData[MediaDataController.MEDIA_MUSIC].messages : null, false); + return result; + } else if (messageObject.isMusic()) { + return MediaController.getInstance().setPlaylist(sharedMediaData[MediaDataController.MEDIA_MUSIC].messages, messageObject); + } + return false; + } + }; + cell.initStreamingIcons(); + audioCellCache.add(cell); + } + } + + ViewConfiguration configuration = ViewConfiguration.get(context); + maximumVelocity = configuration.getScaledMaximumFlingVelocity(); + + searching = false; + searchWas = false; + + pinnedHeaderShadowDrawable = context.getResources().getDrawable(R.drawable.photos_header_shadow); + pinnedHeaderShadowDrawable.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_windowBackgroundGrayShadow), PorterDuff.Mode.MULTIPLY)); + + if (scrollSlidingTextTabStrip != null) { + initialTab = scrollSlidingTextTabStrip.getCurrentTabId(); + } + scrollSlidingTextTabStrip = new ScrollSlidingTextTabStrip(context); + if (initialTab != -1) { + scrollSlidingTextTabStrip.setInitialTabId(initialTab); + initialTab = -1; + } + scrollSlidingTextTabStrip.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite)); + scrollSlidingTextTabStrip.setColors(Theme.key_profile_tabSelectedLine, Theme.key_profile_tabSelectedText, Theme.key_profile_tabText, Theme.key_profile_tabSelector); + scrollSlidingTextTabStrip.setDelegate(new ScrollSlidingTextTabStrip.ScrollSlidingTabStripDelegate() { + @Override + public void onPageSelected(int id, boolean forward) { + if (mediaPages[0].selectedType == id) { + return; + } + mediaPages[1].selectedType = id; + mediaPages[1].setVisibility(View.VISIBLE); + hideFloatingDateView(true); + switchToCurrentSelectedMode(true); + animatingForward = forward; + onSelectedTabChanged(); + } + + @Override + public void onSamePageSelected() { + scrollToTop(); + } + + @Override + public void onPageScrolled(float progress) { + if (progress == 1 && mediaPages[1].getVisibility() != View.VISIBLE) { + return; + } + if (animatingForward) { + mediaPages[0].setTranslationX(-progress * mediaPages[0].getMeasuredWidth()); + mediaPages[1].setTranslationX(mediaPages[0].getMeasuredWidth() - progress * mediaPages[0].getMeasuredWidth()); + } else { + mediaPages[0].setTranslationX(progress * mediaPages[0].getMeasuredWidth()); + mediaPages[1].setTranslationX(progress * mediaPages[0].getMeasuredWidth() - mediaPages[0].getMeasuredWidth()); + } + if (canShowSearchItem()) { + if (searchItemState == 1) { + searchItem.setAlpha(progress); + } else if (searchItemState == 2) { + searchItem.setAlpha(1.0f - progress); + } + } else { + searchItem.setVisibility(INVISIBLE); + searchItem.setAlpha(0.0f); + } + if (progress == 1) { + MediaPage tempPage = mediaPages[0]; + mediaPages[0] = mediaPages[1]; + mediaPages[1] = tempPage; + mediaPages[1].setVisibility(View.GONE); + if (searchItemState == 2) { + searchItem.setVisibility(View.INVISIBLE); + } + searchItemState = 0; + } + } + }); + + for (int a = 1; a >= 0; a--) { + selectedFiles[a].clear(); + } + cantDeleteMessagesCount = 0; + actionModeViews.clear(); + + final ActionBarMenu menu = actionBar.createMenu(); + searchItem = menu.addItem(0, R.drawable.ic_ab_search).setIsSearchField(true).setActionBarMenuItemSearchListener(new ActionBarMenuItem.ActionBarMenuItemSearchListener() { + @Override + public void onSearchExpand() { + searching = true; + onSearchStateChanged(true); + } + + @Override + public void onSearchCollapse() { + searching = false; + searchWas = false; + documentsSearchAdapter.search(null); + linksSearchAdapter.search(null); + audioSearchAdapter.search(null); + onSearchStateChanged(false); + if (ignoreSearchCollapse) { + ignoreSearchCollapse = false; + return; + } + switchToCurrentSelectedMode(false); + } + + @Override + public void onTextChanged(EditText editText) { + String text = editText.getText().toString(); + if (text.length() != 0) { + searchWas = true; + } else { + searchWas = false; + if (!ignoreSearchCollapse) { + switchToCurrentSelectedMode(false); + } + } + if (mediaPages[0].selectedType == 1) { + if (documentsSearchAdapter == null) { + return; + } + documentsSearchAdapter.search(text); + } else if (mediaPages[0].selectedType == 3) { + if (linksSearchAdapter == null) { + return; + } + linksSearchAdapter.search(text); + } else if (mediaPages[0].selectedType == 4) { + if (audioSearchAdapter == null) { + return; + } + audioSearchAdapter.search(text); + } + } + + @Override + public void onLayout(int l, int t, int r, int b) { + View parent = (View) searchItem.getParent(); + searchItem.setTranslationX(parent.getMeasuredWidth() - r); + } + }); + searchItem.setTranslationY(AndroidUtilities.dp(10)); + searchItem.setSearchFieldHint(LocaleController.getString("Search", R.string.Search)); + searchItem.setContentDescription(LocaleController.getString("Search", R.string.Search)); + searchItem.setVisibility(View.INVISIBLE); + EditTextBoldCursor editText = searchItem.getSearchField(); + editText.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText)); + editText.setHintTextColor(Theme.getColor(Theme.key_player_time)); + editText.setCursorColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText)); + searchItemState = 0; + + actionModeLayout = new LinearLayout(context); + actionModeLayout.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite)); + actionModeLayout.setAlpha(0.0f); + actionModeLayout.setClickable(true); + actionModeLayout.setVisibility(INVISIBLE); + + closeButton = new ImageView(context); + closeButton.setScaleType(ImageView.ScaleType.CENTER); + closeButton.setImageDrawable(backDrawable = new BackDrawable(true)); + backDrawable.setColor(Theme.getColor(Theme.key_player_actionBarTitle)); + closeButton.setBackground(Theme.createSelectorDrawable(Theme.getColor(Theme.key_actionBarActionModeDefaultSelector), 1)); + actionModeLayout.addView(closeButton, new LinearLayout.LayoutParams(AndroidUtilities.dp(54), ViewGroup.LayoutParams.MATCH_PARENT)); + actionModeViews.add(closeButton); + closeButton.setOnClickListener(v -> closeActionMode()); + + selectedMessagesCountTextView = new NumberTextView(context); + selectedMessagesCountTextView.setTextSize(18); + selectedMessagesCountTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); + selectedMessagesCountTextView.setTextColor(Theme.getColor(Theme.key_player_actionBarTitle)); + actionModeLayout.addView(selectedMessagesCountTextView, LayoutHelper.createLinear(0, LayoutHelper.MATCH_PARENT, 1.0f, 18, 0, 0, 0)); + actionModeViews.add(selectedMessagesCountTextView); + + if ((int) dialog_id != 0) { + gotoItem = new ActionBarMenuItem(context, null, Theme.getColor(Theme.key_actionBarActionModeDefaultSelector), Theme.getColor(Theme.key_player_actionBarTitle), false); + gotoItem.setIcon(R.drawable.msg_message); + gotoItem.setContentDescription(LocaleController.getString("AccDescrGoToMessage", R.string.AccDescrGoToMessage)); + gotoItem.setDuplicateParentStateEnabled(false); + actionModeLayout.addView(gotoItem, new LinearLayout.LayoutParams(AndroidUtilities.dp(54), ViewGroup.LayoutParams.MATCH_PARENT)); + actionModeViews.add(gotoItem); + gotoItem.setOnClickListener(v -> onActionBarItemClick(gotochat)); + + forwardItem = new ActionBarMenuItem(context, null, Theme.getColor(Theme.key_actionBarActionModeDefaultSelector), Theme.getColor(Theme.key_player_actionBarTitle), false); + forwardItem.setIcon(R.drawable.msg_forward); + forwardItem.setContentDescription(LocaleController.getString("Forward", R.string.Forward)); + forwardItem.setDuplicateParentStateEnabled(false); + actionModeLayout.addView(forwardItem, new LinearLayout.LayoutParams(AndroidUtilities.dp(54), ViewGroup.LayoutParams.MATCH_PARENT)); + actionModeViews.add(forwardItem); + forwardItem.setOnClickListener(v -> onActionBarItemClick(forward)); + } + deleteItem = new ActionBarMenuItem(context, null, Theme.getColor(Theme.key_actionBarActionModeDefaultSelector), Theme.getColor(Theme.key_player_actionBarTitle), false); + deleteItem.setIcon(R.drawable.msg_delete); + deleteItem.setContentDescription(LocaleController.getString("Delete", R.string.Delete)); + deleteItem.setDuplicateParentStateEnabled(false); + actionModeLayout.addView(deleteItem, new LinearLayout.LayoutParams(AndroidUtilities.dp(54), ViewGroup.LayoutParams.MATCH_PARENT)); + actionModeViews.add(deleteItem); + deleteItem.setOnClickListener(v -> onActionBarItemClick(delete)); + + photoVideoAdapter = new SharedPhotoVideoAdapter(context); + documentsAdapter = new SharedDocumentsAdapter(context, 1); + voiceAdapter = new SharedDocumentsAdapter(context, 2); + audioAdapter = new SharedDocumentsAdapter(context, 4); + documentsSearchAdapter = new MediaSearchAdapter(context, 1); + audioSearchAdapter = new MediaSearchAdapter(context, 4); + linksSearchAdapter = new MediaSearchAdapter(context, 3); + commonGroupsAdapter = new CommonGroupsAdapter(context); + chatUsersAdapter = new ChatUsersAdapter(context); + chatUsersAdapter.sortedUsers = sortedUsers; + chatUsersAdapter.chatInfo = chatInfo; + linksAdapter = new SharedLinksAdapter(context); + + setWillNotDraw(false); + + int scrollToPositionOnRecreate = -1; + int scrollToOffsetOnRecreate = 0; + + for (int a = 0; a < mediaPages.length; a++) { + if (a == 0) { + if (mediaPages[a] != null && mediaPages[a].layoutManager != null) { + scrollToPositionOnRecreate = mediaPages[a].layoutManager.findFirstVisibleItemPosition(); + if (scrollToPositionOnRecreate != mediaPages[a].layoutManager.getItemCount() - 1) { + RecyclerListView.Holder holder = (RecyclerListView.Holder) mediaPages[a].listView.findViewHolderForAdapterPosition(scrollToPositionOnRecreate); + if (holder != null) { + scrollToOffsetOnRecreate = holder.itemView.getTop(); + } else { + scrollToPositionOnRecreate = -1; + } + } else { + scrollToPositionOnRecreate = -1; + } + } + } + final MediaPage mediaPage = new MediaPage(context) { + @Override + public void setTranslationX(float translationX) { + super.setTranslationX(translationX); + if (tabsAnimationInProgress) { + if (mediaPages[0] == this) { + float scrollProgress = Math.abs(mediaPages[0].getTranslationX()) / (float) mediaPages[0].getMeasuredWidth(); + scrollSlidingTextTabStrip.selectTabWithId(mediaPages[1].selectedType, scrollProgress); + if (canShowSearchItem()) { + if (searchItemState == 2) { + searchItem.setAlpha(1.0f - scrollProgress); + } else if (searchItemState == 1) { + searchItem.setAlpha(scrollProgress); + } + } else { + searchItem.setAlpha(0.0f); + } + } + } + } + }; + addView(mediaPage, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.LEFT | Gravity.TOP, 0, 48, 0, 0)); + mediaPages[a] = mediaPage; + + final LinearLayoutManager layoutManager = mediaPages[a].layoutManager = new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false) { + @Override + public boolean supportsPredictiveItemAnimations() { + return false; + } + + @Override + protected void calculateExtraLayoutSpace(RecyclerView.State state, int[] extraLayoutSpace) { + super.calculateExtraLayoutSpace(state, extraLayoutSpace); + if (mediaPage.selectedType == 0) { + extraLayoutSpace[1] = Math.max(extraLayoutSpace[1], SharedPhotoVideoCell.getItemSize(columnsCount) * 2); + } else if (mediaPage.selectedType == 1) { + extraLayoutSpace[1] = Math.max(extraLayoutSpace[1], AndroidUtilities.dp(56f) * 2); + } + } + }; + mediaPages[a].listView = new RecyclerListView(context) { + @Override + protected void onLayout(boolean changed, int l, int t, int r, int b) { + super.onLayout(changed, l, t, r, b); + checkLoadMoreScroll(mediaPage, mediaPage.listView, layoutManager); + } + }; + mediaPages[a].listView.setPinnedSectionOffsetY(-AndroidUtilities.dp(2)); + mediaPages[a].listView.setPadding(0, AndroidUtilities.dp(2), 0, 0); + mediaPages[a].listView.setItemAnimator(null); + mediaPages[a].listView.setClipToPadding(false); + mediaPages[a].listView.setSectionsType(2); + mediaPages[a].listView.setLayoutManager(layoutManager); + mediaPages[a].addView(mediaPages[a].listView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT)); + mediaPages[a].listView.setOnItemClickListener((view, position) -> { + if (mediaPage.selectedType == 6 && view instanceof UserCell) { + TLRPC.ChatParticipant participant; + if (!chatUsersAdapter.sortedUsers.isEmpty()) { + participant = chatUsersAdapter.chatInfo.participants.participants.get(chatUsersAdapter.sortedUsers.get(position)); + } else { + participant = chatUsersAdapter.chatInfo.participants.participants.get(position); + } + onMemberClick(participant, false); + } else if (mediaPage.selectedType == 5 && view instanceof ProfileSearchCell) { + TLRPC.Chat chat = ((ProfileSearchCell) view).getChat(); + Bundle args = new Bundle(); + args.putInt("chat_id", chat.id); + if (!profileActivity.getMessagesController().checkCanOpenChat(args, profileActivity)) { + return; + } + profileActivity.presentFragment(new ChatActivity(args)); + } else if (mediaPage.selectedType == 1 && view instanceof SharedDocumentCell) { + onItemClick(position, view, ((SharedDocumentCell) view).getMessage(), 0, mediaPage.selectedType); + } else if (mediaPage.selectedType == 3 && view instanceof SharedLinkCell) { + onItemClick(position, view, ((SharedLinkCell) view).getMessage(), 0, mediaPage.selectedType); + } else if ((mediaPage.selectedType == 2 || mediaPage.selectedType == 4) && view instanceof SharedAudioCell) { + onItemClick(position, view, ((SharedAudioCell) view).getMessage(), 0, mediaPage.selectedType); + } + }); + mediaPages[a].listView.setOnScrollListener(new RecyclerView.OnScrollListener() { + @Override + public void onScrollStateChanged(RecyclerView recyclerView, int newState) { + scrolling = newState != RecyclerView.SCROLL_STATE_IDLE; + } + + @Override + public void onScrolled(RecyclerView recyclerView, int dx, int dy) { + checkLoadMoreScroll(mediaPage, recyclerView, layoutManager); + if (dy != 0 && mediaPages[0].selectedType == 0 && !mediaData[0].messages.isEmpty()) { + showFloatingDateView(); + } + } + }); + mediaPages[a].listView.setOnItemLongClickListener((view, position) -> { + if (isActionModeShowed) { + mediaPage.listView.getOnItemClickListener().onItemClick(view, position); + return true; + } + if (mediaPage.selectedType == 6 && view instanceof UserCell) { + final TLRPC.ChatParticipant participant; + if (!chatUsersAdapter.sortedUsers.isEmpty()) { + participant = chatUsersAdapter.chatInfo.participants.participants.get(chatUsersAdapter.sortedUsers.get(position)); + } else { + participant = chatUsersAdapter.chatInfo.participants.participants.get(position); + } + return onMemberClick(participant, true); + } else if (mediaPage.selectedType == 1 && view instanceof SharedDocumentCell) { + return onItemLongClick(((SharedDocumentCell) view).getMessage(), view, 0); + } else if (mediaPage.selectedType == 3 && view instanceof SharedLinkCell) { + return onItemLongClick(((SharedLinkCell) view).getMessage(), view, 0); + } else if ((mediaPage.selectedType == 2 || mediaPage.selectedType == 4) && view instanceof SharedAudioCell) { + return onItemLongClick(((SharedAudioCell) view).getMessage(), view, 0); + } + return false; + }); + if (a == 0 && scrollToPositionOnRecreate != -1) { + layoutManager.scrollToPositionWithOffset(scrollToPositionOnRecreate, scrollToOffsetOnRecreate); + } + + final RecyclerListView listView = mediaPages[a].listView; + + mediaPages[a].animatingImageView = new ClippingImageView(context) { + @Override + public void invalidate() { + super.invalidate(); + listView.invalidate(); + } + }; + mediaPages[a].animatingImageView.setVisibility(View.GONE); + mediaPages[a].listView.addOverlayView(mediaPages[a].animatingImageView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT)); + + mediaPages[a].emptyView = new LinearLayout(context); + mediaPages[a].emptyView.setWillNotDraw(false); + mediaPages[a].emptyView.setOrientation(LinearLayout.VERTICAL); + mediaPages[a].emptyView.setGravity(Gravity.CENTER); + mediaPages[a].emptyView.setVisibility(View.GONE); + mediaPages[a].addView(mediaPages[a].emptyView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT)); + mediaPages[a].emptyView.setOnTouchListener((v, event) -> true); + + mediaPages[a].emptyImageView = new ImageView(context); + mediaPages[a].emptyView.addView(mediaPages[a].emptyImageView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT)); + + mediaPages[a].emptyTextView = new TextView(context); + mediaPages[a].emptyTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText2)); + mediaPages[a].emptyTextView.setGravity(Gravity.CENTER); + mediaPages[a].emptyTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 17); + mediaPages[a].emptyTextView.setPadding(AndroidUtilities.dp(40), 0, AndroidUtilities.dp(40), AndroidUtilities.dp(128)); + mediaPages[a].emptyView.addView(mediaPages[a].emptyTextView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER, 0, 24, 0, 0)); + + mediaPages[a].progressView = new LinearLayout(context) { + @Override + protected void onDraw(Canvas canvas) { + backgroundPaint.setColor(Theme.getColor(Theme.key_windowBackgroundWhite)); + canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), backgroundPaint); + } + }; + mediaPages[a].progressView.setWillNotDraw(false); + mediaPages[a].progressView.setGravity(Gravity.CENTER); + mediaPages[a].progressView.setOrientation(LinearLayout.VERTICAL); + mediaPages[a].progressView.setVisibility(View.GONE); + mediaPages[a].addView(mediaPages[a].progressView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT)); + + mediaPages[a].progressBar = new RadialProgressView(context); + mediaPages[a].progressView.addView(mediaPages[a].progressBar, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT)); + if (a != 0) { + mediaPages[a].setVisibility(View.GONE); + } + + mediaPages[a].scrollHelper = new RecyclerAnimationScrollHelper(mediaPages[a].listView, mediaPages[a].layoutManager); + } + + floatingDateView = new ChatActionCell(context); + floatingDateView.setCustomDate((int) (System.currentTimeMillis() / 1000), false, false); + floatingDateView.setAlpha(0.0f); + floatingDateView.setOverrideColor(Theme.key_chat_mediaTimeBackground, Theme.key_chat_mediaTimeText); + floatingDateView.setTranslationY(-AndroidUtilities.dp(48)); + addView(floatingDateView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.TOP | Gravity.CENTER_HORIZONTAL, 0, 48 + 4, 0, 0)); + + addView(scrollSlidingTextTabStrip, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 48, Gravity.LEFT | Gravity.TOP)); + addView(actionModeLayout, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 48, Gravity.LEFT | Gravity.TOP)); + + shadowLine = new View(context); + shadowLine.setBackgroundColor(Theme.getColor(Theme.key_divider)); + FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 1); + layoutParams.topMargin = AndroidUtilities.dp(48) - 1; + addView(shadowLine, layoutParams); + + updateTabs(); + switchToCurrentSelectedMode(false); + } + + private void showFloatingDateView() { + AndroidUtilities.cancelRunOnUIThread(hideFloatingDateRunnable); + AndroidUtilities.runOnUIThread(hideFloatingDateRunnable, 650); + if (floatingDateView.getTag() != null) { + return; + } + if (floatingDateAnimation != null) { + floatingDateAnimation.cancel(); + } + floatingDateView.setTag(1); + floatingDateAnimation = new AnimatorSet(); + floatingDateAnimation.setDuration(180); + floatingDateAnimation.playTogether( + ObjectAnimator.ofFloat(floatingDateView, View.ALPHA, 1.0f), + ObjectAnimator.ofFloat(floatingDateView, View.TRANSLATION_Y, 0)); + floatingDateAnimation.setInterpolator(CubicBezierInterpolator.EASE_OUT); + floatingDateAnimation.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + floatingDateAnimation = null; + } + }); + floatingDateAnimation.start(); + } + + private void hideFloatingDateView(boolean animated) { + AndroidUtilities.cancelRunOnUIThread(hideFloatingDateRunnable); + if (floatingDateView.getTag() == null) { + return; + } + floatingDateView.setTag(null); + if (floatingDateAnimation != null) { + floatingDateAnimation.cancel(); + floatingDateAnimation = null; + } + if (animated) { + floatingDateAnimation = new AnimatorSet(); + floatingDateAnimation.setDuration(180); + floatingDateAnimation.playTogether( + ObjectAnimator.ofFloat(floatingDateView, View.ALPHA, 0.0f), + ObjectAnimator.ofFloat(floatingDateView, View.TRANSLATION_Y, -AndroidUtilities.dp(48))); + floatingDateAnimation.setInterpolator(CubicBezierInterpolator.EASE_OUT); + floatingDateAnimation.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + floatingDateAnimation = null; + } + }); + floatingDateAnimation.start(); + } else { + floatingDateView.setAlpha(0.0f); + } + } + + private void scrollToTop() { + int height; + switch (mediaPages[0].selectedType) { + case 0: + height = SharedPhotoVideoCell.getItemSize(columnsCount); + break; + case 1: + case 2: + case 4: + height = AndroidUtilities.dp(56); + break; + case 3: + height = AndroidUtilities.dp(100); + break; + case 5: + height = AndroidUtilities.dp(60); + break; + case 6: + default: + height = AndroidUtilities.dp(58); + break; + } + int scrollDistance = mediaPages[0].layoutManager.findFirstVisibleItemPosition() * height; + if (scrollDistance >= mediaPages[0].listView.getMeasuredHeight() * 1.2f) { + mediaPages[0].scrollHelper.setScrollDirection(RecyclerAnimationScrollHelper.SCROLL_DIRECTION_UP); + mediaPages[0].scrollHelper.scrollToPosition(0, 0, false, true); + } else { + mediaPages[0].listView.smoothScrollToPosition(0); + } + } + + private void checkLoadMoreScroll(MediaPage mediaPage, RecyclerView recyclerView, LinearLayoutManager layoutManager) { + if (searching && searchWas || mediaPage.selectedType == 6) { + return; + } + int firstVisibleItem = layoutManager.findFirstVisibleItemPosition(); + int visibleItemCount = firstVisibleItem == RecyclerView.NO_POSITION ? 0 : Math.abs(layoutManager.findLastVisibleItemPosition() - firstVisibleItem) + 1; + int totalItemCount = recyclerView.getAdapter().getItemCount(); + + if (mediaPage.selectedType == 6) { + + } else if (mediaPage.selectedType == 5) { + if (visibleItemCount > 0) { + if (!commonGroupsAdapter.endReached && !commonGroupsAdapter.loading && !commonGroupsAdapter.chats.isEmpty() && firstVisibleItem + visibleItemCount >= totalItemCount - 5) { + commonGroupsAdapter.getChats(commonGroupsAdapter.chats.get(commonGroupsAdapter.chats.size() - 1).id, 100); + } + } + } else { + final int threshold = mediaPage.selectedType == 0 ? 3 : 6; + if (visibleItemCount != 0 && firstVisibleItem + visibleItemCount > totalItemCount - threshold && !sharedMediaData[mediaPage.selectedType].loading) { + int type; + if (mediaPage.selectedType == 0) { + type = MediaDataController.MEDIA_PHOTOVIDEO; + } else if (mediaPage.selectedType == 1) { + type = MediaDataController.MEDIA_FILE; + } else if (mediaPage.selectedType == 2) { + type = MediaDataController.MEDIA_AUDIO; + } else if (mediaPage.selectedType == 4) { + type = MediaDataController.MEDIA_MUSIC; + } else { + type = MediaDataController.MEDIA_URL; + } + if (!sharedMediaData[mediaPage.selectedType].endReached[0]) { + sharedMediaData[mediaPage.selectedType].loading = true; + profileActivity.getMediaDataController().loadMedia(dialog_id, 50, sharedMediaData[mediaPage.selectedType].max_id[0], type, 1, profileActivity.getClassGuid()); + } else if (mergeDialogId != 0 && !sharedMediaData[mediaPage.selectedType].endReached[1]) { + sharedMediaData[mediaPage.selectedType].loading = true; + profileActivity.getMediaDataController().loadMedia(mergeDialogId, 50, sharedMediaData[mediaPage.selectedType].max_id[1], type, 1, profileActivity.getClassGuid()); + } + } + if (mediaPages[0].selectedType == 0 && firstVisibleItem != RecyclerView.NO_POSITION) { + RecyclerListView.ViewHolder holder = recyclerView.findViewHolderForAdapterPosition(firstVisibleItem); + if (holder != null && holder.getItemViewType() == 0) { + SharedPhotoVideoCell cell = (SharedPhotoVideoCell) holder.itemView; + MessageObject messageObject = cell.getMessageObject(0); + if (messageObject != null) { + floatingDateView.setCustomDate(messageObject.messageOwner.date, false, true); + } + } + } + } + } + + public ActionBarMenuItem getSearchItem() { + return searchItem; + } + + public boolean isSearchItemVisible() { + return mediaPages[0].selectedType != 0 && mediaPages[0].selectedType != 2 && mediaPages[0].selectedType != 5 && mediaPages[0].selectedType != 6; + } + + public int getSelectedTab() { + return scrollSlidingTextTabStrip.getCurrentTabId(); + } + + protected void onSelectedTabChanged() { + + } + + protected boolean canShowSearchItem() { + return true; + } + + protected void onSearchStateChanged(boolean expanded) { + + } + + protected boolean onMemberClick(TLRPC.ChatParticipant participant, boolean isLong) { + return false; + } + + public void onDestroy() { + profileActivity.getNotificationCenter().removeObserver(this, NotificationCenter.mediaDidLoad); + profileActivity.getNotificationCenter().removeObserver(this, NotificationCenter.didReceiveNewMessages); + profileActivity.getNotificationCenter().removeObserver(this, NotificationCenter.messagesDeleted); + profileActivity.getNotificationCenter().removeObserver(this, NotificationCenter.messageReceivedByServer); + profileActivity.getNotificationCenter().removeObserver(this, NotificationCenter.messagePlayingDidReset); + profileActivity.getNotificationCenter().removeObserver(this, NotificationCenter.messagePlayingPlayStateChanged); + profileActivity.getNotificationCenter().removeObserver(this, NotificationCenter.messagePlayingDidStart); + } + + private void checkCurrentTabValid() { + int id = scrollSlidingTextTabStrip.getCurrentTabId(); + if (!scrollSlidingTextTabStrip.hasTab(id)) { + id = scrollSlidingTextTabStrip.getFirstTabId(); + scrollSlidingTextTabStrip.setInitialTabId(id); + mediaPages[0].selectedType = id; + switchToCurrentSelectedMode(false); + } + } + + public void setNewMediaCounts(int[] mediaCounts) { + System.arraycopy(mediaCounts, 0, hasMedia, 0, 5); + updateTabs(); + checkCurrentTabValid(); + } + + public void setCommonGroupsCount(int count) { + hasMedia[5] = count; + updateTabs(); + checkCurrentTabValid(); + } + + public void onActionBarItemClick(int id) { + if (id == delete) { + TLRPC.Chat currentChat = null; + TLRPC.User currentUser = null; + TLRPC.EncryptedChat currentEncryptedChat = null; + int lower_id = (int) dialog_id; + if (lower_id != 0) { + if (lower_id > 0) { + currentUser = profileActivity.getMessagesController().getUser(lower_id); + } else { + currentChat = profileActivity.getMessagesController().getChat(-lower_id); + } + } else { + currentEncryptedChat = profileActivity.getMessagesController().getEncryptedChat((int) (dialog_id >> 32)); + } + AlertsCreator.createDeleteMessagesAlert(profileActivity, currentUser, currentChat, currentEncryptedChat, null, mergeDialogId, null, selectedFiles, null, false, 1, () -> { + showActionMode(false); + actionBar.closeSearchField(); + cantDeleteMessagesCount = 0; + }); + } else if (id == forward) { + Bundle args = new Bundle(); + args.putBoolean("onlySelect", true); + args.putInt("dialogsType", 3); + DialogsActivity fragment = new DialogsActivity(args); + fragment.setDelegate((fragment1, dids, message, param) -> { + ArrayList fmessages = new ArrayList<>(); + for (int a = 1; a >= 0; a--) { + ArrayList ids = new ArrayList<>(); + for (int b = 0; b < selectedFiles[a].size(); b++) { + ids.add(selectedFiles[a].keyAt(b)); + } + Collections.sort(ids); + for (Integer id1 : ids) { + if (id1 > 0) { + fmessages.add(selectedFiles[a].get(id1)); + } + } + selectedFiles[a].clear(); + } + cantDeleteMessagesCount = 0; + showActionMode(false); + + if (dids.size() > 1 || dids.get(0) == profileActivity.getUserConfig().getClientUserId() || message != null) { + updateRowsSelection(); + for (int a = 0; a < dids.size(); a++) { + long did = dids.get(a); + if (message != null) { + profileActivity.getSendMessagesHelper().sendMessage(message.toString(), did, null, null, true, null, null, null, true, 0); + } + profileActivity.getSendMessagesHelper().sendMessage(fmessages, did, true, 0); + } + fragment1.finishFragment(); + } else { + long did = dids.get(0); + int lower_part = (int) did; + int high_part = (int) (did >> 32); + Bundle args1 = new Bundle(); + args1.putBoolean("scrollToTopOnResume", true); + if (lower_part != 0) { + if (lower_part > 0) { + args1.putInt("user_id", lower_part); + } else if (lower_part < 0) { + args1.putInt("chat_id", -lower_part); + } + } else { + args1.putInt("enc_id", high_part); + } + if (lower_part != 0) { + if (!profileActivity.getMessagesController().checkCanOpenChat(args1, fragment1)) { + return; + } + } + + profileActivity.getNotificationCenter().postNotificationName(NotificationCenter.closeChats); + + ChatActivity chatActivity = new ChatActivity(args1); + fragment1.presentFragment(chatActivity, true); + chatActivity.showFieldPanelForForward(true, fmessages); + } + }); + profileActivity.presentFragment(fragment); + } else if (id == gotochat) { + if (selectedFiles[0].size() != 1) { + return; + } + Bundle args = new Bundle(); + int lower_part = (int) dialog_id; + int high_id = (int) (dialog_id >> 32); + if (lower_part != 0) { + if (lower_part > 0) { + args.putInt("user_id", lower_part); + } else if (lower_part < 0) { + TLRPC.Chat chat = profileActivity.getMessagesController().getChat(-lower_part); + if (chat != null && chat.migrated_to != null) { + args.putInt("migrated_to", lower_part); + lower_part = -chat.migrated_to.channel_id; + } + args.putInt("chat_id", -lower_part); + } + } else { + args.putInt("enc_id", high_id); + } + args.putInt("message_id", selectedFiles[0].keyAt(0)); + profileActivity.getNotificationCenter().removeObserver(profileActivity, NotificationCenter.closeChats); + profileActivity.getNotificationCenter().postNotificationName(NotificationCenter.closeChats); + profileActivity.presentFragment(new ChatActivity(args), true); + } + } + + private boolean prepareForMoving(MotionEvent ev, boolean forward) { + int id = scrollSlidingTextTabStrip.getNextPageId(forward); + if (id < 0) { + return false; + } + if (canShowSearchItem()) { + if (searchItemState != 0) { + if (searchItemState == 2) { + searchItem.setAlpha(1.0f); + } else if (searchItemState == 1) { + searchItem.setAlpha(0.0f); + searchItem.setVisibility(View.INVISIBLE); + } + searchItemState = 0; + } + } else { + searchItem.setVisibility(INVISIBLE); + searchItem.setAlpha(0.0f); + } + getParent().requestDisallowInterceptTouchEvent(true); + hideFloatingDateView(true); + maybeStartTracking = false; + startedTracking = true; + startedTrackingX = (int) ev.getX(); + actionBar.setEnabled(false); + scrollSlidingTextTabStrip.setEnabled(false); + mediaPages[1].selectedType = id; + mediaPages[1].setVisibility(View.VISIBLE); + animatingForward = forward; + switchToCurrentSelectedMode(true); + if (forward) { + mediaPages[1].setTranslationX(mediaPages[0].getMeasuredWidth()); + } else { + mediaPages[1].setTranslationX(-mediaPages[0].getMeasuredWidth()); + } + return true; + } + + @Override + public void forceHasOverlappingRendering(boolean hasOverlappingRendering) { + super.forceHasOverlappingRendering(hasOverlappingRendering); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + int widthSize = MeasureSpec.getSize(widthMeasureSpec); + int heightSize = profileActivity.getListView().getHeight(); + if (heightSize == 0) { + heightSize = MeasureSpec.getSize(heightMeasureSpec); + } + + setMeasuredDimension(widthSize, heightSize); + + int childCount = getChildCount(); + for (int i = 0; i < childCount; i++) { + View child = getChildAt(i); + if (child == null || child.getVisibility() == GONE) { + continue; + } + if (child instanceof MediaPage) { + measureChildWithMargins(child, widthMeasureSpec, 0, MeasureSpec.makeMeasureSpec(heightSize, MeasureSpec.EXACTLY), 0); + } else { + measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, 0); + } + } + } + + public boolean checkTabsAnimationInProgress() { + if (tabsAnimationInProgress) { + boolean cancel = false; + if (backAnimation) { + if (Math.abs(mediaPages[0].getTranslationX()) < 1) { + mediaPages[0].setTranslationX(0); + mediaPages[1].setTranslationX(mediaPages[0].getMeasuredWidth() * (animatingForward ? 1 : -1)); + cancel = true; + } + } else if (Math.abs(mediaPages[1].getTranslationX()) < 1) { + mediaPages[0].setTranslationX(mediaPages[0].getMeasuredWidth() * (animatingForward ? -1 : 1)); + mediaPages[1].setTranslationX(0); + cancel = true; + } + if (cancel) { + if (tabsAnimation != null) { + tabsAnimation.cancel(); + tabsAnimation = null; + } + tabsAnimationInProgress = false; + } + return tabsAnimationInProgress; + } + return false; + } + + @Override + public boolean onInterceptTouchEvent(MotionEvent ev) { + return checkTabsAnimationInProgress() || scrollSlidingTextTabStrip.isAnimatingIndicator() || onTouchEvent(ev); + } + + public boolean isCurrentTabFirst() { + return scrollSlidingTextTabStrip.getCurrentTabId() == scrollSlidingTextTabStrip.getFirstTabId(); + } + + public RecyclerListView getCurrentListView() { + return mediaPages[0].listView; + } + + @Override + public boolean onTouchEvent(MotionEvent ev) { + if (!profileActivity.getParentLayout().checkTransitionAnimation() && !checkTabsAnimationInProgress()) { + if (ev != null && ev.getAction() == MotionEvent.ACTION_DOWN && !startedTracking && !maybeStartTracking && ev.getY() >= AndroidUtilities.dp(48)) { + startedTrackingPointerId = ev.getPointerId(0); + maybeStartTracking = true; + startedTrackingX = (int) ev.getX(); + startedTrackingY = (int) ev.getY(); + if (velocityTracker != null) { + velocityTracker.clear(); + } + } else if (ev != null && ev.getAction() == MotionEvent.ACTION_MOVE && ev.getPointerId(0) == startedTrackingPointerId) { + if (velocityTracker == null) { + velocityTracker = VelocityTracker.obtain(); + } + int dx = (int) (ev.getX() - startedTrackingX); + int dy = Math.abs((int) ev.getY() - startedTrackingY); + velocityTracker.addMovement(ev); + if (startedTracking && (animatingForward && dx > 0 || !animatingForward && dx < 0)) { + if (!prepareForMoving(ev, dx < 0)) { + maybeStartTracking = true; + startedTracking = false; + mediaPages[0].setTranslationX(0); + if (animatingForward) { + mediaPages[1].setTranslationX(mediaPages[0].getMeasuredWidth()); + } else { + mediaPages[1].setTranslationX(-mediaPages[0].getMeasuredWidth()); + } + } + } + if (maybeStartTracking && !startedTracking) { + float touchSlop = AndroidUtilities.getPixelsInCM(0.3f, true); + if (Math.abs(dx) >= touchSlop && Math.abs(dx) / 3 > dy) { + prepareForMoving(ev, dx < 0); + } + } else if (startedTracking) { + mediaPages[0].setTranslationX(dx); + if (animatingForward) { + mediaPages[1].setTranslationX(mediaPages[0].getMeasuredWidth() + dx); + } else { + mediaPages[1].setTranslationX(dx - mediaPages[0].getMeasuredWidth()); + } + float scrollProgress = Math.abs(dx) / (float) mediaPages[0].getMeasuredWidth(); + if (canShowSearchItem()) { + if (searchItemState == 2) { + searchItem.setAlpha(1.0f - scrollProgress); + } else if (searchItemState == 1) { + searchItem.setAlpha(scrollProgress); + } + } else { + searchItem.setAlpha(0.0f); + } + scrollSlidingTextTabStrip.selectTabWithId(mediaPages[1].selectedType, scrollProgress); + } + } else if (ev != null && ev.getPointerId(0) == startedTrackingPointerId && (ev.getAction() == MotionEvent.ACTION_CANCEL || ev.getAction() == MotionEvent.ACTION_UP || ev.getAction() == MotionEvent.ACTION_POINTER_UP)) { + if (velocityTracker == null) { + velocityTracker = VelocityTracker.obtain(); + } + velocityTracker.computeCurrentVelocity(1000, maximumVelocity); + if (!startedTracking) { + float velX = velocityTracker.getXVelocity(); + float velY = velocityTracker.getYVelocity(); + if (Math.abs(velX) >= 3000 && Math.abs(velX) > Math.abs(velY)) { + prepareForMoving(ev, velX < 0); + } + } + if (startedTracking) { + float x = mediaPages[0].getX(); + tabsAnimation = new AnimatorSet(); + float velX = velocityTracker.getXVelocity(); + float velY = velocityTracker.getYVelocity(); + backAnimation = Math.abs(x) < mediaPages[0].getMeasuredWidth() / 3.0f && (Math.abs(velX) < 3500 || Math.abs(velX) < Math.abs(velY)); + float distToMove; + float dx; + if (backAnimation) { + dx = Math.abs(x); + if (animatingForward) { + tabsAnimation.playTogether( + ObjectAnimator.ofFloat(mediaPages[0], View.TRANSLATION_X, 0), + ObjectAnimator.ofFloat(mediaPages[1], View.TRANSLATION_X, mediaPages[1].getMeasuredWidth()) + ); + } else { + tabsAnimation.playTogether( + ObjectAnimator.ofFloat(mediaPages[0], View.TRANSLATION_X, 0), + ObjectAnimator.ofFloat(mediaPages[1], View.TRANSLATION_X, -mediaPages[1].getMeasuredWidth()) + ); + } + } else { + dx = mediaPages[0].getMeasuredWidth() - Math.abs(x); + if (animatingForward) { + tabsAnimation.playTogether( + ObjectAnimator.ofFloat(mediaPages[0], View.TRANSLATION_X, -mediaPages[0].getMeasuredWidth()), + ObjectAnimator.ofFloat(mediaPages[1], View.TRANSLATION_X, 0) + ); + } else { + tabsAnimation.playTogether( + ObjectAnimator.ofFloat(mediaPages[0], View.TRANSLATION_X, mediaPages[0].getMeasuredWidth()), + ObjectAnimator.ofFloat(mediaPages[1], View.TRANSLATION_X, 0) + ); + } + } + tabsAnimation.setInterpolator(interpolator); + + int width = getMeasuredWidth(); + int halfWidth = width / 2; + float distanceRatio = Math.min(1.0f, 1.0f * dx / (float) width); + float distance = (float) halfWidth + (float) halfWidth * AndroidUtilities.distanceInfluenceForSnapDuration(distanceRatio); + velX = Math.abs(velX); + int duration; + if (velX > 0) { + duration = 4 * Math.round(1000.0f * Math.abs(distance / velX)); + } else { + float pageDelta = dx / getMeasuredWidth(); + duration = (int) ((pageDelta + 1.0f) * 100.0f); + } + duration = Math.max(150, Math.min(duration, 600)); + + tabsAnimation.setDuration(duration); + tabsAnimation.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animator) { + tabsAnimation = null; + if (backAnimation) { + mediaPages[1].setVisibility(View.GONE); + if (canShowSearchItem()) { + if (searchItemState == 2) { + searchItem.setAlpha(1.0f); + } else if (searchItemState == 1) { + searchItem.setAlpha(0.0f); + searchItem.setVisibility(View.INVISIBLE); + } + } else { + searchItem.setVisibility(INVISIBLE); + searchItem.setAlpha(0.0f); + } + searchItemState = 0; + } else { + MediaPage tempPage = mediaPages[0]; + mediaPages[0] = mediaPages[1]; + mediaPages[1] = tempPage; + mediaPages[1].setVisibility(View.GONE); + if (searchItemState == 2) { + searchItem.setVisibility(View.INVISIBLE); + } + searchItemState = 0; + scrollSlidingTextTabStrip.selectTabWithId(mediaPages[0].selectedType, 1.0f); + onSelectedTabChanged(); + } + tabsAnimationInProgress = false; + maybeStartTracking = false; + startedTracking = false; + actionBar.setEnabled(true); + scrollSlidingTextTabStrip.setEnabled(true); + } + }); + tabsAnimation.start(); + tabsAnimationInProgress = true; + } else { + maybeStartTracking = false; + startedTracking = false; + actionBar.setEnabled(true); + scrollSlidingTextTabStrip.setEnabled(true); + } + if (velocityTracker != null) { + velocityTracker.recycle(); + velocityTracker = null; + } + } + return startedTracking; + } + return false; + } + + public boolean closeActionMode() { + if (isActionModeShowed) { + for (int a = 1; a >= 0; a--) { + selectedFiles[a].clear(); + } + cantDeleteMessagesCount = 0; + showActionMode(false); + updateRowsSelection(); + return true; + } else { + return false; + } + } + + private AnimatorSet actionModeAnimation; + private void showActionMode(boolean show) { + if (isActionModeShowed == show) { + return; + } + isActionModeShowed = show; + if (actionModeAnimation != null) { + actionModeAnimation.cancel(); + } + if (show) { + actionModeLayout.setVisibility(VISIBLE); + } + actionModeAnimation = new AnimatorSet(); + actionModeAnimation.playTogether(ObjectAnimator.ofFloat(actionModeLayout, View.ALPHA, show ? 1.0f : 0.0f)); + actionModeAnimation.setDuration(180); + actionModeAnimation.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationCancel(Animator animation) { + actionModeAnimation = null; + } + + @Override + public void onAnimationEnd(Animator animation) { + if (actionModeAnimation == null) { + return; + } + actionModeAnimation = null; + if (!show) { + actionModeLayout.setVisibility(INVISIBLE); + } + } + }); + actionModeAnimation.start(); + } + + @Override + public void didReceivedNotification(int id, int account, Object... args) { + if (id == NotificationCenter.mediaDidLoad) { + long uid = (Long) args[0]; + int guid = (Integer) args[3]; + if (guid == profileActivity.getClassGuid()) { + int type = (Integer) args[4]; + sharedMediaData[type].loading = false; + sharedMediaData[type].totalCount = (Integer) args[1]; + ArrayList arr = (ArrayList) args[2]; + boolean enc = ((int) dialog_id) == 0; + int loadIndex = uid == dialog_id ? 0 : 1; + + RecyclerListView.Adapter adapter = null; + if (type == 0) { + adapter = photoVideoAdapter; + } else if (type == 1) { + adapter = documentsAdapter; + } else if (type == 2) { + adapter = voiceAdapter; + } else if (type == 3) { + adapter = linksAdapter; + } else if (type == 4) { + adapter = audioAdapter; + } + int oldItemCount; + if (adapter != null) { + oldItemCount = adapter.getItemCount(); + if (adapter instanceof RecyclerListView.SectionsAdapter) { + RecyclerListView.SectionsAdapter sectionsAdapter = (RecyclerListView.SectionsAdapter) adapter; + sectionsAdapter.notifySectionsChanged(); + } + } else { + oldItemCount = 0; + } + for (int a = 0; a < arr.size(); a++) { + MessageObject message = arr.get(a); + sharedMediaData[type].addMessage(message, loadIndex, false, enc); + } + sharedMediaData[type].endReached[loadIndex] = (Boolean) args[5]; + if (loadIndex == 0 && sharedMediaData[type].endReached[loadIndex] && mergeDialogId != 0) { + sharedMediaData[type].loading = true; + profileActivity.getMediaDataController().loadMedia(mergeDialogId, 50, sharedMediaData[type].max_id[1], type, 1, profileActivity.getClassGuid()); + } + if (adapter != null) { + for (int a = 0; a < mediaPages.length; a++) { + if (mediaPages[a].listView.getAdapter() == adapter) { + mediaPages[a].listView.stopScroll(); + } + } + int newItemCount = adapter.getItemCount(); + if (type == 0) { + if (oldItemCount > 1) { + adapter.notifyItemRangeChanged(oldItemCount - 2, 2); + } + if (newItemCount > oldItemCount) { + adapter.notifyItemRangeInserted(oldItemCount, newItemCount); + } else if (newItemCount < oldItemCount) { + adapter.notifyItemRangeRemoved(newItemCount, (oldItemCount - newItemCount)); + } + } else { + if (oldItemCount > 1) { + adapter.notifyItemChanged(oldItemCount - 2); + } + if (newItemCount > oldItemCount) { + adapter.notifyItemRangeInserted(oldItemCount, newItemCount); + } else if (newItemCount < oldItemCount) { + adapter.notifyItemRangeRemoved(newItemCount, (oldItemCount - newItemCount)); + } + } + } + scrolling = true; + for (int a = 0; a < mediaPages.length; a++) { + if (mediaPages[a].selectedType == type) { + if (!sharedMediaData[type].loading) { + if (mediaPages[a].progressView != null) { + mediaPages[a].progressView.setVisibility(View.GONE); + } + if (mediaPages[a].listView != null) { + if (mediaPages[a].listView.getEmptyView() == null) { + mediaPages[a].listView.setEmptyView(mediaPages[a].emptyView); + } + } + } + } + } + } + } else if (id == NotificationCenter.messagesDeleted) { + boolean scheduled = (Boolean) args[2]; + if (scheduled) { + return; + } + TLRPC.Chat currentChat = null; + if ((int) dialog_id < 0) { + currentChat = profileActivity.getMessagesController().getChat(-(int) dialog_id); + } + int channelId = (Integer) args[1]; + int loadIndex = 0; + if (ChatObject.isChannel(currentChat)) { + if (channelId == 0 && mergeDialogId != 0) { + loadIndex = 1; + } else if (channelId == currentChat.id) { + loadIndex = 0; + } else { + return; + } + } else if (channelId != 0) { + return; + } + ArrayList markAsDeletedMessages = (ArrayList) args[0]; + boolean updated = false; + for (int a = 0, N = markAsDeletedMessages.size(); a < N; a++) { + for (int b = 0; b < sharedMediaData.length; b++) { + if (sharedMediaData[b].deleteMessage(markAsDeletedMessages.get(a), loadIndex) != null) { + updated = true; + } + } + } + if (updated) { + scrolling = true; + if (photoVideoAdapter != null) { + photoVideoAdapter.notifyDataSetChanged(); + } + if (documentsAdapter != null) { + documentsAdapter.notifyDataSetChanged(); + } + if (voiceAdapter != null) { + voiceAdapter.notifyDataSetChanged(); + } + if (linksAdapter != null) { + linksAdapter.notifyDataSetChanged(); + } + if (audioAdapter != null) { + audioAdapter.notifyDataSetChanged(); + } + } + } else if (id == NotificationCenter.didReceiveNewMessages) { + boolean scheduled = (Boolean) args[2]; + if (scheduled) { + return; + } + long uid = (Long) args[0]; + if (uid == dialog_id) { + ArrayList arr = (ArrayList) args[1]; + boolean enc = ((int) dialog_id) == 0; + boolean updated = false; + for (int a = 0; a < arr.size(); a++) { + MessageObject obj = arr.get(a); + if (obj.messageOwner.media == null || obj.needDrawBluredPreview()) { + continue; + } + int type = MediaDataController.getMediaType(obj.messageOwner); + if (type == -1) { + return; + } + if (sharedMediaData[type].addMessage(obj, obj.getDialogId() == dialog_id ? 0 : 1, true, enc)) { + updated = true; + hasMedia[type] = 1; + } + } + if (updated) { + scrolling = true; + for (int a = 0; a < mediaPages.length; a++) { + RecyclerListView.Adapter adapter = null; + if (mediaPages[a].selectedType == 0) { + adapter = photoVideoAdapter; + } else if (mediaPages[a].selectedType == 1) { + adapter = documentsAdapter; + } else if (mediaPages[a].selectedType == 2) { + adapter = voiceAdapter; + } else if (mediaPages[a].selectedType == 3) { + adapter = linksAdapter; + } else if (mediaPages[a].selectedType == 4) { + adapter = audioAdapter; + } + if (adapter != null) { + int count = adapter.getItemCount(); + photoVideoAdapter.notifyDataSetChanged(); + documentsAdapter.notifyDataSetChanged(); + voiceAdapter.notifyDataSetChanged(); + linksAdapter.notifyDataSetChanged(); + audioAdapter.notifyDataSetChanged(); + } + } + updateTabs(); + } + } + } else if (id == NotificationCenter.messageReceivedByServer) { + Boolean scheduled = (Boolean) args[6]; + if (scheduled) { + return; + } + Integer msgId = (Integer) args[0]; + Integer newMsgId = (Integer) args[1]; + for (int a = 0; a < sharedMediaData.length; a++) { + sharedMediaData[a].replaceMid(msgId, newMsgId); + } + } else if (id == NotificationCenter.messagePlayingDidStart || id == NotificationCenter.messagePlayingPlayStateChanged || id == NotificationCenter.messagePlayingDidReset) { + if (id == NotificationCenter.messagePlayingDidReset || id == NotificationCenter.messagePlayingPlayStateChanged) { + for (int b = 0; b < mediaPages.length; b++) { + int count = mediaPages[b].listView.getChildCount(); + for (int a = 0; a < count; a++) { + View view = mediaPages[b].listView.getChildAt(a); + if (view instanceof SharedAudioCell) { + SharedAudioCell cell = (SharedAudioCell) view; + MessageObject messageObject = cell.getMessage(); + if (messageObject != null) { + cell.updateButtonState(false, true); + } + } + } + } + } else if (id == NotificationCenter.messagePlayingDidStart) { + MessageObject messageObject = (MessageObject) args[0]; + if (messageObject.eventId != 0) { + return; + } + for (int b = 0; b < mediaPages.length; b++) { + int count = mediaPages[b].listView.getChildCount(); + for (int a = 0; a < count; a++) { + View view = mediaPages[b].listView.getChildAt(a); + if (view instanceof SharedAudioCell) { + SharedAudioCell cell = (SharedAudioCell) view; + MessageObject messageObject1 = cell.getMessage(); + if (messageObject1 != null) { + cell.updateButtonState(false, true); + } + } + } + } + } + } + } + + public void onResume() { + scrolling = true; + if (photoVideoAdapter != null) { + photoVideoAdapter.notifyDataSetChanged(); + } + if (documentsAdapter != null) { + documentsAdapter.notifyDataSetChanged(); + } + if (linksAdapter != null) { + linksAdapter.notifyDataSetChanged(); + } + for (int a = 0; a < mediaPages.length; a++) { + fixLayoutInternal(a); + } + } + + public void onConfigurationChanged(android.content.res.Configuration newConfig) { + super.onConfigurationChanged(newConfig); + for (int a = 0; a < mediaPages.length; a++) { + if (mediaPages[a].listView != null) { + final int num = a; + ViewTreeObserver obs = mediaPages[a].listView.getViewTreeObserver(); + obs.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { + @Override + public boolean onPreDraw() { + mediaPages[num].getViewTreeObserver().removeOnPreDrawListener(this); + fixLayoutInternal(num); + return true; + } + }); + } + } + } + + public void setChatInfo(TLRPC.ChatFull chatInfo) { + info = chatInfo; + if (info != null && info.migrated_from_chat_id != 0 && mergeDialogId == 0) { + mergeDialogId = -info.migrated_from_chat_id; + for (int a = 0; a < sharedMediaData.length; a++) { + sharedMediaData[a].max_id[1] = info.migrated_from_max_id; + sharedMediaData[a].endReached[1] = false; + } + } + } + + public void setChatUsers(ArrayList sortedUsers, TLRPC.ChatFull chatInfo) { + chatUsersAdapter.chatInfo = chatInfo; + chatUsersAdapter.sortedUsers = sortedUsers; + updateTabs(); + for (int a = 0; a < mediaPages.length; a++) { + if (mediaPages[a].selectedType == 6) { + mediaPages[a].listView.getAdapter().notifyDataSetChanged(); + } + } + } + + public void updateAdapters() { + if (photoVideoAdapter != null) { + photoVideoAdapter.notifyDataSetChanged(); + } + if (documentsAdapter != null) { + documentsAdapter.notifyDataSetChanged(); + } + if (voiceAdapter != null) { + voiceAdapter.notifyDataSetChanged(); + } + if (linksAdapter != null) { + linksAdapter.notifyDataSetChanged(); + } + if (audioAdapter != null) { + audioAdapter.notifyDataSetChanged(); + } + } + + private void updateRowsSelection() { + for (int i = 0; i < mediaPages.length; i++) { + int count = mediaPages[i].listView.getChildCount(); + for (int a = 0; a < count; a++) { + View child = mediaPages[i].listView.getChildAt(a); + if (child instanceof SharedDocumentCell) { + ((SharedDocumentCell) child).setChecked(false, true); + } else if (child instanceof SharedPhotoVideoCell) { + for (int b = 0; b < 6; b++) { + ((SharedPhotoVideoCell) child).setChecked(b, false, true); + } + } else if (child instanceof SharedLinkCell) { + ((SharedLinkCell) child).setChecked(false, true); + } else if (child instanceof SharedAudioCell) { + ((SharedAudioCell) child).setChecked(false, true); + } + } + } + } + + public void setMergeDialogId(long did) { + mergeDialogId = did; + } + + private void updateTabs() { + if (scrollSlidingTextTabStrip == null) { + return; + } + boolean changed = false; + if ((chatUsersAdapter.chatInfo == null) == scrollSlidingTextTabStrip.hasTab(6)) { + changed = true; + } + if ((hasMedia[0] <= 0) == scrollSlidingTextTabStrip.hasTab(0)) { + changed = true; + } + if ((hasMedia[1] <= 0) == scrollSlidingTextTabStrip.hasTab(1)) { + changed = true; + } + if ((int) dialog_id != 0) { + if ((hasMedia[3] <= 0) == scrollSlidingTextTabStrip.hasTab(3)) { + changed = true; + } + if ((hasMedia[4] <= 0) == scrollSlidingTextTabStrip.hasTab(4)) { + changed = true; + } + } else { + TLRPC.EncryptedChat currentEncryptedChat = profileActivity.getMessagesController().getEncryptedChat((int) (dialog_id >> 32)); + if (currentEncryptedChat != null && AndroidUtilities.getPeerLayerVersion(currentEncryptedChat.layer) >= 46) { + if ((hasMedia[4] <= 0) == scrollSlidingTextTabStrip.hasTab(4)) { + changed = true; + } + } + } + if ((hasMedia[2] <= 0) == scrollSlidingTextTabStrip.hasTab(2)) { + changed = true; + } + if ((hasMedia[5] <= 0) == scrollSlidingTextTabStrip.hasTab(5)) { + changed = true; + } + if (changed) { + scrollSlidingTextTabStrip.removeTabs(); + if (chatUsersAdapter.chatInfo != null) { + if (!scrollSlidingTextTabStrip.hasTab(6)) { + scrollSlidingTextTabStrip.addTextTab(6, LocaleController.getString("GroupMembers", R.string.GroupMembers)); + } + } + if (hasMedia[0] > 0) { + if (!scrollSlidingTextTabStrip.hasTab(0)) { + if (hasMedia[1] == 0 && hasMedia[2] == 0 && hasMedia[3] == 0 && hasMedia[4] == 0 && hasMedia[5] == 0 && chatUsersAdapter.chatInfo == null) { + scrollSlidingTextTabStrip.addTextTab(0, LocaleController.getString("SharedMediaTabFull2", R.string.SharedMediaTabFull2)); + } else { + scrollSlidingTextTabStrip.addTextTab(0, LocaleController.getString("SharedMediaTab2", R.string.SharedMediaTab2)); + } + } + } + if (hasMedia[1] > 0) { + if (!scrollSlidingTextTabStrip.hasTab(1)) { + scrollSlidingTextTabStrip.addTextTab(1, LocaleController.getString("SharedFilesTab2", R.string.SharedFilesTab2)); + } + } + if ((int) dialog_id != 0) { + if (hasMedia[3] > 0) { + if (!scrollSlidingTextTabStrip.hasTab(3)) { + scrollSlidingTextTabStrip.addTextTab(3, LocaleController.getString("SharedLinksTab2", R.string.SharedLinksTab2)); + } + } + if (hasMedia[4] > 0) { + if (!scrollSlidingTextTabStrip.hasTab(4)) { + scrollSlidingTextTabStrip.addTextTab(4, LocaleController.getString("SharedMusicTab2", R.string.SharedMusicTab2)); + } + } + } else { + TLRPC.EncryptedChat currentEncryptedChat = profileActivity.getMessagesController().getEncryptedChat((int) (dialog_id >> 32)); + if (currentEncryptedChat != null && AndroidUtilities.getPeerLayerVersion(currentEncryptedChat.layer) >= 46) { + if (hasMedia[4] > 0) { + if (!scrollSlidingTextTabStrip.hasTab(4)) { + scrollSlidingTextTabStrip.addTextTab(4, LocaleController.getString("SharedMusicTab2", R.string.SharedMusicTab2)); + } + } + } + } + if (hasMedia[2] > 0) { + if (!scrollSlidingTextTabStrip.hasTab(2)) { + scrollSlidingTextTabStrip.addTextTab(2, LocaleController.getString("SharedVoiceTab2", R.string.SharedVoiceTab2)); + } + } + if (hasMedia[5] > 0) { + if (!scrollSlidingTextTabStrip.hasTab(5)) { + scrollSlidingTextTabStrip.addTextTab(5, LocaleController.getString("SharedGroupsTab2", R.string.SharedGroupsTab2)); + } + } + } + int id = scrollSlidingTextTabStrip.getCurrentTabId(); + if (id >= 0) { + mediaPages[0].selectedType = id; + } + scrollSlidingTextTabStrip.finishAddingTabs(); + } + + private void switchToCurrentSelectedMode(boolean animated) { + for (int a = 0; a < mediaPages.length; a++) { + mediaPages[a].listView.stopScroll(); + } + int a = animated ? 1 : 0; + RecyclerView.Adapter currentAdapter = mediaPages[a].listView.getAdapter(); + if (searching && searchWas) { + if (animated) { + if (mediaPages[a].selectedType == 0 || mediaPages[a].selectedType == 2 || mediaPages[a].selectedType == 5 || mediaPages[a].selectedType == 6) { + searching = false; + searchWas = false; + switchToCurrentSelectedMode(true); + return; + } else { + String text = searchItem.getSearchField().getText().toString(); + if (mediaPages[a].selectedType == 1) { + if (documentsSearchAdapter != null) { + documentsSearchAdapter.search(text); + if (currentAdapter != documentsSearchAdapter) { + recycleAdapter(currentAdapter); + mediaPages[a].listView.setAdapter(documentsSearchAdapter); + } + } + } else if (mediaPages[a].selectedType == 3) { + if (linksSearchAdapter != null) { + linksSearchAdapter.search(text); + if (currentAdapter != linksSearchAdapter) { + recycleAdapter(currentAdapter); + mediaPages[a].listView.setAdapter(linksSearchAdapter); + } + } + } else if (mediaPages[a].selectedType == 4) { + if (audioSearchAdapter != null) { + audioSearchAdapter.search(text); + if (currentAdapter != audioSearchAdapter) { + recycleAdapter(currentAdapter); + mediaPages[a].listView.setAdapter(audioSearchAdapter); + } + } + } + if (searchItemState != 2 && mediaPages[a].emptyTextView != null) { + mediaPages[a].emptyTextView.setText(LocaleController.getString("NoResult", R.string.NoResult)); + mediaPages[a].emptyTextView.setPadding(AndroidUtilities.dp(40), 0, AndroidUtilities.dp(40), AndroidUtilities.dp(30)); + mediaPages[a].emptyTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20); + mediaPages[a].emptyImageView.setVisibility(View.GONE); + } + } + } else { + if (mediaPages[a].listView != null) { + if (mediaPages[a].selectedType == 1) { + if (currentAdapter != documentsSearchAdapter) { + recycleAdapter(currentAdapter); + mediaPages[a].listView.setAdapter(documentsSearchAdapter); + } + documentsSearchAdapter.notifyDataSetChanged(); + } else if (mediaPages[a].selectedType == 3) { + if (currentAdapter != linksSearchAdapter) { + recycleAdapter(currentAdapter); + mediaPages[a].listView.setAdapter(linksSearchAdapter); + } + linksSearchAdapter.notifyDataSetChanged(); + } else if (mediaPages[a].selectedType == 4) { + if (currentAdapter != audioSearchAdapter) { + recycleAdapter(currentAdapter); + mediaPages[a].listView.setAdapter(audioSearchAdapter); + } + audioSearchAdapter.notifyDataSetChanged(); + } + } + if (searchItemState != 2 && mediaPages[a].emptyTextView != null) { + mediaPages[a].emptyTextView.setText(LocaleController.getString("NoResult", R.string.NoResult)); + mediaPages[a].emptyTextView.setPadding(AndroidUtilities.dp(40), 0, AndroidUtilities.dp(40), AndroidUtilities.dp(30)); + mediaPages[a].emptyTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20); + mediaPages[a].emptyImageView.setVisibility(View.GONE); + } + } + + } else { + mediaPages[a].emptyTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 17); + mediaPages[a].emptyImageView.setVisibility(View.VISIBLE); + mediaPages[a].listView.setPinnedHeaderShadowDrawable(null); + + if (mediaPages[a].selectedType == 0) { + if (currentAdapter != photoVideoAdapter) { + recycleAdapter(currentAdapter); + mediaPages[a].listView.setAdapter(photoVideoAdapter); + } + mediaPages[a].listView.setPinnedHeaderShadowDrawable(pinnedHeaderShadowDrawable); + mediaPages[a].emptyImageView.setImageResource(R.drawable.tip1); + if ((int) dialog_id == 0) { + mediaPages[a].emptyTextView.setText(LocaleController.getString("NoMediaSecret", R.string.NoMediaSecret)); + } else { + mediaPages[a].emptyTextView.setText(LocaleController.getString("NoMedia", R.string.NoMedia)); + } + } else if (mediaPages[a].selectedType == 1) { + if (currentAdapter != documentsAdapter) { + recycleAdapter(currentAdapter); + mediaPages[a].listView.setAdapter(documentsAdapter); + } + mediaPages[a].emptyImageView.setImageResource(R.drawable.tip2); + if ((int) dialog_id == 0) { + mediaPages[a].emptyTextView.setText(LocaleController.getString("NoSharedFilesSecret", R.string.NoSharedFilesSecret)); + } else { + mediaPages[a].emptyTextView.setText(LocaleController.getString("NoSharedFiles", R.string.NoSharedFiles)); + } + } else if (mediaPages[a].selectedType == 2) { + if (currentAdapter != voiceAdapter) { + recycleAdapter(currentAdapter); + mediaPages[a].listView.setAdapter(voiceAdapter); + } + mediaPages[a].emptyImageView.setImageResource(R.drawable.tip5); + if ((int) dialog_id == 0) { + mediaPages[a].emptyTextView.setText(LocaleController.getString("NoSharedVoiceSecret", R.string.NoSharedVoiceSecret)); + } else { + mediaPages[a].emptyTextView.setText(LocaleController.getString("NoSharedVoice", R.string.NoSharedVoice)); + } + } else if (mediaPages[a].selectedType == 3) { + if (currentAdapter != linksAdapter) { + recycleAdapter(currentAdapter); + mediaPages[a].listView.setAdapter(linksAdapter); + } + mediaPages[a].emptyImageView.setImageResource(R.drawable.tip3); + if ((int) dialog_id == 0) { + mediaPages[a].emptyTextView.setText(LocaleController.getString("NoSharedLinksSecret", R.string.NoSharedLinksSecret)); + } else { + mediaPages[a].emptyTextView.setText(LocaleController.getString("NoSharedLinks", R.string.NoSharedLinks)); + } + } else if (mediaPages[a].selectedType == 4) { + if (currentAdapter != audioAdapter) { + recycleAdapter(currentAdapter); + mediaPages[a].listView.setAdapter(audioAdapter); + } + mediaPages[a].emptyImageView.setImageResource(R.drawable.tip4); + if ((int) dialog_id == 0) { + mediaPages[a].emptyTextView.setText(LocaleController.getString("NoSharedAudioSecret", R.string.NoSharedAudioSecret)); + } else { + mediaPages[a].emptyTextView.setText(LocaleController.getString("NoSharedAudio", R.string.NoSharedAudio)); + } + } else if (mediaPages[a].selectedType == 5) { + if (currentAdapter != commonGroupsAdapter) { + recycleAdapter(currentAdapter); + mediaPages[a].listView.setAdapter(commonGroupsAdapter); + } + mediaPages[a].emptyImageView.setImageDrawable(null); + mediaPages[a].emptyTextView.setText(LocaleController.getString("NoGroupsInCommon", R.string.NoGroupsInCommon)); + } else if (mediaPages[a].selectedType == 6) { + if (currentAdapter != chatUsersAdapter) { + recycleAdapter(currentAdapter); + mediaPages[a].listView.setAdapter(chatUsersAdapter); + } + mediaPages[a].emptyImageView.setImageDrawable(null); + mediaPages[a].emptyTextView.setText(""); + } + mediaPages[a].emptyTextView.setPadding(AndroidUtilities.dp(40), 0, AndroidUtilities.dp(40), AndroidUtilities.dp(128)); + if (mediaPages[a].selectedType == 0 || mediaPages[a].selectedType == 2 || mediaPages[a].selectedType == 5 || mediaPages[a].selectedType == 6) { + if (animated) { + searchItemState = 2; + } else { + searchItemState = 0; + searchItem.setVisibility(View.INVISIBLE); + } + } else { + if (animated) { + if (searchItem.getVisibility() == View.INVISIBLE && !actionBar.isSearchFieldVisible()) { + if (canShowSearchItem()) { + searchItemState = 1; + searchItem.setVisibility(View.VISIBLE); + searchItem.setAlpha(0.0f); + } else { + searchItem.setVisibility(INVISIBLE); + searchItem.setAlpha(0.0f); + } + } else { + searchItemState = 0; + } + } else if (searchItem.getVisibility() == View.INVISIBLE) { + if (canShowSearchItem()) { + searchItemState = 0; + searchItem.setAlpha(1.0f); + searchItem.setVisibility(View.VISIBLE); + } else { + searchItem.setVisibility(INVISIBLE); + searchItem.setAlpha(0.0f); + } + } + } + if (mediaPages[a].selectedType == 5) { + if (!commonGroupsAdapter.loading && !commonGroupsAdapter.endReached && commonGroupsAdapter.chats.isEmpty()) { + commonGroupsAdapter.getChats(0, 100); + } + if (commonGroupsAdapter.loading && commonGroupsAdapter.chats.isEmpty()) { + mediaPages[a].progressView.setVisibility(View.VISIBLE); + mediaPages[a].listView.setEmptyView(null); + mediaPages[a].emptyView.setVisibility(View.GONE); + } else { + mediaPages[a].progressView.setVisibility(View.GONE); + mediaPages[a].listView.setEmptyView(mediaPages[a].emptyView); + } + } else if (mediaPages[a].selectedType == 6) { + mediaPages[a].progressView.setVisibility(View.GONE); + mediaPages[a].listView.setEmptyView(mediaPages[a].emptyView); + } else { + if (!sharedMediaData[mediaPages[a].selectedType].loading && !sharedMediaData[mediaPages[a].selectedType].endReached[0] && sharedMediaData[mediaPages[a].selectedType].messages.isEmpty()) { + sharedMediaData[mediaPages[a].selectedType].loading = true; + profileActivity.getMediaDataController().loadMedia(dialog_id, 50, 0, mediaPages[a].selectedType, 1, profileActivity.getClassGuid()); + } + if (sharedMediaData[mediaPages[a].selectedType].loading && sharedMediaData[mediaPages[a].selectedType].messages.isEmpty()) { + mediaPages[a].progressView.setVisibility(View.VISIBLE); + mediaPages[a].listView.setEmptyView(null); + mediaPages[a].emptyView.setVisibility(View.GONE); + } else { + mediaPages[a].progressView.setVisibility(View.GONE); + mediaPages[a].listView.setEmptyView(mediaPages[a].emptyView); + } + } + mediaPages[a].listView.setVisibility(View.VISIBLE); + } + if (searchItemState == 2 && actionBar.isSearchFieldVisible()) { + ignoreSearchCollapse = true; + actionBar.closeSearchField(); + searchItemState = 0; + searchItem.setAlpha(0.0f); + searchItem.setVisibility(View.INVISIBLE); + } + } + + private boolean onItemLongClick(MessageObject item, View view, int a) { + if (isActionModeShowed || profileActivity.getParentActivity() == null) { + return false; + } + AndroidUtilities.hideKeyboard(profileActivity.getParentActivity().getCurrentFocus()); + selectedFiles[item.getDialogId() == dialog_id ? 0 : 1].put(item.getId(), item); + if (!item.canDeleteMessage(false, null)) { + cantDeleteMessagesCount++; + } + deleteItem.setVisibility(cantDeleteMessagesCount == 0 ? View.VISIBLE : View.GONE); + if (gotoItem != null) { + gotoItem.setVisibility(View.VISIBLE); + } + selectedMessagesCountTextView.setNumber(1, false); + AnimatorSet animatorSet = new AnimatorSet(); + ArrayList animators = new ArrayList<>(); + for (int i = 0; i < actionModeViews.size(); i++) { + View view2 = actionModeViews.get(i); + AndroidUtilities.clearDrawableAnimation(view2); + animators.add(ObjectAnimator.ofFloat(view2, View.SCALE_Y, 0.1f, 1.0f)); + } + animatorSet.playTogether(animators); + animatorSet.setDuration(250); + animatorSet.start(); + scrolling = false; + if (view instanceof SharedDocumentCell) { + ((SharedDocumentCell) view).setChecked(true, true); + } else if (view instanceof SharedPhotoVideoCell) { + ((SharedPhotoVideoCell) view).setChecked(a, true, true); + } else if (view instanceof SharedLinkCell) { + ((SharedLinkCell) view).setChecked(true, true); + } else if (view instanceof SharedAudioCell) { + ((SharedAudioCell) view).setChecked(true, true); + } + if (!isActionModeShowed) { + showActionMode(true); + } + return true; + } + + private void onItemClick(int index, View view, MessageObject message, int a, int selectedMode) { + if (message == null) { + return; + } + if (isActionModeShowed) { + int loadIndex = message.getDialogId() == dialog_id ? 0 : 1; + if (selectedFiles[loadIndex].indexOfKey(message.getId()) >= 0) { + selectedFiles[loadIndex].remove(message.getId()); + if (!message.canDeleteMessage(false, null)) { + cantDeleteMessagesCount--; + } + } else { + if (selectedFiles[0].size() + selectedFiles[1].size() >= 100) { + return; + } + selectedFiles[loadIndex].put(message.getId(), message); + if (!message.canDeleteMessage(false, null)) { + cantDeleteMessagesCount++; + } + } + if (selectedFiles[0].size() == 0 && selectedFiles[1].size() == 0) { + showActionMode(false); + } else { + selectedMessagesCountTextView.setNumber(selectedFiles[0].size() + selectedFiles[1].size(), true); + deleteItem.setVisibility(cantDeleteMessagesCount == 0 ? View.VISIBLE : View.GONE); + if (gotoItem != null) { + gotoItem.setVisibility(selectedFiles[0].size() == 1 ? View.VISIBLE : View.GONE); + } + } + scrolling = false; + if (view instanceof SharedDocumentCell) { + ((SharedDocumentCell) view).setChecked(selectedFiles[loadIndex].indexOfKey(message.getId()) >= 0, true); + } else if (view instanceof SharedPhotoVideoCell) { + ((SharedPhotoVideoCell) view).setChecked(a, selectedFiles[loadIndex].indexOfKey(message.getId()) >= 0, true); + } else if (view instanceof SharedLinkCell) { + ((SharedLinkCell) view).setChecked(selectedFiles[loadIndex].indexOfKey(message.getId()) >= 0, true); + } else if (view instanceof SharedAudioCell) { + ((SharedAudioCell) view).setChecked(selectedFiles[loadIndex].indexOfKey(message.getId()) >= 0, true); + } + } else { + if (selectedMode == 0) { + PhotoViewer.getInstance().setParentActivity(profileActivity.getParentActivity()); + PhotoViewer.getInstance().openPhoto(sharedMediaData[selectedMode].messages, index, dialog_id, mergeDialogId, provider); + } else if (selectedMode == 2 || selectedMode == 4) { + if (view instanceof SharedAudioCell) { + ((SharedAudioCell) view).didPressedButton(); + } + } else if (selectedMode == 1) { + if (view instanceof SharedDocumentCell) { + SharedDocumentCell cell = (SharedDocumentCell) view; + TLRPC.Document document = message.getDocument(); + if (cell.isLoaded()) { + if (message.canPreviewDocument()) { + PhotoViewer.getInstance().setParentActivity(profileActivity.getParentActivity()); + index = sharedMediaData[selectedMode].messages.indexOf(message); + if (index < 0) { + ArrayList documents = new ArrayList<>(); + documents.add(message); + PhotoViewer.getInstance().openPhoto(documents, 0, 0, 0, provider); + } else { + PhotoViewer.getInstance().openPhoto(sharedMediaData[selectedMode].messages, index, dialog_id, mergeDialogId, provider); + } + return; + } + AndroidUtilities.openDocument(message, profileActivity.getParentActivity(), profileActivity); + } else if (!cell.isLoading()) { + MessageObject messageObject = cell.getMessage(); + profileActivity.getFileLoader().loadFile(document, messageObject, 0, 0); + cell.updateFileExistIcon(); + } else { + profileActivity.getFileLoader().cancelLoadFile(document); + cell.updateFileExistIcon(); + } + } + } else if (selectedMode == 3) { + try { + TLRPC.WebPage webPage = message.messageOwner.media != null ? message.messageOwner.media.webpage : null; + String link = null; + if (webPage != null && !(webPage instanceof TLRPC.TL_webPageEmpty)) { + if (webPage.cached_page != null) { + ArticleViewer.getInstance().setParentActivity(profileActivity.getParentActivity(), profileActivity); + ArticleViewer.getInstance().open(message); + return; + } else if (webPage.embed_url != null && webPage.embed_url.length() != 0) { + openWebView(webPage); + return; + } else { + link = webPage.url; + } + } + if (link == null) { + link = ((SharedLinkCell) view).getLink(0); + } + if (link != null) { + Browser.openUrl(profileActivity.getParentActivity(), link); + } + } catch (Exception e) { + FileLog.e(e); + } + } + } + } + + private void openWebView(TLRPC.WebPage webPage) { + EmbedBottomSheet.show(profileActivity.getParentActivity(), webPage.site_name, webPage.description, webPage.url, webPage.embed_url, webPage.embed_width, webPage.embed_height); + } + + private void recycleAdapter(RecyclerView.Adapter adapter) { + if (adapter instanceof SharedPhotoVideoAdapter) { + cellCache.addAll(cache); + cache.clear(); + } else if (adapter == audioAdapter) { + audioCellCache.addAll(audioCache); + audioCache.clear(); + } + } + + private void fixLayoutInternal(int num) { + WindowManager manager = (WindowManager) ApplicationLoader.applicationContext.getSystemService(Activity.WINDOW_SERVICE); + int rotation = manager.getDefaultDisplay().getRotation(); + if (num == 0) { + if (!AndroidUtilities.isTablet() && ApplicationLoader.applicationContext.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { + selectedMessagesCountTextView.setTextSize(18); + } else { + selectedMessagesCountTextView.setTextSize(20); + } + } + + if (AndroidUtilities.isTablet()) { + columnsCount = 3; + mediaPages[num].emptyTextView.setPadding(AndroidUtilities.dp(40), 0, AndroidUtilities.dp(40), AndroidUtilities.dp(128)); + } else { + if (rotation == Surface.ROTATION_270 || rotation == Surface.ROTATION_90) { + columnsCount = 6; + mediaPages[num].emptyTextView.setPadding(AndroidUtilities.dp(40), 0, AndroidUtilities.dp(40), 0); + } else { + columnsCount = 3; + mediaPages[num].emptyTextView.setPadding(AndroidUtilities.dp(40), 0, AndroidUtilities.dp(40), AndroidUtilities.dp(128)); + } + } + if (num == 0) { + photoVideoAdapter.notifyDataSetChanged(); + } + } + + SharedLinkCell.SharedLinkCellDelegate sharedLinkCellDelegate = new SharedLinkCell.SharedLinkCellDelegate() { + @Override + public void needOpenWebView(TLRPC.WebPage webPage) { + openWebView(webPage); + } + + @Override + public boolean canPerformActions() { + return !isActionModeShowed; + } + + @Override + public void onLinkLongPress(final String urlFinal) { + BottomSheet.Builder builder = new BottomSheet.Builder(profileActivity.getParentActivity()); + builder.setTitle(urlFinal); + builder.setItems(new CharSequence[]{LocaleController.getString("Open", R.string.Open), LocaleController.getString("Copy", R.string.Copy)}, (dialog, which) -> { + if (which == 0) { + Browser.openUrl(profileActivity.getParentActivity(), urlFinal, true); + } else if (which == 1) { + String url = urlFinal; + if (url.startsWith("mailto:")) { + url = url.substring(7); + } else if (url.startsWith("tel:")) { + url = url.substring(4); + } + AndroidUtilities.addToClipboard(url); + } + }); + profileActivity.showDialog(builder.create()); + } + }; + + private class SharedLinksAdapter extends RecyclerListView.SectionsAdapter { + + private Context mContext; + + public SharedLinksAdapter(Context context) { + mContext = context; + } + + @Override + public Object getItem(int section, int position) { + return null; + } + + @Override + public boolean isEnabled(int section, int row) { + return row != 0; + } + + @Override + public int getSectionCount() { + return sharedMediaData[3].sections.size() + (sharedMediaData[3].sections.isEmpty() || sharedMediaData[3].endReached[0] && sharedMediaData[3].endReached[1] ? 0 : 1); + } + + @Override + public int getCountForSection(int section) { + if (section < sharedMediaData[3].sections.size()) { + return sharedMediaData[3].sectionArrays.get(sharedMediaData[3].sections.get(section)).size() + (section != 0 ? 1 : 0); + } + return 1; + } + + @Override + public View getSectionHeaderView(int section, View view) { + if (view == null) { + view = new GraySectionCell(mContext); + view.setBackgroundColor(Theme.getColor(Theme.key_graySection) & 0xf2ffffff); + } + if (section == 0) { + view.setAlpha(0.0f); + } else if (section < sharedMediaData[3].sections.size()) { + view.setAlpha(1.0f); + String name = sharedMediaData[3].sections.get(section); + ArrayList messageObjects = sharedMediaData[3].sectionArrays.get(name); + MessageObject messageObject = messageObjects.get(0); + ((GraySectionCell) view).setText(LocaleController.formatSectionDate(messageObject.messageOwner.date)); + } + return view; + } + + @Override + public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + View view; + switch (viewType) { + case 0: + view = new GraySectionCell(mContext); + break; + case 1: + view = new SharedLinkCell(mContext); + ((SharedLinkCell) view).setDelegate(sharedLinkCellDelegate); + break; + case 2: + default: + view = new LoadingCell(mContext, AndroidUtilities.dp(32), AndroidUtilities.dp(54)); + break; + } + view.setLayoutParams(new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); + return new RecyclerListView.Holder(view); + } + + @Override + public void onBindViewHolder(int section, int position, RecyclerView.ViewHolder holder) { + if (holder.getItemViewType() != 2) { + String name = sharedMediaData[3].sections.get(section); + ArrayList messageObjects = sharedMediaData[3].sectionArrays.get(name); + switch (holder.getItemViewType()) { + case 0: { + MessageObject messageObject = messageObjects.get(0); + ((GraySectionCell) holder.itemView).setText(LocaleController.formatSectionDate(messageObject.messageOwner.date)); + break; + } + case 1: { + if (section != 0) { + position--; + } + SharedLinkCell sharedLinkCell = (SharedLinkCell) holder.itemView; + MessageObject messageObject = messageObjects.get(position); + sharedLinkCell.setLink(messageObject, position != messageObjects.size() - 1 || section == sharedMediaData[3].sections.size() - 1 && sharedMediaData[3].loading); + if (isActionModeShowed) { + sharedLinkCell.setChecked(selectedFiles[messageObject.getDialogId() == dialog_id ? 0 : 1].indexOfKey(messageObject.getId()) >= 0, !scrolling); + } else { + sharedLinkCell.setChecked(false, !scrolling); + } + break; + } + } + } + } + + @Override + public int getItemViewType(int section, int position) { + if (section < sharedMediaData[3].sections.size()) { + if (section != 0 && position == 0) { + return 0; + } else { + return 1; + } + } + return 2; + } + + @Override + public String getLetter(int position) { + return null; + } + + @Override + public int getPositionForScrollProgress(float progress) { + return 0; + } + } + + private class SharedDocumentsAdapter extends RecyclerListView.SectionsAdapter { + + private Context mContext; + private int currentType; + + public SharedDocumentsAdapter(Context context, int type) { + mContext = context; + currentType = type; + } + + @Override + public boolean isEnabled(int section, int row) { + return row != 0; + } + + @Override + public int getSectionCount() { + return sharedMediaData[currentType].sections.size() + (sharedMediaData[currentType].sections.isEmpty() || sharedMediaData[currentType].endReached[0] && sharedMediaData[currentType].endReached[1] ? 0 : 1); + } + + @Override + public Object getItem(int section, int position) { + return null; + } + + @Override + public int getCountForSection(int section) { + if (section < sharedMediaData[currentType].sections.size()) { + return sharedMediaData[currentType].sectionArrays.get(sharedMediaData[currentType].sections.get(section)).size() + (section != 0 ? 1 : 0); + } + return 1; + } + + @Override + public View getSectionHeaderView(int section, View view) { + if (view == null) { + view = new GraySectionCell(mContext); + view.setBackgroundColor(Theme.getColor(Theme.key_graySection) & 0xf2ffffff); + } + if (section == 0) { + view.setAlpha(0.0f); + } else if (section < sharedMediaData[currentType].sections.size()) { + view.setAlpha(1.0f); + String name = sharedMediaData[currentType].sections.get(section); + ArrayList messageObjects = sharedMediaData[currentType].sectionArrays.get(name); + MessageObject messageObject = messageObjects.get(0); + ((GraySectionCell) view).setText(LocaleController.formatSectionDate(messageObject.messageOwner.date)); + } + return view; + } + + @Override + public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + View view; + switch (viewType) { + case 0: + view = new GraySectionCell(mContext); + break; + case 1: + view = new SharedDocumentCell(mContext); + break; + case 2: + view = new LoadingCell(mContext, AndroidUtilities.dp(32), AndroidUtilities.dp(54)); + break; + case 3: + default: + if (currentType == MediaDataController.MEDIA_MUSIC && !audioCellCache.isEmpty()) { + view = audioCellCache.get(0); + audioCellCache.remove(0); + ViewGroup p = (ViewGroup) view.getParent(); + if (p != null) { + p.removeView(view); + } + } else { + view = new SharedAudioCell(mContext) { + @Override + public boolean needPlayMessage(MessageObject messageObject) { + if (messageObject.isVoice() || messageObject.isRoundVideo()) { + boolean result = MediaController.getInstance().playMessage(messageObject); + MediaController.getInstance().setVoiceMessagesPlaylist(result ? sharedMediaData[currentType].messages : null, false); + return result; + } else if (messageObject.isMusic()) { + return MediaController.getInstance().setPlaylist(sharedMediaData[currentType].messages, messageObject); + } + return false; + } + }; + } + if (currentType == MediaDataController.MEDIA_MUSIC) { + audioCache.add((SharedAudioCell) view); + } + break; + } + view.setLayoutParams(new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); + return new RecyclerListView.Holder(view); + } + + @Override + public void onBindViewHolder(int section, int position, RecyclerView.ViewHolder holder) { + if (holder.getItemViewType() != 2) { + String name = sharedMediaData[currentType].sections.get(section); + ArrayList messageObjects = sharedMediaData[currentType].sectionArrays.get(name); + switch (holder.getItemViewType()) { + case 0: { + MessageObject messageObject = messageObjects.get(0); + ((GraySectionCell) holder.itemView).setText(LocaleController.formatSectionDate(messageObject.messageOwner.date)); + break; + } + case 1: { + if (section != 0) { + position--; + } + SharedDocumentCell sharedDocumentCell = (SharedDocumentCell) holder.itemView; + MessageObject messageObject = messageObjects.get(position); + sharedDocumentCell.setDocument(messageObject, position != messageObjects.size() - 1 || section == sharedMediaData[currentType].sections.size() - 1 && sharedMediaData[currentType].loading); + if (isActionModeShowed) { + sharedDocumentCell.setChecked(selectedFiles[messageObject.getDialogId() == dialog_id ? 0 : 1].indexOfKey(messageObject.getId()) >= 0, !scrolling); + } else { + sharedDocumentCell.setChecked(false, !scrolling); + } + break; + } + case 3: { + if (section != 0) { + position--; + } + SharedAudioCell sharedAudioCell = (SharedAudioCell) holder.itemView; + MessageObject messageObject = messageObjects.get(position); + sharedAudioCell.setMessageObject(messageObject, position != messageObjects.size() - 1 || section == sharedMediaData[currentType].sections.size() - 1 && sharedMediaData[currentType].loading); + if (isActionModeShowed) { + sharedAudioCell.setChecked(selectedFiles[messageObject.getDialogId() == dialog_id ? 0 : 1].indexOfKey(messageObject.getId()) >= 0, !scrolling); + } else { + sharedAudioCell.setChecked(false, !scrolling); + } + break; + } + } + } + } + + @Override + public int getItemViewType(int section, int position) { + if (section < sharedMediaData[currentType].sections.size()) { + if (section != 0 && position == 0) { + return 0; + } else { + if (currentType == 2 || currentType == 4) { + return 3; + } else { + return 1; + } + } + } + return 2; + } + + @Override + public String getLetter(int position) { + return null; + } + + @Override + public int getPositionForScrollProgress(float progress) { + return 0; + } + } + + private class SharedPhotoVideoAdapter extends RecyclerListView.SelectionAdapter { + + private Context mContext; + + public SharedPhotoVideoAdapter(Context context) { + mContext = context; + } + + @Override + public int getItemCount() { + int count = (int) Math.ceil(sharedMediaData[0].messages.size() / (float) columnsCount); + if (count != 0 && (!sharedMediaData[0].endReached[0] || !sharedMediaData[0].endReached[1])) { + count++; + } + return count; + } + + @Override + public boolean isEnabled(RecyclerView.ViewHolder holder) { + return false; + } + + @Override + public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + View view; + switch (viewType) { + case 0: + if (!cellCache.isEmpty()) { + view = cellCache.get(0); + cellCache.remove(0); + ViewGroup p = (ViewGroup) view.getParent(); + if (p != null) { + p.removeView(view); + } + } else { + view = new SharedPhotoVideoCell(mContext); + } + SharedPhotoVideoCell cell = (SharedPhotoVideoCell) view; + cell.setDelegate(new SharedPhotoVideoCell.SharedPhotoVideoCellDelegate() { + @Override + public void didClickItem(SharedPhotoVideoCell cell, int index, MessageObject messageObject, int a) { + onItemClick(index, cell, messageObject, a, 0); + } + + @Override + public boolean didLongClickItem(SharedPhotoVideoCell cell, int index, MessageObject messageObject, int a) { + if (isActionModeShowed) { + didClickItem(cell, index, messageObject, a); + return true; + } + return onItemLongClick(messageObject, cell, a); + } + }); + cache.add((SharedPhotoVideoCell) view); + break; + case 1: + default: + view = new LoadingCell(mContext, AndroidUtilities.dp(32), AndroidUtilities.dp(74)); + break; + } + view.setLayoutParams(new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); + return new RecyclerListView.Holder(view); + } + + @Override + public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { + if (holder.getItemViewType() == 0) { + ArrayList messageObjects = sharedMediaData[0].messages; + SharedPhotoVideoCell cell = (SharedPhotoVideoCell) holder.itemView; + cell.setItemsCount(columnsCount); + cell.setIsFirst(position == 0); + for (int a = 0; a < columnsCount; a++) { + int index = position * columnsCount + a; + if (index < messageObjects.size()) { + MessageObject messageObject = messageObjects.get(index); + cell.setItem(a, sharedMediaData[0].messages.indexOf(messageObject), messageObject); + if (isActionModeShowed) { + cell.setChecked(a, selectedFiles[messageObject.getDialogId() == dialog_id ? 0 : 1].indexOfKey(messageObject.getId()) >= 0, !scrolling); + } else { + cell.setChecked(a, false, !scrolling); + } + } else { + cell.setItem(a, index, null); + } + } + cell.requestLayout(); + } + } + + @Override + public int getItemViewType(int position) { + if (position < sharedMediaData[0].messages.size()) { + return 0; + } + return 1; + } + } + + public class MediaSearchAdapter extends RecyclerListView.SelectionAdapter { + + private Context mContext; + private ArrayList searchResult = new ArrayList<>(); + private Runnable searchRunnable; + protected ArrayList globalSearch = new ArrayList<>(); + private int reqId = 0; + private int lastReqId; + private int currentType; + private int searchesInProgress; + + public MediaSearchAdapter(Context context, int type) { + mContext = context; + currentType = type; + } + + public void queryServerSearch(final String query, final int max_id, long did) { + int uid = (int) did; + if (uid == 0) { + return; + } + if (reqId != 0) { + profileActivity.getConnectionsManager().cancelRequest(reqId, true); + reqId = 0; + searchesInProgress--; + } + if (query == null || query.length() == 0) { + globalSearch.clear(); + lastReqId = 0; + notifyDataSetChanged(); + return; + } + TLRPC.TL_messages_search req = new TLRPC.TL_messages_search(); + req.limit = 50; + req.offset_id = max_id; + if (currentType == 1) { + req.filter = new TLRPC.TL_inputMessagesFilterDocument(); + } else if (currentType == 3) { + req.filter = new TLRPC.TL_inputMessagesFilterUrl(); + } else if (currentType == 4) { + req.filter = new TLRPC.TL_inputMessagesFilterMusic(); + } + req.q = query; + req.peer = profileActivity.getMessagesController().getInputPeer(uid); + if (req.peer == null) { + return; + } + final int currentReqId = ++lastReqId; + searchesInProgress++; + reqId = profileActivity.getConnectionsManager().sendRequest(req, (response, error) -> { + final ArrayList messageObjects = new ArrayList<>(); + if (error == null) { + TLRPC.messages_Messages res = (TLRPC.messages_Messages) response; + for (int a = 0; a < res.messages.size(); a++) { + TLRPC.Message message = res.messages.get(a); + if (max_id != 0 && message.id > max_id) { + continue; + } + messageObjects.add(new MessageObject(profileActivity.getCurrentAccount(), message, false)); + } + } + AndroidUtilities.runOnUIThread(() -> { + if (reqId != 0) { + if (currentReqId == lastReqId) { + globalSearch = messageObjects; + searchesInProgress--; + int count = getItemCount(); + if (searchesInProgress == 0 || count != 0) { + switchToCurrentSelectedMode(false); + } + notifyDataSetChanged(); + } + reqId = 0; + } + }); + }, ConnectionsManager.RequestFlagFailOnServerErrors); + profileActivity.getConnectionsManager().bindRequestToGuid(reqId, profileActivity.getClassGuid()); + } + + public void search(final String query) { + if (searchRunnable != null) { + AndroidUtilities.cancelRunOnUIThread(searchRunnable); + searchRunnable = null; + } + if (TextUtils.isEmpty(query)) { + if (!searchResult.isEmpty() || !globalSearch.isEmpty() || searchesInProgress != 0) { + searchResult.clear(); + globalSearch.clear(); + if (reqId != 0) { + profileActivity.getConnectionsManager().cancelRequest(reqId, true); + reqId = 0; + searchesInProgress--; + } + } + notifyDataSetChanged(); + } else { + for (int a = 0; a < mediaPages.length; a++) { + if (mediaPages[a].selectedType == currentType) { + //if (getItemCount() != 0) { + mediaPages[a].listView.setEmptyView(mediaPages[a].emptyView); + mediaPages[a].progressView.setVisibility(View.GONE); + /*} else { + mediaPages[a].listView.setEmptyView(null); + mediaPages[a].emptyView.setVisibility(View.GONE); + mediaPages[a].progressView.setVisibility(View.VISIBLE); + }*/ + } + } + + + AndroidUtilities.runOnUIThread(searchRunnable = () -> { + if (!sharedMediaData[currentType].messages.isEmpty() && (currentType == 1 || currentType == 4)) { + MessageObject messageObject = sharedMediaData[currentType].messages.get(sharedMediaData[currentType].messages.size() - 1); + queryServerSearch(query, messageObject.getId(), messageObject.getDialogId()); + } else if (currentType == 3) { + queryServerSearch(query, 0, dialog_id); + } + if (currentType == 1 || currentType == 4) { + final ArrayList copy = new ArrayList<>(sharedMediaData[currentType].messages); + searchesInProgress++; + Utilities.searchQueue.postRunnable(() -> { + String search1 = query.trim().toLowerCase(); + if (search1.length() == 0) { + updateSearchResults(new ArrayList<>()); + return; + } + String search2 = LocaleController.getInstance().getTranslitString(search1); + if (search1.equals(search2) || search2.length() == 0) { + search2 = null; + } + String[] search = new String[1 + (search2 != null ? 1 : 0)]; + search[0] = search1; + if (search2 != null) { + search[1] = search2; + } + + ArrayList resultArray = new ArrayList<>(); + + for (int a = 0; a < copy.size(); a++) { + MessageObject messageObject = copy.get(a); + for (int b = 0; b < search.length; b++) { + String q = search[b]; + String name = messageObject.getDocumentName(); + if (name == null || name.length() == 0) { + continue; + } + name = name.toLowerCase(); + if (name.contains(q)) { + resultArray.add(messageObject); + break; + } + if (currentType == 4) { + TLRPC.Document document; + if (messageObject.type == 0) { + document = messageObject.messageOwner.media.webpage.document; + } else { + document = messageObject.messageOwner.media.document; + } + boolean ok = false; + for (int c = 0; c < document.attributes.size(); c++) { + TLRPC.DocumentAttribute attribute = document.attributes.get(c); + if (attribute instanceof TLRPC.TL_documentAttributeAudio) { + if (attribute.performer != null) { + ok = attribute.performer.toLowerCase().contains(q); + } + if (!ok && attribute.title != null) { + ok = attribute.title.toLowerCase().contains(q); + } + break; + } + } + if (ok) { + resultArray.add(messageObject); + break; + } + } + } + } + + updateSearchResults(resultArray); + }); + } + }, 300); + } + } + + private void updateSearchResults(final ArrayList documents) { + AndroidUtilities.runOnUIThread(() -> { + if (!searching) { + return; + } + searchesInProgress--; + searchResult = documents; + int count = getItemCount(); + if (searchesInProgress == 0 || count != 0) { + switchToCurrentSelectedMode(false); + } + notifyDataSetChanged(); + }); + } + + @Override + public void notifyDataSetChanged() { + super.notifyDataSetChanged(); + if (searchesInProgress == 0) { + for (int a = 0; a < mediaPages.length; a++) { + if (mediaPages[a].selectedType == currentType) { + mediaPages[a].listView.setEmptyView(mediaPages[a].emptyView); + mediaPages[a].progressView.setVisibility(View.GONE); + } + } + } + } + + @Override + public boolean isEnabled(RecyclerView.ViewHolder holder) { + return holder.getItemViewType() != searchResult.size() + globalSearch.size(); + } + + @Override + public int getItemCount() { + int count = searchResult.size(); + int globalCount = globalSearch.size(); + if (globalCount != 0) { + count += globalCount; + } + return count; + } + + public boolean isGlobalSearch(int i) { + int localCount = searchResult.size(); + int globalCount = globalSearch.size(); + if (i >= 0 && i < localCount) { + return false; + } else if (i > localCount && i <= globalCount + localCount) { + return true; + } + return false; + } + + public MessageObject getItem(int i) { + if (i < searchResult.size()) { + return searchResult.get(i); + } else { + return globalSearch.get(i - searchResult.size()); + } + } + + @Override + public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + View view; + if (currentType == 1) { + view = new SharedDocumentCell(mContext); + } else if (currentType == 4) { + view = new SharedAudioCell(mContext) { + @Override + public boolean needPlayMessage(MessageObject messageObject) { + if (messageObject.isVoice() || messageObject.isRoundVideo()) { + boolean result = MediaController.getInstance().playMessage(messageObject); + MediaController.getInstance().setVoiceMessagesPlaylist(result ? searchResult : null, false); + if (messageObject.isRoundVideo()) { + MediaController.getInstance().setCurrentVideoVisible(false); + } + return result; + } else if (messageObject.isMusic()) { + return MediaController.getInstance().setPlaylist(searchResult, messageObject); + } + return false; + } + }; + } else { + view = new SharedLinkCell(mContext); + ((SharedLinkCell) view).setDelegate(sharedLinkCellDelegate); + } + view.setLayoutParams(new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); + return new RecyclerListView.Holder(view); + } + + @Override + public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { + if (currentType == 1) { + SharedDocumentCell sharedDocumentCell = (SharedDocumentCell) holder.itemView; + MessageObject messageObject = getItem(position); + sharedDocumentCell.setDocument(messageObject, position != getItemCount() - 1); + if (isActionModeShowed) { + sharedDocumentCell.setChecked(selectedFiles[messageObject.getDialogId() == dialog_id ? 0 : 1].indexOfKey(messageObject.getId()) >= 0, !scrolling); + } else { + sharedDocumentCell.setChecked(false, !scrolling); + } + } else if (currentType == 3) { + SharedLinkCell sharedLinkCell = (SharedLinkCell) holder.itemView; + MessageObject messageObject = getItem(position); + sharedLinkCell.setLink(messageObject, position != getItemCount() - 1); + if (isActionModeShowed) { + sharedLinkCell.setChecked(selectedFiles[messageObject.getDialogId() == dialog_id ? 0 : 1].indexOfKey(messageObject.getId()) >= 0, !scrolling); + } else { + sharedLinkCell.setChecked(false, !scrolling); + } + } else if (currentType == 4) { + SharedAudioCell sharedAudioCell = (SharedAudioCell) holder.itemView; + MessageObject messageObject = getItem(position); + sharedAudioCell.setMessageObject(messageObject, position != getItemCount() - 1); + if (isActionModeShowed) { + sharedAudioCell.setChecked(selectedFiles[messageObject.getDialogId() == dialog_id ? 0 : 1].indexOfKey(messageObject.getId()) >= 0, !scrolling); + } else { + sharedAudioCell.setChecked(false, !scrolling); + } + } + } + + @Override + public int getItemViewType(int i) { + return 0; + } + } + + private class CommonGroupsAdapter extends RecyclerListView.SelectionAdapter { + + private Context mContext; + private ArrayList chats = new ArrayList<>(); + private boolean loading; + private boolean firstLoaded; + private boolean endReached; + + public CommonGroupsAdapter(Context context) { + mContext = context; + } + + private void getChats(int max_id, final int count) { + if (loading) { + return; + } + TLRPC.TL_messages_getCommonChats req = new TLRPC.TL_messages_getCommonChats(); + int uid; + int lowerId = (int) dialog_id; + int hightId = (int) (dialog_id >> 32); + if (lowerId != 0) { + uid = lowerId; + } else { + TLRPC.EncryptedChat encryptedChat = profileActivity.getMessagesController().getEncryptedChat(hightId); + uid = encryptedChat.user_id; + } + req.user_id = profileActivity.getMessagesController().getInputUser(uid); + if (req.user_id instanceof TLRPC.TL_inputUserEmpty) { + return; + } + req.limit = count; + req.max_id = max_id; + loading = true; + notifyDataSetChanged(); + int reqId = profileActivity.getConnectionsManager().sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> { + if (error == null) { + TLRPC.messages_Chats res = (TLRPC.messages_Chats) response; + profileActivity.getMessagesController().putChats(res.chats, false); + endReached = res.chats.isEmpty() || res.chats.size() != count; + chats.addAll(res.chats); + } else { + endReached = true; + } + loading = false; + firstLoaded = true; + for (int a = 0; a < mediaPages.length; a++) { + if (mediaPages[a].selectedType == 5) { + if (mediaPages[a].progressView != null) { + mediaPages[a].progressView.setVisibility(View.GONE); + } + if (mediaPages[a].listView != null) { + if (mediaPages[a].listView.getEmptyView() == null) { + mediaPages[a].listView.setEmptyView(mediaPages[a].emptyView); + } + } + } + } + notifyDataSetChanged(); + })); + profileActivity.getConnectionsManager().bindRequestToGuid(reqId, profileActivity.getClassGuid()); + } + + @Override + public boolean isEnabled(RecyclerView.ViewHolder holder) { + return holder.getAdapterPosition() != chats.size(); + } + + @Override + public int getItemCount() { + int count = chats.size(); + if (!chats.isEmpty()) { + if (!endReached) { + count++; + } + } + return count; + } + + @Override + public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + View view; + switch (viewType) { + case 0: + view = new ProfileSearchCell(mContext); + break; + case 1: + default: + view = new LoadingCell(mContext); + break; + } + view.setLayoutParams(new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); + return new RecyclerListView.Holder(view); + } + + @Override + public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { + if (holder.getItemViewType() == 0) { + ProfileSearchCell cell = (ProfileSearchCell) holder.itemView; + TLRPC.Chat chat = chats.get(position); + cell.setData(chat, null, null, null, false, false); + cell.useSeparator = position != chats.size() - 1 || !endReached; + } + } + + @Override + public int getItemViewType(int i) { + if (i < chats.size()) { + return 0; + } else { + return 1; + } + } + } + + private class ChatUsersAdapter extends RecyclerListView.SelectionAdapter { + + private Context mContext; + private TLRPC.ChatFull chatInfo; + private ArrayList sortedUsers; + + public ChatUsersAdapter(Context context) { + mContext = context; + } + + @Override + public boolean isEnabled(RecyclerView.ViewHolder holder) { + return true; + } + + @Override + public int getItemCount() { + return chatInfo != null ? chatInfo.participants.participants.size() : 0; + } + + @Override + public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + View view = new UserCell(mContext, 9, 0, true); + view.setLayoutParams(new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); + return new RecyclerListView.Holder(view); + } + + @Override + public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { + UserCell userCell = (UserCell) holder.itemView; + TLRPC.ChatParticipant part; + if (!sortedUsers.isEmpty()) { + part = chatInfo.participants.participants.get(sortedUsers.get(position)); + } else { + part = chatInfo.participants.participants.get(position); + } + if (part != null) { + String role; + if (part instanceof TLRPC.TL_chatChannelParticipant) { + TLRPC.ChannelParticipant channelParticipant = ((TLRPC.TL_chatChannelParticipant) part).channelParticipant; + if (!TextUtils.isEmpty(channelParticipant.rank)) { + role = channelParticipant.rank; + } else { + if (channelParticipant instanceof TLRPC.TL_channelParticipantCreator) { + role = LocaleController.getString("ChannelCreator", R.string.ChannelCreator); + } else if (channelParticipant instanceof TLRPC.TL_channelParticipantAdmin) { + role = LocaleController.getString("ChannelAdmin", R.string.ChannelAdmin); + } else { + role = null; + } + } + } else { + if (part instanceof TLRPC.TL_chatParticipantCreator) { + role = LocaleController.getString("ChannelCreator", R.string.ChannelCreator); + } else if (part instanceof TLRPC.TL_chatParticipantAdmin) { + role = LocaleController.getString("ChannelAdmin", R.string.ChannelAdmin); + } else { + role = null; + } + } + userCell.setAdminRole(role); + userCell.setData(profileActivity.getMessagesController().getUser(part.user_id), null, null, 0, position != chatInfo.participants.participants.size() - 1); + } + } + + @Override + public int getItemViewType(int i) { + return 0; + } + } + + public ArrayList getThemeDescriptions() { + ArrayList arrayList = new ArrayList<>(); + + arrayList.add(new ThemeDescription(selectedMessagesCountTextView, ThemeDescription.FLAG_TEXTCOLOR, null, null, null, null, Theme.key_player_actionBarTitle)); + + arrayList.add(new ThemeDescription(shadowLine, ThemeDescription.FLAG_BACKGROUND, null, null, null, null, Theme.key_divider)); + + arrayList.add(new ThemeDescription(deleteItem.getIconView(), ThemeDescription.FLAG_IMAGECOLOR, null, null, null, null, Theme.key_player_actionBarTitle)); + arrayList.add(new ThemeDescription(deleteItem, ThemeDescription.FLAG_BACKGROUNDFILTER, null, null, null, null, Theme.key_actionBarActionModeDefaultSelector)); + if (gotoItem != null) { + arrayList.add(new ThemeDescription(gotoItem.getIconView(), ThemeDescription.FLAG_IMAGECOLOR, null, null, null, null, Theme.key_player_actionBarTitle)); + arrayList.add(new ThemeDescription(gotoItem, ThemeDescription.FLAG_BACKGROUNDFILTER, null, null, null, null, Theme.key_actionBarActionModeDefaultSelector)); + } + if (forwardItem != null) { + arrayList.add(new ThemeDescription(forwardItem.getIconView(), ThemeDescription.FLAG_IMAGECOLOR, null, null, null, null, Theme.key_player_actionBarTitle)); + arrayList.add(new ThemeDescription(forwardItem, ThemeDescription.FLAG_BACKGROUNDFILTER, null, null, null, null, Theme.key_actionBarActionModeDefaultSelector)); + } + arrayList.add(new ThemeDescription(closeButton, ThemeDescription.FLAG_IMAGECOLOR, null, null, new Drawable[]{backDrawable}, null, Theme.key_player_actionBarTitle)); + arrayList.add(new ThemeDescription(closeButton, ThemeDescription.FLAG_BACKGROUNDFILTER, null, null, null, null, Theme.key_actionBarActionModeDefaultSelector)); + + arrayList.add(new ThemeDescription(actionModeLayout, ThemeDescription.FLAG_BACKGROUND, null, null, null, null, Theme.key_windowBackgroundWhite)); + arrayList.add(new ThemeDescription(scrollSlidingTextTabStrip, ThemeDescription.FLAG_BACKGROUND, null, null, null, null, Theme.key_windowBackgroundWhite)); + + arrayList.add(new ThemeDescription(floatingDateView, 0, null, null, null, null, Theme.key_chat_mediaTimeBackground)); + arrayList.add(new ThemeDescription(floatingDateView, 0, null, null, null, null, Theme.key_chat_mediaTimeText)); + + arrayList.add(new ThemeDescription(scrollSlidingTextTabStrip, 0, new Class[]{ScrollSlidingTextTabStrip.class}, new String[]{"selectorDrawable"}, null, null, null, Theme.key_profile_tabSelectedLine)); + arrayList.add(new ThemeDescription(scrollSlidingTextTabStrip.getTabsContainer(), ThemeDescription.FLAG_TEXTCOLOR | ThemeDescription.FLAG_CHECKTAG, new Class[]{TextView.class}, null, null, null, Theme.key_profile_tabSelectedText)); + arrayList.add(new ThemeDescription(scrollSlidingTextTabStrip.getTabsContainer(), ThemeDescription.FLAG_TEXTCOLOR | ThemeDescription.FLAG_CHECKTAG, new Class[]{TextView.class}, null, null, null, Theme.key_profile_tabText)); + arrayList.add(new ThemeDescription(scrollSlidingTextTabStrip.getTabsContainer(), ThemeDescription.FLAG_BACKGROUNDFILTER | ThemeDescription.FLAG_DRAWABLESELECTEDSTATE, new Class[]{TextView.class}, null, null, null, Theme.key_profile_tabSelector)); + + for (int a = 0; a < mediaPages.length; a++) { + final int num = a; + ThemeDescription.ThemeDescriptionDelegate cellDelegate = () -> { + if (mediaPages[num].listView != null) { + int count = mediaPages[num].listView.getChildCount(); + for (int a1 = 0; a1 < count; a1++) { + View child = mediaPages[num].listView.getChildAt(a1); + if (child instanceof SharedPhotoVideoCell) { + ((SharedPhotoVideoCell) child).updateCheckboxColor(); + } else if (child instanceof ProfileSearchCell) { + ((ProfileSearchCell) child).update(0); + } else if (child instanceof UserCell) { + ((UserCell) child).update(0); + } + } + } + }; + + arrayList.add(new ThemeDescription(mediaPages[a].listView, 0, new Class[]{View.class}, Theme.dividerPaint, null, null, Theme.key_divider)); + + arrayList.add(new ThemeDescription(mediaPages[a].progressView, 0, null, null, null, null, Theme.key_windowBackgroundWhite)); + arrayList.add(new ThemeDescription(mediaPages[a].listView, ThemeDescription.FLAG_LISTGLOWCOLOR, null, null, null, null, Theme.key_actionBarDefault)); + arrayList.add(new ThemeDescription(mediaPages[a].listView, ThemeDescription.FLAG_SELECTOR, null, null, null, null, Theme.key_listSelector)); + arrayList.add(new ThemeDescription(mediaPages[a].emptyView, ThemeDescription.FLAG_TEXTCOLOR, null, null, null, null, Theme.key_emptyListPlaceholder)); + + arrayList.add(new ThemeDescription(mediaPages[a].progressBar, ThemeDescription.FLAG_PROGRESSBAR, null, null, null, null, Theme.key_progressCircle)); + + arrayList.add(new ThemeDescription(mediaPages[a].emptyTextView, ThemeDescription.FLAG_TEXTCOLOR, null, null, null, null, Theme.key_windowBackgroundWhiteGrayText2)); + + arrayList.add(new ThemeDescription(mediaPages[a].listView, ThemeDescription.FLAG_SECTIONS, new Class[]{GraySectionCell.class}, new String[]{"textView"}, null, null, null, Theme.key_graySectionText)); + arrayList.add(new ThemeDescription(mediaPages[a].listView, ThemeDescription.FLAG_CELLBACKGROUNDCOLOR | ThemeDescription.FLAG_SECTIONS, new Class[]{GraySectionCell.class}, null, null, null, Theme.key_graySection)); + + arrayList.add(new ThemeDescription(mediaPages[a].listView, 0, new Class[]{LoadingCell.class}, new String[]{"progressBar"}, null, null, null, Theme.key_progressCircle)); + + arrayList.add(new ThemeDescription(mediaPages[a].listView, ThemeDescription.FLAG_TEXTCOLOR, new Class[]{UserCell.class}, new String[]{"adminTextView"}, null, null, null, Theme.key_profile_creatorIcon)); + arrayList.add(new ThemeDescription(mediaPages[a].listView, 0, new Class[]{UserCell.class}, new String[]{"imageView"}, null, null, null, Theme.key_windowBackgroundWhiteGrayIcon)); + arrayList.add(new ThemeDescription(mediaPages[a].listView, 0, new Class[]{UserCell.class}, new String[]{"nameTextView"}, null, null, null, Theme.key_windowBackgroundWhiteBlackText)); + arrayList.add(new ThemeDescription(mediaPages[a].listView, 0, new Class[]{UserCell.class}, new String[]{"statusColor"}, null, null, cellDelegate, Theme.key_windowBackgroundWhiteGrayText)); + arrayList.add(new ThemeDescription(mediaPages[a].listView, 0, new Class[]{UserCell.class}, new String[]{"statusOnlineColor"}, null, null, cellDelegate, Theme.key_windowBackgroundWhiteBlueText)); + arrayList.add(new ThemeDescription(mediaPages[a].listView, 0, new Class[]{UserCell.class}, null, new Drawable[]{Theme.avatar_savedDrawable}, null, Theme.key_avatar_text)); + + arrayList.add(new ThemeDescription(mediaPages[a].listView, 0, new Class[]{ProfileSearchCell.class}, null, new Paint[]{Theme.dialogs_namePaint[0], Theme.dialogs_namePaint[1], Theme.dialogs_searchNamePaint}, null, null, Theme.key_chats_name)); + arrayList.add(new ThemeDescription(mediaPages[a].listView, 0, new Class[]{ProfileSearchCell.class}, null, new Paint[]{Theme.dialogs_nameEncryptedPaint[0], Theme.dialogs_nameEncryptedPaint[1], Theme.dialogs_searchNameEncryptedPaint}, null, null, Theme.key_chats_secretName)); + arrayList.add(new ThemeDescription(mediaPages[a].listView, 0, new Class[]{ProfileSearchCell.class}, null, new Drawable[]{Theme.avatar_savedDrawable}, null, Theme.key_avatar_text)); + arrayList.add(new ThemeDescription(null, 0, null, null, null, cellDelegate, Theme.key_avatar_backgroundRed)); + arrayList.add(new ThemeDescription(null, 0, null, null, null, cellDelegate, Theme.key_avatar_backgroundOrange)); + arrayList.add(new ThemeDescription(null, 0, null, null, null, cellDelegate, Theme.key_avatar_backgroundViolet)); + arrayList.add(new ThemeDescription(null, 0, null, null, null, cellDelegate, Theme.key_avatar_backgroundGreen)); + arrayList.add(new ThemeDescription(null, 0, null, null, null, cellDelegate, Theme.key_avatar_backgroundCyan)); + arrayList.add(new ThemeDescription(null, 0, null, null, null, cellDelegate, Theme.key_avatar_backgroundBlue)); + arrayList.add(new ThemeDescription(null, 0, null, null, null, cellDelegate, Theme.key_avatar_backgroundPink)); + + arrayList.add(new ThemeDescription(mediaPages[a].listView, ThemeDescription.FLAG_TEXTCOLOR, new Class[]{SharedDocumentCell.class}, new String[]{"nameTextView"}, null, null, null, Theme.key_windowBackgroundWhiteBlackText)); + arrayList.add(new ThemeDescription(mediaPages[a].listView, ThemeDescription.FLAG_TEXTCOLOR, new Class[]{SharedDocumentCell.class}, new String[]{"dateTextView"}, null, null, null, Theme.key_windowBackgroundWhiteGrayText3)); + arrayList.add(new ThemeDescription(mediaPages[a].listView, ThemeDescription.FLAG_PROGRESSBAR, new Class[]{SharedDocumentCell.class}, new String[]{"progressView"}, null, null, null, Theme.key_sharedMedia_startStopLoadIcon)); + arrayList.add(new ThemeDescription(mediaPages[a].listView, ThemeDescription.FLAG_IMAGECOLOR, new Class[]{SharedDocumentCell.class}, new String[]{"statusImageView"}, null, null, null, Theme.key_sharedMedia_startStopLoadIcon)); + arrayList.add(new ThemeDescription(mediaPages[a].listView, ThemeDescription.FLAG_CHECKBOX, new Class[]{SharedDocumentCell.class}, new String[]{"checkBox"}, null, null, null, Theme.key_checkbox)); + arrayList.add(new ThemeDescription(mediaPages[a].listView, ThemeDescription.FLAG_CHECKBOXCHECK, new Class[]{SharedDocumentCell.class}, new String[]{"checkBox"}, null, null, null, Theme.key_checkboxCheck)); + arrayList.add(new ThemeDescription(mediaPages[a].listView, ThemeDescription.FLAG_IMAGECOLOR, new Class[]{SharedDocumentCell.class}, new String[]{"thumbImageView"}, null, null, null, Theme.key_files_folderIcon)); + arrayList.add(new ThemeDescription(mediaPages[a].listView, ThemeDescription.FLAG_TEXTCOLOR, new Class[]{SharedDocumentCell.class}, new String[]{"extTextView"}, null, null, null, Theme.key_files_iconText)); + + arrayList.add(new ThemeDescription(mediaPages[a].listView, 0, new Class[]{LoadingCell.class}, new String[]{"progressBar"}, null, null, null, Theme.key_progressCircle)); + + arrayList.add(new ThemeDescription(mediaPages[a].listView, ThemeDescription.FLAG_CHECKBOX, new Class[]{SharedAudioCell.class}, new String[]{"checkBox"}, null, null, null, Theme.key_checkbox)); + arrayList.add(new ThemeDescription(mediaPages[a].listView, ThemeDescription.FLAG_CHECKBOXCHECK, new Class[]{SharedAudioCell.class}, new String[]{"checkBox"}, null, null, null, Theme.key_checkboxCheck)); + arrayList.add(new ThemeDescription(mediaPages[a].listView, ThemeDescription.FLAG_TEXTCOLOR, new Class[]{SharedAudioCell.class}, Theme.chat_contextResult_titleTextPaint, null, null, Theme.key_windowBackgroundWhiteBlackText)); + arrayList.add(new ThemeDescription(mediaPages[a].listView, ThemeDescription.FLAG_TEXTCOLOR, new Class[]{SharedAudioCell.class}, Theme.chat_contextResult_descriptionTextPaint, null, null, Theme.key_windowBackgroundWhiteGrayText2)); + + arrayList.add(new ThemeDescription(mediaPages[a].listView, ThemeDescription.FLAG_CHECKBOX, new Class[]{SharedLinkCell.class}, new String[]{"checkBox"}, null, null, null, Theme.key_checkbox)); + arrayList.add(new ThemeDescription(mediaPages[a].listView, ThemeDescription.FLAG_CHECKBOXCHECK, new Class[]{SharedLinkCell.class}, new String[]{"checkBox"}, null, null, null, Theme.key_checkboxCheck)); + arrayList.add(new ThemeDescription(mediaPages[a].listView, 0, new Class[]{SharedLinkCell.class}, new String[]{"titleTextPaint"}, null, null, null, Theme.key_windowBackgroundWhiteBlackText)); + arrayList.add(new ThemeDescription(mediaPages[a].listView, 0, new Class[]{SharedLinkCell.class}, null, null, null, Theme.key_windowBackgroundWhiteLinkText)); + arrayList.add(new ThemeDescription(mediaPages[a].listView, 0, new Class[]{SharedLinkCell.class}, Theme.linkSelectionPaint, null, null, Theme.key_windowBackgroundWhiteLinkSelection)); + arrayList.add(new ThemeDescription(mediaPages[a].listView, 0, new Class[]{SharedLinkCell.class}, new String[]{"letterDrawable"}, null, null, null, Theme.key_sharedMedia_linkPlaceholderText)); + arrayList.add(new ThemeDescription(mediaPages[a].listView, ThemeDescription.FLAG_BACKGROUNDFILTER, new Class[]{SharedLinkCell.class}, new String[]{"letterDrawable"}, null, null, null, Theme.key_sharedMedia_linkPlaceholder)); + + arrayList.add(new ThemeDescription(mediaPages[a].listView, ThemeDescription.FLAG_CELLBACKGROUNDCOLOR | ThemeDescription.FLAG_SECTIONS, new Class[]{SharedMediaSectionCell.class}, null, null, null, Theme.key_windowBackgroundWhite)); + arrayList.add(new ThemeDescription(mediaPages[a].listView, ThemeDescription.FLAG_SECTIONS, new Class[]{SharedMediaSectionCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteBlackText)); + arrayList.add(new ThemeDescription(mediaPages[a].listView, 0, new Class[]{SharedMediaSectionCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteBlackText)); + + arrayList.add(new ThemeDescription(mediaPages[a].listView, 0, new Class[]{SharedPhotoVideoCell.class}, new String[]{"backgroundPaint"}, null, null, null, Theme.key_sharedMedia_photoPlaceholder)); + arrayList.add(new ThemeDescription(mediaPages[a].listView, ThemeDescription.FLAG_CHECKBOX, new Class[]{SharedPhotoVideoCell.class}, null, null, cellDelegate, Theme.key_checkbox)); + arrayList.add(new ThemeDescription(mediaPages[a].listView, ThemeDescription.FLAG_CHECKBOXCHECK, new Class[]{SharedPhotoVideoCell.class}, null, null, cellDelegate, Theme.key_checkboxCheck)); + + arrayList.add(new ThemeDescription(mediaPages[a].listView, 0, null, null, new Drawable[]{pinnedHeaderShadowDrawable}, null, Theme.key_windowBackgroundGrayShadow)); + } + + return arrayList; + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/SizeNotifierFrameLayout.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/SizeNotifierFrameLayout.java index 2b959d938..d9a04ae82 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/SizeNotifierFrameLayout.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/SizeNotifierFrameLayout.java @@ -18,14 +18,14 @@ import android.graphics.drawable.Drawable; import android.graphics.drawable.GradientDrawable; import android.os.Build; import android.view.View; -import android.widget.FrameLayout; import org.telegram.messenger.AndroidUtilities; import org.telegram.ui.ActionBar.ActionBar; import org.telegram.ui.ActionBar.ActionBarLayout; +import org.telegram.ui.ActionBar.AdjustPanFrameLayout; import org.telegram.ui.ActionBar.Theme; -public class SizeNotifierFrameLayout extends FrameLayout { +public class SizeNotifierFrameLayout extends AdjustPanFrameLayout { private Rect rect = new Rect(); private Drawable backgroundDrawable; @@ -37,21 +37,24 @@ public class SizeNotifierFrameLayout extends FrameLayout { private float translationX; private float translationY; private float parallaxScale = 1.0f; + private int backgroundTranslationY; private boolean paused = true; private Drawable oldBackgroundDrawable; private ActionBarLayout parentLayout; + private boolean useSmoothKeyboard; public interface SizeNotifierFrameLayoutDelegate { void onSizeChanged(int keyboardHeight, boolean isWidthGreater); } - public SizeNotifierFrameLayout(Context context) { - this(context, null); + public SizeNotifierFrameLayout(Context context, boolean smoothKeyboard) { + this(context, smoothKeyboard, null); } - public SizeNotifierFrameLayout(Context context, ActionBarLayout layout) { + public SizeNotifierFrameLayout(Context context, boolean smoothKeyboard, ActionBarLayout layout) { super(context); setWillNotDraw(false); + useSmoothKeyboard = smoothKeyboard; parentLayout = layout; } @@ -143,6 +146,10 @@ public class SizeNotifierFrameLayout extends FrameLayout { bottomClip = value; } + public void setBackgroundTranslation(int translation) { + backgroundTranslationY = translation; + } + public int getHeightWithKeyboard() { return getKeyboardHeight() + getMeasuredHeight(); } @@ -153,6 +160,7 @@ public class SizeNotifierFrameLayout extends FrameLayout { super.onDraw(canvas); return; } + int kbHeight = useSmoothKeyboard ? 0 : keyboardHeight; Drawable newDrawable = Theme.getCachedWallpaperNonBlocking(); if (newDrawable != backgroundDrawable && newDrawable != null) { if (Theme.isAnimatingColor()) { @@ -186,7 +194,7 @@ public class SizeNotifierFrameLayout extends FrameLayout { canvas.save(); canvas.clipRect(0, 0, getMeasuredWidth(), getMeasuredHeight() - bottomClip); } - drawable.setBounds(0, 0, getMeasuredWidth(), getMeasuredHeight() + keyboardHeight); + drawable.setBounds(0, backgroundTranslationY, getMeasuredWidth(), backgroundTranslationY + getMeasuredHeight() + kbHeight); drawable.draw(canvas); if (bottomClip != 0) { canvas.restore(); @@ -204,12 +212,12 @@ public class SizeNotifierFrameLayout extends FrameLayout { int actionBarHeight = (isActionBarVisible() ? ActionBar.getCurrentActionBarHeight() : 0) + (Build.VERSION.SDK_INT >= 21 && occupyStatusBar ? AndroidUtilities.statusBarHeight : 0); int viewHeight = getMeasuredHeight() - actionBarHeight; float scaleX = (float) getMeasuredWidth() / (float) drawable.getIntrinsicWidth(); - float scaleY = (float) (viewHeight + keyboardHeight) / (float) drawable.getIntrinsicHeight(); + float scaleY = (float) (viewHeight + kbHeight) / (float) drawable.getIntrinsicHeight(); float scale = scaleX < scaleY ? scaleY : scaleX; int width = (int) Math.ceil(drawable.getIntrinsicWidth() * scale * parallaxScale); int height = (int) Math.ceil(drawable.getIntrinsicHeight() * scale * parallaxScale); int x = (getMeasuredWidth() - width) / 2 + (int) translationX; - int y = (viewHeight - height + keyboardHeight) / 2 + actionBarHeight + (int) translationY; + int y = backgroundTranslationY + (viewHeight - height + kbHeight) / 2 + actionBarHeight + (int) translationY; canvas.save(); canvas.clipRect(0, actionBarHeight, width, getMeasuredHeight() - bottomClip); drawable.setBounds(x, y, x + width, y + height); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/SizeNotifierFrameLayoutPhoto.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/SizeNotifierFrameLayoutPhoto.java index efff71fc4..9eca554d5 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/SizeNotifierFrameLayoutPhoto.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/SizeNotifierFrameLayoutPhoto.java @@ -12,24 +12,26 @@ import android.content.Context; import android.graphics.Rect; import android.view.View; import android.view.WindowManager; -import android.widget.FrameLayout; import org.telegram.messenger.AndroidUtilities; +import org.telegram.ui.ActionBar.AdjustPanFrameLayout; -public class SizeNotifierFrameLayoutPhoto extends FrameLayout { +public class SizeNotifierFrameLayoutPhoto extends AdjustPanFrameLayout { private Rect rect = new Rect(); private int keyboardHeight; private SizeNotifierFrameLayoutPhotoDelegate delegate; private WindowManager windowManager; private boolean withoutWindow; + private boolean useSmoothKeyboard; public interface SizeNotifierFrameLayoutPhotoDelegate { void onSizeChanged(int keyboardHeight, boolean isWidthGreater); } - public SizeNotifierFrameLayoutPhoto(Context context) { + public SizeNotifierFrameLayoutPhoto(Context context, boolean smoothKeyboard) { super(context); + useSmoothKeyboard = smoothKeyboard; } public void setDelegate(SizeNotifierFrameLayoutPhotoDelegate sizeNotifierFrameLayoutPhotoDelegate) { @@ -55,7 +57,12 @@ public class SizeNotifierFrameLayoutPhoto extends FrameLayout { } else { int usableViewHeight = rootView.getHeight() - AndroidUtilities.getViewInset(rootView); int top = rect.top; - int size = AndroidUtilities.displaySize.y - top - usableViewHeight; + int size; + if (useSmoothKeyboard) { + size = Math.max(0, usableViewHeight - (rect.bottom - rect.top)); + } else { + size = AndroidUtilities.displaySize.y - top - usableViewHeight; + } if (size <= Math.max(AndroidUtilities.dp(10), AndroidUtilities.statusBarHeight)) { size = 0; } @@ -67,12 +74,9 @@ public class SizeNotifierFrameLayoutPhoto extends FrameLayout { if (delegate != null) { keyboardHeight = getKeyboardHeight(); final boolean isWidthGreater = AndroidUtilities.displaySize.x > AndroidUtilities.displaySize.y; - post(new Runnable() { - @Override - public void run() { - if (delegate != null) { - delegate.onSizeChanged(keyboardHeight, isWidthGreater); - } + post(() -> { + if (delegate != null) { + delegate.onSizeChanged(keyboardHeight, isWidthGreater); } }); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/CountrySelectActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/CountrySelectActivity.java index 1fe70e64b..bb565e972 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/CountrySelectActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/CountrySelectActivity.java @@ -168,7 +168,7 @@ public class CountrySelectActivity extends BaseFragment { listView.setOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { - if (newState == RecyclerView.SCROLL_STATE_DRAGGING && searching && searchWas) { + if (newState == RecyclerView.SCROLL_STATE_DRAGGING) { AndroidUtilities.hideKeyboard(getParentActivity().getCurrentFocus()); } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/DataUsageActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/DataUsageActivity.java index 05525954f..8f0204be4 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/DataUsageActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/DataUsageActivity.java @@ -79,6 +79,8 @@ public class DataUsageActivity extends BaseFragment { return t * t * t * t * t + 1.0F; }; + private boolean swipeBackEnabled = true; + public DataUsageActivity() { super(); } @@ -548,6 +550,11 @@ public class DataUsageActivity extends BaseFragment { } } + @Override + public boolean isSwipeBackEnabled(MotionEvent event) { + return swipeBackEnabled; + } + private void setScrollY(float value) { actionBar.setTranslationY(value); for (int a = 0; a < viewPages.length; a++) { @@ -560,9 +567,9 @@ public class DataUsageActivity extends BaseFragment { if (scrollSlidingTextTabStrip == null) { return; } - scrollSlidingTextTabStrip.addTextTab(0, LocaleController.getString("NetworkUsageMobile", R.string.NetworkUsageMobile)); - scrollSlidingTextTabStrip.addTextTab(1, LocaleController.getString("NetworkUsageWiFi", R.string.NetworkUsageWiFi)); - scrollSlidingTextTabStrip.addTextTab(2, LocaleController.getString("NetworkUsageRoaming", R.string.NetworkUsageRoaming)); + scrollSlidingTextTabStrip.addTextTab(0, LocaleController.getString("NetworkUsageMobileTab", R.string.NetworkUsageMobileTab)); + scrollSlidingTextTabStrip.addTextTab(1, LocaleController.getString("NetworkUsageWiFiTab", R.string.NetworkUsageWiFiTab)); + scrollSlidingTextTabStrip.addTextTab(2, LocaleController.getString("NetworkUsageRoamingTab", R.string.NetworkUsageRoamingTab)); scrollSlidingTextTabStrip.setVisibility(View.VISIBLE); actionBar.setExtraHeight(AndroidUtilities.dp(44)); int id = scrollSlidingTextTabStrip.getCurrentTabId(); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/DialogOrContactPickerActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/DialogOrContactPickerActivity.java index e4cdf2901..edb464245 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/DialogOrContactPickerActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/DialogOrContactPickerActivity.java @@ -78,6 +78,8 @@ public class DialogOrContactPickerActivity extends BaseFragment { return t * t * t * t * t + 1.0F; }; + private boolean swipeBackEnabled = true; + public DialogOrContactPickerActivity() { super(); @@ -582,6 +584,11 @@ public class DialogOrContactPickerActivity extends BaseFragment { } } + @Override + public boolean isSwipeBackEnabled(MotionEvent event) { + return swipeBackEnabled; + } + @Override public void onFragmentDestroy() { if (dialogsActivity != null) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/DialogsActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/DialogsActivity.java index e5993c699..dcfb5a36a 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/DialogsActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/DialogsActivity.java @@ -39,7 +39,7 @@ import android.os.Vibrator; import androidx.recyclerview.widget.ItemTouchHelper; import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.LinearSmoothScrollerMiddle; +import androidx.recyclerview.widget.LinearSmoothScrollerCustom; import androidx.recyclerview.widget.RecyclerView; import android.text.TextUtils; @@ -183,6 +183,7 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter. private ActionBarMenuSubItem archiveItem; private ActionBarMenuSubItem clearItem; private ActionBarMenuSubItem readItem; + private ActionBarMenuSubItem blockItem; private float additionalFloatingTranslation; private float floatingButtonTranslation; @@ -250,6 +251,7 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter. private int canMuteCount; private int canUnmuteCount; private int canClearCacheCount; + private int canReportSpamCount; private int folderId; @@ -259,6 +261,7 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter. private final static int clear = 103; private final static int mute = 104; private final static int archive = 105; + private final static int block = 106; private final static int ARCHIVE_ITEM_STATE_PINNED = 0; private final static int ARCHIVE_ITEM_STATE_SHOWED = 1; @@ -277,7 +280,7 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter. private int inputFieldHeight; public ContentView(Context context) { - super(context); + super(context, SharedConfig.smoothKeyboard); } @Override @@ -290,7 +293,7 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter. measureChildWithMargins(actionBar, widthMeasureSpec, 0, heightMeasureSpec, 0); - int keyboardSize = getKeyboardHeight(); + int keyboardSize = SharedConfig.smoothKeyboard ? 0 : getKeyboardHeight(); int childCount = getChildCount(); if (commentView != null) { @@ -304,6 +307,12 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter. } else { inputFieldHeight = 0; } + + if (SharedConfig.smoothKeyboard && commentView.isPopupShowing()) { + fragmentView.setTranslationY(getCurrentPanTranslationY()); + listView.setTranslationY(0); + searchListView.setTranslationY(0); + } } for (int i = 0; i < childCount; i++) { @@ -338,8 +347,9 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter. int paddingBottom; Object tag = commentView != null ? commentView.getTag() : null; + int keyboardSize = SharedConfig.smoothKeyboard ? 0 : getKeyboardHeight(); if (tag != null && tag.equals(2)) { - paddingBottom = getKeyboardHeight() <= AndroidUtilities.dp(20) && !AndroidUtilities.isInMultiwindow ? commentView.getEmojiPadding() : 0; + paddingBottom = keyboardSize <= AndroidUtilities.dp(20) && !AndroidUtilities.isInMultiwindow ? commentView.getEmojiPadding() : 0; } else { paddingBottom = 0; } @@ -1164,7 +1174,7 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter. DialogsActivity dialogsActivity = new DialogsActivity(arguments); dialogsActivity.setDelegate(oldDelegate); launchActivity.presentFragment(dialogsActivity, false, true); - } else if (id == pin || id == read || id == delete || id == clear || id == mute || id == archive) { + } else if (id == pin || id == read || id == delete || id == clear || id == mute || id == archive || id == block) { perfromSelectedDialogsAction(id, true); } } @@ -1192,6 +1202,7 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter. archiveItem = otherItem.addSubItem(archive, R.drawable.msg_archive, LocaleController.getString("Archive", R.string.Archive)); readItem = otherItem.addSubItem(read, R.drawable.msg_markread, LocaleController.getString("MarkAsRead", R.string.MarkAsRead)); clearItem = otherItem.addSubItem(clear, R.drawable.msg_clear, LocaleController.getString("ClearHistory", R.string.ClearHistory)); + blockItem = otherItem.addSubItem(block, R.drawable.msg_block, LocaleController.getString("BlockUser", R.string.BlockUser)); actionModeViews.add(pinItem); actionModeViews.add(muteItem); @@ -1259,7 +1270,7 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter. if (hasHiddenArchive() && position == 1) { super.smoothScrollToPosition(recyclerView, state, position); } else { - LinearSmoothScrollerMiddle linearSmoothScroller = new LinearSmoothScrollerMiddle(recyclerView.getContext()); + LinearSmoothScrollerCustom linearSmoothScroller = new LinearSmoothScrollerCustom(recyclerView.getContext(), LinearSmoothScrollerCustom.POSITION_MIDDLE); linearSmoothScroller.setTargetPosition(position); startSmoothScroll(linearSmoothScroller); } @@ -2001,6 +2012,21 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter. return fragmentView; } + @Override + protected void onPanTranslationUpdate(int y) { + if (listView == null) { + return; + } + if (commentView != null && commentView.isPopupShowing()) { + fragmentView.setTranslationY(y); + listView.setTranslationY(0); + searchListView.setTranslationY(0); + } else { + listView.setTranslationY(y); + searchListView.setTranslationY(y); + } + } + @Override public void onResume() { super.onResume(); @@ -2674,42 +2700,64 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter. return; } } else if ((action == delete || action == clear) && count > 1 && alert) { - if (alert) { - AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); - if (action == delete) { - builder.setTitle(LocaleController.formatString("DeleteFewChatsTitle", R.string.DeleteFewChatsTitle, LocaleController.formatPluralString("ChatsSelected", count))); - builder.setMessage(LocaleController.getString("AreYouSureDeleteFewChats", R.string.AreYouSureDeleteFewChats)); - builder.setPositiveButton(LocaleController.getString("Delete", R.string.Delete), (dialog1, which) -> { - getMessagesController().setDialogsInTransaction(true); - perfromSelectedDialogsAction(action, false); - getMessagesController().setDialogsInTransaction(false); - MessagesController.getInstance(currentAccount).checkIfFolderEmpty(folderId); - if (folderId != 0 && getDialogsArray(currentAccount, dialogsType, folderId, false).size() == 0) { - listView.setEmptyView(null); - progressView.setVisibility(View.INVISIBLE); - finishFragment(); - } - }); - } else { - if (canClearCacheCount != 0) { - builder.setTitle(LocaleController.formatString("ClearCacheFewChatsTitle", R.string.ClearCacheFewChatsTitle, LocaleController.formatPluralString("ChatsSelectedClearCache", count))); - builder.setMessage(LocaleController.getString("AreYouSureClearHistoryCacheFewChats", R.string.AreYouSureClearHistoryCacheFewChats)); - builder.setPositiveButton(LocaleController.getString("ClearHistoryCache", R.string.ClearHistoryCache), (dialog1, which) -> perfromSelectedDialogsAction(action, false)); - } else { - builder.setTitle(LocaleController.formatString("ClearFewChatsTitle", R.string.ClearFewChatsTitle, LocaleController.formatPluralString("ChatsSelectedClear", count))); - builder.setMessage(LocaleController.getString("AreYouSureClearHistoryFewChats", R.string.AreYouSureClearHistoryFewChats)); - builder.setPositiveButton(LocaleController.getString("ClearHistory", R.string.ClearHistory), (dialog1, which) -> perfromSelectedDialogsAction(action, false)); + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + if (action == delete) { + builder.setTitle(LocaleController.formatString("DeleteFewChatsTitle", R.string.DeleteFewChatsTitle, LocaleController.formatPluralString("ChatsSelected", count))); + builder.setMessage(LocaleController.getString("AreYouSureDeleteFewChats", R.string.AreYouSureDeleteFewChats)); + builder.setPositiveButton(LocaleController.getString("Delete", R.string.Delete), (dialog1, which) -> { + getMessagesController().setDialogsInTransaction(true); + perfromSelectedDialogsAction(action, false); + getMessagesController().setDialogsInTransaction(false); + MessagesController.getInstance(currentAccount).checkIfFolderEmpty(folderId); + if (folderId != 0 && getDialogsArray(currentAccount, dialogsType, folderId, false).size() == 0) { + listView.setEmptyView(null); + progressView.setVisibility(View.INVISIBLE); + finishFragment(); } + }); + } else { + if (canClearCacheCount != 0) { + builder.setTitle(LocaleController.formatString("ClearCacheFewChatsTitle", R.string.ClearCacheFewChatsTitle, LocaleController.formatPluralString("ChatsSelectedClearCache", count))); + builder.setMessage(LocaleController.getString("AreYouSureClearHistoryCacheFewChats", R.string.AreYouSureClearHistoryCacheFewChats)); + builder.setPositiveButton(LocaleController.getString("ClearHistoryCache", R.string.ClearHistoryCache), (dialog1, which) -> perfromSelectedDialogsAction(action, false)); + } else { + builder.setTitle(LocaleController.formatString("ClearFewChatsTitle", R.string.ClearFewChatsTitle, LocaleController.formatPluralString("ChatsSelectedClear", count))); + builder.setMessage(LocaleController.getString("AreYouSureClearHistoryFewChats", R.string.AreYouSureClearHistoryFewChats)); + builder.setPositiveButton(LocaleController.getString("ClearHistory", R.string.ClearHistory), (dialog1, which) -> perfromSelectedDialogsAction(action, false)); } - builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); - AlertDialog alertDialog = builder.create(); - showDialog(alertDialog); - TextView button = (TextView) alertDialog.getButton(DialogInterface.BUTTON_POSITIVE); - if (button != null) { - button.setTextColor(Theme.getColor(Theme.key_dialogTextRed2)); - } - return; } + builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); + AlertDialog alertDialog = builder.create(); + showDialog(alertDialog); + TextView button = (TextView) alertDialog.getButton(DialogInterface.BUTTON_POSITIVE); + if (button != null) { + button.setTextColor(Theme.getColor(Theme.key_dialogTextRed2)); + } + return; + } else if (action == block && alert) { + TLRPC.User user; + if (count == 1) { + long did = selectedDialogs.get(0); + user = getMessagesController().getUser((int) did); + } else { + user = null; + } + AlertsCreator.createBlockDialogAlert(DialogsActivity.this, count, canReportSpamCount != 0, user, (report, delete) -> { + for (int a = 0, N = selectedDialogs.size(); a < N; a++) { + long did = selectedDialogs.get(a); + int lowerId = (int) did; + if (report) { + TLRPC.User u = getMessagesController().getUser(lowerId); + getMessagesController().reportSpam(did, u, null, null, false); + } + if (delete) { + getMessagesController().deleteDialog(did, 0, true); + } + getMessagesController().blockUser(lowerId); + } + hideActionMode(false); + }); + return; } boolean scrollToTop = false; for (int a = 0; a < count; a++) { @@ -2844,6 +2892,8 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter. getNotificationsController().setDialogNotificationsSettings(selectedDialog, NotificationsController.SETTING_MUTE_FOREVER); } } + } else if (action == block) { + } } if (action == pin) { @@ -2878,11 +2928,15 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter. canPinCount = 0; canReadCount = 0; canClearCacheCount = 0; + int cantBlockCount = 0; + canReportSpamCount = 0; if (hide) { return; } ArrayList selectedDialogs = dialogsAdapter.getSelectedDialogs(); int count = selectedDialogs.size(); + int selfUserId = getUserConfig().getClientUserId(); + SharedPreferences preferences = getNotificationsSettings(); for (int a = 0; a < count; a++) { TLRPC.Dialog dialog = getMessagesController().dialogs_dict.get(selectedDialogs.get(a)); if (dialog == null) { @@ -2904,13 +2958,26 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter. if (folderId == 1) { canUnarchiveCount++; - } else if (selectedDialog != getUserConfig().getClientUserId() && selectedDialog != 777000 && !getMessagesController().isProxyDialog(selectedDialog, false)) { + } else if (selectedDialog != selfUserId && selectedDialog != 777000 && !getMessagesController().isProxyDialog(selectedDialog, false)) { canArchiveCount++; } int lower_id = (int) selectedDialog; int high_id = (int) (selectedDialog >> 32); + if (lower_id <= 0 || lower_id == selfUserId) { + cantBlockCount++; + } else { + TLRPC.User user = getMessagesController().getUser(lower_id); + if (MessagesController.isSupportUser(user)) { + cantBlockCount++; + } else { + if (lower_id == 0 || preferences.getBoolean("dialog_bar_report" + selectedDialog, true)) { + canReportSpamCount++; + } + } + } + if (DialogObject.isChannel(dialog)) { final TLRPC.Chat chat = getMessagesController().getChat(-lower_id); CharSequence[] items; @@ -2988,6 +3055,11 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter. } else { pinItem.setVisibility(View.VISIBLE); } + if (cantBlockCount != 0) { + blockItem.setVisibility(View.GONE); + } else { + blockItem.setVisibility(View.VISIBLE); + } if (canUnmuteCount != 0) { muteItem.setIcon(R.drawable.msg_unmute); muteItem.setContentDescription(LocaleController.getString("ChatsUnmute", R.string.ChatsUnmute)); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/DocumentSelectActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/DocumentSelectActivity.java index ea78a4dc5..246741305 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/DocumentSelectActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/DocumentSelectActivity.java @@ -309,7 +309,7 @@ public class DocumentSelectActivity extends BaseFragment { selectedFiles.clear(); - sizeNotifierFrameLayout = new SizeNotifierFrameLayout(context) { + sizeNotifierFrameLayout = new SizeNotifierFrameLayout(context, SharedConfig.smoothKeyboard) { private int lastNotifyWidth; private boolean ignoreLayout; @@ -322,18 +322,27 @@ public class DocumentSelectActivity extends BaseFragment { setMeasuredDimension(widthSize, heightSize); - int keyboardSize = getKeyboardHeight(); + int kbHeight = getKeyboardHeight(); + int keyboardSize = SharedConfig.smoothKeyboard ? 0 : kbHeight; if (keyboardSize <= AndroidUtilities.dp(20)) { if (!AndroidUtilities.isInMultiwindow && commentTextView != null && frameLayout2.getParent() == this) { heightSize -= commentTextView.getEmojiPadding(); heightMeasureSpec = MeasureSpec.makeMeasureSpec(heightSize, MeasureSpec.EXACTLY); } - } else if (commentTextView != null) { + } + + if (kbHeight > AndroidUtilities.dp(20) && commentTextView != null) { ignoreLayout = true; commentTextView.hideEmojiView(); ignoreLayout = false; } + if (SharedConfig.smoothKeyboard && commentTextView != null && commentTextView.isPopupShowing()) { + fragmentView.setTranslationY(getCurrentPanTranslationY()); + listView.setTranslationY(0); + emptyView.setTranslationY(0); + } + int childCount = getChildCount(); for (int i = 0; i < childCount; i++) { View child = getChildAt(i); @@ -366,7 +375,8 @@ public class DocumentSelectActivity extends BaseFragment { } final int count = getChildCount(); - int paddingBottom = commentTextView != null && frameLayout2.getParent() == this && getKeyboardHeight() <= AndroidUtilities.dp(20) && !AndroidUtilities.isInMultiwindow && !AndroidUtilities.isTablet() ? commentTextView.getEmojiPadding() : 0; + int keyboardSize = SharedConfig.smoothKeyboard ? 0 : getKeyboardHeight(); + int paddingBottom = commentTextView != null && frameLayout2.getParent() == this && keyboardSize <= AndroidUtilities.dp(20) && !AndroidUtilities.isInMultiwindow && !AndroidUtilities.isTablet() ? commentTextView.getEmojiPadding() : 0; setBottomClip(paddingBottom); for (int i = 0; i < count; i++) { @@ -420,7 +430,7 @@ public class DocumentSelectActivity extends BaseFragment { if (AndroidUtilities.isTablet()) { childTop = getMeasuredHeight() - child.getMeasuredHeight(); } else { - childTop = getMeasuredHeight() + getKeyboardHeight() - child.getMeasuredHeight(); + childTop = getMeasuredHeight() + keyboardSize - child.getMeasuredHeight(); } } child.layout(childLeft, childTop, childLeft + width, childTop + height); @@ -480,7 +490,7 @@ public class DocumentSelectActivity extends BaseFragment { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { scrolling = newState != RecyclerView.SCROLL_STATE_IDLE; - if (newState == RecyclerView.SCROLL_STATE_DRAGGING && searching && searchWas) { + if (newState == RecyclerView.SCROLL_STATE_DRAGGING) { AndroidUtilities.hideKeyboard(getParentActivity().getCurrentFocus()); } } @@ -769,6 +779,21 @@ public class DocumentSelectActivity extends BaseFragment { return fragmentView; } + @Override + protected void onPanTranslationUpdate(int y) { + if (listView == null) { + return; + } + if (commentTextView.isPopupShowing()) { + fragmentView.setTranslationY(y); + listView.setTranslationY(0); + emptyView.setTranslationY(0); + } else { + listView.setTranslationY(y); + emptyView.setTranslationY(y); + } + } + private boolean onItemClick(View view, ListItem item) { if (item == null || item.file == null || item.file.isDirectory()) { return false; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/GroupCreateActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/GroupCreateActivity.java index a2cbd3bf5..30d5e8fc7 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/GroupCreateActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/GroupCreateActivity.java @@ -983,7 +983,8 @@ public class GroupCreateActivity extends BaseFragment implements NotificationCen if (selectedContacts.size() == 0) { actionBar.setSubtitle(LocaleController.formatString("MembersCountZero", R.string.MembersCountZero, LocaleController.formatPluralString("Members", maxCount))); } else { - actionBar.setSubtitle(LocaleController.formatString("MembersCount", R.string.MembersCount, selectedContacts.size(), maxCount)); + String str = LocaleController.getPluralString("MembersCountSelected", selectedContacts.size()); + actionBar.setSubtitle(String.format(str, selectedContacts.size(), maxCount)); } } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/GroupCreateFinalActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/GroupCreateFinalActivity.java index 02606446d..a30ecb4b3 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/GroupCreateFinalActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/GroupCreateFinalActivity.java @@ -41,6 +41,7 @@ import org.telegram.messenger.ChatObject; import org.telegram.messenger.ImageLocation; import org.telegram.messenger.LocaleController; import org.telegram.messenger.MessagesStorage; +import org.telegram.messenger.SharedConfig; import org.telegram.tgnet.ConnectionsManager; import org.telegram.tgnet.TLRPC; import org.telegram.messenger.FileLog; @@ -231,7 +232,7 @@ public class GroupCreateFinalActivity extends BaseFragment implements Notificati } }); - SizeNotifierFrameLayout sizeNotifierFrameLayout = new SizeNotifierFrameLayout(context) { + SizeNotifierFrameLayout sizeNotifierFrameLayout = new SizeNotifierFrameLayout(context, SharedConfig.smoothKeyboard) { private boolean ignoreLayout; @@ -245,7 +246,7 @@ public class GroupCreateFinalActivity extends BaseFragment implements Notificati measureChildWithMargins(actionBar, widthMeasureSpec, 0, heightMeasureSpec, 0); - int keyboardSize = getKeyboardHeight(); + int keyboardSize = SharedConfig.smoothKeyboard ? 0 : getKeyboardHeight(); if (keyboardSize > AndroidUtilities.dp(20)) { ignoreLayout = true; editText.hideEmojiView(); @@ -278,7 +279,8 @@ public class GroupCreateFinalActivity extends BaseFragment implements Notificati protected void onLayout(boolean changed, int l, int t, int r, int b) { final int count = getChildCount(); - int paddingBottom = getKeyboardHeight() <= AndroidUtilities.dp(20) && !AndroidUtilities.isInMultiwindow && !AndroidUtilities.isTablet() ? editText.getEmojiPadding() : 0; + int keyboardSize = SharedConfig.smoothKeyboard ? 0 : getKeyboardHeight(); + int paddingBottom = keyboardSize <= AndroidUtilities.dp(20) && !AndroidUtilities.isInMultiwindow && !AndroidUtilities.isTablet() ? editText.getEmojiPadding() : 0; setBottomClip(paddingBottom); for (int i = 0; i < count; i++) { @@ -332,7 +334,7 @@ public class GroupCreateFinalActivity extends BaseFragment implements Notificati if (AndroidUtilities.isTablet()) { childTop = getMeasuredHeight() - child.getMeasuredHeight(); } else { - childTop = getMeasuredHeight() + getKeyboardHeight() - child.getMeasuredHeight(); + childTop = getMeasuredHeight() + keyboardSize - child.getMeasuredHeight(); } } child.layout(childLeft, childTop, childLeft + width, childTop + height); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/LanguageSelectActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/LanguageSelectActivity.java index 39f3d50d1..ce97891bd 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/LanguageSelectActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/LanguageSelectActivity.java @@ -196,7 +196,7 @@ public class LanguageSelectActivity extends BaseFragment implements Notification listView.setOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { - if (newState == RecyclerView.SCROLL_STATE_DRAGGING && searching && searchWas) { + if (newState == RecyclerView.SCROLL_STATE_DRAGGING) { AndroidUtilities.hideKeyboard(getParentActivity().getCurrentFocus()); } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java index 9e76c215d..6dd2a4ff5 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java @@ -25,6 +25,7 @@ import android.graphics.Color; import android.graphics.Point; import android.graphics.Shader; import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.ColorDrawable; import android.net.Uri; import android.os.Build; import android.os.Bundle; @@ -231,7 +232,31 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa } } - getWindow().setBackgroundDrawableResource(R.drawable.transparent); + getWindow().setBackgroundDrawable(new ColorDrawable(0xffffffff) { + @Override + public void setBounds(int left, int top, int right, int bottom) { + bottom += AndroidUtilities.dp(500); + super.setBounds(left, top, right, bottom); + } + + @Override + public void draw(Canvas canvas) { + if (SharedConfig.smoothKeyboard) { + int color = getColor(); + int newColor; + if (PhotoViewer.hasInstance() && PhotoViewer.getInstance().isVisible()) { + newColor = 0xff000000; + } else { + newColor = Theme.getColor(Theme.key_windowBackgroundWhite); + } + if (color != newColor) { + setColor(newColor); + } + super.draw(canvas); + } + } + }); + if (SharedConfig.passcodeHash.length() > 0 && !SharedConfig.allowScreenCapture) { try { getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/LocationActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/LocationActivity.java index ae935d535..0cbf4f34f 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/LocationActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/LocationActivity.java @@ -405,7 +405,6 @@ public class LocationActivity extends BaseFragment implements NotificationCenter @Override public boolean onFragmentCreate() { super.onFragmentCreate(); - swipeBackEnabled = false; getNotificationCenter().addObserver(this, NotificationCenter.closeChats); NotificationCenter.getGlobalInstance().addObserver(this, NotificationCenter.locationPermissionGranted); if (messageObject != null && messageObject.isLiveLocation()) { @@ -452,6 +451,11 @@ public class LocationActivity extends BaseFragment implements NotificationCenter } } + @Override + public boolean isSwipeBackEnabled(MotionEvent event) { + return false; + } + @Override public View createView(Context context) { searchWas = false; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/MediaActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/MediaActivity.java index a78c7e908..f7fb68ca4 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/MediaActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/MediaActivity.java @@ -92,6 +92,7 @@ import org.telegram.ui.Components.NumberTextView; import org.telegram.ui.Components.RadialProgressView; import org.telegram.ui.Components.RecyclerListView; import org.telegram.ui.Components.ScrollSlidingTextTabStrip; +import org.telegram.ui.Components.SharedMediaLayout; import java.util.ArrayList; import java.util.Collections; @@ -164,8 +165,10 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No private boolean animatingForward; private boolean backAnimation; + private boolean swipeBackEnabled; + private long dialog_id; - private int columnsCount = 4; + private int columnsCount = 3; private static final Interpolator interpolator = t -> { --t; @@ -265,91 +268,7 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No } }; - public static class SharedMediaData { - private ArrayList messages = new ArrayList<>(); - private SparseArray[] messagesDict = new SparseArray[]{new SparseArray<>(), new SparseArray<>()}; - private ArrayList sections = new ArrayList<>(); - private HashMap> sectionArrays = new HashMap<>(); - private int totalCount; - private boolean loading; - private boolean[] endReached = new boolean[]{false, true}; - private int[] max_id = new int[]{0, 0}; - - public void setTotalCount(int count) { - totalCount = count; - } - - public void setMaxId(int num, int value) { - max_id[num] = value; - } - - public void setEndReached(int num, boolean value) { - endReached[num] = value; - } - - public boolean addMessage(MessageObject messageObject, int loadIndex, boolean isNew, boolean enc) { - if (messagesDict[loadIndex].indexOfKey(messageObject.getId()) >= 0) { - return false; - } - ArrayList messageObjects = sectionArrays.get(messageObject.monthKey); - if (messageObjects == null) { - messageObjects = new ArrayList<>(); - sectionArrays.put(messageObject.monthKey, messageObjects); - if (isNew) { - sections.add(0, messageObject.monthKey); - } else { - sections.add(messageObject.monthKey); - } - } - if (isNew) { - messageObjects.add(0, messageObject); - messages.add(0, messageObject); - } else { - messageObjects.add(messageObject); - messages.add(messageObject); - } - messagesDict[loadIndex].put(messageObject.getId(), messageObject); - if (!enc) { - if (messageObject.getId() > 0) { - max_id[loadIndex] = Math.min(messageObject.getId(), max_id[loadIndex]); - } - } else { - max_id[loadIndex] = Math.max(messageObject.getId(), max_id[loadIndex]); - } - return true; - } - - public boolean deleteMessage(int mid, int loadIndex) { - MessageObject messageObject = messagesDict[loadIndex].get(mid); - if (messageObject == null) { - return false; - } - ArrayList messageObjects = sectionArrays.get(messageObject.monthKey); - if (messageObjects == null) { - return false; - } - messageObjects.remove(messageObject); - messages.remove(messageObject); - messagesDict[loadIndex].remove(messageObject.getId()); - if (messageObjects.isEmpty()) { - sectionArrays.remove(messageObject.monthKey); - sections.remove(messageObject.monthKey); - } - totalCount--; - return true; - } - - public void replaceMid(int oldMid, int newMid) { - MessageObject obj = messagesDict[0].get(oldMid); - if (obj != null) { - messagesDict[0].remove(oldMid); - messagesDict[0].put(newMid, obj); - obj.messageOwner.id = newMid; - } - } - } - - private SharedMediaData[] sharedMediaData = new SharedMediaData[5]; + private SharedMediaLayout.SharedMediaData[] sharedMediaData = new SharedMediaLayout.SharedMediaData[5]; private final static int forward = 3; private final static int delete = 4; @@ -359,13 +278,13 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No this(args, media, null, MediaDataController.MEDIA_PHOTOVIDEO); } - public MediaActivity(Bundle args, int[] media, SharedMediaData[] mediaData, int initTab) { + public MediaActivity(Bundle args, int[] media, SharedMediaLayout.SharedMediaData[] mediaData, int initTab) { super(args); hasMedia = media; initialTab = initTab; dialog_id = args.getLong("dialog_id", 0); for (int a = 0; a < sharedMediaData.length; a++) { - sharedMediaData[a] = new SharedMediaData(); + sharedMediaData[a] = new SharedMediaLayout.SharedMediaData(); sharedMediaData[a].max_id[0] = ((int) dialog_id) == 0 ? Integer.MIN_VALUE : Integer.MAX_VALUE; if (mergeDialogId != 0 && info != null) { sharedMediaData[a].max_id[1] = info.migrated_from_max_id; @@ -373,13 +292,13 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No } if (mediaData != null) { sharedMediaData[a].totalCount = mediaData[a].totalCount; - //sharedMediaData[a].endReached = mediaData[a].endReached; sharedMediaData[a].messages.addAll(mediaData[a].messages); sharedMediaData[a].sections.addAll(mediaData[a].sections); for (HashMap.Entry> entry : mediaData[a].sectionArrays.entrySet()) { sharedMediaData[a].sectionArrays.put(entry.getKey(), new ArrayList<>(entry.getValue())); } for (int i = 0; i < 2; i++) { + sharedMediaData[a].endReached[i] = mediaData[a].endReached[i]; sharedMediaData[a].messagesDict[i] = mediaData[a].messagesDict[i].clone(); sharedMediaData[a].max_id[i] = mediaData[a].max_id[i]; } @@ -1181,7 +1100,7 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { - if (newState == RecyclerView.SCROLL_STATE_DRAGGING && searching && searchWas) { + if (newState == RecyclerView.SCROLL_STATE_DRAGGING) { AndroidUtilities.hideKeyboard(getParentActivity().getCurrentFocus()); } scrolling = newState != RecyclerView.SCROLL_STATE_IDLE; @@ -1343,6 +1262,7 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No return false; } } + private void setScrollY(float value) { actionBar.setTranslationY(value); if (fragmentContextView != null) { @@ -1470,7 +1390,7 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No boolean updated = false; for (int a = 0, N = markAsDeletedMessages.size(); a < N; a++) { for (int b = 0; b < sharedMediaData.length; b++) { - if (sharedMediaData[b].deleteMessage(markAsDeletedMessages.get(a), loadIndex)) { + if (sharedMediaData[b].deleteMessage(markAsDeletedMessages.get(a), loadIndex) != null) { updated = true; } } @@ -1554,8 +1474,8 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No } Integer msgId = (Integer) args[0]; Integer newMsgId = (Integer) args[1]; - for (SharedMediaData data : sharedMediaData) { - data.replaceMid(msgId, newMsgId); + for (int a = 0; a < sharedMediaData.length; a++) { + sharedMediaData[a].replaceMid(msgId, newMsgId); } } else if (id == NotificationCenter.messagePlayingDidStart || id == NotificationCenter.messagePlayingPlayStateChanged || id == NotificationCenter.messagePlayingDidReset) { if (id == NotificationCenter.messagePlayingDidReset || id == NotificationCenter.messagePlayingPlayStateChanged) { @@ -1612,6 +1532,11 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No } } + @Override + public boolean isSwipeBackEnabled(MotionEvent event) { + return swipeBackEnabled; + } + @Override public void onConfigurationChanged(android.content.res.Configuration newConfig) { super.onConfigurationChanged(newConfig); @@ -1772,23 +1697,23 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No scrollSlidingTextTabStrip.removeTabs(); if (hasMedia[0] != 0 || hasMedia[1] == 0 && hasMedia[2] == 0 && hasMedia[3] == 0 && hasMedia[4] == 0) { if (!scrollSlidingTextTabStrip.hasTab(0)) { - scrollSlidingTextTabStrip.addTextTab(0, LocaleController.getString("SharedMediaTab", R.string.SharedMediaTab)); + scrollSlidingTextTabStrip.addTextTab(0, LocaleController.getString("SharedMediaTab2", R.string.SharedMediaTab2)); } } if (hasMedia[1] != 0) { if (!scrollSlidingTextTabStrip.hasTab(1)) { - scrollSlidingTextTabStrip.addTextTab(1, LocaleController.getString("SharedFilesTab", R.string.SharedFilesTab)); + scrollSlidingTextTabStrip.addTextTab(1, LocaleController.getString("SharedFilesTab2", R.string.SharedFilesTab2)); } } if ((int) dialog_id != 0) { if (hasMedia[3] != 0) { if (!scrollSlidingTextTabStrip.hasTab(3)) { - scrollSlidingTextTabStrip.addTextTab(3, LocaleController.getString("SharedLinksTab", R.string.SharedLinksTab)); + scrollSlidingTextTabStrip.addTextTab(3, LocaleController.getString("SharedLinksTab2", R.string.SharedLinksTab2)); } } if (hasMedia[4] != 0) { if (!scrollSlidingTextTabStrip.hasTab(4)) { - scrollSlidingTextTabStrip.addTextTab(4, LocaleController.getString("SharedMusicTab", R.string.SharedMusicTab)); + scrollSlidingTextTabStrip.addTextTab(4, LocaleController.getString("SharedMusicTab2", R.string.SharedMusicTab2)); } } } else { @@ -1796,14 +1721,14 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No if (currentEncryptedChat != null && AndroidUtilities.getPeerLayerVersion(currentEncryptedChat.layer) >= 46) { if (hasMedia[4] != 0) { if (!scrollSlidingTextTabStrip.hasTab(4)) { - scrollSlidingTextTabStrip.addTextTab(4, LocaleController.getString("SharedMusicTab", R.string.SharedMusicTab)); + scrollSlidingTextTabStrip.addTextTab(4, LocaleController.getString("SharedMusicTab2", R.string.SharedMusicTab2)); } } } } if (hasMedia[2] != 0) { if (!scrollSlidingTextTabStrip.hasTab(2)) { - scrollSlidingTextTabStrip.addTextTab(2, LocaleController.getString("SharedVoiceTab", R.string.SharedVoiceTab)); + scrollSlidingTextTabStrip.addTextTab(2, LocaleController.getString("SharedVoiceTab2", R.string.SharedVoiceTab2)); } } } @@ -2177,14 +2102,14 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No } if (AndroidUtilities.isTablet()) { - columnsCount = 4; + columnsCount = 3; mediaPages[num].emptyTextView.setPadding(AndroidUtilities.dp(40), 0, AndroidUtilities.dp(40), AndroidUtilities.dp(128)); } else { if (rotation == Surface.ROTATION_270 || rotation == Surface.ROTATION_90) { columnsCount = 6; mediaPages[num].emptyTextView.setPadding(AndroidUtilities.dp(40), 0, AndroidUtilities.dp(40), 0); } else { - columnsCount = 4; + columnsCount = 3; mediaPages[num].emptyTextView.setPadding(AndroidUtilities.dp(40), 0, AndroidUtilities.dp(40), AndroidUtilities.dp(128)); } } @@ -2766,14 +2691,14 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No } else { for (int a = 0; a < mediaPages.length; a++) { if (mediaPages[a].selectedType == currentType) { - if (getItemCount() != 0) { - mediaPages[a].listView.setEmptyView(mediaPages[a].emptyView); - mediaPages[a].progressView.setVisibility(View.GONE); - } else { + //if (getItemCount() != 0) { + mediaPages[a].listView.setEmptyView(mediaPages[a].emptyView); + mediaPages[a].progressView.setVisibility(View.GONE); + /*} else { mediaPages[a].listView.setEmptyView(null); mediaPages[a].emptyView.setVisibility(View.GONE); mediaPages[a].progressView.setVisibility(View.VISIBLE); - } + }*/ } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/NotificationsCustomSettingsActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/NotificationsCustomSettingsActivity.java index 49aeb5476..899220357 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/NotificationsCustomSettingsActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/NotificationsCustomSettingsActivity.java @@ -527,7 +527,7 @@ public class NotificationsCustomSettingsActivity extends BaseFragment { listView.setOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { - if (newState == RecyclerView.SCROLL_STATE_DRAGGING && searching && searchWas) { + if (newState == RecyclerView.SCROLL_STATE_DRAGGING) { AndroidUtilities.hideKeyboard(getParentActivity().getCurrentFocus()); } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/PaymentFormActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/PaymentFormActivity.java index ff6c54fc6..213978011 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/PaymentFormActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/PaymentFormActivity.java @@ -185,6 +185,8 @@ public class PaymentFormActivity extends BaseFragment implements NotificationCen private boolean shouldNavigateBack; private ScrollView scrollView; + private boolean swipeBackEnabled = true; + private TextView textView; private HeaderCell[] headerCell = new HeaderCell[3]; private ArrayList dividers = new ArrayList<>(); @@ -3043,13 +3045,19 @@ public class PaymentFormActivity extends BaseFragment implements NotificationCen AndroidUtilities.runOnUIThread(() -> { NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.paymentFinished); setDonePressed(false); - webView.setVisibility(View.VISIBLE); webviewLoading = true; showEditDoneProgress(true, true); - progressView.setVisibility(View.VISIBLE); - doneItem.setEnabled(false); - doneItem.getContentView().setVisibility(View.INVISIBLE); - webView.loadUrl(webViewUrl = ((TLRPC.TL_payments_paymentVerificationNeeded) response).url); + if (progressView != null) { + progressView.setVisibility(View.VISIBLE); + } + if (doneItem != null) { + doneItem.setEnabled(false); + doneItem.getContentView().setVisibility(View.INVISIBLE); + } + if (webView != null) { + webView.setVisibility(View.VISIBLE); + webView.loadUrl(webViewUrl = ((TLRPC.TL_payments_paymentVerificationNeeded) response).url); + } }); } } else { @@ -3085,6 +3093,11 @@ public class PaymentFormActivity extends BaseFragment implements NotificationCen } } + @Override + public boolean isSwipeBackEnabled(MotionEvent event) { + return swipeBackEnabled; + } + private void checkPassword() { if (UserConfig.getInstance(currentAccount).tmpPassword != null) { if (UserConfig.getInstance(currentAccount).tmpPassword.valid_until < ConnectionsManager.getInstance(currentAccount).getCurrentTime() + 60) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/PeopleNearbyActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/PeopleNearbyActivity.java index f1f11542a..e018048b4 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/PeopleNearbyActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/PeopleNearbyActivity.java @@ -13,8 +13,11 @@ import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Paint; import android.graphics.drawable.Drawable; import android.location.Location; +import android.os.Build; import android.os.Bundle; import android.os.SystemClock; import android.util.TypedValue; @@ -33,6 +36,7 @@ import org.telegram.messenger.LocaleController; import org.telegram.messenger.LocationController; import org.telegram.messenger.NotificationCenter; import org.telegram.messenger.R; +import org.telegram.messenger.UserConfig; import org.telegram.tgnet.TLRPC; import org.telegram.ui.ActionBar.ActionBar; import org.telegram.ui.ActionBar.AlertDialog; @@ -61,6 +65,10 @@ public class PeopleNearbyActivity extends BaseFragment implements NotificationCe private RecyclerListView listView; private ActionIntroActivity groupCreateActivity; private UndoView undoView; + private LinearLayoutManager layoutManager; + + private View actionBarBackground; + private AnimatorSet actionBarAnimator; private String currentGroupCreateAddress; private String currentGroupCreateDisplayAddress; @@ -70,6 +78,8 @@ public class PeopleNearbyActivity extends BaseFragment implements NotificationCe private boolean canCreateGroup; private AlertDialog loadingDialog; + private boolean expanded; + private Runnable checkExpiredRunnable; private int reqId; @@ -88,7 +98,7 @@ public class PeopleNearbyActivity extends BaseFragment implements NotificationCe @Override public void run() { if (shortPollRunnable != null) { - sendRequest(true); + sendRequest(true, 0); AndroidUtilities.cancelRunOnUIThread(shortPollRunnable); AndroidUtilities.runOnUIThread(shortPollRunnable, SHORT_POLL_TIMEOUT); } @@ -99,12 +109,15 @@ public class PeopleNearbyActivity extends BaseFragment implements NotificationCe private ArrayList chats; private int currentChatId; + private boolean showingMe; private int helpRow; + private int helpSectionRow; private int usersHeaderRow; + private int showMeRow; private int usersStartRow; private int usersEndRow; - private int usersEmptyRow; + private int showMoreRow; private int usersSectionRow; private int chatsHeaderRow; private int chatsStartRow; @@ -125,19 +138,29 @@ public class PeopleNearbyActivity extends BaseFragment implements NotificationCe rowCount = 0; usersStartRow = -1; usersEndRow = -1; - usersEmptyRow = -1; + showMoreRow = -1; chatsStartRow = -1; chatsEndRow = -1; chatsCreateRow = -1; + showMeRow = -1; helpRow = rowCount++; + helpSectionRow = rowCount++; usersHeaderRow = rowCount++; - if (users.isEmpty()) { - usersEmptyRow = rowCount++; - } else { + showMeRow = rowCount++; + if (!users.isEmpty()) { + int count; + if (expanded) { + count = users.size(); + } else { + count = Math.min(5, users.size()); + } usersStartRow = rowCount; - rowCount += users.size(); + rowCount += count; usersEndRow = rowCount; + if (count != users.size()) { + showMoreRow = rowCount++; + } } usersSectionRow = rowCount++; @@ -162,7 +185,7 @@ public class PeopleNearbyActivity extends BaseFragment implements NotificationCe getNotificationCenter().addObserver(this, NotificationCenter.newPeopleNearbyAvailable); getNotificationCenter().addObserver(this, NotificationCenter.needDeleteDialog); checkCanCreateGroup(); - sendRequest(false); + sendRequest(false, 0); AndroidUtilities.runOnUIThread(shortPollRunnable, SHORT_POLL_TIMEOUT); return true; } @@ -193,8 +216,18 @@ public class PeopleNearbyActivity extends BaseFragment implements NotificationCe @Override public View createView(Context context) { actionBar.setBackButtonImage(R.drawable.ic_ab_back); - actionBar.setAllowOverlayTitle(true); + actionBar.setBackgroundDrawable(null); + actionBar.setTitleColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText)); + actionBar.setItemsColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText), false); + actionBar.setItemsBackgroundColor(Theme.getColor(Theme.key_listSelector), false); + actionBar.setCastShadows(false); + actionBar.setAddToContainer(false); + actionBar.setOccupyStatusBar(Build.VERSION.SDK_INT >= 21 && !AndroidUtilities.isTablet()); actionBar.setTitle(LocaleController.getString("PeopleNearby", R.string.PeopleNearby)); + actionBar.getTitleTextView().setAlpha(0.0f); + if (!AndroidUtilities.isTablet()) { + actionBar.showActionModeTop(); + } actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { @Override public void onItemClick(int id) { @@ -204,24 +237,45 @@ public class PeopleNearbyActivity extends BaseFragment implements NotificationCe } }); - fragmentView = new FrameLayout(context); + fragmentView = new FrameLayout(context) { + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) actionBarBackground.getLayoutParams(); + layoutParams.height = ActionBar.getCurrentActionBarHeight() + (actionBar.getOccupyStatusBar() ? AndroidUtilities.statusBarHeight : 0) + AndroidUtilities.dp(3); + + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + } + + @Override + protected void onLayout(boolean changed, int left, int top, int right, int bottom) { + super.onLayout(changed, left, top, right, bottom); + checkScroll(false); + } + }; fragmentView.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundGray)); fragmentView.setTag(Theme.key_windowBackgroundGray); FrameLayout frameLayout = (FrameLayout) fragmentView; listView = new RecyclerListView(context); - listView.setLayoutManager(new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)); + listView.setGlowColor(0); + listView.setLayoutManager(layoutManager = new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)); listView.setAdapter(listViewAdapter = new ListAdapter(context)); listView.setVerticalScrollbarPosition(LocaleController.isRTL ? RecyclerListView.SCROLLBAR_POSITION_LEFT : RecyclerListView.SCROLLBAR_POSITION_RIGHT); frameLayout.addView(listView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT)); listView.setOnItemClickListener((view, position) -> { + if (getParentActivity() == null) { + return; + } if (position >= usersStartRow && position < usersEndRow) { + ManageChatUserCell cell = (ManageChatUserCell) view; TLRPC.TL_peerLocated peerLocated = users.get(position - usersStartRow); Bundle args1 = new Bundle(); args1.putInt("user_id", peerLocated.peer.user_id); - ChatActivity chatActivity = new ChatActivity(args1); - presentFragment(chatActivity); + if (cell.hasAvatarSet()) { + args1.putBoolean("expandPhoto", true); + } + presentFragment(new ProfileActivity(args1)); } else if (position >= chatsStartRow && position < chatsEndRow) { TLRPC.TL_peerLocated peerLocated = chats.get(position - chatsStartRow); Bundle args1 = new Bundle(); @@ -242,8 +296,54 @@ public class PeopleNearbyActivity extends BaseFragment implements NotificationCe return; } openGroupCreate(); + } else if (position == showMeRow) { + UserConfig userConfig = getUserConfig(); + if (showingMe) { + userConfig.sharingMyLocationUntil = 0; + userConfig.saveConfig(false); + sendRequest(false, 2); + updateRows(); + } else { + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setTitle(LocaleController.getString("MakeMyselfVisibleTitle", R.string.MakeMyselfVisibleTitle)); + builder.setMessage(LocaleController.getString("MakeMyselfVisibleInfo", R.string.MakeMyselfVisibleInfo)); + builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), (dialog, which) -> { + userConfig.sharingMyLocationUntil = 0x7fffffff; + userConfig.saveConfig(false); + sendRequest(false, 1); + updateRows(); + }); + builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); + showDialog(builder.create()); + } + userConfig.saveConfig(false); + } else if (position == showMoreRow) { + expanded = true; + updateRows(); } }); + listView.setOnScrollListener(new RecyclerView.OnScrollListener() { + @Override + public void onScrolled(RecyclerView recyclerView, int dx, int dy) { + checkScroll(true); + } + }); + + actionBarBackground = new View(context) { + + private Paint paint = new Paint(); + + @Override + protected void onDraw(Canvas canvas) { + paint.setColor(Theme.getColor(Theme.key_windowBackgroundWhite)); + int h = getMeasuredHeight() - AndroidUtilities.dp(3); + canvas.drawRect(0, 0, getMeasuredWidth(), h, paint); + parentLayout.drawHeaderShadow(canvas, h); + } + }; + actionBarBackground.setAlpha(0.0f); + frameLayout.addView(actionBarBackground, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT)); + frameLayout.addView(actionBar, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT)); undoView = new UndoView(context); frameLayout.addView(undoView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.BOTTOM | Gravity.LEFT, 8, 0, 8, 8)); @@ -252,6 +352,52 @@ public class PeopleNearbyActivity extends BaseFragment implements NotificationCe return fragmentView; } + private int[] location = new int[2]; + private void checkScroll(boolean animated) { + int first = layoutManager.findFirstVisibleItemPosition(); + boolean show; + if (first != 0) { + show = true; + } else { + RecyclerView.ViewHolder holder = listView.findViewHolderForAdapterPosition(first); + if (holder == null) { + show = true; + } else { + HintInnerCell hintInnerCell = (HintInnerCell) holder.itemView; + hintInnerCell.titleTextView.getLocationOnScreen(location); + show = location[1] + hintInnerCell.titleTextView.getMeasuredHeight() < actionBar.getBottom(); + } + } + boolean visible = actionBarBackground.getTag() == null; + if (show != visible) { + actionBarBackground.setTag(show ? null : 1); + if (actionBarAnimator != null) { + actionBarAnimator.cancel(); + actionBarAnimator = null; + } + if (animated) { + actionBarAnimator = new AnimatorSet(); + actionBarAnimator.playTogether( + ObjectAnimator.ofFloat(actionBarBackground, View.ALPHA, show ? 1.0f : 0.0f), + ObjectAnimator.ofFloat(actionBar.getTitleTextView(), View.ALPHA, show ? 1.0f : 0.0f) + ); + actionBarAnimator.setDuration(150); + actionBarAnimator.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + if (animation.equals(actionBarAnimator)) { + actionBarAnimator = null; + } + } + }); + actionBarAnimator.start(); + } else { + actionBarBackground.setAlpha(show ? 1.0f : 0.0f); + actionBar.getTitleTextView().setAlpha(show ? 1.0f : 0.0f); + } + } + } + private void openGroupCreate() { if (!canCreateGroup) { AlertsCreator.showSimpleAlert(PeopleNearbyActivity.this, LocaleController.getString("YourLocatedChannelsTooMuch", R.string.YourLocatedChannelsTooMuch)); @@ -324,7 +470,7 @@ public class PeopleNearbyActivity extends BaseFragment implements NotificationCe showProgressAnimation.start(); } - private void sendRequest(boolean shortpoll) { + private void sendRequest(boolean shortpoll, int share) { if (!firstLoaded) { AndroidUtilities.runOnUIThread(showProgressRunnable = () -> { showLoadingProgress(true); @@ -342,7 +488,7 @@ public class PeopleNearbyActivity extends BaseFragment implements NotificationCe if (BuildVars.DEBUG_VERSION) { FileLog.d("located distance = " + distance); } - if ((SystemClock.elapsedRealtime() - lastLoadedLocationTime) >= 3000L && lastLoadedLocation.distanceTo(location) > 20) { + if (share != 0 || (SystemClock.elapsedRealtime() - lastLoadedLocationTime) >= 3000L && lastLoadedLocation.distanceTo(location) > 20) { if (reqId != 0) { getConnectionsManager().cancelRequest(reqId, true); reqId = 0; @@ -361,6 +507,10 @@ public class PeopleNearbyActivity extends BaseFragment implements NotificationCe req.geo_point = new TLRPC.TL_inputGeoPoint(); req.geo_point.lat = location.getLatitude(); req.geo_point._long = location.getLongitude(); + if (share != 0) { + req.flags |= 1; + req.self_expires = share == 1 ? 0x7fffffff : 0; + } reqId = getConnectionsManager().sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> { reqId = 0; if (showProgressRunnable != null) { @@ -368,26 +518,50 @@ public class PeopleNearbyActivity extends BaseFragment implements NotificationCe showProgressRunnable = null; } showLoadingProgress(false); - if (response != null) { + if (response != null && share != 2) { TLRPC.Updates updates = (TLRPC.TL_updates) response; getMessagesController().putUsers(updates.users, false); getMessagesController().putChats(updates.chats, false); users.clear(); chats.clear(); + boolean hasSelf = false; + UserConfig userConfig = getUserConfig(); + boolean saveConfig = false; + if (userConfig.sharingMyLocationUntil != 0) { + userConfig.lastMyLocationShareTime = (int) (System.currentTimeMillis() / 1000); + saveConfig = true; + } for (int a = 0, N = updates.updates.size(); a < N; a++) { TLRPC.Update baseUpdate = updates.updates.get(a); if (baseUpdate instanceof TLRPC.TL_updatePeerLocated) { TLRPC.TL_updatePeerLocated update = (TLRPC.TL_updatePeerLocated) baseUpdate; for (int b = 0, N2 = update.peers.size(); b < N2; b++) { - TLRPC.TL_peerLocated peerLocated = update.peers.get(b); - if (peerLocated.peer instanceof TLRPC.TL_peerUser) { - users.add(peerLocated); - } else { - chats.add(peerLocated); + TLRPC.PeerLocated object = update.peers.get(b); + if (object instanceof TLRPC.TL_peerLocated) { + TLRPC.TL_peerLocated peerLocated = (TLRPC.TL_peerLocated) object; + if (peerLocated.peer instanceof TLRPC.TL_peerUser) { + users.add(peerLocated); + } else { + chats.add(peerLocated); + } + } else if (object instanceof TLRPC.TL_peerSelfLocated) { + hasSelf = true; + TLRPC.TL_peerSelfLocated peerSelfLocated = (TLRPC.TL_peerSelfLocated) object; + if (userConfig.sharingMyLocationUntil != peerSelfLocated.expires) { + userConfig.sharingMyLocationUntil = peerSelfLocated.expires; + saveConfig = true; + } } } } } + if (!hasSelf && userConfig.sharingMyLocationUntil != 0) { + userConfig.sharingMyLocationUntil = 0; + saveConfig = true; + } + if (saveConfig) { + userConfig.saveConfig(false); + } checkForExpiredLocations(true); updateRows(); } @@ -453,27 +627,30 @@ public class PeopleNearbyActivity extends BaseFragment implements NotificationCe @Override public void didReceivedNotification(int id, int account, Object... args) { if (id == NotificationCenter.newLocationAvailable) { - sendRequest(false); + sendRequest(false, 0); } else if (id == NotificationCenter.newPeopleNearbyAvailable) { TLRPC.TL_updatePeerLocated update = (TLRPC.TL_updatePeerLocated) args[0]; for (int b = 0, N2 = update.peers.size(); b < N2; b++) { - TLRPC.TL_peerLocated peerLocated = update.peers.get(b); - boolean found = false; - ArrayList arrayList; - if (peerLocated.peer instanceof TLRPC.TL_peerUser) { - arrayList = users; - } else { - arrayList = chats; - } - for (int a = 0, N = arrayList.size(); a < N; a++) { - TLRPC.TL_peerLocated old = arrayList.get(a); - if (old.peer.user_id != 0 && old.peer.user_id == peerLocated.peer.user_id || old.peer.chat_id != 0 && old.peer.chat_id == peerLocated.peer.chat_id || old.peer.channel_id != 0 && old.peer.channel_id == peerLocated.peer.channel_id) { - arrayList.set(a, peerLocated); - found = true; + TLRPC.PeerLocated object = update.peers.get(b); + if (object instanceof TLRPC.TL_peerLocated) { + TLRPC.TL_peerLocated peerLocated = (TLRPC.TL_peerLocated) object; + boolean found = false; + ArrayList arrayList; + if (peerLocated.peer instanceof TLRPC.TL_peerUser) { + arrayList = users; + } else { + arrayList = chats; + } + for (int a = 0, N = arrayList.size(); a < N; a++) { + TLRPC.TL_peerLocated old = arrayList.get(a); + if (old.peer.user_id != 0 && old.peer.user_id == peerLocated.peer.user_id || old.peer.chat_id != 0 && old.peer.chat_id == peerLocated.peer.chat_id || old.peer.channel_id != 0 && old.peer.channel_id == peerLocated.peer.channel_id) { + arrayList.set(a, peerLocated); + found = true; + } + } + if (!found) { + arrayList.add(peerLocated); } - } - if (!found) { - arrayList.add(peerLocated); } } checkForExpiredLocations(true); @@ -559,26 +736,37 @@ public class PeopleNearbyActivity extends BaseFragment implements NotificationCe } } + @SuppressWarnings("FieldCanBeLocal") public class HintInnerCell extends FrameLayout { private ImageView imageView; + private TextView titleTextView; private TextView messageTextView; public HintInnerCell(Context context) { super(context); + int top = (int) ((ActionBar.getCurrentActionBarHeight() + (actionBar.getOccupyStatusBar() ? AndroidUtilities.statusBarHeight : 0)) / AndroidUtilities.density) - 44; + imageView = new ImageView(context); imageView.setBackgroundDrawable(Theme.createCircleDrawable(AndroidUtilities.dp(74), Theme.getColor(Theme.key_chats_archiveBackground))); imageView.setImageDrawable(new ShareLocationDrawable(context, 2)); imageView.setScaleType(ImageView.ScaleType.CENTER); - addView(imageView, LayoutHelper.createFrame(74, 74, Gravity.TOP | Gravity.CENTER_HORIZONTAL, 0, 27, 0, 0)); + addView(imageView, LayoutHelper.createFrame(74, 74, Gravity.TOP | Gravity.CENTER_HORIZONTAL, 0, top + 27, 0, 0)); + + titleTextView = new TextView(context); + titleTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText)); + titleTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 24); + titleTextView.setGravity(Gravity.CENTER); + titleTextView.setText(AndroidUtilities.replaceTags(LocaleController.formatString("PeopleNearby", R.string.PeopleNearby))); + addView(titleTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.TOP | Gravity.LEFT, 52, top + 120, 52, 27)); messageTextView = new TextView(context); - messageTextView.setTextColor(Theme.getColor(Theme.key_chats_message)); - messageTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); + messageTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText)); + messageTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15); messageTextView.setGravity(Gravity.CENTER); - messageTextView.setText(AndroidUtilities.replaceTags(LocaleController.formatString("PeopleNearbyInfo", R.string.PeopleNearbyInfo))); - addView(messageTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.TOP | Gravity.LEFT, 52, 125, 52, 27)); + messageTextView.setText(AndroidUtilities.replaceTags(LocaleController.formatString("PeopleNearbyInfo2", R.string.PeopleNearbyInfo2))); + addView(messageTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.TOP | Gravity.LEFT, 40, top + 161, 40, 27)); } } @@ -610,7 +798,7 @@ public class PeopleNearbyActivity extends BaseFragment implements NotificationCe view.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite)); break; case 1: - view = new ShadowSectionCell(mContext, 22); + view = new ShadowSectionCell(mContext); break; case 2: view = new ManageChatTextCell(mContext); @@ -637,6 +825,7 @@ public class PeopleNearbyActivity extends BaseFragment implements NotificationCe case 5: default: view = new HintInnerCell(mContext); + view.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite)); break; } view.setLayoutParams(new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); @@ -666,7 +855,7 @@ public class PeopleNearbyActivity extends BaseFragment implements NotificationCe TLRPC.TL_peerLocated peerLocated = users.get(index); TLRPC.User user = getMessagesController().getUser(peerLocated.peer.user_id); if (user != null) { - userCell.setData(user, null, formatDistance(peerLocated), index != users.size() - 1); + userCell.setData(user, null, formatDistance(peerLocated), showMoreRow != -1 || position != usersEndRow - 1); } } else if (position >= chatsStartRow && position < chatsEndRow) { int index = position - chatsStartRow; @@ -693,6 +882,8 @@ public class PeopleNearbyActivity extends BaseFragment implements NotificationCe privacyCell.setBackgroundDrawable(Theme.getThemedDrawable(mContext, R.drawable.greydivider, Theme.key_windowBackgroundGrayShadow)); } else if (position == chatsSectionRow) { privacyCell.setBackgroundDrawable(Theme.getThemedDrawable(mContext, R.drawable.greydivider_bottom, Theme.key_windowBackgroundGrayShadow)); + } else if (position == helpSectionRow) { + privacyCell.setBackgroundDrawable(Theme.getThemedDrawable(mContext, R.drawable.greydivider, Theme.key_windowBackgroundGrayShadow)); } break; case 2: @@ -700,6 +891,15 @@ public class PeopleNearbyActivity extends BaseFragment implements NotificationCe actionCell.setColors(Theme.key_windowBackgroundWhiteBlueIcon, Theme.key_windowBackgroundWhiteBlueButton); if (position == chatsCreateRow) { actionCell.setText(LocaleController.getString("NearbyCreateGroup", R.string.NearbyCreateGroup), null, R.drawable.groups_create, chatsStartRow != -1); + } else if (position == showMeRow) { + if (showingMe = (getUserConfig().sharingMyLocationUntil > getConnectionsManager().getCurrentTime())) { + actionCell.setText(LocaleController.getString("StopShowingMe", R.string.StopShowingMe), null, R.drawable.actions_nearby_off, chatsStartRow != -1); + actionCell.setColors(Theme.key_windowBackgroundWhiteRedText5, Theme.key_windowBackgroundWhiteRedText5); + } else { + actionCell.setText(LocaleController.getString("MakeMyselfVisible", R.string.MakeMyselfVisible), null, R.drawable.actions_nearby_on, usersStartRow != -1); + } + } else if (position == showMoreRow) { + actionCell.setText(LocaleController.formatPluralString("ShowVotes", users.size() - 5), null, R.drawable.arrow_more, false); } break; case 3: @@ -710,12 +910,6 @@ public class PeopleNearbyActivity extends BaseFragment implements NotificationCe headerCell.setText(LocaleController.getString("ChatsNearbyHeader", R.string.ChatsNearbyHeader)); } break; - case 4: - TextView textView = (TextView) holder.itemView; - if (position == usersEmptyRow) { - textView.setText(AndroidUtilities.replaceTags(LocaleController.getString("PeopleNearbyEmpty", R.string.PeopleNearbyEmpty))); - } - break; } } @@ -730,14 +924,12 @@ public class PeopleNearbyActivity extends BaseFragment implements NotificationCe public int getItemViewType(int position) { if (position == helpRow) { return 5; - } else if (position == chatsCreateRow) { + } else if (position == chatsCreateRow || position == showMeRow || position == showMoreRow) { return 2; } else if (position == usersHeaderRow || position == chatsHeaderRow) { return 3; - } else if (position == usersSectionRow || position == chatsSectionRow) { + } else if (position == usersSectionRow || position == chatsSectionRow || position == helpSectionRow) { return 1; - } else if (position == usersEmptyRow) { - return 4; } return 0; } @@ -758,15 +950,14 @@ public class PeopleNearbyActivity extends BaseFragment implements NotificationCe }; return new ThemeDescription[]{ - new ThemeDescription(listView, ThemeDescription.FLAG_CELLBACKGROUNDCOLOR, new Class[]{ManageChatUserCell.class, ManageChatTextCell.class, HeaderCell.class, TextView.class}, null, null, null, Theme.key_windowBackgroundWhite), + new ThemeDescription(listView, ThemeDescription.FLAG_CELLBACKGROUNDCOLOR, new Class[]{ManageChatUserCell.class, ManageChatTextCell.class, HeaderCell.class, TextView.class, HintInnerCell.class}, null, null, null, Theme.key_windowBackgroundWhite), new ThemeDescription(fragmentView, ThemeDescription.FLAG_BACKGROUND | ThemeDescription.FLAG_CHECKTAG, null, null, null, null, Theme.key_windowBackgroundGray), new ThemeDescription(fragmentView, ThemeDescription.FLAG_BACKGROUND | ThemeDescription.FLAG_CHECKTAG, null, null, null, null, Theme.key_windowBackgroundWhite), - new ThemeDescription(actionBar, ThemeDescription.FLAG_BACKGROUND, null, null, null, null, Theme.key_actionBarDefault), - new ThemeDescription(listView, ThemeDescription.FLAG_LISTGLOWCOLOR, null, null, null, null, Theme.key_actionBarDefault), - new ThemeDescription(actionBar, ThemeDescription.FLAG_AB_ITEMSCOLOR, null, null, null, null, Theme.key_actionBarDefaultIcon), - new ThemeDescription(actionBar, ThemeDescription.FLAG_AB_TITLECOLOR, null, null, null, null, Theme.key_actionBarDefaultTitle), - new ThemeDescription(actionBar, ThemeDescription.FLAG_AB_SELECTORCOLOR, null, null, null, null, Theme.key_actionBarDefaultSelector), + new ThemeDescription(actionBarBackground, ThemeDescription.FLAG_BACKGROUND, null, null, null, null, Theme.key_windowBackgroundWhite), + new ThemeDescription(actionBar, ThemeDescription.FLAG_AB_ITEMSCOLOR, null, null, null, null, Theme.key_windowBackgroundWhiteBlackText), + new ThemeDescription(actionBar, ThemeDescription.FLAG_AB_TITLECOLOR, null, null, null, null, Theme.key_windowBackgroundWhiteBlackText), + new ThemeDescription(actionBar, ThemeDescription.FLAG_AB_SELECTORCOLOR, null, null, null, null, Theme.key_listSelector), new ThemeDescription(listView, ThemeDescription.FLAG_SELECTOR, null, null, null, null, Theme.key_listSelector), @@ -796,6 +987,8 @@ public class PeopleNearbyActivity extends BaseFragment implements NotificationCe new ThemeDescription(listView, ThemeDescription.FLAG_CHECKTAG, new Class[]{ManageChatTextCell.class}, new String[]{"imageView"}, null, null, null, Theme.key_windowBackgroundWhiteGrayIcon), new ThemeDescription(listView, ThemeDescription.FLAG_CHECKTAG, new Class[]{ManageChatTextCell.class}, new String[]{"imageView"}, null, null, null, Theme.key_windowBackgroundWhiteBlueButton), new ThemeDescription(listView, ThemeDescription.FLAG_CHECKTAG, new Class[]{ManageChatTextCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteBlueIcon), + new ThemeDescription(listView, ThemeDescription.FLAG_CHECKTAG, new Class[]{ManageChatTextCell.class}, new String[]{"imageView"}, null, null, null, Theme.key_windowBackgroundWhiteRedText5), + new ThemeDescription(listView, ThemeDescription.FLAG_CHECKTAG, new Class[]{ManageChatTextCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteRedText5), new ThemeDescription(undoView, ThemeDescription.FLAG_BACKGROUNDFILTER, null, null, null, null, Theme.key_undo_background), new ThemeDescription(undoView, 0, new Class[]{UndoView.class}, new String[]{"undoImageView"}, null, null, null, Theme.key_undo_cancelColor), diff --git a/TMessagesProj/src/main/java/org/telegram/ui/PhotoAlbumPickerActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/PhotoAlbumPickerActivity.java index 2be4a748e..7e0af80c1 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/PhotoAlbumPickerActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/PhotoAlbumPickerActivity.java @@ -43,6 +43,7 @@ import org.telegram.messenger.NotificationCenter; import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.R; import org.telegram.messenger.SendMessagesHelper; +import org.telegram.messenger.SharedConfig; import org.telegram.messenger.UserConfig; import org.telegram.messenger.UserObject; import org.telegram.tgnet.TLRPC; @@ -180,7 +181,7 @@ public class PhotoAlbumPickerActivity extends BaseFragment implements Notificati menuItem.setContentDescription(LocaleController.getString("AccDescrMoreOptions", R.string.AccDescrMoreOptions)); menuItem.addSubItem(1, R.drawable.msg_openin, LocaleController.getString("OpenInExternalApp", R.string.OpenInExternalApp)); - sizeNotifierFrameLayout = new SizeNotifierFrameLayout(context) { + sizeNotifierFrameLayout = new SizeNotifierFrameLayout(context, SharedConfig.smoothKeyboard) { private int lastNotifyWidth; private boolean ignoreLayout; @@ -192,7 +193,7 @@ public class PhotoAlbumPickerActivity extends BaseFragment implements Notificati setMeasuredDimension(widthSize, heightSize); - int keyboardSize = getKeyboardHeight(); + int keyboardSize = SharedConfig.smoothKeyboard ? 0 : getKeyboardHeight(); if (keyboardSize <= AndroidUtilities.dp(20)) { if (!AndroidUtilities.isInMultiwindow) { heightSize -= commentTextView.getEmojiPadding(); @@ -236,7 +237,8 @@ public class PhotoAlbumPickerActivity extends BaseFragment implements Notificati } final int count = getChildCount(); - int paddingBottom = getKeyboardHeight() <= AndroidUtilities.dp(20) && !AndroidUtilities.isInMultiwindow && !AndroidUtilities.isTablet() ? commentTextView.getEmojiPadding() : 0; + int keyboardSize = SharedConfig.smoothKeyboard ? 0 : getKeyboardHeight(); + int paddingBottom = keyboardSize <= AndroidUtilities.dp(20) && !AndroidUtilities.isInMultiwindow && !AndroidUtilities.isTablet() ? commentTextView.getEmojiPadding() : 0; setBottomClip(paddingBottom); for (int i = 0; i < count; i++) { @@ -290,7 +292,7 @@ public class PhotoAlbumPickerActivity extends BaseFragment implements Notificati if (AndroidUtilities.isTablet()) { childTop = getMeasuredHeight() - child.getMeasuredHeight(); } else { - childTop = getMeasuredHeight() + getKeyboardHeight() - child.getMeasuredHeight(); + childTop = getMeasuredHeight() + keyboardSize - child.getMeasuredHeight(); } } child.layout(childLeft, childTop, childLeft + width, childTop + height); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/PhotoCropActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/PhotoCropActivity.java index c1fb4ea0b..b65943a65 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/PhotoCropActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/PhotoCropActivity.java @@ -372,7 +372,6 @@ public class PhotoCropActivity extends BaseFragment { @Override public boolean onFragmentCreate() { - swipeBackEnabled = false; if (imageToCrop == null) { String photoPath = getArguments().getString("photoPath"); Uri photoUri = getArguments().getParcelable("photoUri"); @@ -454,6 +453,11 @@ public class PhotoCropActivity extends BaseFragment { return fragmentView; } + @Override + public boolean isSwipeBackEnabled(MotionEvent event) { + return false; + } + public void setDelegate(PhotoEditActivityDelegate delegate) { this.delegate = delegate; } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/PhotoPickerActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/PhotoPickerActivity.java index ac81ff909..17abe8a8c 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/PhotoPickerActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/PhotoPickerActivity.java @@ -55,6 +55,7 @@ import org.telegram.messenger.MediaController; import org.telegram.messenger.MessagesController; import org.telegram.messenger.MessagesStorage; import org.telegram.messenger.NotificationCenter; +import org.telegram.messenger.SharedConfig; import org.telegram.messenger.UserConfig; import org.telegram.messenger.UserObject; import org.telegram.messenger.VideoEditedInfo; @@ -543,7 +544,7 @@ public class PhotoPickerActivity extends BaseFragment implements NotificationCen } } - sizeNotifierFrameLayout = new SizeNotifierFrameLayout(context) { + sizeNotifierFrameLayout = new SizeNotifierFrameLayout(context, SharedConfig.smoothKeyboard) { private int lastNotifyWidth; private boolean ignoreLayout; @@ -585,18 +586,26 @@ public class PhotoPickerActivity extends BaseFragment implements NotificationCen setMeasuredDimension(widthSize, heightSize); - int keyboardSize = getKeyboardHeight(); + int kbHeight = getKeyboardHeight(); + int keyboardSize = SharedConfig.smoothKeyboard ? 0 : kbHeight; if (keyboardSize <= AndroidUtilities.dp(20)) { if (!AndroidUtilities.isInMultiwindow && commentTextView != null && frameLayout2.getParent() == this) { heightSize -= commentTextView.getEmojiPadding(); heightMeasureSpec = MeasureSpec.makeMeasureSpec(heightSize, MeasureSpec.EXACTLY); } - } else if (commentTextView != null) { + } + if (kbHeight > AndroidUtilities.dp(20) && commentTextView != null) { ignoreLayout = true; commentTextView.hideEmojiView(); ignoreLayout = false; } + if (SharedConfig.smoothKeyboard && commentTextView != null && commentTextView.isPopupShowing()) { + fragmentView.setTranslationY(getCurrentPanTranslationY()); + listView.setTranslationY(0); + emptyView.setTranslationY(0); + } + int childCount = getChildCount(); for (int i = 0; i < childCount; i++) { View child = getChildAt(i); @@ -632,7 +641,8 @@ public class PhotoPickerActivity extends BaseFragment implements NotificationCen } final int count = getChildCount(); - int paddingBottom = commentTextView != null && frameLayout2.getParent() == this && getKeyboardHeight() <= AndroidUtilities.dp(20) && !AndroidUtilities.isInMultiwindow && !AndroidUtilities.isTablet() ? commentTextView.getEmojiPadding() : 0; + int keyboardSize = SharedConfig.smoothKeyboard ? 0 : getKeyboardHeight(); + int paddingBottom = commentTextView != null && frameLayout2.getParent() == this && keyboardSize <= AndroidUtilities.dp(20) && !AndroidUtilities.isInMultiwindow && !AndroidUtilities.isTablet() ? commentTextView.getEmojiPadding() : 0; setBottomClip(paddingBottom); for (int i = 0; i < count; i++) { @@ -686,7 +696,7 @@ public class PhotoPickerActivity extends BaseFragment implements NotificationCen if (AndroidUtilities.isTablet()) { childTop = getMeasuredHeight() - child.getMeasuredHeight(); } else { - childTop = getMeasuredHeight() + getKeyboardHeight() - child.getMeasuredHeight(); + childTop = getMeasuredHeight() + keyboardSize - child.getMeasuredHeight(); } } child.layout(childLeft, childTop, childLeft + width, childTop + height); @@ -866,17 +876,17 @@ public class PhotoPickerActivity extends BaseFragment implements NotificationCen } sizeNotifierFrameLayout.addView(emptyView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.LEFT | Gravity.TOP, 0, 0, 0, selectPhotoType != 0 ? 0 : 48)); - if (selectedAlbum == null) { - listView.setOnScrollListener(new RecyclerView.OnScrollListener() { - @Override - public void onScrollStateChanged(RecyclerView recyclerView, int newState) { - if (newState == RecyclerView.SCROLL_STATE_DRAGGING) { - AndroidUtilities.hideKeyboard(getParentActivity().getCurrentFocus()); - } + listView.setOnScrollListener(new RecyclerView.OnScrollListener() { + @Override + public void onScrollStateChanged(RecyclerView recyclerView, int newState) { + if (newState == RecyclerView.SCROLL_STATE_DRAGGING) { + AndroidUtilities.hideKeyboard(getParentActivity().getCurrentFocus()); } + } - @Override - public void onScrolled(RecyclerView recyclerView, int dx, int dy) { + @Override + public void onScrolled(RecyclerView recyclerView, int dx, int dy) { + if (selectedAlbum == null) { int firstVisibleItem = layoutManager.findFirstVisibleItemPosition(); int visibleItemCount = firstVisibleItem == RecyclerView.NO_POSITION ? 0 : Math.abs(layoutManager.findLastVisibleItemPosition() - firstVisibleItem) + 1; if (visibleItemCount > 0) { @@ -888,8 +898,10 @@ public class PhotoPickerActivity extends BaseFragment implements NotificationCen } } } - }); + } + }); + if (selectedAlbum == null) { updateSearchInterface(); } @@ -1108,6 +1120,21 @@ public class PhotoPickerActivity extends BaseFragment implements NotificationCen return fragmentView; } + @Override + protected void onPanTranslationUpdate(int y) { + if (listView == null) { + return; + } + if (commentTextView.isPopupShowing()) { + fragmentView.setTranslationY(y); + listView.setTranslationY(0); + emptyView.setTranslationY(0); + } else { + listView.setTranslationY(y); + emptyView.setTranslationY(y); + } + } + public void setLayoutViews(FrameLayout f2, FrameLayout button, View count, View s, EditTextEmoji emoji) { frameLayout2 = f2; writeButtonContainer = button; @@ -1173,7 +1200,7 @@ public class PhotoPickerActivity extends BaseFragment implements NotificationCen initialSearchString = null; processSearch(searchItem.getSearchField()); } - getParentActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); + getParentActivity().getWindow().setSoftInputMode(SharedConfig.smoothKeyboard ? WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN : WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/PhotoPickerSearchActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/PhotoPickerSearchActivity.java index d1f17682c..e0d33c92d 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/PhotoPickerSearchActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/PhotoPickerSearchActivity.java @@ -23,6 +23,7 @@ import android.widget.TextView; import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.LocaleController; import org.telegram.messenger.R; +import org.telegram.messenger.SharedConfig; import org.telegram.ui.ActionBar.ActionBar; import org.telegram.ui.ActionBar.ActionBarMenu; import org.telegram.ui.ActionBar.ActionBarMenuItem; @@ -66,6 +67,8 @@ public class PhotoPickerSearchActivity extends BaseFragment { private int selectPhotoType; private ChatActivity chatActivity; + private boolean swipeBackEnabled = true; + private final static int search_button = 0; private Paint backgroundPaint = new Paint(); @@ -193,7 +196,7 @@ public class PhotoPickerSearchActivity extends BaseFragment { maximumVelocity = configuration.getScaledMaximumFlingVelocity(); SizeNotifierFrameLayout sizeNotifierFrameLayout; - fragmentView = sizeNotifierFrameLayout = new SizeNotifierFrameLayout(context) { + fragmentView = sizeNotifierFrameLayout = new SizeNotifierFrameLayout(context, SharedConfig.smoothKeyboard) { private int startedTrackingPointerId; private boolean startedTracking; @@ -239,7 +242,7 @@ public class PhotoPickerSearchActivity extends BaseFragment { setMeasuredDimension(widthSize, heightSize); measureChildWithMargins(actionBar, widthMeasureSpec, 0, heightMeasureSpec, 0); - int keyboardSize = getKeyboardHeight(); + int keyboardSize = SharedConfig.smoothKeyboard ? 0 : getKeyboardHeight(); if (keyboardSize <= AndroidUtilities.dp(20)) { if (!AndroidUtilities.isInMultiwindow) { heightSize -= commentTextView.getEmojiPadding(); @@ -289,7 +292,8 @@ public class PhotoPickerSearchActivity extends BaseFragment { protected void onLayout(boolean changed, int l, int t, int r, int b) { final int count = getChildCount(); - int paddingBottom = getKeyboardHeight() <= AndroidUtilities.dp(20) && !AndroidUtilities.isInMultiwindow && !AndroidUtilities.isTablet() ? commentTextView.getEmojiPadding() : 0; + int keyboardSize = SharedConfig.smoothKeyboard ? 0 : getKeyboardHeight(); + int paddingBottom = keyboardSize <= AndroidUtilities.dp(20) && !AndroidUtilities.isInMultiwindow && !AndroidUtilities.isTablet() ? commentTextView.getEmojiPadding() : 0; setBottomClip(paddingBottom); for (int i = 0; i < count; i++) { @@ -343,7 +347,7 @@ public class PhotoPickerSearchActivity extends BaseFragment { if (AndroidUtilities.isTablet()) { childTop = getMeasuredHeight() - child.getMeasuredHeight(); } else { - childTop = getMeasuredHeight() + getKeyboardHeight() - child.getMeasuredHeight(); + childTop = getMeasuredHeight() + keyboardSize - child.getMeasuredHeight(); } } child.layout(childLeft, childTop, childLeft + width, childTop + height); @@ -661,7 +665,7 @@ public class PhotoPickerSearchActivity extends BaseFragment { super.onResume(); if (searchItem != null) { searchItem.openSearch(true); - getParentActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); + getParentActivity().getWindow().setSoftInputMode(SharedConfig.smoothKeyboard ? WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN : WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); } if (imagesSearch != null) { imagesSearch.onResume(); @@ -688,6 +692,11 @@ public class PhotoPickerSearchActivity extends BaseFragment { } } + @Override + public boolean isSwipeBackEnabled(MotionEvent event) { + return swipeBackEnabled; + } + @Override public void onFragmentDestroy() { if (imagesSearch != null) { @@ -762,8 +771,8 @@ public class PhotoPickerSearchActivity extends BaseFragment { if (scrollSlidingTextTabStrip == null) { return; } - scrollSlidingTextTabStrip.addTextTab(0, LocaleController.getString("ImagesTab", R.string.ImagesTab)); - scrollSlidingTextTabStrip.addTextTab(1, LocaleController.getString("GifsTab", R.string.GifsTab)); + scrollSlidingTextTabStrip.addTextTab(0, LocaleController.getString("ImagesTab2", R.string.ImagesTab2)); + scrollSlidingTextTabStrip.addTextTab(1, LocaleController.getString("GifsTab2", R.string.GifsTab2)); scrollSlidingTextTabStrip.setVisibility(View.VISIBLE); actionBar.setExtraHeight(AndroidUtilities.dp(44)); int id = scrollSlidingTextTabStrip.getCurrentTabId(); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/PhotoViewer.java b/TMessagesProj/src/main/java/org/telegram/ui/PhotoViewer.java index 604b9c48a..97c657836 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/PhotoViewer.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/PhotoViewer.java @@ -36,6 +36,7 @@ import android.graphics.SurfaceTexture; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; +import android.graphics.drawable.GradientDrawable; import android.media.MediaCodecInfo; import android.net.Uri; import android.os.Build; @@ -64,7 +65,6 @@ import android.util.SparseArray; import android.util.TypedValue; import android.view.ActionMode; import android.view.ContextThemeWrapper; -import android.view.GestureDetector; import android.view.Gravity; import android.view.HapticFeedbackConstants; import android.view.KeyEvent; @@ -147,6 +147,7 @@ import org.telegram.ui.Components.ChatAttachAlert; import org.telegram.ui.Components.CheckBox; import org.telegram.ui.Components.ClippingImageView; import org.telegram.messenger.ImageReceiver; +import org.telegram.ui.Components.GestureDetector2; import org.telegram.ui.Components.GroupedPhotosListView; import org.telegram.ui.Components.LayoutHelper; import org.telegram.ui.Components.NumberPicker; @@ -179,7 +180,7 @@ import java.util.HashMap; import java.util.Locale; @SuppressWarnings("unchecked") -public class PhotoViewer implements NotificationCenter.NotificationCenterDelegate, GestureDetector.OnGestureListener, GestureDetector.OnDoubleTapListener { +public class PhotoViewer implements NotificationCenter.NotificationCenterDelegate, GestureDetector2.OnGestureListener, GestureDetector2.OnDoubleTapListener { private int classGuid; private PhotoViewerProvider placeProvider; @@ -249,6 +250,12 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat private ImageReceiver sideImage; private boolean isCurrentVideo; + private GradientDrawable[] pressedDrawable = new GradientDrawable[2]; + private boolean[] drawPressedDrawable = new boolean[2]; + private float[] pressedDrawableAlpha = new float[2]; + + private boolean useSmoothKeyboard; + private VideoForwardDrawable videoForwardDrawable; private AnimatorSet currentListViewAnimation; @@ -330,6 +337,8 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat private boolean firstAnimationDelay; private long lastBufferedPositionCheck; private View playButtonAccessibilityOverlay; + + private int currentPanTranslationY; public final static int SELECT_TYPE_AVATAR = 1; public final static int SELECT_TYPE_WALLPAPER = 3; @@ -632,7 +641,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat private long animationStartTime; private AnimatorSet imageMoveAnimation; private AnimatorSet changeModeAnimation; - private GestureDetector gestureDetector; + private GestureDetector2 gestureDetector; private boolean doubleTapEnabled; private DecelerateInterpolator interpolator = new DecelerateInterpolator(1.5f); private float pinchStartDistance; @@ -1034,6 +1043,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat public float scale = 1.0f; public boolean isEvent; public ClippingImageView animatingImageView; + public int animatingImageViewYOffset; } public static class EmptyPhotoViewerProvider implements PhotoViewerProvider { @@ -1193,7 +1203,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat private boolean ignoreLayout; public FrameLayoutDrawer(Context context) { - super(context); + super(context, false); setWillNotDraw(false); paint.setColor(0x33000000); } @@ -1243,7 +1253,8 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat @Override protected void onLayout(boolean changed, int _l, int t, int _r, int _b) { final int count = getChildCount(); - int paddingBottom = getKeyboardHeight() <= AndroidUtilities.dp(20) && !AndroidUtilities.isInMultiwindow ? captionEditText.getEmojiPadding() : 0; + int keyboardSize = useSmoothKeyboard ? 0 : getKeyboardHeight(); + int paddingBottom = keyboardSize <= AndroidUtilities.dp(20) && !AndroidUtilities.isInMultiwindow ? captionEditText.getEmojiPadding() : 0; for (int i = 0; i < count; i++) { final View child = getChildAt(i); @@ -1336,7 +1347,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat if (Build.VERSION.SDK_INT >= 21 && AndroidUtilities.statusBarHeight != 0 && actionBar != null) { paint.setAlpha((int) (255 * actionBar.getAlpha() * 0.2f)); - canvas.drawRect(0, 0, getMeasuredWidth(), AndroidUtilities.statusBarHeight, paint); + canvas.drawRect(0, currentPanTranslationY, getMeasuredWidth(), currentPanTranslationY + AndroidUtilities.statusBarHeight, paint); paint.setAlpha((int) (255 * actionBar.getAlpha() * 0.498f)); if (getPaddingRight() > 0) { canvas.drawRect(getMeasuredWidth() - getPaddingRight(), 0, getMeasuredWidth(), getMeasuredHeight(), paint); @@ -1388,6 +1399,43 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat } super.requestLayout(); } + + @Override + protected void onPanTranslationUpdate(int y) { + currentPanTranslationY = y; + actionBar.setTranslationY(y); + if (miniProgressView != null) { + miniProgressView.setTranslationY(y); + } + if (progressView != null) { + progressView.setTranslationY(y); + } + if (checkImageView != null) { + checkImageView.setTranslationY(y); + } + if (photosCounterView != null) { + photosCounterView.setTranslationY(y); + } + if (selectedPhotosListView != null) { + selectedPhotosListView.setTranslationY(y); + } + if (aspectRatioFrameLayout != null) { + aspectRatioFrameLayout.setTranslationY(y); + } + if (textureImageView != null) { + textureImageView.setTranslationY(y); + } + if (photoCropView != null) { + photoCropView.setTranslationY(y); + } + if (photoFilterView != null) { + photoFilterView.setTranslationY(y); + } + if (photoPaintView != null) { + photoPaintView.setTranslationY(y); + } + invalidate(); + } } @SuppressLint("StaticFieldLeak") @@ -2410,6 +2458,11 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat bottomLayout.setBackgroundColor(0x7f000000); containerView.addView(bottomLayout, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 48, Gravity.BOTTOM | Gravity.LEFT)); + pressedDrawable[0] = new GradientDrawable(GradientDrawable.Orientation.LEFT_RIGHT, new int[] {0x32000000, 0}); + pressedDrawable[0].setShape(GradientDrawable.RECTANGLE); + pressedDrawable[1] = new GradientDrawable(GradientDrawable.Orientation.RIGHT_LEFT, new int[] {0x32000000, 0}); + pressedDrawable[1].setShape(GradientDrawable.RECTANGLE); + groupedPhotosListView = new GroupedPhotosListView(actvityContext); containerView.addView(groupedPhotosListView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 62, Gravity.BOTTOM | Gravity.LEFT, 0, 0, 0, 48)); groupedPhotosListView.setDelegate(new GroupedPhotosListView.GroupedPhotosListViewDelegate() { @@ -3108,7 +3161,8 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat editorDoneLayout.addView(resetButton, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.MATCH_PARENT, Gravity.TOP | Gravity.CENTER)); resetButton.setOnClickListener(v -> photoCropView.reset()); - gestureDetector = new GestureDetector(containerView.getContext(), this); + gestureDetector = new GestureDetector2(containerView.getContext(), this); + gestureDetector.setIsLongpressEnabled(false); setDoubleTapEnabled(true); ImageReceiver.ImageReceiverDelegate imageReceiverDelegate = (imageReceiver, set, thumb) -> { @@ -3279,8 +3333,9 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat } } }); - if (Build.VERSION.SDK_INT >= 19) + if (Build.VERSION.SDK_INT >= 19) { captionEditText.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS); + } containerView.addView(captionEditText, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.BOTTOM | Gravity.LEFT)); mentionListView = new RecyclerListView(actvityContext) { @@ -5040,7 +5095,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat } }); changeModeAnimation.start(); - } else if (mode == 3) { // painting/text/masks + } else if (mode == 3) { if (photoPaintView == null) { photoPaintView = new PhotoPaintView(parentActivity, centerImage.getBitmap(), centerImage.getOrientation()); containerView.addView(photoPaintView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT)); @@ -7154,7 +7209,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat } else { windowLayoutParams.flags &=~ WindowManager.LayoutParams.FLAG_SECURE; } - windowLayoutParams.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE | WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION; + windowLayoutParams.softInputMode = (useSmoothKeyboard ? WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN : WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE) | WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION; windowView.setFocusable(false); containerView.setFocusable(false); wm.addView(windowView, windowLayoutParams); @@ -7399,7 +7454,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat } else { windowLayoutParams.flags = 0; } - windowLayoutParams.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE | WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION; + windowLayoutParams.softInputMode = (useSmoothKeyboard ? WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN : WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE) | WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION; WindowManager wm1 = (WindowManager) parentActivity.getSystemService(Context.WINDOW_SERVICE); wm1.updateViewLayout(windowView, windowLayoutParams); windowView.setFocusable(true); @@ -7474,7 +7529,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat } else { windowLayoutParams.flags = 0; } - windowLayoutParams.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE | WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION; + windowLayoutParams.softInputMode = (useSmoothKeyboard ? WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN : WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE) | WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION; wm.updateViewLayout(windowView, windowLayoutParams); windowView.setFocusable(true); containerView.setFocusable(true); @@ -7806,6 +7861,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat animatingImageViews[0] = animatingImageView; if (hasSecondAnimatingImageView) { animatingImageViews[1] = object.animatingImageView; + object.animatingImageView.setAdditionalTranslationY(object.animatingImageViewYOffset); } return animatingImageViews; } @@ -8069,6 +8125,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat pinchStartY = translationY; zooming = true; moving = false; + hidePressedDrawables(); if (velocityTracker != null) { velocityTracker.clear(); } @@ -8098,12 +8155,14 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat float dy = Math.abs(ev.getY() - dragY); if (dx > AndroidUtilities.dp(3) || dy > AndroidUtilities.dp(3)) { discardTap = true; + hidePressedDrawables(); if (qualityChooseView != null && qualityChooseView.getVisibility() == View.VISIBLE) { return true; } } if (placeProvider.canScrollAway() && currentEditMode == 0 && sendPhotoType != SELECT_TYPE_AVATAR && canDragDown && !draggingDown && scale == 1 && dy >= AndroidUtilities.dp(30) && dy / 2 > dx) { draggingDown = true; + hidePressedDrawables(); moving = false; dragY = ev.getY(); if (isActionBarVisible && containerView.getTag() != null) { @@ -8126,6 +8185,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat moveDy = 0; moving = true; canDragDown = false; + hidePressedDrawables(); } moveStartX = ev.getX(); @@ -8311,6 +8371,18 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat return animationValue; } + private void switchToNextIndex(int add, boolean init) { + if (currentMessageObject != null) { + releasePlayer(false); + FileLoader.getInstance(currentAccount).cancelLoadFile(currentMessageObject.getDocument()); + } + setImageIndex(currentIndex + add, init); + if (currentMessageObject != null && currentMessageObject.isVideo() && (currentMessageObject.mediaExists || currentMessageObject.attachPathExists || currentMessageObject.canStreamVideo() && SharedConfig.streamMedia) && SharedConfig.autoplayVideo) { + onActionClick(true); + checkProgress(0, false, true); + } + } + @SuppressLint({"NewApi", "DrawAllocation"}) private void onDraw(Canvas canvas) { if (animationInProgress == 1 || animationInProgress == 3 || !isVisible && animationInProgress != 2 && !pipAnimationInProgress) { @@ -8326,6 +8398,12 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat float currentTranslationX; float currentScale; float aty = -1; + long newUpdateTime = System.currentTimeMillis(); + long dt = newUpdateTime - videoCrossfadeAlphaLastTime; + if (dt > 20) { + dt = 17; + } + videoCrossfadeAlphaLastTime = newUpdateTime; if (imageMoveAnimation != null) { if (!scroller.isFinished()) { @@ -8372,9 +8450,9 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat } } if (switchImageAfterAnimation == 1) { - AndroidUtilities.runOnUIThread(() -> setImageIndex(currentIndex + 1, false)); + AndroidUtilities.runOnUIThread(() -> switchToNextIndex(1, false)); } else if (switchImageAfterAnimation == 2) { - AndroidUtilities.runOnUIThread(() -> setImageIndex(currentIndex - 1, false)); + AndroidUtilities.runOnUIThread(() -> switchToNextIndex(-1, false)); } switchImageAfterAnimation = 0; } @@ -8462,7 +8540,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat if (centerImage.hasBitmapImage() || drawTextureView && textureUploaded) { canvas.save(); canvas.translate(getContainerViewWidth() / 2 + getAdditionX(), getContainerViewHeight() / 2 + getAdditionY()); - canvas.translate(translateX, currentTranslationY); + canvas.translate(translateX, currentTranslationY + currentPanTranslationY); canvas.scale(currentScale - scaleDiff, currentScale - scaleDiff); int bitmapWidth; @@ -8500,9 +8578,6 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat videoTextureView.setAlpha(alpha * videoCrossfadeAlpha); aspectRatioFrameLayout.draw(canvas); if (videoCrossfadeStarted && videoCrossfadeAlpha < 1.0f) { - long newUpdateTime = System.currentTimeMillis(); - long dt = newUpdateTime - videoCrossfadeAlphaLastTime; - videoCrossfadeAlphaLastTime = newUpdateTime; videoCrossfadeAlpha += dt / (playerInjected ? 100.0f : 200.0f); containerView.invalidate(); if (videoCrossfadeAlpha > 1.0f) { @@ -8511,6 +8586,34 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat } } canvas.restore(); + for (int a = 0; a < pressedDrawable.length; a++) { + if (drawPressedDrawable[a] || pressedDrawableAlpha[a] != 0) { + pressedDrawable[a].setAlpha((int) (pressedDrawableAlpha[a] * 255)); + if (a == 0) { + pressedDrawable[a].setBounds(0, 0, containerView.getMeasuredWidth() / 5, containerView.getMeasuredHeight()); + } else { + pressedDrawable[a].setBounds(containerView.getMeasuredWidth() - containerView.getMeasuredWidth() / 5, 0, containerView.getMeasuredWidth(), containerView.getMeasuredHeight()); + } + pressedDrawable[a].draw(canvas); + } + if (drawPressedDrawable[a]) { + if (pressedDrawableAlpha[a] < 1.0f) { + pressedDrawableAlpha[a] += dt / 180.0f; + if (pressedDrawableAlpha[a] > 1.0f) { + pressedDrawableAlpha[a] = 1.0f; + } + containerView.invalidate(); + } + } else { + if (pressedDrawableAlpha[a] > 0.0f) { + pressedDrawableAlpha[a] -= dt / 180.0f; + if (pressedDrawableAlpha[a] < 0.0f) { + pressedDrawableAlpha[a] = 0.0f; + } + containerView.invalidate(); + } + } + } } boolean drawProgress; if (isCurrentVideo) { @@ -8701,9 +8804,34 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat @Override public boolean onDown(MotionEvent e) { + if (checkImageView.getVisibility() != View.VISIBLE && !drawPressedDrawable[0] && !drawPressedDrawable[1]) { + float x = e.getX(); + int side = containerView.getMeasuredWidth() / 5; + if (x < side) { + if (leftImage.hasImageSet()) { + drawPressedDrawable[0] = true; + containerView.invalidate(); + } + } else if (x > containerView.getMeasuredWidth() - side) { + if (rightImage.hasImageSet()) { + drawPressedDrawable[1] = true; + containerView.invalidate(); + } + } + } return false; } + private void hidePressedDrawables() { + drawPressedDrawable[0] = drawPressedDrawable[1] = false; + containerView.invalidate(); + } + + @Override + public void onUp(MotionEvent e) { + hidePressedDrawables(); + } + @Override public void onShowPress(MotionEvent e) { @@ -8742,9 +8870,23 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat if (discardTap) { return false; } + float x = e.getX(); + if (checkImageView.getVisibility() != View.VISIBLE) { + int side = containerView.getMeasuredWidth() / 5; + if (x < side) { + if (leftImage.hasImageSet()) { + switchToNextIndex(-1, true); + return true; + } + } else if (x > containerView.getMeasuredWidth() - side) { + if (rightImage.hasImageSet()) { + switchToNextIndex(1, true); + return true; + } + } + } if (containerView.getTag() != null) { boolean drawTextureView = aspectRatioFrameLayout != null && aspectRatioFrameLayout.getVisibility() == View.VISIBLE; - float x = e.getX(); float y = e.getY(); if (sharedMediaType == MediaDataController.MEDIA_FILE && currentMessageObject != null) { if (!currentMessageObject.canPreviewDocument()) { @@ -8777,7 +8919,6 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat } else if (currentBotInlineResult != null && (currentBotInlineResult.type.equals("video") || MessageObject.isVideoDocument(currentBotInlineResult.document))) { int state = photoProgressViews[0].backgroundState; if (state > 0 && state <= 3) { - float x = e.getX(); float y = e.getY(); if (x >= (getContainerViewWidth() - AndroidUtilities.dp(100)) / 2.0f && x <= (getContainerViewWidth() + AndroidUtilities.dp(100)) / 2.0f && y >= (getContainerViewHeight() - AndroidUtilities.dp(100)) / 2.0f && y <= (getContainerViewHeight() + AndroidUtilities.dp(100)) / 2.0f) { @@ -8985,8 +9126,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat int x = cx - circleSize / 2 - gapSize - lineSize; float startPadding = a == (selectedCompression + 1) ? AndroidUtilities.dpf2(2) : 0; float endPadding = a == selectedCompression ? AndroidUtilities.dpf2(2) : 0; - canvas.drawRect(x + startPadding, cy - AndroidUtilities.dp(1), - x + lineSize - endPadding, cy + AndroidUtilities.dp(2), paint); + canvas.drawRect(x + startPadding, cy - AndroidUtilities.dp(1), x + lineSize - endPadding, cy + AndroidUtilities.dp(2), paint); } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/PopupNotificationActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/PopupNotificationActivity.java index f2d1a307d..4338c0291 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/PopupNotificationActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/PopupNotificationActivity.java @@ -177,7 +177,7 @@ public class PopupNotificationActivity extends Activity implements NotificationC statusDrawables[3] = new PlayingGameDrawable(); statusDrawables[4] = new RoundStatusDrawable(); - SizeNotifierFrameLayout contentView = new SizeNotifierFrameLayout(this) { + SizeNotifierFrameLayout contentView = new SizeNotifierFrameLayout(this, false) { @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int widthMode = MeasureSpec.getMode(widthMeasureSpec); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/PrivacyControlActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/PrivacyControlActivity.java index 976a8f668..d3646efea 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/PrivacyControlActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/PrivacyControlActivity.java @@ -1160,11 +1160,13 @@ public class PrivacyControlActivity extends BaseFragment implements Notification new ThemeDescription(listView, 0, null, null, new Drawable[]{Theme.chat_msgInDrawable, Theme.chat_msgInMediaDrawable}, null, Theme.key_chat_inBubble), new ThemeDescription(listView, 0, null, null, new Drawable[]{Theme.chat_msgInSelectedDrawable, Theme.chat_msgInMediaSelectedDrawable}, null, Theme.key_chat_inBubbleSelected), - new ThemeDescription(listView, 0, null, null, new Drawable[]{Theme.chat_msgInDrawable.getShadowDrawable(), Theme.chat_msgInMediaDrawable.getShadowDrawable()}, null, Theme.key_chat_inBubbleShadow), + new ThemeDescription(listView, 0, null, null, Theme.chat_msgInDrawable.getShadowDrawables(), null, Theme.key_chat_inBubbleShadow), + new ThemeDescription(listView, 0, null, null, Theme.chat_msgInMediaDrawable.getShadowDrawables(), null, Theme.key_chat_inBubbleShadow), new ThemeDescription(listView, 0, null, null, new Drawable[]{Theme.chat_msgOutDrawable, Theme.chat_msgOutMediaDrawable}, null, Theme.key_chat_outBubble), new ThemeDescription(listView, 0, null, null, new Drawable[]{Theme.chat_msgOutDrawable, Theme.chat_msgOutMediaDrawable}, null, Theme.key_chat_outBubbleGradient), new ThemeDescription(listView, 0, null, null, new Drawable[]{Theme.chat_msgOutSelectedDrawable, Theme.chat_msgOutMediaSelectedDrawable}, null, Theme.key_chat_outBubbleSelected), - new ThemeDescription(listView, 0, null, null, new Drawable[]{Theme.chat_msgOutDrawable.getShadowDrawable(), Theme.chat_msgOutMediaDrawable.getShadowDrawable()}, null, Theme.key_chat_outBubbleShadow), + new ThemeDescription(listView, 0, null, null, Theme.chat_msgOutDrawable.getShadowDrawables(), null, Theme.key_chat_outBubbleShadow), + new ThemeDescription(listView, 0, null, null, Theme.chat_msgOutMediaDrawable.getShadowDrawables(), null, Theme.key_chat_outBubbleShadow), new ThemeDescription(listView, 0, null, null, null, null, Theme.key_chat_messageTextIn), new ThemeDescription(listView, 0, null, null, null, null, Theme.key_chat_messageTextOut), new ThemeDescription(listView, 0, null, null, new Drawable[]{Theme.chat_msgOutCheckDrawable}, null, Theme.key_chat_outSentCheck), diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java index dfe96d7e6..3140aeaec 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java @@ -8,6 +8,7 @@ package org.telegram.ui; +import android.Manifest; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; @@ -39,8 +40,10 @@ import android.graphics.drawable.GradientDrawable; import android.net.Uri; import android.os.Build; import android.os.Bundle; +import android.os.SystemClock; import android.text.TextPaint; import android.text.TextUtils; +import android.util.Property; import android.util.SparseArray; import android.util.TypedValue; import android.view.Display; @@ -61,6 +64,9 @@ import android.widget.Toast; import androidx.annotation.Keep; import androidx.core.content.ContextCompat; import androidx.core.graphics.ColorUtils; +import androidx.core.view.NestedScrollingParent3; +import androidx.core.view.NestedScrollingParentHelper; +import androidx.core.view.ViewCompat; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import androidx.viewpager.widget.PagerAdapter; @@ -76,6 +82,7 @@ import org.telegram.messenger.FileLog; import org.telegram.messenger.ImageLocation; import org.telegram.messenger.ImageReceiver; import org.telegram.messenger.LocaleController; +import org.telegram.messenger.MediaController; import org.telegram.messenger.MediaDataController; import org.telegram.messenger.MessageObject; import org.telegram.messenger.MessagesController; @@ -101,7 +108,6 @@ import org.telegram.ui.ActionBar.Theme; import org.telegram.ui.ActionBar.ThemeDescription; import org.telegram.ui.Cells.AboutLinkCell; import org.telegram.ui.Cells.DividerCell; -import org.telegram.ui.Cells.EmptyCell; import org.telegram.ui.Cells.HeaderCell; import org.telegram.ui.Cells.NotificationsCheckCell; import org.telegram.ui.Cells.ShadowSectionCell; @@ -110,6 +116,7 @@ import org.telegram.ui.Cells.TextDetailCell; import org.telegram.ui.Cells.TextInfoPrivacyCell; import org.telegram.ui.Cells.UserCell; import org.telegram.ui.Components.AlertsCreator; +import org.telegram.ui.Components.AnimationProperties; import org.telegram.ui.Components.AvatarDrawable; import org.telegram.ui.Components.BackupImageView; import org.telegram.ui.Components.CombinedDrawable; @@ -120,21 +127,24 @@ import org.telegram.ui.Components.LayoutHelper; import org.telegram.ui.Components.ProfileGalleryView; import org.telegram.ui.Components.RecyclerListView; import org.telegram.ui.Components.ScamDrawable; +import org.telegram.ui.Components.SharedMediaLayout; import org.telegram.ui.Components.UndoView; import org.telegram.ui.Components.voip.VoIPHelper; +import java.io.File; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.concurrent.CountDownLatch; -public class ProfileActivity extends BaseFragment implements NotificationCenter.NotificationCenterDelegate, DialogsActivity.DialogsActivityDelegate { +public class ProfileActivity extends BaseFragment implements NotificationCenter.NotificationCenterDelegate, DialogsActivity.DialogsActivityDelegate, SharedMediaLayout.SharedMediaPreloaderDelegate { private RecyclerListView listView; private LinearLayoutManager layoutManager; private ListAdapter listAdapter; private AvatarImageView avatarImage; private SimpleTextView[] nameTextView = new SimpleTextView[2]; - private SimpleTextView[] onlineTextView = new SimpleTextView[2]; + private SimpleTextView[] onlineTextView = new SimpleTextView[3]; private ImageView writeButton; private AnimatorSet writeButtonAnimation; private Drawable lockIconDrawable; @@ -142,21 +152,31 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. private Drawable verifiedCheckDrawable; private CrossfadeDrawable verifiedCrossfadeDrawable; private ScamDrawable scamDrawable; - private MediaActivity mediaActivity; private UndoView undoView; private ProfileGalleryView avatarsViewPager; private PagerIndicatorView avatarsViewPagerIndicatorView; private OverlaysView overlaysView; + private SharedMediaLayout sharedMediaLayout; + private boolean sharedMediaLayoutAttached; + private SharedMediaLayout.SharedMediaPreloader sharedMediaPreloader; + private int avatarColor; + + private int overlayCountVisible; private int lastMeasuredContentWidth; private int listContentHeight; + private boolean openingAvatar; private boolean[] isOnline = new boolean[1]; + private boolean callItemVisible; + private boolean editItemVisible; private AvatarDrawable avatarDrawable; private ActionBarMenuItem animatingItem; private ActionBarMenuItem callItem; private ActionBarMenuItem editItem; + private ActionBarMenuItem otherItem; + protected float headerShadowAlpha = 1.0f; private TopView topView; private int user_id; private int chat_id; @@ -165,13 +185,8 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. private boolean userBlocked; private boolean reportSpam; private long mergeDialogId; - - private int[] mediaCount = new int[]{-1, -1, -1, -1, -1}; - private int[] mediaMergeCount = new int[]{-1, -1, -1, -1, -1}; - private int[] lastMediaCount = new int[]{-1, -1, -1, -1, -1}; - private int[] prevMediaCount = new int[]{-1, -1, -1, -1, -1}; - - private MediaActivity.SharedMediaData[] sharedMediaData; + private boolean expandPhoto; + private boolean needSendMessage; private boolean loadingUsers; private SparseArray participantsMap = new SparseArray<>(); @@ -180,12 +195,14 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. private int banFromGroup; private boolean openAnimationInProgress; private boolean recreateMenuAfterAnimation; - private boolean playProfileAnimation; + private int playProfileAnimation; private boolean allowProfileAnimation = true; private float extraHeight; private float initialAnimationExtraHeight; private float animationProgress; + private HashMap positionToOffset = new HashMap<>(); + private float avatarX; private float avatarY; private float avatarScale; @@ -196,6 +213,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. private float expandProgress; private float listViewVelocityY; private ValueAnimator expandAnimator; + private float currentExpanAnimatorFracture; private float[] expandAnimatorValues = new float[]{0f, 1f}; private boolean isInLandscapeMode; private boolean allowPullingDown; @@ -229,6 +247,10 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. private final static int search_members = 17; private final static int add_member = 18; private final static int statistics = 19; + private final static int start_secret_chat = 20; + private final static int gallery_menu_save = 21; + + private Rect rect = new Rect(); private int rowCount; @@ -243,6 +265,8 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. private int notificationsDividerRow; private int notificationsRow; private int infoSectionRow; + private int sendMessageRow; + private int reportRow; private int settingsTimerRow; private int settingsKeyRow; @@ -257,21 +281,25 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. private int blockedUsersRow; private int membersSectionRow; - private int sharedHeaderRow; - private int photosRow; - private int filesRow; - private int linksRow; - private int audioRow; - private int voiceRow; - private int groupsInCommonRow; - private int sharedSectionRow; + private int sharedMediaRow; private int unblockRow; - private int startSecretChatRow; - private int leaveChannelRow; private int joinRow; private int lastSectionRow; + private final Property HEADER_SHADOW = new AnimationProperties.FloatProperty("headerShadow") { + @Override + public void setValue(ProfileActivity object, float value) { + headerShadowAlpha = value; + topView.invalidate(); + } + + @Override + public Float get(ProfileActivity object) { + return headerShadowAlpha; + } + }; + private PhotoViewer.PhotoViewerProvider provider = new PhotoViewer.EmptyPhotoViewerProvider() { @Override @@ -424,9 +452,21 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. protected void onDraw(Canvas canvas) { final int height = ActionBar.getCurrentActionBarHeight() + (actionBar.getOccupyStatusBar() ? AndroidUtilities.statusBarHeight : 0); final float v = extraHeight + height; - canvas.drawRect(0, 0, getMeasuredWidth(), v, paint); + + int y1 = (int) (v * (1.0f - mediaHeaderAnimationProgress)); + + if (y1 != 0) { + paint.setColor(currentColor); + canvas.drawRect(0, 0, getMeasuredWidth(), y1, paint); + } + if (y1 != v) { + int color = Theme.getColor(Theme.key_windowBackgroundWhite); + paint.setColor(color); + canvas.drawRect(0, y1, getMeasuredWidth(), v, paint); + } + if (parentLayout != null) { - parentLayout.drawHeaderShadow(canvas, (int) v); + parentLayout.drawHeaderShadow(canvas, (int) (headerShadowAlpha * 255), (int) v); } } } @@ -437,19 +477,30 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. private final Rect topOverlayRect = new Rect(); private final Rect bottomOverlayRect = new Rect(); + private final RectF rect = new RectF(); private final GradientDrawable topOverlayGradient; private final GradientDrawable bottomOverlayGradient; private final ValueAnimator animator; private final float[] animatorValues = new float[]{0f, 1f}; private final Paint backgroundPaint; + private final Paint barPaint; + private final Paint selectedBarPaint; private boolean isOverlaysVisible; + private float currentAnimationValue; + private float alpha = 1.0f; + private long lastTime; public OverlaysView(Context context) { super(context); setVisibility(GONE); + barPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + barPaint.setColor(0x55ffffff); + selectedBarPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + selectedBarPaint.setColor(0xffffffff); + topOverlayGradient = new GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM, new int[] {0x42000000, 0}); topOverlayGradient.setShape(GradientDrawable.RECTANGLE); @@ -458,16 +509,13 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. backgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG); backgroundPaint.setColor(Color.BLACK); + backgroundPaint.setAlpha(66); animator = ValueAnimator.ofFloat(0f, 1f); animator.setDuration(250); animator.setInterpolator(CubicBezierInterpolator.EASE_BOTH); animator.addUpdateListener(anim -> { - float value = AndroidUtilities.lerp(animatorValues, anim.getAnimatedFraction()); - int alpha = (int) (255 * value); - topOverlayGradient.setAlpha(alpha); - bottomOverlayGradient.setAlpha(alpha); - backgroundPaint.setAlpha((int) (66 * value)); - invalidate(); + float value = AndroidUtilities.lerp(animatorValues, currentAnimationValue = anim.getAnimatedFraction()); + setAlphaValue(value, true); }); animator.addListener(new AnimatorListenerAdapter() { @Override @@ -484,15 +532,37 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. }); } + public void setAlphaValue(float value, boolean self) { + if (Build.VERSION.SDK_INT > 18) { + int alpha = (int) (255 * value); + topOverlayGradient.setAlpha(alpha); + bottomOverlayGradient.setAlpha(alpha); + backgroundPaint.setAlpha((int) (66 * value)); + barPaint.setAlpha((int) (0x55 * value)); + selectedBarPaint.setAlpha(alpha); + } else { + setAlpha(value); + } + if (!self) { + currentAnimationValue = value; + } + invalidate(); + } + public boolean isOverlaysVisible() { return isOverlaysVisible; } + public void setOverlaysVisible() { + isOverlaysVisible = true; + setVisibility(VISIBLE); + } + public void setOverlaysVisible(boolean overlaysVisible, float durationFactor) { if (overlaysVisible != isOverlaysVisible) { isOverlaysVisible = overlaysVisible; animator.cancel(); - final float value = AndroidUtilities.lerp(animatorValues, animator.getAnimatedFraction()); + final float value = AndroidUtilities.lerp(animatorValues, currentAnimationValue); if (overlaysVisible) { animator.setDuration((long) ((1f - value) * 250f / durationFactor)); } else { @@ -520,6 +590,142 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. bottomOverlayGradient.draw(canvas); canvas.drawRect(topOverlayRect, backgroundPaint); canvas.drawRect(bottomOverlayRect, backgroundPaint); + + int count = avatarsViewPager.getRealCount(); + if (count > 1 && count <= 20) { + if (overlayCountVisible == 0) { + alpha = 1.0f; + overlayCountVisible = 3; + } else if (overlayCountVisible == 1) { + alpha = 0.0f; + overlayCountVisible = 2; + } + if (overlayCountVisible == 2) { + barPaint.setAlpha((int) (0x55 * alpha)); + selectedBarPaint.setAlpha((int) (0xff * alpha)); + } + int selected = avatarsViewPager.getRealPosition(); + int width = (getMeasuredWidth() - AndroidUtilities.dp(5 * 2) - AndroidUtilities.dp(2 * (count - 1))) / count; + int y = AndroidUtilities.dp(4) + (Build.VERSION.SDK_INT >= 21 ? AndroidUtilities.statusBarHeight : 0); + for (int a = 0; a < count; a++) { + int x = AndroidUtilities.dp(5 + a * 2) + width * a; + rect.set(x, y, x + width, y + AndroidUtilities.dp(2)); + canvas.drawRoundRect(rect, AndroidUtilities.dp(1), AndroidUtilities.dp(1), a == selected ? selectedBarPaint : barPaint); + } + if (overlayCountVisible == 2) { + if (alpha < 1.0f) { + long newTime = SystemClock.elapsedRealtime(); + long dt = (newTime - lastTime); + lastTime = newTime; + if (dt < 0 || dt > 20) { + dt = 17; + } + alpha += dt / 180.0f; + if (alpha >= 1.0f) { + alpha = 1.0f; + } + invalidate(); + } else { + overlayCountVisible = 3; + } + } + } + } + } + + private class NestedFrameLayout extends FrameLayout implements NestedScrollingParent3 { + + private NestedScrollingParentHelper nestedScrollingParentHelper; + + public NestedFrameLayout(Context context) { + super(context); + nestedScrollingParentHelper = new NestedScrollingParentHelper(this); + } + + @Override + public void onNestedScroll(View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, int type, int[] consumed) { + if (target == listView && sharedMediaLayoutAttached) { + RecyclerListView innerListView = sharedMediaLayout.getCurrentListView(); + int top = sharedMediaLayout.getTop(); + if (top == 0) { + consumed[1] = dyUnconsumed; + innerListView.scrollBy(0, dyUnconsumed); + } + } + } + + @Override + public void onNestedScroll(View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, int type) { + + } + + @Override + public boolean onNestedPreFling(View target, float velocityX, float velocityY) { + return super.onNestedPreFling(target, velocityX, velocityY); + } + + @Override + public void onNestedPreScroll(View target, int dx, int dy, int[] consumed, int type) { + if (target == listView && sharedMediaRow != -1 && sharedMediaLayoutAttached) { + boolean searchVisible = actionBar.isSearchFieldVisible(); + int t = sharedMediaLayout.getTop(); + if (dy < 0) { + boolean scrolledInner = false; + if (t <= 0) { + RecyclerListView innerListView = sharedMediaLayout.getCurrentListView(); + LinearLayoutManager linearLayoutManager = (LinearLayoutManager) innerListView.getLayoutManager(); + int pos = linearLayoutManager.findFirstVisibleItemPosition(); + if (pos != RecyclerView.NO_POSITION) { + RecyclerView.ViewHolder holder = innerListView.findViewHolderForAdapterPosition(pos); + int top = holder != null ? holder.itemView.getTop() : -1; + int paddingTop = innerListView.getPaddingTop(); + if (top != paddingTop || pos != 0) { + consumed[1] = pos != 0 ? dy : Math.max(dy, (top - paddingTop)); + innerListView.scrollBy(0, dy); + scrolledInner = true; + } + } + } + if (searchVisible) { + if (!scrolledInner && t < 0) { + consumed[1] = dy - Math.max(t, dy); + } else { + consumed[1] = dy; + } + } + } else { + if (searchVisible) { + RecyclerListView innerListView = sharedMediaLayout.getCurrentListView(); + consumed[1] = dy; + if (t > 0) { + consumed[1] -= Math.min(consumed[1], dy); + } + if (consumed[1] > 0) { + innerListView.scrollBy(0, consumed[1]); + } + } + } + } + } + + @Override + public boolean onStartNestedScroll(View child, View target, int axes, int type) { + return sharedMediaRow != -1 && axes == ViewCompat.SCROLL_AXIS_VERTICAL; + } + + @Override + public void onNestedScrollAccepted(View child, View target, int axes, int type) { + nestedScrollingParentHelper.onNestedScrollAccepted(child, target, axes); + } + + @Override + public void onStopNestedScroll(View target, int type) { + nestedScrollingParentHelper.onStopNestedScroll(target); + } + + @Override + public void onStopNestedScroll(View child) { + } } @@ -547,7 +753,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. textPaint.setTextAlign(Paint.Align.CENTER); textPaint.setTextSize(AndroidUtilities.dpf2(15f)); backgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG); - backgroundPaint.setColor(Color.parseColor("#26000000")); + backgroundPaint.setColor(0x26000000); animator = ValueAnimator.ofFloat(0f, 1f); animator.setInterpolator(CubicBezierInterpolator.EASE_BOTH); animator.addUpdateListener(a -> { @@ -601,6 +807,10 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. adapter.registerDataSetObserver(new DataSetObserver() { @Override public void onChanged() { + int count = avatarsViewPager.getRealCount(); + if (overlayCountVisible == 0 && count > 1 && count <= 20 && overlaysView.isOverlaysVisible()) { + overlayCountVisible = 1; + } invalidateIndicatorRect(); refreshVisibility(1f); } @@ -634,7 +844,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. } public void refreshVisibility(float durationFactor) { - setIndicatorVisible(isPulledDown && adapter.getCount() > 1, durationFactor); + setIndicatorVisible(isPulledDown && avatarsViewPager.getRealCount() > 20, durationFactor); } @Override @@ -643,6 +853,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. } private void invalidateIndicatorRect() { + overlaysView.invalidate(); final float textWidth = textPaint.measureText(getCurrentTitle()); indicatorRect.right = getMeasuredWidth() - AndroidUtilities.dp(54f); indicatorRect.left = indicatorRect.right - (textWidth + AndroidUtilities.dpf2(16f)); @@ -665,9 +876,9 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. } private ActionBarMenuItem getSecondaryMenuItem() { - if (callItem != null) { + if (callItemVisible) { return callItem; - } else if (editItem != null) { + } else if (editItemVisible) { return editItem; } else { return null; @@ -676,7 +887,12 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. } public ProfileActivity(Bundle args) { + this(args, null); + } + + public ProfileActivity(Bundle args, SharedMediaLayout.SharedMediaPreloader preloader) { super(args); + sharedMediaPreloader = preloader; } @Override @@ -685,6 +901,12 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. chat_id = arguments.getInt("chat_id", 0); banFromGroup = arguments.getInt("ban_chat_id", 0); reportSpam = arguments.getBoolean("reportSpam", false); + if (!expandPhoto) { + expandPhoto = arguments.getBoolean("expandPhoto", false); + if (expandPhoto) { + needSendMessage = true; + } + } if (user_id != 0) { dialog_id = arguments.getLong("dialog_id", 0); if (dialog_id != 0) { @@ -750,21 +972,13 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. } else { return false; } - - sharedMediaData = new MediaActivity.SharedMediaData[5]; - for (int a = 0; a < sharedMediaData.length; a++) { - sharedMediaData[a] = new MediaActivity.SharedMediaData(); - sharedMediaData[a].setMaxId(0, dialog_id != 0 ? Integer.MIN_VALUE : Integer.MAX_VALUE); + if (sharedMediaPreloader == null) { + sharedMediaPreloader = new SharedMediaLayout.SharedMediaPreloader(this); } + sharedMediaPreloader.addDelegate(this); - loadMediaCounts(); - - NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.mediaCountDidLoad); - NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.mediaCountsDidLoad); - NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.mediaDidLoad); NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.updateInterfaces); NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.didReceiveNewMessages); - NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.messagesDeleted); NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.closeChats); NotificationCenter.getGlobalInstance().addObserver(this, NotificationCenter.emojiDidLoad); updateRowsIds(); @@ -775,13 +989,19 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. @Override public void onFragmentDestroy() { super.onFragmentDestroy(); - NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.mediaCountDidLoad); - NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.mediaCountsDidLoad); - NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.mediaDidLoad); + if (sharedMediaLayout != null) { + sharedMediaLayout.onDestroy(); + } + if (sharedMediaPreloader != null) { + sharedMediaPreloader.onDestroy(this); + } + if (sharedMediaPreloader != null) { + sharedMediaPreloader.removeDelegate(this); + } + NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.updateInterfaces); NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.closeChats); NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.didReceiveNewMessages); - NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.messagesDeleted); NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.emojiDidLoad); if (avatarsViewPager != null) { avatarsViewPager.onDestroy(); @@ -803,18 +1023,24 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. @Override protected ActionBar createActionBar(Context context) { ActionBar actionBar = new ActionBar(context) { + @Override public boolean onTouchEvent(MotionEvent event) { + avatarImage.getHitRect(rect); + if (rect.contains((int) event.getX(), (int) event.getY())) { + return false; + } return super.onTouchEvent(event); } }; actionBar.setBackgroundColor(Color.TRANSPARENT); actionBar.setItemsBackgroundColor(AvatarDrawable.getButtonColorForId(user_id != 0 || ChatObject.isChannel(chat_id, currentAccount) && !currentChat.megagroup ? 5 : chat_id), false); actionBar.setItemsColor(Theme.getColor(Theme.key_actionBarDefaultIcon), false); - actionBar.setItemsColor(Theme.getColor(Theme.key_actionBarActionModeDefaultIcon), true); + actionBar.setItemsColor(Theme.getColor(Theme.key_player_actionBarTitle), true); actionBar.setBackButtonDrawable(new BackDrawable(false)); actionBar.setCastShadows(false); actionBar.setAddToContainer(false); + actionBar.setClipContent(true); actionBar.setOccupyStatusBar(Build.VERSION.SDK_INT >= 21 && !AndroidUtilities.isTablet()); return actionBar; } @@ -848,7 +1074,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. if (param == 1) { NotificationCenter.getInstance(currentAccount).removeObserver(ProfileActivity.this, NotificationCenter.closeChats); NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.closeChats); - playProfileAnimation = false; + playProfileAnimation = 0; finishFragment(); } else { getNotificationCenter().postNotificationName(NotificationCenter.peerSettingsDidLoad, (long) user_id); @@ -1046,17 +1272,90 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. } progressDialog[0].setOnCancelListener(dialog -> ConnectionsManager.getInstance(currentAccount).cancelRequest(requestId, true)); showDialog(progressDialog[0]); + } else if (id == start_secret_chat) { + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setTitle(LocaleController.getString("AreYouSureSecretChatTitle", R.string.AreYouSureSecretChatTitle)); + builder.setMessage(LocaleController.getString("AreYouSureSecretChat", R.string.AreYouSureSecretChat)); + builder.setPositiveButton(LocaleController.getString("Start", R.string.Start), (dialogInterface, i) -> { + creatingChat = true; + SecretChatHelper.getInstance(currentAccount).startSecretChat(getParentActivity(), MessagesController.getInstance(currentAccount).getUser(user_id)); + }); + builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); + showDialog(builder.create()); + } else if (id == gallery_menu_save) { + if (getParentActivity() == null) { + return; + } + if (Build.VERSION.SDK_INT >= 23 && getParentActivity().checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { + getParentActivity().requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 4); + return; + } + ImageLocation location = avatarsViewPager.getImageLocation(avatarsViewPager.getRealPosition()); + if (location != null) { + File f = FileLoader.getPathToAttach(location.location, true); + if (f != null && f.exists()) { + MediaController.saveFile(f.toString(), getParentActivity(), 0, null, null); + } + } } } }); + if (sharedMediaLayout != null) { + sharedMediaLayout.onDestroy(); + } + final long did; + if (dialog_id != 0) { + did = dialog_id; + } else if (user_id != 0) { + did = user_id; + } else { + did = -chat_id; + } + ArrayList users = chatInfo != null && chatInfo.participants != null && chatInfo.participants.participants.size() > 5 ? sortedUsers : null; + TLRPC.ChatFull chatFull = users != null ? chatInfo : null; + sharedMediaLayout = new SharedMediaLayout(context, did, sharedMediaPreloader.getLastMediaCount(), sharedMediaPreloader.getSharedMediaData(), userInfo != null ? userInfo.common_chats_count : 0, sortedUsers, chatFull, this) { + @Override + protected void onSelectedTabChanged() { + updateSelectedMediaTabText(); + } + + @Override + protected boolean canShowSearchItem() { + return mediaHeaderVisible; + } + + @Override + protected void onSearchStateChanged(boolean expanded) { + listView.stopScroll(); + avatarImage.setVisibility(expanded ? INVISIBLE : VISIBLE); + nameTextView[1].setVisibility(expanded ? INVISIBLE : VISIBLE); + onlineTextView[1].setVisibility(expanded ? INVISIBLE : VISIBLE); + onlineTextView[2].setVisibility(expanded ? INVISIBLE : VISIBLE); + callItem.setVisibility(expanded || !callItemVisible ? GONE : INVISIBLE); + editItem.setVisibility(expanded || !editItemVisible ? GONE : INVISIBLE); + otherItem.setVisibility(expanded ? GONE : INVISIBLE); + } + + @Override + protected boolean onMemberClick(TLRPC.ChatParticipant participant, boolean isLong) { + return ProfileActivity.this.onMemberClick(participant, isLong); + } + }; + sharedMediaLayout.setLayoutParams(new RecyclerView.LayoutParams(RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.MATCH_PARENT)); + + ActionBarMenu menu = actionBar.createMenu(); + callItem = menu.addItem(call_item, R.drawable.ic_call); + editItem = menu.addItem(edit_channel, R.drawable.group_edit_profile); + otherItem = menu.addItem(10, R.drawable.ic_ab_other); + createActionBarMenu(); listAdapter = new ListAdapter(context); avatarDrawable = new AvatarDrawable(); avatarDrawable.setProfile(true); - fragmentView = new FrameLayout(context) { + fragmentView = new NestedFrameLayout(context) { private boolean ignoreLayout; private boolean firstLayout = true; @@ -1068,45 +1367,92 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - final int newTop = (actionBar.getOccupyStatusBar() ? AndroidUtilities.statusBarHeight : 0) + ActionBar.getCurrentActionBarHeight(); + final int actionBarHeight = ActionBar.getCurrentActionBarHeight() + (actionBar.getOccupyStatusBar() ? AndroidUtilities.statusBarHeight : 0); if (listView != null) { FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) listView.getLayoutParams(); - if (layoutParams.topMargin != newTop) { - layoutParams.topMargin = newTop; + if (layoutParams.topMargin != actionBarHeight) { + layoutParams.topMargin = actionBarHeight; } } super.onMeasure(widthMeasureSpec, heightMeasureSpec); + int height = MeasureSpec.getSize(heightMeasureSpec); boolean changed = false; - final int actionBarHeight = ActionBar.getCurrentActionBarHeight() + (actionBar.getOccupyStatusBar() ? AndroidUtilities.statusBarHeight : 0); if (lastMeasuredContentWidth != getMeasuredWidth()) { changed = lastMeasuredContentWidth != 0; listContentHeight = 0; int count = listAdapter.getItemCount(); lastMeasuredContentWidth = getMeasuredWidth(); int ws = MeasureSpec.makeMeasureSpec(getMeasuredWidth(), MeasureSpec.EXACTLY); - int hs = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); + int hs = MeasureSpec.makeMeasureSpec(listView.getMeasuredHeight(), MeasureSpec.UNSPECIFIED); + positionToOffset.clear(); for (int i = 0; i < count; i++) { RecyclerView.ViewHolder holder = listAdapter.createViewHolder(null, listAdapter.getItemViewType(i)); listAdapter.onBindViewHolder(holder, i); - holder.itemView.measure(ws, hs); - listContentHeight += holder.itemView.getMeasuredHeight(); - if (listContentHeight + actionBarHeight + AndroidUtilities.dp(88) >= fragmentView.getMeasuredHeight()) { - break; + positionToOffset.put(i, listContentHeight); + if (holder.itemView instanceof SharedMediaLayout) { + listContentHeight += listView.getMeasuredHeight(); + } else { + holder.itemView.measure(ws, hs); + listContentHeight += holder.itemView.getMeasuredHeight(); } } } - if (!openAnimationInProgress && !firstLayout) { + if (firstLayout && (expandPhoto || openAnimationInProgress && playProfileAnimation == 2)) { + ignoreLayout = true; + + if (expandPhoto) { + nameTextView[1].setTextColor(Color.WHITE); + onlineTextView[1].setTextColor(Color.argb(179, 255, 255, 255)); + actionBar.setItemsBackgroundColor(Theme.ACTION_BAR_WHITE_SELECTOR_COLOR, false); + overlaysView.setOverlaysVisible(); + overlaysView.setAlphaValue(1.0f, false); + avatarImage.setForegroundAlpha(1.0f); + avatarImage.setVisibility(View.GONE); + avatarsViewPager.resetCurrentItem(); + avatarsViewPager.setVisibility(View.VISIBLE); + expandPhoto = false; + } + + allowPullingDown = true; + isPulledDown = true; + if (otherItem != null) { + otherItem.showSubItem(gallery_menu_save); + } + currentExpanAnimatorFracture = 1.0f; + + int paddingTop; + int paddingBottom; + if (isInLandscapeMode) { + paddingTop = AndroidUtilities.dp(88f); + paddingBottom = 0; + } else { + paddingTop = listView.getMeasuredWidth(); + paddingBottom = Math.max(0, fragmentView.getMeasuredHeight() - (listContentHeight + AndroidUtilities.dp(88) + actionBarHeight)); + } + if (banFromGroup != 0) { + paddingBottom += AndroidUtilities.dp(48); + listView.setBottomGlowOffset(AndroidUtilities.dp(48)); + } else { + listView.setBottomGlowOffset(0); + } + initialAnimationExtraHeight = paddingTop - actionBarHeight; + layoutManager.scrollToPositionWithOffset(0, -actionBarHeight); + listView.setPadding(0, paddingTop, 0, paddingBottom); + measureChildWithMargins(listView, widthMeasureSpec, 0, heightMeasureSpec, 0); + listView.layout(0, actionBarHeight, listView.getMeasuredWidth(), actionBarHeight + listView.getMeasuredHeight()); + ignoreLayout = false; + } else if (!openAnimationInProgress && !firstLayout) { ignoreLayout = true; int paddingTop; int paddingBottom; - if (!isInLandscapeMode) { - paddingTop = listView.getMeasuredWidth() - actionBarHeight; - paddingBottom = Math.max(0, fragmentView.getMeasuredHeight() - (listContentHeight + actionBarHeight + AndroidUtilities.dp(88))); - } else { + if (isInLandscapeMode) { paddingTop = AndroidUtilities.dp(88f); paddingBottom = 0; + } else { + paddingTop = listView.getMeasuredWidth(); + paddingBottom = Math.max(0, fragmentView.getMeasuredHeight() - (listContentHeight + AndroidUtilities.dp(88) + actionBarHeight)); } if (banFromGroup != 0) { paddingBottom += AndroidUtilities.dp(48); @@ -1137,7 +1483,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. } if (layout) { measureChildWithMargins(listView, widthMeasureSpec, 0, heightMeasureSpec, 0); - listView.layout(0, newTop, listView.getMeasuredWidth(), newTop + listView.getMeasuredHeight()); + listView.layout(0, actionBarHeight, listView.getMeasuredWidth(), actionBarHeight + listView.getMeasuredHeight()); } ignoreLayout = false; } @@ -1171,14 +1517,19 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. return false; } + @Override + protected void requestChildOnScreen(View child, View focused) { + + } + @Override public void onDraw(Canvas c) { ViewHolder holder; - if (lastSectionRow != -1) { + if (sharedMediaRow != -1) { + holder = null; + } else if (lastSectionRow != -1) { holder = findViewHolderForAdapterPosition(lastSectionRow); - } else if (sharedSectionRow != -1 && (membersSectionRow == -1 || membersSectionRow < sharedSectionRow)) { - holder = findViewHolderForAdapterPosition(sharedSectionRow); - } else if (membersSectionRow != -1 && (sharedSectionRow == -1 || membersSectionRow > sharedSectionRow)) { + } else if (membersSectionRow != -1 && (sharedMediaRow == -1 || membersSectionRow > sharedMediaRow)) { holder = findViewHolderForAdapterPosition(membersSectionRow); } else if (settingsSectionRow != -1) { holder = findViewHolderForAdapterPosition(settingsSectionRow); @@ -1259,7 +1610,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. @Override public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler, RecyclerView.State state) { final View view = layoutManager.findViewByPosition(0); - if (view != null) { + if (view != null && !openingAvatar) { final int canScroll = view.getTop() - AndroidUtilities.dp(88); if (!allowPullingDown && canScroll > dy) { dy = canScroll; @@ -1271,7 +1622,9 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. dy = canScroll; allowPullingDown = false; } else if (listView.getScrollState() == RecyclerListView.SCROLL_STATE_DRAGGING) { - if (!isPulledDown) dy /= 2; + if (!isPulledDown) { + dy /= 2; + } } } } @@ -1280,56 +1633,20 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. }; layoutManager.setOrientation(LinearLayoutManager.VERTICAL); listView.setLayoutManager(layoutManager); - listView.setGlowColor(AvatarDrawable.getProfileBackColorForId(user_id != 0 || ChatObject.isChannel(chat_id, currentAccount) && !currentChat.megagroup ? 5 : chat_id)); - frameLayout.addView(listView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.TOP | Gravity.LEFT)); - + listView.setGlowColor(0); listView.setAdapter(listAdapter); + frameLayout.addView(listView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.TOP | Gravity.LEFT)); listView.setOnItemClickListener((view, position, x, y) -> { if (getParentActivity() == null) { return; } - if (position == photosRow || position == filesRow || position == linksRow || position == audioRow || position == voiceRow) { - int tab; - if (position == photosRow) { - tab = MediaDataController.MEDIA_PHOTOVIDEO; - } else if (position == filesRow) { - tab = MediaDataController.MEDIA_FILE; - } else if (position == linksRow) { - tab = MediaDataController.MEDIA_URL; - } else if (position == audioRow) { - tab = MediaDataController.MEDIA_MUSIC; - } else { - tab = MediaDataController.MEDIA_AUDIO; - } - Bundle args = new Bundle(); - if (user_id != 0) { - args.putLong("dialog_id", dialog_id != 0 ? dialog_id : user_id); - } else { - args.putLong("dialog_id", -chat_id); - } - int[] media = new int[MediaDataController.MEDIA_TYPES_COUNT]; - System.arraycopy(lastMediaCount, 0, media, 0, media.length); - mediaActivity = new MediaActivity(args, media, sharedMediaData, tab); - mediaActivity.setChatInfo(chatInfo); - presentFragment(mediaActivity); - } else if (position == groupsInCommonRow) { - presentFragment(new CommonGroupsActivity(user_id)); - } else if (position == settingsKeyRow) { + if (position == settingsKeyRow) { Bundle args = new Bundle(); args.putInt("chat_id", (int) (dialog_id >> 32)); presentFragment(new IdenticonActivity(args)); } else if (position == settingsTimerRow) { showDialog(AlertsCreator.createTTLAlert(getParentActivity(), currentEncryptedChat).create()); } else if (position == notificationsRow) { - final long did; - if (dialog_id != 0) { - did = dialog_id; - } else if (user_id != 0) { - did = user_id; - } else { - did = -chat_id; - } - if (LocaleController.isRTL && x <= AndroidUtilities.dp(76) || !LocaleController.isRTL && x >= view.getMeasuredWidth() - AndroidUtilities.dp(76)) { NotificationsCheckCell checkCell = (NotificationsCheckCell) view; boolean checked = !checkCell.isChecked(); @@ -1383,32 +1700,21 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. return; } AlertsCreator.showCustomNotificationsDialog(ProfileActivity.this, did, -1, null, currentAccount, param -> listAdapter.notifyItemChanged(notificationsRow)); - } else if (position == startSecretChatRow) { - AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); - builder.setTitle(LocaleController.getString("AreYouSureSecretChatTitle", R.string.AreYouSureSecretChatTitle)); - builder.setMessage(LocaleController.getString("AreYouSureSecretChat", R.string.AreYouSureSecretChat)); - builder.setPositiveButton(LocaleController.getString("Start", R.string.Start), (dialogInterface, i) -> { - creatingChat = true; - SecretChatHelper.getInstance(currentAccount).startSecretChat(getParentActivity(), MessagesController.getInstance(currentAccount).getUser(user_id)); - }); - builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); - showDialog(builder.create()); } else if (position == unblockRow) { MessagesController.getInstance(currentAccount).unblockUser(user_id); AlertsCreator.showSimpleToast(ProfileActivity.this, LocaleController.getString("UserUnblocked", R.string.UserUnblocked)); + } else if (position == sendMessageRow) { + writeButton.callOnClick(); + } else if (position == reportRow) { + AlertsCreator.createReportAlert(getParentActivity(), getDialogId(), 0, ProfileActivity.this); } else if (position >= membersStartRow && position < membersEndRow) { - int user_id; + TLRPC.ChatParticipant participant; if (!sortedUsers.isEmpty()) { - user_id = chatInfo.participants.participants.get(sortedUsers.get(position - membersStartRow)).user_id; + participant = chatInfo.participants.participants.get(sortedUsers.get(position - membersStartRow)); } else { - user_id = chatInfo.participants.participants.get(position - membersStartRow).user_id; + participant = chatInfo.participants.participants.get(position - membersStartRow); } - if (user_id == UserConfig.getInstance(currentAccount).getClientUserId()) { - return; - } - Bundle args = new Bundle(); - args.putInt("user_id", user_id); - presentFragment(new ProfileActivity(args)); + onMemberClick(participant, false); } else if (position == addMemberRow) { openAddMember(); } else if (position == usernameRow) { @@ -1432,8 +1738,6 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. fragment.setChatLocation(chat_id, (TLRPC.TL_channelLocation) chatInfo.location); presentFragment(fragment); } - } else if (position == leaveChannelRow) { - leaveChatPressed(); } else if (position == joinRow) { MessagesController.getInstance(currentAccount).addUserToChat(currentChat.id, UserConfig.getInstance(currentAccount).getCurrentUser(), null, 0, null, ProfileActivity.this, null); NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.closeSearchByActiveAction); @@ -1465,102 +1769,13 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. listView.setOnItemLongClickListener((view, position) -> { if (position >= membersStartRow && position < membersEndRow) { - if (getParentActivity() == null) { - return false; - } final TLRPC.ChatParticipant participant; if (!sortedUsers.isEmpty()) { participant = chatInfo.participants.participants.get(sortedUsers.get(position - membersStartRow)); } else { participant = chatInfo.participants.participants.get(position - membersStartRow); } - TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(participant.user_id); - if (user == null || participant.user_id == UserConfig.getInstance(currentAccount).getClientUserId()) { - return false; - } - selectedUser = participant.user_id; - boolean allowKick; - boolean canEditAdmin; - boolean canRestrict; - boolean editingAdmin; - final TLRPC.ChannelParticipant channelParticipant; - - if (ChatObject.isChannel(currentChat)) { - channelParticipant = ((TLRPC.TL_chatChannelParticipant) participant).channelParticipant; - TLRPC.User u = MessagesController.getInstance(currentAccount).getUser(participant.user_id); - canEditAdmin = ChatObject.canAddAdmins(currentChat); - if (canEditAdmin && (channelParticipant instanceof TLRPC.TL_channelParticipantCreator || channelParticipant instanceof TLRPC.TL_channelParticipantAdmin && !channelParticipant.can_edit)) { - canEditAdmin = false; - } - allowKick = canRestrict = ChatObject.canBlockUsers(currentChat) && (!(channelParticipant instanceof TLRPC.TL_channelParticipantAdmin || channelParticipant instanceof TLRPC.TL_channelParticipantCreator) || channelParticipant.can_edit); - editingAdmin = channelParticipant instanceof TLRPC.TL_channelParticipantAdmin; - } else { - channelParticipant = null; - allowKick = currentChat.creator || participant instanceof TLRPC.TL_chatParticipant && (ChatObject.canBlockUsers(currentChat) || participant.inviter_id == UserConfig.getInstance(currentAccount).getClientUserId()); - canEditAdmin = currentChat.creator; - canRestrict = currentChat.creator; - editingAdmin = participant instanceof TLRPC.TL_chatParticipantAdmin; - } - - ArrayList items = new ArrayList<>(); - ArrayList icons = new ArrayList<>(); - final ArrayList actions = new ArrayList<>(); - boolean hasRemove = false; - - if (canEditAdmin) { - items.add(editingAdmin ? LocaleController.getString("EditAdminRights", R.string.EditAdminRights) : LocaleController.getString("SetAsAdmin", R.string.SetAsAdmin)); - icons.add(R.drawable.actions_addadmin); - actions.add(0); - } - if (canRestrict) { - items.add(LocaleController.getString("ChangePermissions", R.string.ChangePermissions)); - icons.add(R.drawable.actions_permissions); - actions.add(1); - } - if (allowKick) { - items.add(LocaleController.getString("KickFromGroup", R.string.KickFromGroup)); - icons.add(R.drawable.actions_remove_user); - actions.add(2); - hasRemove = true; - } - - if (items.isEmpty()) { - return false; - } - AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); - builder.setItems(items.toArray(new CharSequence[0]), AndroidUtilities.toIntArray(icons), (dialogInterface, i) -> { - if (actions.get(i) == 2) { - kickUser(selectedUser); - } else { - int action = actions.get(i); - if (action == 1 && (channelParticipant instanceof TLRPC.TL_channelParticipantAdmin || participant instanceof TLRPC.TL_chatParticipantAdmin)) { - AlertDialog.Builder builder2 = new AlertDialog.Builder(getParentActivity()); - builder2.setTitle(LocaleController.getString("AppName", R.string.AppName)); - builder2.setMessage(LocaleController.formatString("AdminWillBeRemoved", R.string.AdminWillBeRemoved, ContactsController.formatName(user.first_name, user.last_name))); - builder2.setPositiveButton(LocaleController.getString("OK", R.string.OK), (dialog, which) -> { - if (channelParticipant != null) { - openRightsEdit(action, user.id, participant, channelParticipant.admin_rights, channelParticipant.banned_rights, channelParticipant.rank); - } else { - openRightsEdit(action, user.id, participant, null, null, ""); - } - }); - builder2.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); - showDialog(builder2.create()); - } else { - if (channelParticipant != null) { - openRightsEdit(action, user.id, participant, channelParticipant.admin_rights, channelParticipant.banned_rights, channelParticipant.rank); - } else { - openRightsEdit(action, user.id, participant, null, null, ""); - } - } - } - }); - AlertDialog alertDialog = builder.create(); - showDialog(alertDialog); - if (hasRemove) { - alertDialog.setItemColor(items.size() - 1, Theme.getColor(Theme.key_dialogTextRed2), Theme.getColor(Theme.key_dialogRedIcon)); - } - return true; + return onMemberClick(participant, true); } else { return processOnClickOrPress(position); } @@ -1630,27 +1845,24 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. avatarImage.setPivotY(0); frameLayout.addView(avatarImage, LayoutHelper.createFrame(42, 42, Gravity.TOP | Gravity.LEFT, 64, 0, 0, 0)); avatarImage.setOnClickListener(v -> { - if (listView.getScrollState() != RecyclerView.SCROLL_STATE_DRAGGING) { - if (user_id != 0) { - TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(user_id); - if (user.photo != null && user.photo.photo_big != null) { - PhotoViewer.getInstance().setParentActivity(getParentActivity()); - if (user.photo.dc_id != 0) { - user.photo.photo_big.dc_id = user.photo.dc_id; - } - PhotoViewer.getInstance().openPhoto(user.photo.photo_big, provider); - } - } else if (chat_id != 0) { - TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(chat_id); - if (chat.photo != null && chat.photo.photo_big != null) { - PhotoViewer.getInstance().setParentActivity(getParentActivity()); - if (chat.photo.dc_id != 0) { - chat.photo.photo_big.dc_id = chat.photo.dc_id; - } - PhotoViewer.getInstance().openPhoto(chat.photo.photo_big, provider); + if (!isInLandscapeMode && avatarImage.getImageReceiver().hasNotThumb()) { + openingAvatar = true; + allowPullingDown = true; + View child = listView.getChildAt(0); + RecyclerView.ViewHolder holder = listView.findContainingViewHolder(child); + if (holder != null) { + Integer offset = positionToOffset.get(holder.getAdapterPosition()); + if (offset != null) { + listView.smoothScrollBy(0, -(offset + (listView.getPaddingTop() - child.getTop() - actionBar.getMeasuredHeight())), CubicBezierInterpolator.EASE_OUT_QUINT); + return; } } } + openAvatar(); + }); + avatarImage.setOnLongClickListener(v -> { + openAvatar(); + return false; }); avatarImage.setContentDescription(LocaleController.getString("AccDescrProfilePicture", R.string.AccDescrProfilePicture)); @@ -1668,8 +1880,8 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. frameLayout.addView(actionBar); - for (int a = 0; a < 2; a++) { - if (!playProfileAnimation && a == 0) { + for (int a = 0; a < nameTextView.length; a++) { + if (playProfileAnimation == 0 && a == 0) { continue; } nameTextView[a] = new SimpleTextView(context); @@ -1687,15 +1899,19 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. nameTextView[a].setAlpha(a == 0 ? 0.0f : 1.0f); if (a == 1) { nameTextView[a].setScrollNonFitText(true); - nameTextView[a].setBackgroundColor(Theme.getColor(Theme.key_avatar_backgroundActionBarBlue)); } frameLayout.addView(nameTextView[a], LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.TOP, 118, 0, a == 0 ? 48 : 0, 0)); - + } + for (int a = 0; a < onlineTextView.length; a++) { onlineTextView[a] = new SimpleTextView(context); - onlineTextView[a].setTextColor(Theme.getColor(Theme.key_avatar_subtitleInProfileBlue)); + if (a == 2) { + onlineTextView[a].setTextColor(Theme.getColor(Theme.key_player_actionBarSubtitle)); + } else { + onlineTextView[a].setTextColor(Theme.getColor(Theme.key_avatar_subtitleInProfileBlue)); + } onlineTextView[a].setTextSize(14); onlineTextView[a].setGravity(Gravity.LEFT); - onlineTextView[a].setAlpha(a == 0 ? 0.0f : 1.0f); + onlineTextView[a].setAlpha(a == 0 || a == 2 ? 0.0f : 1.0f); frameLayout.addView(onlineTextView[a], LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.TOP, 118, 0, a == 0 ? 48 : 8, 0)); } updateProfileData(); @@ -1730,7 +1946,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. } frameLayout.addView(writeButton, LayoutHelper.createFrame(Build.VERSION.SDK_INT >= 21 ? 56 : 60, Build.VERSION.SDK_INT >= 21 ? 56 : 60, Gravity.RIGHT | Gravity.TOP, 0, 0, 16, 0)); writeButton.setOnClickListener(v -> { - if (playProfileAnimation && parentLayout.fragmentsStack.get(parentLayout.fragmentsStack.size() - 2) instanceof ChatActivity) { + if (playProfileAnimation != 0 && parentLayout.fragmentsStack.get(parentLayout.fragmentsStack.size() - 2) instanceof ChatActivity) { finishFragment(); } else { TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(user_id); @@ -1751,6 +1967,17 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. needLayout(); listView.setOnScrollListener(new RecyclerView.OnScrollListener() { + + @Override + public void onScrollStateChanged(RecyclerView recyclerView, int newState) { + if (newState == RecyclerView.SCROLL_STATE_DRAGGING) { + AndroidUtilities.hideKeyboard(getParentActivity().getCurrentFocus()); + } + if (openingAvatar && newState != RecyclerView.SCROLL_STATE_SETTLING) { + openingAvatar = false; + } + } + @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { checkListViewScroll(); @@ -1763,9 +1990,237 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. undoView = new UndoView(context); frameLayout.addView(undoView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.BOTTOM | Gravity.LEFT, 8, 0, 8, 8)); + expandAnimator = ValueAnimator.ofFloat(0f, 1f); + expandAnimator.addUpdateListener(anim -> { + final int newTop = ActionBar.getCurrentActionBarHeight() + (actionBar.getOccupyStatusBar() ? AndroidUtilities.statusBarHeight : 0); + final float value = AndroidUtilities.lerp(expandAnimatorValues, currentExpanAnimatorFracture = anim.getAnimatedFraction()); + + avatarImage.setScaleX(avatarScale); + avatarImage.setScaleY(avatarScale); + avatarImage.setTranslationX(AndroidUtilities.lerp(avatarX, 0f, value)); + avatarImage.setTranslationY(AndroidUtilities.lerp((float) Math.ceil(avatarY), 0f, value)); + avatarImage.setRoundRadius((int) AndroidUtilities.lerp(AndroidUtilities.dpf2(21f), 0f, value)); + + if (extraHeight > AndroidUtilities.dpf2(88f) && expandProgress < 0.33f) { + refreshNameAndOnlineXY(); + } + + if (scamDrawable != null) { + scamDrawable.setColor(ColorUtils.blendARGB(Theme.getColor(Theme.key_avatar_subtitleInProfileBlue), Color.argb(179, 255, 255, 255), value)); + } + + if (lockIconDrawable != null) { + lockIconDrawable.setColorFilter(ColorUtils.blendARGB(Theme.getColor(Theme.key_chat_lockIcon), Color.WHITE, value), PorterDuff.Mode.MULTIPLY); + } + + if (verifiedCrossfadeDrawable != null) { + verifiedCrossfadeDrawable.setProgress(value); + } + + final float k = AndroidUtilities.dpf2(8f); + + final float nameTextViewXEnd = AndroidUtilities.dpf2(16f) - nameTextView[1].getLeft(); + final float nameTextViewYEnd = newTop + extraHeight - AndroidUtilities.dpf2(38f) - nameTextView[1].getBottom(); + final float nameTextViewCx = k + nameX + (nameTextViewXEnd - nameX) / 2f; + final float nameTextViewCy = k + nameY + (nameTextViewYEnd - nameY) / 2f; + final float nameTextViewX = (1 - value) * (1 - value) * nameX + 2 * (1 - value) * value * nameTextViewCx + value * value * nameTextViewXEnd; + final float nameTextViewY = (1 - value) * (1 - value) * nameY + 2 * (1 - value) * value * nameTextViewCy + value * value * nameTextViewYEnd; + + final float onlineTextViewXEnd = AndroidUtilities.dpf2(16f) - onlineTextView[1].getLeft(); + final float onlineTextViewYEnd = newTop + extraHeight - AndroidUtilities.dpf2(18f) - onlineTextView[1].getBottom(); + final float onlineTextViewCx = k + onlineX + (onlineTextViewXEnd - onlineX) / 2f; + final float onlineTextViewCy = k + onlineY + (onlineTextViewYEnd - onlineY) / 2f; + final float onlineTextViewX = (1 - value) * (1 - value) * onlineX + 2 * (1 - value) * value * onlineTextViewCx + value * value * onlineTextViewXEnd; + final float onlineTextViewY = (1 - value) * (1 - value) * onlineY + 2 * (1 - value) * value * onlineTextViewCy + value * value * onlineTextViewYEnd; + + nameTextView[1].setTranslationX(nameTextViewX); + nameTextView[1].setTranslationY(nameTextViewY); + onlineTextView[1].setTranslationX(onlineTextViewX); + onlineTextView[1].setTranslationY(onlineTextViewY); + onlineTextView[2].setTranslationX(onlineTextViewX); + onlineTextView[2].setTranslationY(onlineTextViewY); + final Object onlineTextViewTag = onlineTextView[1].getTag(); + int statusColor; + if (onlineTextViewTag instanceof String) { + statusColor = Theme.getColor((String) onlineTextViewTag); + } else { + statusColor = Theme.getColor(Theme.key_avatar_subtitleInProfileBlue); + } + onlineTextView[1].setTextColor(ColorUtils.blendARGB(statusColor, Color.argb(179, 255, 255, 255), value)); + if (extraHeight > AndroidUtilities.dpf2(88f)) { + nameTextView[1].setPivotY(AndroidUtilities.lerp(0, nameTextView[1].getMeasuredHeight(), value)); + nameTextView[1].setScaleX(AndroidUtilities.lerp(1.12f, 1.67f, value)); + nameTextView[1].setScaleY(AndroidUtilities.lerp(1.12f, 1.67f, value)); + } + + needLayoutText(Math.min(1f, extraHeight / AndroidUtilities.dpf2(88f))); + + nameTextView[1].setTextColor(ColorUtils.blendARGB(Theme.getColor(Theme.key_profile_title), Color.WHITE, value)); + actionBar.setItemsColor(ColorUtils.blendARGB(Theme.getColor(Theme.key_actionBarDefaultIcon), Color.WHITE, value), false); + + avatarImage.setForegroundAlpha(value); + + final FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) avatarImage.getLayoutParams(); + params.width = (int) AndroidUtilities.lerp(AndroidUtilities.dpf2(42f), listView.getMeasuredWidth() / avatarScale, value); + params.height = (int) AndroidUtilities.lerp(AndroidUtilities.dpf2(42f), (extraHeight + newTop) / avatarScale, value); + params.leftMargin = (int) AndroidUtilities.lerp(AndroidUtilities.dpf2(64f), 0f, value); + avatarImage.requestLayout(); + }); + expandAnimator.setInterpolator(CubicBezierInterpolator.EASE_BOTH); + expandAnimator.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationStart(Animator animation) { + + } + + @Override + public void onAnimationEnd(Animator animation) { + actionBar.setItemsBackgroundColor(isPulledDown ? Theme.ACTION_BAR_WHITE_SELECTOR_COLOR : Theme.getColor(Theme.key_avatar_actionBarSelectorBlue), false); + } + }); + + updateSelectedMediaTabText(); + return fragmentView; } + public long getDialogId() { + if (dialog_id != 0) { + return dialog_id; + } else if (user_id != 0) { + return user_id; + } else { + return -chat_id; + } + } + + private void openAvatar() { + if (listView.getScrollState() == RecyclerView.SCROLL_STATE_DRAGGING) { + return; + } + if (user_id != 0) { + TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(user_id); + if (user.photo != null && user.photo.photo_big != null) { + PhotoViewer.getInstance().setParentActivity(getParentActivity()); + if (user.photo.dc_id != 0) { + user.photo.photo_big.dc_id = user.photo.dc_id; + } + PhotoViewer.getInstance().openPhoto(user.photo.photo_big, provider); + } + } else if (chat_id != 0) { + TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(chat_id); + if (chat.photo != null && chat.photo.photo_big != null) { + PhotoViewer.getInstance().setParentActivity(getParentActivity()); + if (chat.photo.dc_id != 0) { + chat.photo.photo_big.dc_id = chat.photo.dc_id; + } + PhotoViewer.getInstance().openPhoto(chat.photo.photo_big, provider); + } + } + } + + private boolean onMemberClick(TLRPC.ChatParticipant participant, boolean isLong) { + if (getParentActivity() == null) { + return false; + } + if (isLong) { + TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(participant.user_id); + if (user == null || participant.user_id == UserConfig.getInstance(currentAccount).getClientUserId()) { + return false; + } + selectedUser = participant.user_id; + boolean allowKick; + boolean canEditAdmin; + boolean canRestrict; + boolean editingAdmin; + final TLRPC.ChannelParticipant channelParticipant; + + if (ChatObject.isChannel(currentChat)) { + channelParticipant = ((TLRPC.TL_chatChannelParticipant) participant).channelParticipant; + TLRPC.User u = MessagesController.getInstance(currentAccount).getUser(participant.user_id); + canEditAdmin = ChatObject.canAddAdmins(currentChat); + if (canEditAdmin && (channelParticipant instanceof TLRPC.TL_channelParticipantCreator || channelParticipant instanceof TLRPC.TL_channelParticipantAdmin && !channelParticipant.can_edit)) { + canEditAdmin = false; + } + allowKick = canRestrict = ChatObject.canBlockUsers(currentChat) && (!(channelParticipant instanceof TLRPC.TL_channelParticipantAdmin || channelParticipant instanceof TLRPC.TL_channelParticipantCreator) || channelParticipant.can_edit); + editingAdmin = channelParticipant instanceof TLRPC.TL_channelParticipantAdmin; + } else { + channelParticipant = null; + allowKick = currentChat.creator || participant instanceof TLRPC.TL_chatParticipant && (ChatObject.canBlockUsers(currentChat) || participant.inviter_id == UserConfig.getInstance(currentAccount).getClientUserId()); + canEditAdmin = currentChat.creator; + canRestrict = currentChat.creator; + editingAdmin = participant instanceof TLRPC.TL_chatParticipantAdmin; + } + + ArrayList items = new ArrayList<>(); + ArrayList icons = new ArrayList<>(); + final ArrayList actions = new ArrayList<>(); + boolean hasRemove = false; + + if (canEditAdmin) { + items.add(editingAdmin ? LocaleController.getString("EditAdminRights", R.string.EditAdminRights) : LocaleController.getString("SetAsAdmin", R.string.SetAsAdmin)); + icons.add(R.drawable.actions_addadmin); + actions.add(0); + } + if (canRestrict) { + items.add(LocaleController.getString("ChangePermissions", R.string.ChangePermissions)); + icons.add(R.drawable.actions_permissions); + actions.add(1); + } + if (allowKick) { + items.add(LocaleController.getString("KickFromGroup", R.string.KickFromGroup)); + icons.add(R.drawable.actions_remove_user); + actions.add(2); + hasRemove = true; + } + + if (items.isEmpty()) { + return false; + } + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setItems(items.toArray(new CharSequence[0]), AndroidUtilities.toIntArray(icons), (dialogInterface, i) -> { + if (actions.get(i) == 2) { + kickUser(selectedUser); + } else { + int action = actions.get(i); + if (action == 1 && (channelParticipant instanceof TLRPC.TL_channelParticipantAdmin || participant instanceof TLRPC.TL_chatParticipantAdmin)) { + AlertDialog.Builder builder2 = new AlertDialog.Builder(getParentActivity()); + builder2.setTitle(LocaleController.getString("AppName", R.string.AppName)); + builder2.setMessage(LocaleController.formatString("AdminWillBeRemoved", R.string.AdminWillBeRemoved, ContactsController.formatName(user.first_name, user.last_name))); + builder2.setPositiveButton(LocaleController.getString("OK", R.string.OK), (dialog, which) -> { + if (channelParticipant != null) { + openRightsEdit(action, user.id, participant, channelParticipant.admin_rights, channelParticipant.banned_rights, channelParticipant.rank); + } else { + openRightsEdit(action, user.id, participant, null, null, ""); + } + }); + builder2.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); + showDialog(builder2.create()); + } else { + if (channelParticipant != null) { + openRightsEdit(action, user.id, participant, channelParticipant.admin_rights, channelParticipant.banned_rights, channelParticipant.rank); + } else { + openRightsEdit(action, user.id, participant, null, null, ""); + } + } + } + }); + AlertDialog alertDialog = builder.create(); + showDialog(alertDialog); + if (hasRemove) { + alertDialog.setItemColor(items.size() - 1, Theme.getColor(Theme.key_dialogTextRed2), Theme.getColor(Theme.key_dialogRedIcon)); + } + } else { + if (participant.user_id == UserConfig.getInstance(currentAccount).getClientUserId()) { + return false; + } + Bundle args = new Bundle(); + args.putInt("user_id", participant.user_id); + presentFragment(new ProfileActivity(args)); + } + return true; + } + private void openRightsEdit(int action, int user_id, TLRPC.ChatParticipant participant, TLRPC.TL_chatAdminRights adminRights, TLRPC.TL_chatBannedRights bannedRights, String rank) { ChatRightsEditActivity fragment = new ChatRightsEditActivity(user_id, chat_id, adminRights, currentChat.default_banned_rights, bannedRights, rank, action, true, false); fragment.setDelegate(new ChatRightsEditActivity.ChatRightsEditActivityDelegate() { @@ -1948,7 +2403,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. private void leaveChatPressed() { AlertsCreator.createClearOrDeleteDialogAlert(ProfileActivity.this, false, currentChat, null, false, (param) -> { - playProfileAnimation = false; + playProfileAnimation = 0; NotificationCenter.getInstance(currentAccount).removeObserver(ProfileActivity.this, NotificationCenter.closeChats); NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.closeChats); finishFragment(); @@ -2003,6 +2458,134 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. ConnectionsManager.getInstance(currentAccount).bindRequestToGuid(reqId, classGuid); } + private AnimatorSet headerAnimatorSet; + private AnimatorSet headerShadowAnimatorSet; + private float mediaHeaderAnimationProgress; + private boolean mediaHeaderVisible; + private Property ACTIONBAR_HEADER_PROGRESS = new AnimationProperties.FloatProperty("animationProgress") { + @Override + public void setValue(ActionBar object, float value) { + mediaHeaderAnimationProgress = value; + topView.invalidate(); + + int color1 = Theme.getColor(Theme.key_profile_title); + int color2 = Theme.getColor(Theme.key_player_actionBarTitle); + int c = AndroidUtilities.getOffsetColor(color1, color2, value, 1.0f); + nameTextView[1].setTextColor(c); + if (lockIconDrawable != null) { + lockIconDrawable.setColorFilter(c, PorterDuff.Mode.MULTIPLY); + } + if (scamDrawable != null) { + color1 = Theme.getColor(Theme.key_avatar_subtitleInProfileBlue); + scamDrawable.setColor(AndroidUtilities.getOffsetColor(color1, color2, value, 1.0f)); + } + + color1 = Theme.getColor(Theme.key_actionBarDefaultIcon); + color2 = Theme.getColor(Theme.key_player_actionBarTitle); + actionBar.setItemsColor(AndroidUtilities.getOffsetColor(color1, color2, value, 1.0f), false); + + color1 = Theme.getColor(Theme.key_avatar_actionBarSelectorBlue); + color2 = Theme.getColor(Theme.key_actionBarActionModeDefaultSelector); + actionBar.setItemsBackgroundColor(AndroidUtilities.getOffsetColor(color1, color2, value, 1.0f), false); + + topView.invalidate(); + otherItem.setIconColor(Theme.getColor(Theme.key_actionBarDefaultIcon)); + callItem.setIconColor(Theme.getColor(Theme.key_actionBarDefaultIcon)); + editItem.setIconColor(Theme.getColor(Theme.key_actionBarDefaultIcon)); + } + + @Override + public Float get(ActionBar object) { + return mediaHeaderAnimationProgress; + } + }; + + private void setMediaHeaderVisible(boolean visible) { + if (mediaHeaderVisible == visible) { + return; + } + mediaHeaderVisible = visible; + if (headerAnimatorSet != null) { + headerAnimatorSet.cancel(); + } + if (headerShadowAnimatorSet != null) { + headerShadowAnimatorSet.cancel(); + } + ActionBarMenuItem searchItem = sharedMediaLayout.getSearchItem(); + if (!mediaHeaderVisible) { + if (callItemVisible) { + callItem.setVisibility(View.VISIBLE); + } + if (editItemVisible) { + editItem.setVisibility(View.VISIBLE); + } + otherItem.setVisibility(View.VISIBLE); + } else { + if (sharedMediaLayout.isSearchItemVisible()) { + searchItem.setVisibility(View.VISIBLE); + } + } + + ArrayList animators = new ArrayList<>(); + + animators.add(ObjectAnimator.ofFloat(callItem, View.ALPHA, visible ? 0.0f : 1.0f)); + animators.add(ObjectAnimator.ofFloat(otherItem, View.ALPHA, visible ? 0.0f : 1.0f)); + animators.add(ObjectAnimator.ofFloat(editItem, View.ALPHA, visible ? 0.0f : 1.0f)); + animators.add(ObjectAnimator.ofFloat(callItem, View.TRANSLATION_Y, visible ? -AndroidUtilities.dp(10) : 0.0f)); + animators.add(ObjectAnimator.ofFloat(otherItem, View.TRANSLATION_Y, visible ? -AndroidUtilities.dp(10) : 0.0f)); + animators.add(ObjectAnimator.ofFloat(editItem, View.TRANSLATION_Y, visible ? -AndroidUtilities.dp(10) : 0.0f)); + animators.add(ObjectAnimator.ofFloat(searchItem, View.ALPHA, visible ? 1.0f : 0.0f)); + animators.add(ObjectAnimator.ofFloat(searchItem, View.TRANSLATION_Y, visible ? 0.0f : AndroidUtilities.dp(10))); + animators.add(ObjectAnimator.ofFloat(actionBar, ACTIONBAR_HEADER_PROGRESS, visible ? 1.0f : 0.0f)); + animators.add(ObjectAnimator.ofFloat(onlineTextView[1], View.ALPHA, visible ? 0.0f : 1.0f)); + animators.add(ObjectAnimator.ofFloat(onlineTextView[2], View.ALPHA, visible ? 1.0f : 0.0f)); + if (visible) { + animators.add(ObjectAnimator.ofFloat(this, HEADER_SHADOW, 0.0f)); + } + + headerAnimatorSet = new AnimatorSet(); + headerAnimatorSet.playTogether(animators); + headerAnimatorSet.setInterpolator(CubicBezierInterpolator.DEFAULT); + headerAnimatorSet.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + if (headerAnimatorSet != null) { + if (mediaHeaderVisible) { + if (callItemVisible) { + callItem.setVisibility(View.INVISIBLE); + } + if (editItemVisible) { + editItem.setVisibility(View.INVISIBLE); + } + otherItem.setVisibility(View.INVISIBLE); + } else { + if (sharedMediaLayout.isSearchItemVisible()) { + searchItem.setVisibility(View.VISIBLE); + } + headerShadowAnimatorSet = new AnimatorSet(); + headerShadowAnimatorSet.playTogether(ObjectAnimator.ofFloat(ProfileActivity.this, HEADER_SHADOW, 1.0f)); + headerShadowAnimatorSet.setDuration(100); + headerShadowAnimatorSet.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + headerShadowAnimatorSet = null; + } + }); + headerShadowAnimatorSet.start(); + } + } + headerAnimatorSet = null; + } + + @Override + public void onAnimationCancel(Animator animation) { + headerAnimatorSet = null; + } + }); + headerAnimatorSet.setDuration(150); + headerAnimatorSet.start(); + } + private void openAddMember() { Bundle args = new Bundle(); args.putBoolean("addToGroup", true); @@ -2034,19 +2617,53 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. RecyclerListView.Holder holder = (RecyclerListView.Holder) listView.findContainingViewHolder(child); int top = child.getTop(); int newOffset = 0; - if (top >= 0 && holder != null && holder.getAdapterPosition() == 0) { + int adapterPosition = holder != null ? holder.getAdapterPosition() : RecyclerView.NO_POSITION; + if (top >= 0 && adapterPosition == 0) { newOffset = top; } + boolean mediaHeaderVisible; + boolean searchVisible = actionBar.isSearchFieldVisible(); + if (sharedMediaRow != -1 && !searchVisible) { + holder = (RecyclerListView.Holder) listView.findViewHolderForAdapterPosition(sharedMediaRow); + mediaHeaderVisible = holder != null && holder.itemView.getTop() <= 0; + } else { + mediaHeaderVisible = searchVisible; + } + setMediaHeaderVisible(mediaHeaderVisible); + if (extraHeight != newOffset) { extraHeight = newOffset; topView.invalidate(); - if (playProfileAnimation) { + if (playProfileAnimation != 0) { allowProfileAnimation = extraHeight != 0; } needLayout(); } } + private void updateSelectedMediaTabText() { + if (sharedMediaLayout == null || onlineTextView[2] == null) { + return; + } + int id = sharedMediaLayout.getSelectedTab(); + int[] mediaCount = sharedMediaPreloader.getLastMediaCount(); + if (id == 0) { + onlineTextView[2].setText(LocaleController.formatPluralString("Media", mediaCount[MediaDataController.MEDIA_PHOTOVIDEO])); + } else if (id == 1) { + onlineTextView[2].setText(LocaleController.formatPluralString("Files", mediaCount[MediaDataController.MEDIA_FILE])); + } else if (id == 2) { + onlineTextView[2].setText(LocaleController.formatPluralString("Voice", mediaCount[MediaDataController.MEDIA_AUDIO])); + } else if (id == 3) { + onlineTextView[2].setText(LocaleController.formatPluralString("Links", mediaCount[MediaDataController.MEDIA_URL])); + } else if (id == 4) { + onlineTextView[2].setText(LocaleController.formatPluralString("MusicFiles", mediaCount[MediaDataController.MEDIA_MUSIC])); + } else if (id == 5) { + onlineTextView[2].setText(LocaleController.formatPluralString("CommonGroups", userInfo.common_chats_count)); + } else if (id == 6) { + onlineTextView[2].setText(onlineTextView[1].getText()); + } + } + private void needLayout() { final int newTop = (actionBar.getOccupyStatusBar() ? AndroidUtilities.statusBarHeight : 0) + ActionBar.getCurrentActionBarHeight(); @@ -2114,117 +2731,28 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. } avatarX = -AndroidUtilities.dpf2(47f) * diff; - avatarY = (actionBar.getOccupyStatusBar() ? AndroidUtilities.statusBarHeight : 0) + ActionBar.getCurrentActionBarHeight() / 2.0f * (1.0f + diff) - 21 * AndroidUtilities.density + 27 * AndroidUtilities.density * diff; + avatarY = (actionBar.getOccupyStatusBar() ? AndroidUtilities.statusBarHeight : 0) + ActionBar.getCurrentActionBarHeight() / 2.0f * (1.0f + diff) - 21 * AndroidUtilities.density + 27 * AndroidUtilities.density * diff + actionBar.getTranslationY(); - if (extraHeight > AndroidUtilities.dpf2(88f) || isPulledDown) { - expandProgress = Math.max(0f, Math.min(1f, (extraHeight - AndroidUtilities.dpf2(88f)) / (listView.getMeasuredWidth() - newTop - AndroidUtilities.dpf2(88f)))); + float h = openAnimationInProgress ? initialAnimationExtraHeight : extraHeight; + if (h > AndroidUtilities.dpf2(88f) || isPulledDown) { + expandProgress = Math.max(0f, Math.min(1f, (h - AndroidUtilities.dpf2(88f)) / (listView.getMeasuredWidth() - newTop - AndroidUtilities.dpf2(88f)))); avatarScale = AndroidUtilities.lerp((42f + 18f) / 42f, (42f + 42f + 18f) / 42f, Math.min(1f, expandProgress * 3f)); final float durationFactor = Math.min(AndroidUtilities.dpf2(2000f), Math.max(AndroidUtilities.dpf2(1100f), Math.abs(listViewVelocityY))) / AndroidUtilities.dpf2(1100f); - if (expandProgress >= 0.33f) { + if (openingAvatar || expandProgress >= 0.33f) { if (!isPulledDown) { + if (otherItem != null) { + otherItem.showSubItem(gallery_menu_save); + } isPulledDown = true; overlaysView.setOverlaysVisible(true, durationFactor); avatarsViewPagerIndicatorView.refreshVisibility(durationFactor); - if (expandAnimator == null) { - expandAnimator = ValueAnimator.ofFloat(0f, 1f); - expandAnimator.addUpdateListener(anim -> { - final float value = AndroidUtilities.lerp(expandAnimatorValues, anim.getAnimatedFraction()); - - avatarImage.setScaleX(avatarScale); - avatarImage.setScaleY(avatarScale); - avatarImage.setTranslationX(AndroidUtilities.lerp(avatarX, 0f, value)); - avatarImage.setTranslationY(AndroidUtilities.lerp((float) Math.ceil(avatarY), 0f, value)); - avatarImage.setRoundRadius((int) AndroidUtilities.lerp(AndroidUtilities.dpf2(21f), 0f, value)); - - if (extraHeight > AndroidUtilities.dpf2(88f) && expandProgress < 0.33f) { - refreshNameAndOnlineXY(); - } - - if (scamDrawable != null) { - scamDrawable.setColor(ColorUtils.blendARGB(Theme.getColor(Theme.key_avatar_subtitleInProfileBlue), Color.argb(179, 255, 255, 255), value)); - } - - if (lockIconDrawable != null) { - lockIconDrawable.setColorFilter(ColorUtils.blendARGB(Theme.getColor(Theme.key_chat_lockIcon), Color.WHITE, value), PorterDuff.Mode.MULTIPLY); - } - - if (verifiedCrossfadeDrawable != null) { - verifiedCrossfadeDrawable.setProgress(value); - } - - final float k = AndroidUtilities.dpf2(8f); - - final float nameTextViewXEnd = AndroidUtilities.dpf2(16f) - nameTextView[1].getLeft(); - final float nameTextViewYEnd = newTop + extraHeight - AndroidUtilities.dpf2(38f) - nameTextView[1].getBottom(); - final float nameTextViewCx = k + nameX + (nameTextViewXEnd - nameX) / 2f; - final float nameTextViewCy = k + nameY + (nameTextViewYEnd - nameY) / 2f; - final float nameTextViewX = (1 - value) * (1 - value) * nameX + 2 * (1 - value) * value * nameTextViewCx + value * value * nameTextViewXEnd; - final float nameTextViewY = (1 - value) * (1 - value) * nameY + 2 * (1 - value) * value * nameTextViewCy + value * value * nameTextViewYEnd; - - final float onlineTextViewXEnd = AndroidUtilities.dpf2(16f) - onlineTextView[1].getLeft(); - final float onlineTextViewYEnd = newTop + extraHeight - AndroidUtilities.dpf2(18f) - onlineTextView[1].getBottom(); - final float onlineTextViewCx = k + onlineX + (onlineTextViewXEnd - onlineX) / 2f; - final float onlineTextViewCy = k + onlineY + (onlineTextViewYEnd - onlineY) / 2f; - final float onlineTextViewX = (1 - value) * (1 - value) * onlineX + 2 * (1 - value) * value * onlineTextViewCx + value * value * onlineTextViewXEnd; - final float onlineTextViewY = (1 - value) * (1 - value) * onlineY + 2 * (1 - value) * value * onlineTextViewCy + value * value * onlineTextViewYEnd; - - nameTextView[1].setTranslationX(nameTextViewX); - nameTextView[1].setTranslationY(nameTextViewY); - onlineTextView[1].setTranslationX(onlineTextViewX); - onlineTextView[1].setTranslationY(onlineTextViewY); - final Object onlineTextViewTag = onlineTextView[1].getTag(); - int statusColor; - if (onlineTextViewTag instanceof String) { - statusColor = Theme.getColor((String) onlineTextViewTag); - } else { - statusColor = Theme.getColor(Theme.key_avatar_subtitleInProfileBlue); - } - onlineTextView[1].setTextColor(ColorUtils.blendARGB(statusColor, Color.argb(179, 255, 255, 255), value)); - if (extraHeight > AndroidUtilities.dpf2(88f)) { - nameTextView[1].setPivotY(AndroidUtilities.lerp(0, nameTextView[1].getMeasuredHeight(), value)); - nameTextView[1].setScaleX(AndroidUtilities.lerp(1.12f, 1.67f, value)); - nameTextView[1].setScaleY(AndroidUtilities.lerp(1.12f, 1.67f, value)); - } - - needLayoutText(Math.min(1f, extraHeight / AndroidUtilities.dpf2(88f))); - - nameTextView[1].setTextColor(ColorUtils.blendARGB(Theme.getColor(Theme.key_profile_title), Color.WHITE, value)); - actionBar.setItemsColor(ColorUtils.blendARGB(Theme.getColor(Theme.key_actionBarDefaultIcon), Color.WHITE, value), false); - - avatarImage.setForegroundAlpha(value); - - final FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) avatarImage.getLayoutParams(); - params.width = (int) AndroidUtilities.lerp(AndroidUtilities.dpf2(42f), listView.getMeasuredWidth() / avatarScale, value); - params.height = (int) AndroidUtilities.lerp(AndroidUtilities.dpf2(42f), (extraHeight + newTop) / avatarScale, value); - params.leftMargin = (int) AndroidUtilities.lerp(AndroidUtilities.dpf2(64f), 0f, value); - avatarImage.requestLayout(); - FileLog.d("w = " + params.width + " h = " + params.height + " scale " + avatarScale); - }); - expandAnimator.setDuration((long) (250f / durationFactor)); - expandAnimator.setInterpolator(CubicBezierInterpolator.EASE_BOTH); - expandAnimator.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationStart(Animator animation) { - nameTextView[1].setBackgroundColor(Color.TRANSPARENT); - } - - @Override - public void onAnimationEnd(Animator animation) { - if (!isPulledDown) { - nameTextView[1].setBackgroundColor(Theme.getColor(Theme.key_avatar_backgroundActionBarBlue)); - } - actionBar.setItemsBackgroundColor(isPulledDown ? Theme.ACTION_BAR_WHITE_SELECTOR_COLOR : Theme.getColor(Theme.key_avatar_actionBarSelectorBlue), false); - } - }); - } else { - expandAnimator.cancel(); - float value = AndroidUtilities.lerp(expandAnimatorValues, expandAnimator.getAnimatedFraction()); - expandAnimatorValues[0] = value; - expandAnimatorValues[1] = 1f; - expandAnimator.setDuration((long) ((1f - value) * 250f / durationFactor)); - } + expandAnimator.cancel(); + float value = AndroidUtilities.lerp(expandAnimatorValues, currentExpanAnimatorFracture); + expandAnimatorValues[0] = value; + expandAnimatorValues[1] = 1f; + expandAnimator.setDuration((long) ((1f - value) * 250f / durationFactor)); expandAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationStart(Animator animation) { @@ -2245,22 +2773,31 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. } ViewGroup.LayoutParams params = avatarsViewPager.getLayoutParams(); params.width = listView.getMeasuredWidth(); - params.height = (int) (extraHeight + newTop); + params.height = (int) (h + newTop); avatarsViewPager.requestLayout(); if (!expandAnimator.isRunning()) { + float additionalTranslationY = 0; + if (openAnimationInProgress && playProfileAnimation == 2) { + additionalTranslationY = -(1.0f - animationProgress) * AndroidUtilities.dp(50); + } nameTextView[1].setTranslationX(AndroidUtilities.dpf2(16f) - nameTextView[1].getLeft()); - nameTextView[1].setTranslationY(newTop + extraHeight - AndroidUtilities.dpf2(38f) - nameTextView[1].getBottom()); + nameTextView[1].setTranslationY(newTop + h - AndroidUtilities.dpf2(38f) - nameTextView[1].getBottom() + additionalTranslationY); onlineTextView[1].setTranslationX(AndroidUtilities.dpf2(16f) - onlineTextView[1].getLeft()); - onlineTextView[1].setTranslationY(newTop + extraHeight - AndroidUtilities.dpf2(18f) - onlineTextView[1].getBottom()); + onlineTextView[1].setTranslationY(newTop + h - AndroidUtilities.dpf2(18f) - onlineTextView[1].getBottom() + additionalTranslationY); + onlineTextView[2].setTranslationX(onlineTextView[1].getTranslationX()); + onlineTextView[2].setTranslationY(onlineTextView[1].getTranslationY()); } } else { if (isPulledDown) { isPulledDown = false; + if (otherItem != null) { + otherItem.hideSubItem(gallery_menu_save); + } overlaysView.setOverlaysVisible(false, durationFactor); avatarsViewPagerIndicatorView.refreshVisibility(durationFactor); expandAnimator.cancel(); - float value = AndroidUtilities.lerp(expandAnimatorValues, expandAnimator.getAnimatedFraction()); + float value = AndroidUtilities.lerp(expandAnimatorValues, currentExpanAnimatorFracture); expandAnimatorValues[0] = value; expandAnimatorValues[1] = 0f; if (!isInLandscapeMode) { @@ -2289,11 +2826,54 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. nameTextView[1].setTranslationY(nameY); onlineTextView[1].setTranslationX(onlineX); onlineTextView[1].setTranslationY(onlineY); + onlineTextView[2].setTranslationX(onlineX); + onlineTextView[2].setTranslationY(onlineY); } } } - if (extraHeight <= AndroidUtilities.dpf2(88f)) { + if (openAnimationInProgress && playProfileAnimation == 2) { + float avX = 0; + float avY = (actionBar.getOccupyStatusBar() ? AndroidUtilities.statusBarHeight : 0) + ActionBar.getCurrentActionBarHeight() / 2.0f - 21 * AndroidUtilities.density + actionBar.getTranslationY(); + + nameTextView[0].setTranslationX(0); + nameTextView[0].setTranslationY((float) Math.floor(avY) + AndroidUtilities.dp(1.3f)); + onlineTextView[0].setTranslationX(0); + onlineTextView[0].setTranslationY((float) Math.floor(avY) + AndroidUtilities.dp(24)); + nameTextView[0].setScaleX(1.0f); + nameTextView[0].setScaleY(1.0f); + + nameTextView[1].setPivotY(nameTextView[1].getMeasuredHeight()); + nameTextView[1].setScaleX(1.67f); + nameTextView[1].setScaleY(1.67f); + + avatarScale = AndroidUtilities.lerp(1.0f, (42f + 42f + 18f) / 42f, animationProgress); + + avatarImage.setRoundRadius((int) AndroidUtilities.lerp(AndroidUtilities.dpf2(21f), 0f, animationProgress)); + avatarImage.setTranslationX(AndroidUtilities.lerp(avX, 0, animationProgress)); + avatarImage.setTranslationY(AndroidUtilities.lerp((float) Math.ceil(avY), 0f, animationProgress)); + avatarImage.setScaleX(avatarScale); + avatarImage.setScaleY(avatarScale); + + overlaysView.setAlphaValue(animationProgress, false); + actionBar.setItemsColor(ColorUtils.blendARGB(Theme.getColor(Theme.key_actionBarDefaultIcon), Color.WHITE, animationProgress), false); + + if (scamDrawable != null) { + scamDrawable.setColor(ColorUtils.blendARGB(Theme.getColor(Theme.key_avatar_subtitleInProfileBlue), Color.argb(179, 255, 255, 255), animationProgress)); + } + if (lockIconDrawable != null) { + lockIconDrawable.setColorFilter(ColorUtils.blendARGB(Theme.getColor(Theme.key_chat_lockIcon), Color.WHITE, animationProgress), PorterDuff.Mode.MULTIPLY); + } + if (verifiedCrossfadeDrawable != null) { + verifiedCrossfadeDrawable.setProgress(animationProgress); + } + + final FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) avatarImage.getLayoutParams(); + //params.width = params.height = (int) AndroidUtilities.lerp(AndroidUtilities.dpf2(42f), listView.getMeasuredWidth() / avatarScale, animationProgress); + params.width = params.height = (int) AndroidUtilities.lerp(AndroidUtilities.dpf2(42f), (extraHeight + newTop) / avatarScale, animationProgress); + params.leftMargin = (int) AndroidUtilities.lerp(AndroidUtilities.dpf2(64f), 0f, animationProgress); + avatarImage.requestLayout(); + } else if (extraHeight <= AndroidUtilities.dpf2(88f)) { avatarScale = (42 + 18 * diff) / 42.0f; float nameScale = 1.0f + 0.12f * diff; if (expandAnimator == null || !expandAnimator.isRunning()) { @@ -2306,15 +2886,20 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. nameY = (float) Math.floor(avatarY) + AndroidUtilities.dp(1.3f) + AndroidUtilities.dp(7) * diff; onlineX = -21 * AndroidUtilities.density * diff; onlineY = (float) Math.floor(avatarY) + AndroidUtilities.dp(24) + (float) Math.floor(11 * AndroidUtilities.density) * diff; - for (int a = 0; a < 2; a++) { + for (int a = 0; a < nameTextView.length; a++) { if (nameTextView[a] == null) { continue; } if (expandAnimator == null || !expandAnimator.isRunning()) { nameTextView[a].setTranslationX(nameX); nameTextView[a].setTranslationY(nameY); + onlineTextView[a].setTranslationX(onlineX); onlineTextView[a].setTranslationY(onlineY); + if (a == 1) { + onlineTextView[2].setTranslationX(onlineX); + onlineTextView[2].setTranslationY(onlineY); + } } nameTextView[a].setScaleX(nameScale); nameTextView[a].setScaleY(nameScale); @@ -2341,6 +2926,10 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. onlineY = (float) Math.floor(avatarY) + AndroidUtilities.dp(24) + (float) Math.floor(11 * AndroidUtilities.density) + avatarImage.getMeasuredHeight() * (avatarScale - (42f + 18f) / 42f) / 2f; } + public RecyclerListView getListView() { + return listView; + } + private void needLayoutText(float diff) { FrameLayout.LayoutParams layoutParams; float scale = nameTextView[1].getScaleX(); @@ -2351,7 +2940,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. } int viewWidth = AndroidUtilities.isTablet() ? AndroidUtilities.dp(490) : AndroidUtilities.displaySize.x; - int buttonsWidth = AndroidUtilities.dp(118 + 8 + (40 + (callItem != null || editItem != null ? 48 : 0))); + int buttonsWidth = AndroidUtilities.dp(118 + 8 + (40 + (callItemVisible || editItemVisible ? 48 : 0))); int minWidth = viewWidth - buttonsWidth; int width = (int) (viewWidth - buttonsWidth * Math.max(0.0f, 1.0f - (diff != 1.0f ? diff * 0.15f / (1.0f - diff) : 1.0f)) - nameTextView[1].getTranslationX()); @@ -2370,28 +2959,17 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. width2 = onlineTextView[1].getPaint().measureText(onlineTextView[1].getText().toString()); layoutParams = (FrameLayout.LayoutParams) onlineTextView[1].getLayoutParams(); + FrameLayout.LayoutParams layoutParams2 = (FrameLayout.LayoutParams) onlineTextView[2].getLayoutParams(); prevWidth = layoutParams.width; - layoutParams.rightMargin = (int) Math.ceil(onlineTextView[1].getTranslationX() + AndroidUtilities.dp(8) + AndroidUtilities.dp(40) * (1.0f - diff)); + layoutParams2.rightMargin = layoutParams.rightMargin = (int) Math.ceil(onlineTextView[1].getTranslationX() + AndroidUtilities.dp(8) + AndroidUtilities.dp(40) * (1.0f - diff)); if (width < width2) { - layoutParams.width = (int) Math.ceil(width); + layoutParams2.width = layoutParams.width = (int) Math.ceil(width); } else { - layoutParams.width = LayoutHelper.WRAP_CONTENT; + layoutParams2.width = layoutParams.width = LayoutHelper.WRAP_CONTENT; } if (prevWidth != layoutParams.width) { onlineTextView[1].requestLayout(); - } - } - - private void loadMediaCounts() { - if (dialog_id != 0) { - MediaDataController.getInstance(currentAccount).getMediaCounts(dialog_id, classGuid); - } else if (user_id != 0) { - MediaDataController.getInstance(currentAccount).getMediaCounts(user_id, classGuid); - } else if (chat_id > 0) { - MediaDataController.getInstance(currentAccount).getMediaCounts(-chat_id, classGuid); - if (mergeDialogId != 0) { - MediaDataController.getInstance(currentAccount).getMediaCounts(mergeDialogId, classGuid); - } + onlineTextView[2].requestLayout(); } } @@ -2415,6 +2993,9 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); + if (sharedMediaLayout != null) { + sharedMediaLayout.onConfigurationChanged(newConfig); + } invalidateIsInLandscapeMode(); if (isInLandscapeMode && isPulledDown) { final View view = layoutManager.findViewByPosition(0); @@ -2482,97 +3063,6 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. updateProfileData(); } else if (id == NotificationCenter.contactsDidLoad) { createActionBarMenu(); - } else if (id == NotificationCenter.mediaDidLoad) { - long uid = (Long) args[0]; - int guid = (Integer) args[3]; - if (guid == classGuid) { - long did = dialog_id; - if (did == 0) { - if (user_id != 0) { - did = user_id; - } else if (chat_id != 0) { - did = -chat_id; - } - } - - int type = (Integer) args[4]; - sharedMediaData[type].setTotalCount((Integer) args[1]); - ArrayList arr = (ArrayList) args[2]; - boolean enc = ((int) did) == 0; - int loadIndex = uid == did ? 0 : 1; - if (!arr.isEmpty()) { - sharedMediaData[type].setEndReached(loadIndex, (Boolean) args[5]); - } - for (int a = 0; a < arr.size(); a++) { - MessageObject message = arr.get(a); - sharedMediaData[type].addMessage(message, loadIndex, false, enc); - } - } - } else if (id == NotificationCenter.mediaCountsDidLoad) { - long uid = (Long) args[0]; - long did = dialog_id; - if (did == 0) { - if (user_id != 0) { - did = user_id; - } else if (chat_id != 0) { - did = -chat_id; - } - } - if (uid == did || uid == mergeDialogId) { - int[] counts = (int[]) args[1]; - if (uid == did) { - mediaCount = counts; - } else { - mediaMergeCount = counts; - } - System.arraycopy(lastMediaCount, 0, prevMediaCount, 0, prevMediaCount.length); - for (int a = 0; a < lastMediaCount.length; a++) { - if (mediaCount[a] >= 0 && mediaMergeCount[a] >= 0) { - lastMediaCount[a] = mediaCount[a] + mediaMergeCount[a]; - } else if (mediaCount[a] >= 0) { - lastMediaCount[a] = mediaCount[a]; - } else if (mediaMergeCount[a] >= 0) { - lastMediaCount[a] = mediaMergeCount[a]; - } else { - lastMediaCount[a] = 0; - } - if (uid == did && lastMediaCount[a] != 0) { - MediaDataController.getInstance(currentAccount).loadMedia(did, 50, 0, a, 2, classGuid); - } - } - updateSharedMediaRows(); - } - } else if (id == NotificationCenter.mediaCountDidLoad) { - long uid = (Long) args[0]; - long did = dialog_id; - if (did == 0) { - if (user_id != 0) { - did = user_id; - } else if (chat_id != 0) { - did = -chat_id; - } - } - if (uid == did || uid == mergeDialogId) { - int type = (Integer) args[3]; - int mCount = (Integer) args[1]; - if (uid == did) { - mediaCount[type] = mCount; - } else { - mediaMergeCount[type] = mCount; - } - prevMediaCount[type] = lastMediaCount[type]; - if (mediaCount[type] >= 0 && mediaMergeCount[type] >= 0) { - lastMediaCount[type] = mediaCount[type] + mediaMergeCount[type]; - } else if (mediaCount[type] >= 0) { - lastMediaCount[type] = mediaCount[type]; - } else if (mediaMergeCount[type] >= 0) { - lastMediaCount[type] = mediaMergeCount[type]; - } else { - lastMediaCount[type] = 0; - } - - updateSharedMediaRows(); - } } else if (id == NotificationCenter.encryptedChatCreated) { if (creatingChat) { AndroidUtilities.runOnUIThread(() -> { @@ -2655,20 +3145,15 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. if (listAdapter != null) { listAdapter.notifyDataSetChanged(); } + sharedMediaLayout.setCommonGroupsCount(userInfo.common_chats_count); + updateSelectedMediaTabText(); } } else if (id == NotificationCenter.didReceiveNewMessages) { boolean scheduled = (Boolean) args[2]; if (scheduled) { return; } - long did; - if (dialog_id != 0) { - did = dialog_id; - } else if (user_id != 0) { - did = user_id; - } else { - did = -chat_id; - } + long did = getDialogId(); if (did == (Long) args[0]) { boolean enc = ((int) did) == 0; ArrayList arr = (ArrayList) args[1]; @@ -2680,42 +3165,8 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. listAdapter.notifyDataSetChanged(); } } - - int type = MediaDataController.getMediaType(obj.messageOwner); - if (type == -1) { - return; - } - sharedMediaData[type].addMessage(obj, 0, true, enc); - } - loadMediaCounts(); - } - } else if (id == NotificationCenter.messagesDeleted) { - boolean scheduled = (Boolean) args[2]; - if (scheduled) { - return; - } - int channelId = (Integer) args[1]; - if (ChatObject.isChannel(currentChat)) { - if (!(channelId == 0 && mergeDialogId != 0 || channelId == currentChat.id)) { - return; - } - } else if (channelId != 0) { - return; - } - - ArrayList markAsDeletedMessages = (ArrayList) args[0]; - boolean updated = false; - for (int a = 0, N = markAsDeletedMessages.size(); a < N; a++) { - for (int b = 0; b < sharedMediaData.length; b++) { - if (sharedMediaData[b].deleteMessage(markAsDeletedMessages.get(a), 0)) { - updated = true; - } } } - if (updated && mediaActivity != null) { - mediaActivity.updateAdapters(); - } - loadMediaCounts(); } else if (id == NotificationCenter.emojiDidLoad) { if (listView != null) { listView.invalidateViews(); @@ -2723,9 +3174,21 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. } } + @Override + public void mediaCountUpdated() { + if (sharedMediaLayout != null && sharedMediaPreloader != null) { + sharedMediaLayout.setNewMediaCounts(sharedMediaPreloader.getLastMediaCount()); + } + updateSharedMediaRows(); + updateSelectedMediaTabText(); + } + @Override public void onResume() { super.onResume(); + if (sharedMediaLayout != null) { + sharedMediaLayout.onResume(); + } invalidateIsInLandscapeMode(); if (listAdapter != null) { listAdapter.notifyDataSetChanged(); @@ -2745,6 +3208,22 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. } } + @Override + public boolean isSwipeBackEnabled(MotionEvent event) { + if (sharedMediaRow == -1 || sharedMediaLayout == null) { + return true; + } + sharedMediaLayout.getHitRect(rect); + if (!rect.contains((int) event.getX(), (int) event.getY() - actionBar.getMeasuredHeight())) { + return true; + } + return sharedMediaLayout.isCurrentTabFirst(); + } + + public boolean onBackPressed() { + return actionBar.isEnabled() && (sharedMediaRow == -1 || sharedMediaLayout == null || !sharedMediaLayout.closeActionMode()); + } + @Override protected void onBecomeFullyHidden() { if (undoView != null) { @@ -2752,10 +3231,14 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. } } - public void setPlayProfileAnimation(boolean value) { + public void setPlayProfileAnimation(int type) { SharedPreferences preferences = MessagesController.getGlobalMainSettings(); - if (!AndroidUtilities.isTablet() && preferences.getBoolean("view_animations", true)) { - playProfileAnimation = value; + if (!AndroidUtilities.isTablet()) { + if (preferences.getBoolean("view_animations", true)) { + playProfileAnimation = type; + } else if (type == 2) { + expandPhoto = true; + } } } @@ -2763,110 +3246,16 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. if (listAdapter == null) { return; } - int sharedHeaderRowPrev = sharedHeaderRow; - int photosRowPrev = photosRow; - int filesRowPrev = filesRow; - int linksRowPrev = linksRow; - int audioRowPrev = audioRow; - int voiceRowPrev = voiceRow; - int groupsInCommonRowPrev = groupsInCommonRow; - int sharedSectionRowPrev = sharedSectionRow; - int itemsCount = rowCount; + int sharedMediaRowPrev = sharedMediaRow; updateRowsIds(); - if (sharedHeaderRowPrev == -1 && sharedHeaderRow != -1) { - int newRowsCount = 2; - if (photosRow != -1) { - newRowsCount++; - } - if (filesRow != -1) { - newRowsCount++; - } - if (linksRow != -1) { - newRowsCount++; - } - if (audioRow != -1) { - newRowsCount++; - } - if (voiceRow != -1) { - newRowsCount++; - } - if (groupsInCommonRow != -1) { - newRowsCount++; - } - listAdapter.notifyItemRangeInserted(sharedHeaderRow, newRowsCount); - } else if (sharedHeaderRowPrev != -1 && sharedHeaderRow != -1) { - if (photosRowPrev != -1 && photosRow != -1 && prevMediaCount[MediaDataController.MEDIA_PHOTOVIDEO] != lastMediaCount[MediaDataController.MEDIA_PHOTOVIDEO]) { - listAdapter.notifyItemChanged(photosRow); - } - if (filesRowPrev != -1 && filesRow != -1 && prevMediaCount[MediaDataController.MEDIA_FILE] != lastMediaCount[MediaDataController.MEDIA_FILE]) { - listAdapter.notifyItemChanged(filesRow); - } - if (linksRowPrev != -1 && linksRow != -1 && prevMediaCount[MediaDataController.MEDIA_URL] != lastMediaCount[MediaDataController.MEDIA_URL]) { - listAdapter.notifyItemChanged(linksRow); - } - if (audioRowPrev != -1 && audioRow != -1 && prevMediaCount[MediaDataController.MEDIA_MUSIC] != lastMediaCount[MediaDataController.MEDIA_MUSIC]) { - listAdapter.notifyItemChanged(audioRow); - } - if (voiceRowPrev != -1 && voiceRow != -1 && prevMediaCount[MediaDataController.MEDIA_AUDIO] != lastMediaCount[MediaDataController.MEDIA_AUDIO]) { - listAdapter.notifyItemChanged(voiceRow); - } - if (photosRowPrev == -1 && photosRow != -1) { - listAdapter.notifyItemInserted(photosRow); - } else if (photosRowPrev != -1 && photosRow == -1) { - listAdapter.notifyItemRemoved(photosRowPrev); - } - if (filesRowPrev == -1 && filesRow != -1) { - listAdapter.notifyItemInserted(filesRow); - } else if (filesRowPrev != -1 && filesRow == -1) { - listAdapter.notifyItemRemoved(filesRowPrev); - } - if (linksRowPrev == -1 && linksRow != -1) { - listAdapter.notifyItemInserted(linksRow); - } else if (linksRowPrev != -1 && linksRow == -1) { - listAdapter.notifyItemRemoved(linksRowPrev); - } - if (audioRowPrev == -1 && audioRow != -1) { - listAdapter.notifyItemInserted(audioRow); - } else if (audioRowPrev != -1 && audioRow == -1) { - listAdapter.notifyItemRemoved(audioRowPrev); - } - if (voiceRowPrev == -1 && voiceRow != -1) { - listAdapter.notifyItemInserted(voiceRow); - } else if (voiceRowPrev != -1 && voiceRow == -1) { - listAdapter.notifyItemRemoved(voiceRowPrev); - } - if (groupsInCommonRowPrev == -1 && groupsInCommonRow != -1) { - listAdapter.notifyItemInserted(groupsInCommonRow); - } else if (groupsInCommonRowPrev != -1 && groupsInCommonRow == -1) { - listAdapter.notifyItemRemoved(groupsInCommonRowPrev); - } - } else if (sharedHeaderRowPrev != -1 && sharedHeaderRow == -1) { - int newRowsCountPrev = 2; - if (photosRowPrev != -1) { - newRowsCountPrev++; - } - if (filesRowPrev != -1) { - newRowsCountPrev++; - } - if (linksRowPrev != -1) { - newRowsCountPrev++; - } - if (audioRowPrev != -1) { - newRowsCountPrev++; - } - if (voiceRowPrev != -1) { - newRowsCountPrev++; - } - if (groupsInCommonRowPrev != -1) { - newRowsCountPrev++; - } - listAdapter.notifyItemRangeChanged(sharedHeaderRowPrev, newRowsCountPrev); + if (sharedMediaRowPrev != sharedMediaRow) { + listAdapter.notifyDataSetChanged(); } } @Override protected void onTransitionAnimationStart(boolean isOpen, boolean backward) { - if ((!isOpen && backward || isOpen && !backward) && playProfileAnimation && allowProfileAnimation && !isPulledDown) { + if ((!isOpen && backward || isOpen && !backward) && playProfileAnimation != 0 && allowProfileAnimation && !isPulledDown) { openAnimationInProgress = true; } if (isOpen) { @@ -2879,7 +3268,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. protected void onTransitionAnimationEnd(boolean isOpen, boolean backward) { if (isOpen) { if (!backward) { - if (playProfileAnimation && allowProfileAnimation) { + if (playProfileAnimation != 0 && allowProfileAnimation) { openAnimationInProgress = false; if (recreateMenuAfterAnimation) { createActionBarMenu(); @@ -2902,7 +3291,12 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. listView.setTranslationX(AndroidUtilities.dp(48) - AndroidUtilities.dp(48) * progress); - int color = AvatarDrawable.getProfileBackColorForId(user_id != 0 || ChatObject.isChannel(chat_id, currentAccount) && !currentChat.megagroup ? 5 : chat_id); + int color; + if (playProfileAnimation == 2 && avatarColor != 0) { + color = avatarColor; + } else { + color = AvatarDrawable.getProfileBackColorForId(user_id != 0 || ChatObject.isChannel(chat_id, currentAccount) && !currentChat.megagroup ? 5 : chat_id); + } int actionBarColor = Theme.getColor(Theme.key_actionBarDefault); int r = Color.red(actionBarColor); @@ -2957,7 +3351,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. bD = (int) ((Color.blue(color) - b) * progress); aD = (int) ((Color.alpha(color) - a) * progress); for (int i = 0; i < 2; i++) { - if (onlineTextView[i] == null) { + if (onlineTextView[i] == null || i == 1 && playProfileAnimation == 2) { continue; } onlineTextView[i].setTextColor(Color.argb(a + aD, r + rD, g + gD, b + bD)); @@ -2980,9 +3374,9 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. @Override protected AnimatorSet onCustomTransitionAnimation(final boolean isOpen, final Runnable callback) { - if (playProfileAnimation && allowProfileAnimation && !isPulledDown) { + if (playProfileAnimation != 0 && allowProfileAnimation && !isPulledDown) { final AnimatorSet animatorSet = new AnimatorSet(); - animatorSet.setDuration(180); + animatorSet.setDuration(playProfileAnimation == 2 ? 250 : 180); listView.setLayerType(View.LAYER_TYPE_HARDWARE, null); ActionBarMenu menu = actionBar.createMenu(); if (menu.getItem(10) == null) { @@ -2995,17 +3389,23 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. layoutParams.rightMargin = (int) (-21 * AndroidUtilities.density + AndroidUtilities.dp(8)); onlineTextView[1].setLayoutParams(layoutParams); - int width = (int) Math.ceil(AndroidUtilities.displaySize.x - AndroidUtilities.dp(118 + 8) + 21 * AndroidUtilities.density); - float width2 = nameTextView[1].getPaint().measureText(nameTextView[1].getText().toString()) * 1.12f + nameTextView[1].getSideDrawablesSize(); - layoutParams = (FrameLayout.LayoutParams) nameTextView[1].getLayoutParams(); - if (width < width2) { - layoutParams.width = (int) Math.ceil(width / 1.12f); - } else { - layoutParams.width = LayoutHelper.WRAP_CONTENT; - } - nameTextView[1].setLayoutParams(layoutParams); + if (playProfileAnimation != 2) { + int width = (int) Math.ceil(AndroidUtilities.displaySize.x - AndroidUtilities.dp(118 + 8) + 21 * AndroidUtilities.density); + float width2 = nameTextView[1].getPaint().measureText(nameTextView[1].getText().toString()) * 1.12f + nameTextView[1].getSideDrawablesSize(); + layoutParams = (FrameLayout.LayoutParams) nameTextView[1].getLayoutParams(); + if (width < width2) { + layoutParams.width = (int) Math.ceil(width / 1.12f); + } else { + layoutParams.width = LayoutHelper.WRAP_CONTENT; + } + nameTextView[1].setLayoutParams(layoutParams); - initialAnimationExtraHeight = AndroidUtilities.dpf2(88f); + initialAnimationExtraHeight = AndroidUtilities.dpf2(88f); + } else { + layoutParams = (FrameLayout.LayoutParams) nameTextView[1].getLayoutParams(); + layoutParams.width = (int) ((AndroidUtilities.displaySize.x - AndroidUtilities.dp(32)) / 1.67f); + nameTextView[1].setLayoutParams(layoutParams); + } fragmentView.setBackgroundColor(0); setAnimationProgress(0); ArrayList animators = new ArrayList<>(); @@ -3018,6 +3418,13 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. animators.add(ObjectAnimator.ofFloat(writeButton, View.SCALE_Y, 1.0f)); animators.add(ObjectAnimator.ofFloat(writeButton, View.ALPHA, 1.0f)); } + if (playProfileAnimation == 2) { + avatarColor = AndroidUtilities.calcBitmapColor(avatarImage.getImageReceiver().getBitmap()); + nameTextView[1].setTextColor(Color.WHITE); + onlineTextView[1].setTextColor(Color.argb(179, 255, 255, 255)); + actionBar.setItemsBackgroundColor(Theme.ACTION_BAR_WHITE_SELECTOR_COLOR, false); + overlaysView.setOverlaysVisible(); + } for (int a = 0; a < 2; a++) { onlineTextView[a].setAlpha(a == 0 ? 1.0f : 0.0f); nameTextView[a].setAlpha(a == 0 ? 1.0f : 0.0f); @@ -3028,11 +3435,11 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. animatingItem.setAlpha(1.0f); animators.add(ObjectAnimator.ofFloat(animatingItem, View.ALPHA, 0.0f)); } - if (callItem != null) { + if (callItemVisible) { callItem.setAlpha(0.0f); animators.add(ObjectAnimator.ofFloat(callItem, View.ALPHA, 1.0f)); } - if (editItem != null) { + if (editItemVisible) { editItem.setAlpha(0.0f); animators.add(ObjectAnimator.ofFloat(editItem, View.ALPHA, 1.0f)); } @@ -3054,11 +3461,11 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. animatingItem.setAlpha(0.0f); animators.add(ObjectAnimator.ofFloat(animatingItem, View.ALPHA, 1.0f)); } - if (callItem != null) { + if (callItemVisible) { callItem.setAlpha(1.0f); animators.add(ObjectAnimator.ofFloat(callItem, View.ALPHA, 0.0f)); } - if (editItem != null) { + if (editItemVisible) { editItem.setAlpha(1.0f); animators.add(ObjectAnimator.ofFloat(editItem, View.ALPHA, 0.0f)); } @@ -3074,9 +3481,16 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. animatingItem = null; } callback.run(); + if (playProfileAnimation == 2) { + playProfileAnimation = 1; + avatarImage.setForegroundAlpha(1.0f); + avatarImage.setVisibility(View.GONE); + avatarsViewPager.resetCurrentItem(); + avatarsViewPager.setVisibility(View.VISIBLE); + } } }); - animatorSet.setInterpolator(new DecelerateInterpolator()); + animatorSet.setInterpolator(playProfileAnimation == 2 ? CubicBezierInterpolator.DEFAULT : new DecelerateInterpolator()); AndroidUtilities.runOnUIThread(animatorSet::start, 50); return animatorSet; @@ -3150,6 +3564,9 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. if (listAdapter != null && membersStartRow > 0) { listAdapter.notifyItemRangeChanged(membersStartRow, sortedUsers.size()); } + if (sharedMediaLayout != null && sharedMediaRow != -1 && sortedUsers.size() > 5) { + sharedMediaLayout.setChatUsers(sortedUsers, chatInfo); + } } else if (chatInfo instanceof TLRPC.TL_channelFull && chatInfo.participants_count > 200) { onlineCount = chatInfo.online_count; } @@ -3191,7 +3608,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.closeChats); } MessagesController.getInstance(currentAccount).deleteUserFromChat(chat_id, MessagesController.getInstance(currentAccount).getUser(UserConfig.getInstance(currentAccount).getClientUserId()), chatInfo); - playProfileAnimation = false; + playProfileAnimation = 0; finishFragment(); } } @@ -3204,6 +3621,8 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. int prevRowsCount = rowCount; rowCount = 0; + sendMessageRow = -1; + reportRow = -1; emptyRow = -1; infoHeaderRow = -1; phoneRow = -1; @@ -3217,6 +3636,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. notificationsRow = -1; infoSectionRow = -1; settingsSectionRow = -1; + bottomPaddingRow = -1; membersHeaderRow = -1; membersStartRow = -1; @@ -3226,27 +3646,20 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. administratorsRow = -1; blockedUsersRow = -1; membersSectionRow = -1; - - sharedHeaderRow = -1; - photosRow = -1; - filesRow = -1; - linksRow = -1; - audioRow = -1; - voiceRow = -1; - groupsInCommonRow = -1; - sharedSectionRow = -1; + sharedMediaRow = -1; unblockRow = -1; - startSecretChatRow = -1; - leaveChannelRow = -1; joinRow = -1; lastSectionRow = -1; boolean hasMedia = false; - for (int a = 0; a < lastMediaCount.length; a++) { - if (lastMediaCount[a] > 0) { - hasMedia = true; - break; + if (sharedMediaPreloader != null) { + int[] lastMediaCount = sharedMediaPreloader.getLastMediaCount(); + for (int a = 0; a < lastMediaCount.length; a++) { + if (lastMediaCount[a] > 0) { + hasMedia = true; + break; + } } } @@ -3284,156 +3697,119 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. settingsSectionRow = rowCount++; } - if (hasMedia || userInfo != null && userInfo.common_chats_count != 0) { - sharedHeaderRow = rowCount++; - if (lastMediaCount[MediaDataController.MEDIA_PHOTOVIDEO] > 0) { - photosRow = rowCount++; - } else { - photosRow = -1; - } - if (lastMediaCount[MediaDataController.MEDIA_FILE] > 0) { - filesRow = rowCount++; - } else { - filesRow = -1; - } - if (lastMediaCount[MediaDataController.MEDIA_URL] > 0) { - linksRow = rowCount++; - } else { - linksRow = -1; - } - if (lastMediaCount[MediaDataController.MEDIA_MUSIC] > 0) { - audioRow = rowCount++; - } else { - audioRow = -1; - } - if (lastMediaCount[MediaDataController.MEDIA_AUDIO] > 0) { - voiceRow = rowCount++; - } else { - voiceRow = -1; - } - if (userInfo != null && userInfo.common_chats_count != 0) { - groupsInCommonRow = rowCount++; - } - sharedSectionRow = rowCount++; - } - if (user != null && !isBot && currentEncryptedChat == null && user.id != UserConfig.getInstance(currentAccount).getClientUserId()) { if (userBlocked) { unblockRow = rowCount++; lastSectionRow = rowCount++; - } else if (user.id != 333000 && user.id != 777000 && user.id != 42777) { - startSecretChatRow = rowCount++; - lastSectionRow = rowCount++; } } + + if (hasMedia || userInfo != null && userInfo.common_chats_count != 0) { + sharedMediaRow = rowCount++; + } else if (lastSectionRow == -1 && needSendMessage) { + sendMessageRow = rowCount++; + reportRow = rowCount++; + lastSectionRow = rowCount++; + } } else if (chat_id != 0) { - if (chat_id > 0) { - if (chatInfo != null && (!TextUtils.isEmpty(chatInfo.about) || chatInfo.location instanceof TLRPC.TL_channelLocation) || !TextUtils.isEmpty(currentChat.username)) { - infoHeaderRow = rowCount++; - if (chatInfo != null) { - if (!TextUtils.isEmpty(chatInfo.about)) { - channelInfoRow = rowCount++; - } - if (chatInfo.location instanceof TLRPC.TL_channelLocation) { - locationRow = rowCount++; - } + if (chatInfo != null && (!TextUtils.isEmpty(chatInfo.about) || chatInfo.location instanceof TLRPC.TL_channelLocation) || !TextUtils.isEmpty(currentChat.username)) { + infoHeaderRow = rowCount++; + if (chatInfo != null) { + if (!TextUtils.isEmpty(chatInfo.about)) { + channelInfoRow = rowCount++; } - if (!TextUtils.isEmpty(currentChat.username)) { - usernameRow = rowCount++; + if (chatInfo.location instanceof TLRPC.TL_channelLocation) { + locationRow = rowCount++; } } - if (infoHeaderRow != -1) { - notificationsDividerRow = rowCount++; + if (!TextUtils.isEmpty(currentChat.username)) { + usernameRow = rowCount++; } - notificationsRow = rowCount++; - infoSectionRow = rowCount++; + } + if (infoHeaderRow != -1) { + notificationsDividerRow = rowCount++; + } + notificationsRow = rowCount++; + infoSectionRow = rowCount++; - if (ChatObject.isChannel(currentChat) && !currentChat.megagroup) { - if (chatInfo != null && (currentChat.creator || chatInfo.can_view_participants)) { - membersHeaderRow = rowCount++; - subscribersRow = rowCount++; - administratorsRow = rowCount++; - if (chatInfo.banned_count != 0 || chatInfo.kicked_count != 0) { - blockedUsersRow = rowCount++; - } - membersSectionRow = rowCount++; + if (ChatObject.isChannel(currentChat) && !currentChat.megagroup) { + if (chatInfo != null && (currentChat.creator || chatInfo.can_view_participants)) { + membersHeaderRow = rowCount++; + subscribersRow = rowCount++; + administratorsRow = rowCount++; + if (chatInfo.banned_count != 0 || chatInfo.kicked_count != 0) { + blockedUsersRow = rowCount++; } + membersSectionRow = rowCount++; } + } - if (hasMedia) { - sharedHeaderRow = rowCount++; - if (lastMediaCount[MediaDataController.MEDIA_PHOTOVIDEO] > 0) { - photosRow = rowCount++; - } else { - photosRow = -1; + if (ChatObject.isChannel(currentChat)) { + if (chatInfo != null && currentChat.megagroup && chatInfo.participants != null && !chatInfo.participants.participants.isEmpty()) { + if (!ChatObject.isNotInChat(currentChat) && currentChat.megagroup && ChatObject.canAddUsers(currentChat) && (chatInfo == null || chatInfo.participants_count < MessagesController.getInstance(currentAccount).maxMegagroupCount)) { + addMemberRow = rowCount++; } - if (lastMediaCount[MediaDataController.MEDIA_FILE] > 0) { - filesRow = rowCount++; - } else { - filesRow = -1; - } - if (lastMediaCount[MediaDataController.MEDIA_URL] > 0) { - linksRow = rowCount++; - } else { - linksRow = -1; - } - if (lastMediaCount[MediaDataController.MEDIA_MUSIC] > 0) { - audioRow = rowCount++; - } else { - audioRow = -1; - } - if (lastMediaCount[MediaDataController.MEDIA_AUDIO] > 0) { - voiceRow = rowCount++; - } else { - voiceRow = -1; - } - sharedSectionRow = rowCount++; - } - - if (ChatObject.isChannel(currentChat)) { - if (!currentChat.creator && !currentChat.left && !currentChat.kicked && !currentChat.megagroup) { - leaveChannelRow = rowCount++; - lastSectionRow = rowCount++; - } - if (chatInfo != null && currentChat.megagroup && chatInfo.participants != null && !chatInfo.participants.participants.isEmpty()) { - if (!ChatObject.isNotInChat(currentChat) && currentChat.megagroup && ChatObject.canAddUsers(currentChat) && (chatInfo == null || chatInfo.participants_count < MessagesController.getInstance(currentAccount).maxMegagroupCount)) { - addMemberRow = rowCount++; - } else { + int count = chatInfo.participants.participants.size(); + if (count <= 5 || !hasMedia) { + if (addMemberRow == -1) { membersHeaderRow = rowCount++; } membersStartRow = rowCount; rowCount += chatInfo.participants.participants.size(); membersEndRow = rowCount; membersSectionRow = rowCount++; + if (sharedMediaLayout != null) { + sharedMediaLayout.setChatUsers(null, null); + } + } else { + if (addMemberRow != -1) { + membersSectionRow = rowCount++; + } + if (sharedMediaLayout != null) { + sharedMediaLayout.setChatUsers(sortedUsers, chatInfo); + } } + } - if (lastSectionRow == -1 && currentChat.left && !currentChat.kicked) { - joinRow = rowCount++; - lastSectionRow = rowCount++; + if (lastSectionRow == -1 && currentChat.left && !currentChat.kicked) { + joinRow = rowCount++; + lastSectionRow = rowCount++; + } + } else if (chatInfo != null) { + if (!(chatInfo.participants instanceof TLRPC.TL_chatParticipantsForbidden)) { + if (ChatObject.canAddUsers(currentChat) || currentChat.default_banned_rights == null || !currentChat.default_banned_rights.invite_users) { + addMemberRow = rowCount++; } - } else if (chatInfo != null) { - if (!(chatInfo.participants instanceof TLRPC.TL_chatParticipantsForbidden)) { - if (ChatObject.canAddUsers(currentChat) || currentChat.default_banned_rights == null || !currentChat.default_banned_rights.invite_users) { - addMemberRow = rowCount++; - } else { + int count = chatInfo.participants.participants.size(); + if (count <= 5 || !hasMedia) { + if (addMemberRow == -1) { membersHeaderRow = rowCount++; } membersStartRow = rowCount; rowCount += chatInfo.participants.participants.size(); membersEndRow = rowCount; membersSectionRow = rowCount++; + if (sharedMediaLayout != null) { + sharedMediaLayout.setChatUsers(null, null); + } + } else { + if (addMemberRow != -1) { + membersSectionRow = rowCount++; + } + if (sharedMediaLayout != null) { + sharedMediaLayout.setChatUsers(sortedUsers, chatInfo); + } } } - } else if (!ChatObject.isChannel(currentChat) && chatInfo != null && !(chatInfo.participants instanceof TLRPC.TL_chatParticipantsForbidden)) { - membersHeaderRow = rowCount++; - membersStartRow = rowCount; - rowCount += chatInfo.participants.participants.size(); - membersEndRow = rowCount; - membersSectionRow = rowCount++; - addMemberRow = rowCount++; + } + + if (hasMedia) { + sharedMediaRow = rowCount++; } } - bottomPaddingRow = rowCount++; + if (sharedMediaRow == -1) { + bottomPaddingRow = rowCount++; + } final int actionBarHeight = actionBar != null ? ActionBar.getCurrentActionBarHeight() + (actionBar.getOccupyStatusBar() ? AndroidUtilities.statusBarHeight : 0) : 0; if (listView == null || prevRowsCount > rowCount || listContentHeight != 0 && listContentHeight + actionBarHeight + AndroidUtilities.dp(88) < listView.getMeasuredHeight()) { lastMeasuredContentWidth = 0; @@ -3509,7 +3885,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. } else { isOnline[0] = false; newString2 = LocaleController.formatUserStatus(currentAccount, user, isOnline); - if (onlineTextView[1] != null) { + if (onlineTextView[1] != null && !mediaHeaderVisible) { String key = isOnline[0] ? Theme.key_profile_status : Theme.key_avatar_subtitleInProfileBlue; onlineTextView[1].setTag(key); if (!isPulledDown) { @@ -3695,102 +4071,119 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. private void createActionBarMenu() { ActionBarMenu menu = actionBar.createMenu(); - menu.clearItems(); + otherItem.removeAllSubItems(); animatingItem = null; - ActionBarMenuItem item = null; + editItemVisible = false; + callItemVisible = false; + if (user_id != 0) { + TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(user_id); if (UserConfig.getInstance(currentAccount).getClientUserId() != user_id) { - TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(user_id); if (user == null) { return; } if (userInfo != null && userInfo.phone_calls_available) { - callItem = menu.addItem(call_item, R.drawable.ic_call); + callItemVisible = true; } if (isBot || ContactsController.getInstance(currentAccount).contactsDict.get(user_id) == null) { - item = menu.addItem(10, R.drawable.ic_ab_other); if (MessagesController.isSupportUser(user)) { if (userBlocked) { - item.addSubItem(block_contact, R.drawable.msg_block, LocaleController.getString("Unblock", R.string.Unblock)); + otherItem.addSubItem(block_contact, R.drawable.msg_block, LocaleController.getString("Unblock", R.string.Unblock)); } } else { if (isBot) { if (!user.bot_nochats) { - item.addSubItem(invite_to_group, R.drawable.msg_addbot, LocaleController.getString("BotInvite", R.string.BotInvite)); + otherItem.addSubItem(invite_to_group, R.drawable.msg_addbot, LocaleController.getString("BotInvite", R.string.BotInvite)); } - item.addSubItem(share, R.drawable.msg_share, LocaleController.getString("BotShare", R.string.BotShare)); + otherItem.addSubItem(share, R.drawable.msg_share, LocaleController.getString("BotShare", R.string.BotShare)); } else { - item.addSubItem(add_contact, R.drawable.msg_addcontact, LocaleController.getString("AddContact", R.string.AddContact)); + otherItem.addSubItem(add_contact, R.drawable.msg_addcontact, LocaleController.getString("AddContact", R.string.AddContact)); } if (!TextUtils.isEmpty(user.phone)) { - item.addSubItem(share_contact, R.drawable.msg_share, LocaleController.getString("ShareContact", R.string.ShareContact)); + otherItem.addSubItem(share_contact, R.drawable.msg_share, LocaleController.getString("ShareContact", R.string.ShareContact)); } if (isBot) { - item.addSubItem(block_contact, !userBlocked ? R.drawable.msg_block : R.drawable.msg_retry, !userBlocked ? LocaleController.getString("BotStop", R.string.BotStop) : LocaleController.getString("BotRestart", R.string.BotRestart)); + otherItem.addSubItem(block_contact, !userBlocked ? R.drawable.msg_block : R.drawable.msg_retry, !userBlocked ? LocaleController.getString("BotStop", R.string.BotStop) : LocaleController.getString("BotRestart", R.string.BotRestart)); } else { - item.addSubItem(block_contact, !userBlocked ? R.drawable.msg_block : R.drawable.msg_block, !userBlocked ? LocaleController.getString("BlockContact", R.string.BlockContact) : LocaleController.getString("Unblock", R.string.Unblock)); + otherItem.addSubItem(block_contact, !userBlocked ? R.drawable.msg_block : R.drawable.msg_block, !userBlocked ? LocaleController.getString("BlockContact", R.string.BlockContact) : LocaleController.getString("Unblock", R.string.Unblock)); } } } else { - item = menu.addItem(10, R.drawable.ic_ab_other); if (!TextUtils.isEmpty(user.phone)) { - item.addSubItem(share_contact, R.drawable.msg_share, LocaleController.getString("ShareContact", R.string.ShareContact)); + otherItem.addSubItem(share_contact, R.drawable.msg_share, LocaleController.getString("ShareContact", R.string.ShareContact)); } - item.addSubItem(block_contact, !userBlocked ? R.drawable.msg_block : R.drawable.msg_block, !userBlocked ? LocaleController.getString("BlockContact", R.string.BlockContact) : LocaleController.getString("Unblock", R.string.Unblock)); - item.addSubItem(edit_contact, R.drawable.msg_edit, LocaleController.getString("EditContact", R.string.EditContact)); - item.addSubItem(delete_contact, R.drawable.msg_delete, LocaleController.getString("DeleteContact", R.string.DeleteContact)); + otherItem.addSubItem(block_contact, !userBlocked ? R.drawable.msg_block : R.drawable.msg_block, !userBlocked ? LocaleController.getString("BlockContact", R.string.BlockContact) : LocaleController.getString("Unblock", R.string.Unblock)); + otherItem.addSubItem(edit_contact, R.drawable.msg_edit, LocaleController.getString("EditContact", R.string.EditContact)); + otherItem.addSubItem(delete_contact, R.drawable.msg_delete, LocaleController.getString("DeleteContact", R.string.DeleteContact)); } } else { - item = menu.addItem(10, R.drawable.ic_ab_other); - item.addSubItem(share_contact, R.drawable.msg_share, LocaleController.getString("ShareContact", R.string.ShareContact)); + otherItem.addSubItem(share_contact, R.drawable.msg_share, LocaleController.getString("ShareContact", R.string.ShareContact)); + } + if (!UserObject.isDeleted(user) && !isBot && currentEncryptedChat == null && user_id != getUserConfig().getClientUserId() && !userBlocked && user_id != 333000 && user_id != 777000 && user_id != 42777) { + otherItem.addSubItem(start_secret_chat, R.drawable.msg_start_secret, LocaleController.getString("StartEncryptedChat", R.string.StartEncryptedChat)); } } else if (chat_id != 0) { if (chat_id > 0) { TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(chat_id); if (ChatObject.isChannel(chat)) { if (ChatObject.hasAdminRights(chat) || chat.megagroup && ChatObject.canChangeChatInfo(chat)) { - editItem = menu.addItem(edit_channel, R.drawable.group_edit_profile); + editItemVisible = true; } if (!chat.megagroup && chatInfo != null && chatInfo.can_view_stats) { - if (item == null) { - item = menu.addItem(10, R.drawable.ic_ab_other); - } - item.addSubItem(statistics, R.drawable.msg_stats, LocaleController.getString("Statistics", R.string.Statistics)); + otherItem.addSubItem(statistics, R.drawable.msg_stats, LocaleController.getString("Statistics", R.string.Statistics)); } if (chat.megagroup) { - if (item == null) { - item = menu.addItem(10, R.drawable.ic_ab_other); - } - item.addSubItem(search_members, R.drawable.msg_search, LocaleController.getString("SearchMembers", R.string.SearchMembers)); + otherItem.addSubItem(search_members, R.drawable.msg_search, LocaleController.getString("SearchMembers", R.string.SearchMembers)); if (!chat.creator && !chat.left && !chat.kicked) { - item.addSubItem(leave_group, R.drawable.msg_leave, LocaleController.getString("LeaveMegaMenu", R.string.LeaveMegaMenu)); + otherItem.addSubItem(leave_group, R.drawable.msg_leave, LocaleController.getString("LeaveMegaMenu", R.string.LeaveMegaMenu)); } } else { if (!TextUtils.isEmpty(chat.username)) { - if (item == null) { - item = menu.addItem(10, R.drawable.ic_ab_other); - } - item.addSubItem(share, R.drawable.msg_share, LocaleController.getString("BotShare", R.string.BotShare)); + otherItem.addSubItem(share, R.drawable.msg_share, LocaleController.getString("BotShare", R.string.BotShare)); + } + if (!currentChat.creator && !currentChat.left && !currentChat.kicked) { + otherItem.addSubItem(leave_group, R.drawable.msg_leave, LocaleController.getString("LeaveChannelMenu", R.string.LeaveChannelMenu)); } } } else { if (ChatObject.canChangeChatInfo(chat)) { - editItem = menu.addItem(edit_channel, R.drawable.group_edit_profile); + editItemVisible = true; } - item = menu.addItem(10, R.drawable.ic_ab_other); if (!ChatObject.isKickedFromChat(chat) && !ChatObject.isLeftFromChat(chat)) { - item.addSubItem(search_members, R.drawable.msg_search, LocaleController.getString("SearchMembers", R.string.SearchMembers)); + otherItem.addSubItem(search_members, R.drawable.msg_search, LocaleController.getString("SearchMembers", R.string.SearchMembers)); } - item.addSubItem(leave_group, R.drawable.msg_leave, LocaleController.getString("DeleteAndExit", R.string.DeleteAndExit)); + otherItem.addSubItem(leave_group, R.drawable.msg_leave, LocaleController.getString("DeleteAndExit", R.string.DeleteAndExit)); } } } - if (item == null) { - item = menu.addItem(10, R.drawable.ic_ab_other); + otherItem.addSubItem(add_shortcut, R.drawable.msg_home, LocaleController.getString("AddShortcut", R.string.AddShortcut)); + otherItem.addSubItem(gallery_menu_save, R.drawable.msg_gallery, LocaleController.getString("SaveToGallery", R.string.SaveToGallery)); + if (!isPulledDown) { + otherItem.hideSubItem(gallery_menu_save); } - item.addSubItem(add_shortcut, R.drawable.msg_home, LocaleController.getString("AddShortcut", R.string.AddShortcut)); - item.setContentDescription(LocaleController.getString("AccDescrMoreOptions", R.string.AccDescrMoreOptions)); + otherItem.setContentDescription(LocaleController.getString("AccDescrMoreOptions", R.string.AccDescrMoreOptions)); + + if (callItemVisible) { + if (callItem.getVisibility() != View.VISIBLE) { + callItem.setVisibility(View.VISIBLE); + } + } else { + if (callItem.getVisibility() != View.GONE) { + callItem.setVisibility(View.GONE); + } + } + + if (editItemVisible) { + if (editItem.getVisibility() != View.VISIBLE) { + editItem.setVisibility(View.VISIBLE); + } + } else { + if (editItem.getVisibility() != View.GONE) { + editItem.setVisibility(View.GONE); + } + } + if (editItem != null) { editItem.setContentDescription(LocaleController.getString("Edit", R.string.Edit)); } @@ -3799,10 +4192,10 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. } if (avatarsViewPagerIndicatorView != null) { if (avatarsViewPagerIndicatorView.isIndicatorFullyVisible()) { - if (editItem != null) { + if (editItemVisible) { editItem.setVisibility(View.GONE); } - if (callItem != null) { + if (callItemVisible) { callItem.setVisibility(View.GONE); } } @@ -3923,7 +4316,12 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. break; } case 11: { - view = new EmptyCell(mContext, 36); + view = new View(mContext) { + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(32), MeasureSpec.EXACTLY)); + } + }; break; } case 12: { @@ -3962,11 +4360,34 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. }; break; } + case 13: { + if (sharedMediaLayout.getParent() != null) { + ((ViewGroup) sharedMediaLayout.getParent()).removeView(sharedMediaLayout); + } + view = sharedMediaLayout; + break; + } + } + if (viewType != 13) { + view.setLayoutParams(new RecyclerView.LayoutParams(RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.WRAP_CONTENT)); } - view.setLayoutParams(new RecyclerView.LayoutParams(RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.WRAP_CONTENT)); return new RecyclerListView.Holder(view); } + @Override + public void onViewAttachedToWindow(RecyclerView.ViewHolder holder) { + if (holder.itemView == sharedMediaLayout) { + sharedMediaLayoutAttached = true; + } + } + + @Override + public void onViewDetachedFromWindow(RecyclerView.ViewHolder holder) { + if (holder.itemView == sharedMediaLayout) { + sharedMediaLayoutAttached = false; + } + } + @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { switch (holder.getItemViewType()) { @@ -3978,8 +4399,6 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. } else { headerCell.setText(LocaleController.getString("Info", R.string.Info)); } - } else if (position == sharedHeaderRow) { - headerCell.setText(LocaleController.getString("SharedContent", R.string.SharedContent)); } else if (position == membersHeaderRow) { headerCell.setText(LocaleController.getString("ChannelMembers", R.string.ChannelMembers)); } @@ -4032,19 +4451,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. TextCell textCell = (TextCell) holder.itemView; textCell.setColors(Theme.key_windowBackgroundWhiteGrayIcon, Theme.key_windowBackgroundWhiteBlackText); textCell.setTag(Theme.key_windowBackgroundWhiteBlackText); - if (position == photosRow) { - textCell.setTextAndValueAndIcon(LocaleController.getString("SharedPhotosAndVideos", R.string.SharedPhotosAndVideos), String.format("%d", lastMediaCount[MediaDataController.MEDIA_PHOTOVIDEO]), R.drawable.profile_photos, position != sharedSectionRow - 1); - } else if (position == filesRow) { - textCell.setTextAndValueAndIcon(LocaleController.getString("FilesDataUsage", R.string.FilesDataUsage), String.format("%d", lastMediaCount[MediaDataController.MEDIA_FILE]), R.drawable.profile_file, position != sharedSectionRow - 1); - } else if (position == linksRow) { - textCell.setTextAndValueAndIcon(LocaleController.getString("SharedLinks", R.string.SharedLinks), String.format("%d", lastMediaCount[MediaDataController.MEDIA_URL]), R.drawable.profile_link, position != sharedSectionRow - 1); - } else if (position == audioRow) { - textCell.setTextAndValueAndIcon(LocaleController.getString("SharedAudioFiles", R.string.SharedAudioFiles), String.format("%d", lastMediaCount[MediaDataController.MEDIA_MUSIC]), R.drawable.profile_audio, position != sharedSectionRow - 1); - } else if (position == voiceRow) { - textCell.setTextAndValueAndIcon(LocaleController.getString("AudioAutodownload", R.string.AudioAutodownload), String.format("%d", lastMediaCount[MediaDataController.MEDIA_AUDIO]), R.drawable.profile_voice, position != sharedSectionRow - 1); - } else if (position == groupsInCommonRow) { - textCell.setTextAndValueAndIcon(LocaleController.getString("GroupsInCommonTitle", R.string.GroupsInCommonTitle), String.format("%d", userInfo.common_chats_count), R.drawable.actions_viewmembers, position != sharedSectionRow - 1); - } else if (position == settingsTimerRow) { + if (position == settingsTimerRow) { TLRPC.EncryptedChat encryptedChat = MessagesController.getInstance(currentAccount).getEncryptedChat((int) (dialog_id >> 32)); String value; if (encryptedChat.ttl == 0) { @@ -4056,17 +4463,11 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. } else if (position == unblockRow) { textCell.setText(LocaleController.getString("Unblock", R.string.Unblock), false); textCell.setColors(null, Theme.key_windowBackgroundWhiteRedText5); - } else if (position == startSecretChatRow) { - textCell.setText(LocaleController.getString("StartEncryptedChat", R.string.StartEncryptedChat), false); - textCell.setColors(null, Theme.key_windowBackgroundWhiteGreenText2); } else if (position == settingsKeyRow) { IdenticonDrawable identiconDrawable = new IdenticonDrawable(); TLRPC.EncryptedChat encryptedChat = MessagesController.getInstance(currentAccount).getEncryptedChat((int) (dialog_id >> 32)); identiconDrawable.setEncryptedChat(encryptedChat); textCell.setTextAndValueDrawable(LocaleController.getString("EncryptionKey", R.string.EncryptionKey), identiconDrawable, false); - } else if (position == leaveChannelRow) { - textCell.setColors(null, Theme.key_windowBackgroundWhiteRedText5); - textCell.setText(LocaleController.getString("LeaveChannel", R.string.LeaveChannel), false); } else if (position == joinRow) { textCell.setColors(null, Theme.key_windowBackgroundWhiteBlueText2); textCell.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlueText2)); @@ -4108,6 +4509,11 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. } else { textCell.setTextAndIcon(LocaleController.getString("AddRecipient", R.string.AddRecipient), R.drawable.actions_addmember2, true); } + } else if (position == sendMessageRow) { + textCell.setText(LocaleController.getString("SendMessageLocation", R.string.SendMessageLocation), true); + } else if (position == reportRow) { + textCell.setText(LocaleController.getString("ReportUserLocation", R.string.ReportUserLocation), false); + textCell.setColors(null, Theme.key_windowBackgroundWhiteRedText5); } break; case 6: @@ -4177,7 +4583,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. View sectionCell = holder.itemView; sectionCell.setTag(position); Drawable drawable; - if (position == infoSectionRow && sharedSectionRow == -1 && lastSectionRow == -1 && settingsSectionRow == -1 || position == settingsSectionRow && sharedSectionRow == -1 || position == sharedSectionRow && lastSectionRow == -1 || position == lastSectionRow || position == membersSectionRow && lastSectionRow == -1 && (sharedSectionRow == -1 || membersSectionRow > sharedSectionRow)) { + if (position == infoSectionRow && lastSectionRow == -1 && settingsSectionRow == -1 && sharedMediaRow == -1 && membersSectionRow == -1 || position == settingsSectionRow || position == lastSectionRow || position == membersSectionRow && lastSectionRow == -1 && sharedMediaRow == -1) { drawable = Theme.getThemedDrawable(mContext, R.drawable.greydivider_bottom, Theme.key_windowBackgroundGrayShadow); } else { drawable = Theme.getThemedDrawable(mContext, R.drawable.greydivider, Theme.key_windowBackgroundGrayShadow); @@ -4228,7 +4634,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. @Override public boolean isEnabled(RecyclerView.ViewHolder holder) { int type = holder.getItemViewType(); - return type != 1 && type != 5 && type != 7 && type != 9 && type != 10 && type != 11 && type != 12; + return type != 1 && type != 5 && type != 7 && type != 9 && type != 10 && type != 11 && type != 12 && type != 13; } @Override @@ -4238,22 +4644,22 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. @Override public int getItemViewType(int i) { - if (i == infoHeaderRow || i == sharedHeaderRow || i == membersHeaderRow) { + if (i == infoHeaderRow || i == membersHeaderRow) { return 1; } else if (i == phoneRow || i == usernameRow || i == locationRow) { return 2; } else if (i == userInfoRow || i == channelInfoRow) { return 3; - } else if (i == settingsTimerRow || i == settingsKeyRow || i == photosRow || i == filesRow || - i == linksRow || i == audioRow || i == voiceRow || i == groupsInCommonRow || - i == startSecretChatRow || i == subscribersRow || i == administratorsRow || i == blockedUsersRow || - i == leaveChannelRow || i == addMemberRow || i == joinRow || i == unblockRow) { + } else if (i == settingsTimerRow || i == settingsKeyRow || i == reportRow || + i == subscribersRow || i == administratorsRow || i == blockedUsersRow || + i == addMemberRow || i == joinRow || i == unblockRow || + i == sendMessageRow) { return 4; } else if (i == notificationsDividerRow) { return 5; } else if (i == notificationsRow) { return 6; - } else if (i == infoSectionRow || i == sharedSectionRow || i == lastSectionRow || i == membersSectionRow || i == settingsSectionRow) { + } else if (i == infoSectionRow || i == lastSectionRow || i == membersSectionRow || i == settingsSectionRow) { return 7; } else if (i >= membersStartRow && i < membersEndRow) { return 8; @@ -4261,6 +4667,8 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. return 11; } else if (i == bottomPaddingRow) { return 12; + } else if (i == sharedMediaRow) { + return 13; } return 0; } @@ -4295,87 +4703,93 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. actionBar.setItemsBackgroundColor(Theme.getColor(Theme.key_avatar_actionBarSelectorBlue), false); } }; - return new ThemeDescription[]{ - new ThemeDescription(listView, 0, null, null, null, null, Theme.key_windowBackgroundWhite), - new ThemeDescription(listView, 0, null, null, null, null, Theme.key_windowBackgroundGray), - new ThemeDescription(actionBar, ThemeDescription.FLAG_AB_SUBMENUBACKGROUND, null, null, null, null, Theme.key_actionBarDefaultSubmenuBackground), - new ThemeDescription(actionBar, ThemeDescription.FLAG_AB_SUBMENUITEM, null, null, null, null, Theme.key_actionBarDefaultSubmenuItem), - new ThemeDescription(actionBar, ThemeDescription.FLAG_AB_SUBMENUITEM | ThemeDescription.FLAG_IMAGECOLOR, null, null, null, null, Theme.key_actionBarDefaultSubmenuItemIcon), - new ThemeDescription(null, 0, null, null, null, themeDelegate, Theme.key_actionBarDefaultIcon), - new ThemeDescription(null, 0, null, null, null, themeDelegate, Theme.key_avatar_actionBarSelectorBlue), - new ThemeDescription(null, 0, null, null, null, themeDelegate, Theme.key_chat_lockIcon), - new ThemeDescription(null, 0, null, null, null, themeDelegate, Theme.key_avatar_subtitleInProfileBlue), - new ThemeDescription(null, 0, null, null, null, themeDelegate, Theme.key_avatar_backgroundActionBarBlue), - new ThemeDescription(null, 0, null, null, null, themeDelegate, Theme.key_profile_title), - new ThemeDescription(null, 0, null, null, null, themeDelegate, Theme.key_profile_status), - new ThemeDescription(null, 0, null, null, null, themeDelegate, Theme.key_avatar_subtitleInProfileBlue), + ArrayList arrayList = new ArrayList<>(); + if (sharedMediaLayout != null) { + arrayList.addAll(sharedMediaLayout.getThemeDescriptions()); + } - new ThemeDescription(topView, ThemeDescription.FLAG_BACKGROUND, null, null, null, null, Theme.key_avatar_backgroundActionBarBlue), - new ThemeDescription(listView, ThemeDescription.FLAG_LISTGLOWCOLOR, null, null, null, null, Theme.key_avatar_backgroundActionBarBlue), - new ThemeDescription(listView, ThemeDescription.FLAG_SELECTOR, null, null, null, null, Theme.key_listSelector), - new ThemeDescription(listView, 0, new Class[]{View.class}, Theme.dividerPaint, null, null, Theme.key_divider), + arrayList.add(new ThemeDescription(listView, 0, null, null, null, null, Theme.key_windowBackgroundWhite)); + arrayList.add(new ThemeDescription(listView, 0, null, null, null, null, Theme.key_windowBackgroundGray)); + arrayList.add(new ThemeDescription(actionBar, ThemeDescription.FLAG_AB_SUBMENUBACKGROUND, null, null, null, null, Theme.key_actionBarDefaultSubmenuBackground)); + arrayList.add(new ThemeDescription(actionBar, ThemeDescription.FLAG_AB_SUBMENUITEM, null, null, null, null, Theme.key_actionBarDefaultSubmenuItem)); + arrayList.add(new ThemeDescription(actionBar, ThemeDescription.FLAG_AB_SUBMENUITEM | ThemeDescription.FLAG_IMAGECOLOR, null, null, null, null, Theme.key_actionBarDefaultSubmenuItemIcon)); + arrayList.add(new ThemeDescription(null, 0, null, null, null, themeDelegate, Theme.key_actionBarDefaultIcon)); + arrayList.add(new ThemeDescription(null, 0, null, null, null, themeDelegate, Theme.key_avatar_actionBarSelectorBlue)); + arrayList.add(new ThemeDescription(null, 0, null, null, null, themeDelegate, Theme.key_chat_lockIcon)); + arrayList.add(new ThemeDescription(null, 0, null, null, null, themeDelegate, Theme.key_avatar_subtitleInProfileBlue)); + arrayList.add(new ThemeDescription(null, 0, null, null, null, themeDelegate, Theme.key_avatar_backgroundActionBarBlue)); + arrayList.add(new ThemeDescription(null, 0, null, null, null, themeDelegate, Theme.key_profile_title)); + arrayList.add(new ThemeDescription(null, 0, null, null, null, themeDelegate, Theme.key_profile_status)); + arrayList.add(new ThemeDescription(null, 0, null, null, null, themeDelegate, Theme.key_avatar_subtitleInProfileBlue)); - new ThemeDescription(avatarImage, 0, null, null, new Drawable[]{Theme.avatar_savedDrawable}, null, Theme.key_avatar_text), - new ThemeDescription(avatarImage, 0, null, null, new Drawable[]{avatarDrawable}, null, Theme.key_avatar_backgroundInProfileBlue), + arrayList.add(new ThemeDescription(onlineTextView[2], ThemeDescription.FLAG_TEXTCOLOR, null, null, null, themeDelegate, Theme.key_player_actionBarSubtitle)); - new ThemeDescription(writeButton, ThemeDescription.FLAG_IMAGECOLOR, null, null, null, null, Theme.key_profile_actionIcon), - new ThemeDescription(writeButton, ThemeDescription.FLAG_BACKGROUNDFILTER, null, null, null, null, Theme.key_profile_actionBackground), - new ThemeDescription(writeButton, ThemeDescription.FLAG_BACKGROUNDFILTER | ThemeDescription.FLAG_DRAWABLESELECTEDSTATE, null, null, null, null, Theme.key_profile_actionPressedBackground), + arrayList.add(new ThemeDescription(topView, ThemeDescription.FLAG_BACKGROUND, null, null, null, null, Theme.key_avatar_backgroundActionBarBlue)); + arrayList.add(new ThemeDescription(listView, ThemeDescription.FLAG_SELECTOR, null, null, null, null, Theme.key_listSelector)); + arrayList.add(new ThemeDescription(listView, 0, new Class[]{View.class}, Theme.dividerPaint, null, null, Theme.key_divider)); - new ThemeDescription(listView, ThemeDescription.FLAG_CHECKTAG, new Class[]{TextCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteBlackText), - new ThemeDescription(listView, ThemeDescription.FLAG_CHECKTAG, new Class[]{TextCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteGreenText2), - new ThemeDescription(listView, ThemeDescription.FLAG_CHECKTAG, new Class[]{TextCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteRedText5), - new ThemeDescription(listView, ThemeDescription.FLAG_CHECKTAG, new Class[]{TextCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteBlueText2), - new ThemeDescription(listView, ThemeDescription.FLAG_CHECKTAG, new Class[]{TextCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteBlueButton), - new ThemeDescription(listView, 0, new Class[]{TextCell.class}, new String[]{"valueTextView"}, null, null, null, Theme.key_windowBackgroundWhiteValueText), - new ThemeDescription(listView, ThemeDescription.FLAG_CHECKTAG, new Class[]{TextCell.class}, new String[]{"imageView"}, null, null, null, Theme.key_windowBackgroundWhiteGrayIcon), - new ThemeDescription(listView, ThemeDescription.FLAG_CHECKTAG, new Class[]{TextCell.class}, new String[]{"imageView"}, null, null, null, Theme.key_windowBackgroundWhiteBlueIcon), + arrayList.add(new ThemeDescription(avatarImage, 0, null, null, new Drawable[]{Theme.avatar_savedDrawable}, null, Theme.key_avatar_text)); + arrayList.add(new ThemeDescription(avatarImage, 0, null, null, new Drawable[]{avatarDrawable}, null, Theme.key_avatar_backgroundInProfileBlue)); - new ThemeDescription(listView, 0, new Class[]{TextDetailCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteBlackText), - new ThemeDescription(listView, 0, new Class[]{TextDetailCell.class}, new String[]{"valueTextView"}, null, null, null, Theme.key_windowBackgroundWhiteGrayText2), + arrayList.add(new ThemeDescription(writeButton, ThemeDescription.FLAG_IMAGECOLOR, null, null, null, null, Theme.key_profile_actionIcon)); + arrayList.add(new ThemeDescription(writeButton, ThemeDescription.FLAG_BACKGROUNDFILTER, null, null, null, null, Theme.key_profile_actionBackground)); + arrayList.add(new ThemeDescription(writeButton, ThemeDescription.FLAG_BACKGROUNDFILTER | ThemeDescription.FLAG_DRAWABLESELECTEDSTATE, null, null, null, null, Theme.key_profile_actionPressedBackground)); - new ThemeDescription(listView, 0, new Class[]{HeaderCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteBlueHeader), + arrayList.add(new ThemeDescription(listView, ThemeDescription.FLAG_CHECKTAG, new Class[]{TextCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteBlackText)); + arrayList.add(new ThemeDescription(listView, ThemeDescription.FLAG_CHECKTAG, new Class[]{TextCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteGreenText2)); + arrayList.add(new ThemeDescription(listView, ThemeDescription.FLAG_CHECKTAG, new Class[]{TextCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteRedText5)); + arrayList.add(new ThemeDescription(listView, ThemeDescription.FLAG_CHECKTAG, new Class[]{TextCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteBlueText2)); + arrayList.add(new ThemeDescription(listView, ThemeDescription.FLAG_CHECKTAG, new Class[]{TextCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteBlueButton)); + arrayList.add(new ThemeDescription(listView, 0, new Class[]{TextCell.class}, new String[]{"valueTextView"}, null, null, null, Theme.key_windowBackgroundWhiteValueText)); + arrayList.add(new ThemeDescription(listView, ThemeDescription.FLAG_CHECKTAG, new Class[]{TextCell.class}, new String[]{"imageView"}, null, null, null, Theme.key_windowBackgroundWhiteGrayIcon)); + arrayList.add(new ThemeDescription(listView, ThemeDescription.FLAG_CHECKTAG, new Class[]{TextCell.class}, new String[]{"imageView"}, null, null, null, Theme.key_windowBackgroundWhiteBlueIcon)); - new ThemeDescription(listView, 0, new Class[]{NotificationsCheckCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteBlackText), - new ThemeDescription(listView, 0, new Class[]{NotificationsCheckCell.class}, new String[]{"valueTextView"}, null, null, null, Theme.key_windowBackgroundWhiteGrayText2), - new ThemeDescription(listView, 0, new Class[]{NotificationsCheckCell.class}, new String[]{"checkBox"}, null, null, null, Theme.key_switchTrack), - new ThemeDescription(listView, 0, new Class[]{NotificationsCheckCell.class}, new String[]{"checkBox"}, null, null, null, Theme.key_switchTrackChecked), + arrayList.add(new ThemeDescription(listView, 0, new Class[]{TextDetailCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteBlackText)); + arrayList.add(new ThemeDescription(listView, 0, new Class[]{TextDetailCell.class}, new String[]{"valueTextView"}, null, null, null, Theme.key_windowBackgroundWhiteGrayText2)); - new ThemeDescription(listView, ThemeDescription.FLAG_TEXTCOLOR, new Class[]{UserCell.class}, new String[]{"adminTextView"}, null, null, null, Theme.key_profile_creatorIcon), - new ThemeDescription(listView, 0, new Class[]{UserCell.class}, new String[]{"imageView"}, null, null, null, Theme.key_windowBackgroundWhiteGrayIcon), - new ThemeDescription(listView, 0, new Class[]{UserCell.class}, new String[]{"nameTextView"}, null, null, null, Theme.key_windowBackgroundWhiteBlackText), - new ThemeDescription(listView, 0, new Class[]{UserCell.class}, new String[]{"statusColor"}, null, null, themeDelegate, Theme.key_windowBackgroundWhiteGrayText), - new ThemeDescription(listView, 0, new Class[]{UserCell.class}, new String[]{"statusOnlineColor"}, null, null, themeDelegate, Theme.key_windowBackgroundWhiteBlueText), - new ThemeDescription(listView, 0, new Class[]{UserCell.class}, null, new Drawable[]{Theme.avatar_savedDrawable}, null, Theme.key_avatar_text), - new ThemeDescription(null, 0, null, null, null, themeDelegate, Theme.key_avatar_backgroundRed), - new ThemeDescription(null, 0, null, null, null, themeDelegate, Theme.key_avatar_backgroundOrange), - new ThemeDescription(null, 0, null, null, null, themeDelegate, Theme.key_avatar_backgroundViolet), - new ThemeDescription(null, 0, null, null, null, themeDelegate, Theme.key_avatar_backgroundGreen), - new ThemeDescription(null, 0, null, null, null, themeDelegate, Theme.key_avatar_backgroundCyan), - new ThemeDescription(null, 0, null, null, null, themeDelegate, Theme.key_avatar_backgroundBlue), - new ThemeDescription(null, 0, null, null, null, themeDelegate, Theme.key_avatar_backgroundPink), + arrayList.add(new ThemeDescription(listView, 0, new Class[]{HeaderCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteBlueHeader)); - new ThemeDescription(undoView, ThemeDescription.FLAG_BACKGROUNDFILTER, null, null, null, null, Theme.key_undo_background), - new ThemeDescription(undoView, 0, new Class[]{UndoView.class}, new String[]{"undoImageView"}, null, null, null, Theme.key_undo_cancelColor), - new ThemeDescription(undoView, 0, new Class[]{UndoView.class}, new String[]{"undoTextView"}, null, null, null, Theme.key_undo_cancelColor), - new ThemeDescription(undoView, 0, new Class[]{UndoView.class}, new String[]{"infoTextView"}, null, null, null, Theme.key_undo_infoColor), - new ThemeDescription(undoView, 0, new Class[]{UndoView.class}, new String[]{"textPaint"}, null, null, null, Theme.key_undo_infoColor), - new ThemeDescription(undoView, 0, new Class[]{UndoView.class}, new String[]{"progressPaint"}, null, null, null, Theme.key_undo_infoColor), - new ThemeDescription(undoView, ThemeDescription.FLAG_IMAGECOLOR, new Class[]{UndoView.class}, new String[]{"leftImageView"}, null, null, null, Theme.key_undo_infoColor), + arrayList.add(new ThemeDescription(listView, 0, new Class[]{NotificationsCheckCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteBlackText)); + arrayList.add(new ThemeDescription(listView, 0, new Class[]{NotificationsCheckCell.class}, new String[]{"valueTextView"}, null, null, null, Theme.key_windowBackgroundWhiteGrayText2)); + arrayList.add(new ThemeDescription(listView, 0, new Class[]{NotificationsCheckCell.class}, new String[]{"checkBox"}, null, null, null, Theme.key_switchTrack)); + arrayList.add(new ThemeDescription(listView, 0, new Class[]{NotificationsCheckCell.class}, new String[]{"checkBox"}, null, null, null, Theme.key_switchTrackChecked)); - new ThemeDescription(listView, ThemeDescription.FLAG_TEXTCOLOR, new Class[]{AboutLinkCell.class}, Theme.profile_aboutTextPaint, null, null, Theme.key_windowBackgroundWhiteBlackText), - new ThemeDescription(listView, ThemeDescription.FLAG_LINKCOLOR, new Class[]{AboutLinkCell.class}, Theme.profile_aboutTextPaint, null, null, Theme.key_windowBackgroundWhiteLinkText), - new ThemeDescription(listView, 0, new Class[]{AboutLinkCell.class}, Theme.linkSelectionPaint, null, null, Theme.key_windowBackgroundWhiteLinkSelection), + arrayList.add(new ThemeDescription(listView, ThemeDescription.FLAG_TEXTCOLOR, new Class[]{UserCell.class}, new String[]{"adminTextView"}, null, null, null, Theme.key_profile_creatorIcon)); + arrayList.add(new ThemeDescription(listView, 0, new Class[]{UserCell.class}, new String[]{"imageView"}, null, null, null, Theme.key_windowBackgroundWhiteGrayIcon)); + arrayList.add(new ThemeDescription(listView, 0, new Class[]{UserCell.class}, new String[]{"nameTextView"}, null, null, null, Theme.key_windowBackgroundWhiteBlackText)); + arrayList.add(new ThemeDescription(listView, 0, new Class[]{UserCell.class}, new String[]{"statusColor"}, null, null, themeDelegate, Theme.key_windowBackgroundWhiteGrayText)); + arrayList.add(new ThemeDescription(listView, 0, new Class[]{UserCell.class}, new String[]{"statusOnlineColor"}, null, null, themeDelegate, Theme.key_windowBackgroundWhiteBlueText)); + arrayList.add(new ThemeDescription(listView, 0, new Class[]{UserCell.class}, null, new Drawable[]{Theme.avatar_savedDrawable}, null, Theme.key_avatar_text)); + arrayList.add(new ThemeDescription(null, 0, null, null, null, themeDelegate, Theme.key_avatar_backgroundRed)); + arrayList.add(new ThemeDescription(null, 0, null, null, null, themeDelegate, Theme.key_avatar_backgroundOrange)); + arrayList.add(new ThemeDescription(null, 0, null, null, null, themeDelegate, Theme.key_avatar_backgroundViolet)); + arrayList.add(new ThemeDescription(null, 0, null, null, null, themeDelegate, Theme.key_avatar_backgroundGreen)); + arrayList.add(new ThemeDescription(null, 0, null, null, null, themeDelegate, Theme.key_avatar_backgroundCyan)); + arrayList.add(new ThemeDescription(null, 0, null, null, null, themeDelegate, Theme.key_avatar_backgroundBlue)); + arrayList.add(new ThemeDescription(null, 0, null, null, null, themeDelegate, Theme.key_avatar_backgroundPink)); - new ThemeDescription(listView, ThemeDescription.FLAG_BACKGROUNDFILTER, new Class[]{ShadowSectionCell.class}, null, null, null, Theme.key_windowBackgroundGrayShadow), - new ThemeDescription(listView, ThemeDescription.FLAG_BACKGROUNDFILTER | ThemeDescription.FLAG_CELLBACKGROUNDCOLOR, new Class[]{ShadowSectionCell.class}, null, null, null, Theme.key_windowBackgroundGray), + arrayList.add(new ThemeDescription(undoView, ThemeDescription.FLAG_BACKGROUNDFILTER, null, null, null, null, Theme.key_undo_background)); + arrayList.add(new ThemeDescription(undoView, 0, new Class[]{UndoView.class}, new String[]{"undoImageView"}, null, null, null, Theme.key_undo_cancelColor)); + arrayList.add(new ThemeDescription(undoView, 0, new Class[]{UndoView.class}, new String[]{"undoTextView"}, null, null, null, Theme.key_undo_cancelColor)); + arrayList.add(new ThemeDescription(undoView, 0, new Class[]{UndoView.class}, new String[]{"infoTextView"}, null, null, null, Theme.key_undo_infoColor)); + arrayList.add(new ThemeDescription(undoView, 0, new Class[]{UndoView.class}, new String[]{"textPaint"}, null, null, null, Theme.key_undo_infoColor)); + arrayList.add(new ThemeDescription(undoView, 0, new Class[]{UndoView.class}, new String[]{"progressPaint"}, null, null, null, Theme.key_undo_infoColor)); + arrayList.add(new ThemeDescription(undoView, ThemeDescription.FLAG_IMAGECOLOR, new Class[]{UndoView.class}, new String[]{"leftImageView"}, null, null, null, Theme.key_undo_infoColor)); - new ThemeDescription(listView, ThemeDescription.FLAG_BACKGROUNDFILTER, new Class[]{TextInfoPrivacyCell.class}, null, null, null, Theme.key_windowBackgroundGrayShadow), - new ThemeDescription(listView, ThemeDescription.FLAG_BACKGROUNDFILTER | ThemeDescription.FLAG_CELLBACKGROUNDCOLOR, new Class[]{TextInfoPrivacyCell.class}, null, null, null, Theme.key_windowBackgroundGray), - new ThemeDescription(listView, 0, new Class[]{TextInfoPrivacyCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteGrayText4), + arrayList.add(new ThemeDescription(listView, ThemeDescription.FLAG_TEXTCOLOR, new Class[]{AboutLinkCell.class}, Theme.profile_aboutTextPaint, null, null, Theme.key_windowBackgroundWhiteBlackText)); + arrayList.add(new ThemeDescription(listView, ThemeDescription.FLAG_LINKCOLOR, new Class[]{AboutLinkCell.class}, Theme.profile_aboutTextPaint, null, null, Theme.key_windowBackgroundWhiteLinkText)); + arrayList.add(new ThemeDescription(listView, 0, new Class[]{AboutLinkCell.class}, Theme.linkSelectionPaint, null, null, Theme.key_windowBackgroundWhiteLinkSelection)); - new ThemeDescription(nameTextView[1], 0, null, null, new Drawable[]{verifiedCheckDrawable}, null, Theme.key_profile_verifiedCheck), - new ThemeDescription(nameTextView[1], 0, null, null, new Drawable[]{verifiedDrawable}, null, Theme.key_profile_verifiedBackground), - }; + arrayList.add(new ThemeDescription(listView, ThemeDescription.FLAG_BACKGROUNDFILTER, new Class[]{ShadowSectionCell.class}, null, null, null, Theme.key_windowBackgroundGrayShadow)); + arrayList.add(new ThemeDescription(listView, ThemeDescription.FLAG_BACKGROUNDFILTER | ThemeDescription.FLAG_CELLBACKGROUNDCOLOR, new Class[]{ShadowSectionCell.class}, null, null, null, Theme.key_windowBackgroundGray)); + + arrayList.add(new ThemeDescription(listView, ThemeDescription.FLAG_BACKGROUNDFILTER, new Class[]{TextInfoPrivacyCell.class}, null, null, null, Theme.key_windowBackgroundGrayShadow)); + arrayList.add(new ThemeDescription(listView, ThemeDescription.FLAG_BACKGROUNDFILTER | ThemeDescription.FLAG_CELLBACKGROUNDCOLOR, new Class[]{TextInfoPrivacyCell.class}, null, null, null, Theme.key_windowBackgroundGray)); + arrayList.add(new ThemeDescription(listView, 0, new Class[]{TextInfoPrivacyCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteGrayText4)); + + arrayList.add(new ThemeDescription(nameTextView[1], 0, null, null, new Drawable[]{verifiedCheckDrawable}, null, Theme.key_profile_verifiedCheck)); + arrayList.add(new ThemeDescription(nameTextView[1], 0, null, null, new Drawable[]{verifiedDrawable}, null, Theme.key_profile_verifiedBackground)); + + return arrayList.toArray(new ThemeDescription[0]); } } \ No newline at end of file diff --git a/TMessagesProj/src/main/java/org/telegram/ui/SettingsActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/SettingsActivity.java index 44a6b1423..5343c7575 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/SettingsActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/SettingsActivity.java @@ -493,7 +493,9 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter LocaleController.getString("DebugMenuCallSettings", R.string.DebugMenuCallSettings), null, BuildVars.DEBUG_PRIVATE_VERSION ? "Check for app updates" : null, - LocaleController.getString("DebugMenuReadAllDialogs", R.string.DebugMenuReadAllDialogs) + LocaleController.getString("DebugMenuReadAllDialogs", R.string.DebugMenuReadAllDialogs), + SharedConfig.pauseMusicOnRecord ? LocaleController.getString("DebugMenuDisablePauseMusic", R.string.DebugMenuDisablePauseMusic) : LocaleController.getString("DebugMenuEnablePauseMusic", R.string.DebugMenuEnablePauseMusic), + BuildVars.DEBUG_VERSION && !AndroidUtilities.isTablet() ? (SharedConfig.smoothKeyboard ? LocaleController.getString("DebugMenuDisableSmoothKeyboard", R.string.DebugMenuDisableSmoothKeyboard) : LocaleController.getString("DebugMenuEnableSmoothKeyboard", R.string.DebugMenuEnableSmoothKeyboard)) : null }; builder.setItems(items, (dialog, which) -> { if (which == 0) { @@ -526,6 +528,13 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter ((LaunchActivity) getParentActivity()).checkAppUpdate(true); } else if (which == 10) { MessagesStorage.getInstance(currentAccount).readAllDialogs(-1); + } else if (which == 11) { + SharedConfig.togglePauseMusicOnRecord(); + } else if (which == 12) { + SharedConfig.toggleSmoothKeyboard(); + if (SharedConfig.smoothKeyboard && getParentActivity() != null) { + getParentActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN); + } } }); builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ThemeActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ThemeActivity.java index bbb4161a2..bdba17e37 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ThemeActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ThemeActivity.java @@ -2053,14 +2053,15 @@ public class ThemeActivity extends BaseFragment implements NotificationCenter.No new ThemeDescription(listView, 0, new Class[]{NotificationsCheckCell.class}, new String[]{"valueTextView"}, null, null, null, Theme.key_windowBackgroundWhiteGrayText2), new ThemeDescription(listView, 0, new Class[]{NotificationsCheckCell.class}, new String[]{"checkBox"}, null, null, null, Theme.key_switchTrack), new ThemeDescription(listView, 0, new Class[]{NotificationsCheckCell.class}, new String[]{"checkBox"}, null, null, null, Theme.key_switchTrackChecked), - new ThemeDescription(listView, 0, null, null, new Drawable[]{Theme.chat_msgInDrawable, Theme.chat_msgInMediaDrawable}, null, Theme.key_chat_inBubble), new ThemeDescription(listView, 0, null, null, new Drawable[]{Theme.chat_msgInSelectedDrawable, Theme.chat_msgInMediaSelectedDrawable}, null, Theme.key_chat_inBubbleSelected), - new ThemeDescription(listView, 0, null, null, new Drawable[]{Theme.chat_msgInDrawable.getShadowDrawable(), Theme.chat_msgInMediaDrawable.getShadowDrawable()}, null, Theme.key_chat_inBubbleShadow), + new ThemeDescription(listView, 0, null, null, Theme.chat_msgInDrawable.getShadowDrawables(), null, Theme.key_chat_inBubbleShadow), + new ThemeDescription(listView, 0, null, null, Theme.chat_msgInMediaDrawable.getShadowDrawables(), null, Theme.key_chat_inBubbleShadow), new ThemeDescription(listView, 0, null, null, new Drawable[]{Theme.chat_msgOutDrawable, Theme.chat_msgOutMediaDrawable}, null, Theme.key_chat_outBubble), new ThemeDescription(listView, 0, null, null, new Drawable[]{Theme.chat_msgOutDrawable, Theme.chat_msgOutMediaDrawable}, null, Theme.key_chat_outBubbleGradient), new ThemeDescription(listView, 0, null, null, new Drawable[]{Theme.chat_msgOutSelectedDrawable, Theme.chat_msgOutMediaSelectedDrawable}, null, Theme.key_chat_outBubbleSelected), - new ThemeDescription(listView, 0, null, null, new Drawable[]{Theme.chat_msgOutDrawable.getShadowDrawable(), Theme.chat_msgOutMediaDrawable.getShadowDrawable()}, null, Theme.key_chat_outBubbleShadow), + new ThemeDescription(listView, 0, null, null, Theme.chat_msgOutDrawable.getShadowDrawables(), null, Theme.key_chat_outBubbleShadow), + new ThemeDescription(listView, 0, null, null, Theme.chat_msgOutMediaDrawable.getShadowDrawables(), null, Theme.key_chat_outBubbleShadow), new ThemeDescription(listView, 0, null, null, null, null, Theme.key_chat_messageTextIn), new ThemeDescription(listView, 0, null, null, null, null, Theme.key_chat_messageTextOut), new ThemeDescription(listView, 0, null, null, new Drawable[]{Theme.chat_msgOutCheckDrawable}, null, Theme.key_chat_outSentCheck), diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ThemePreviewActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ThemePreviewActivity.java index 12b421132..8992509ab 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ThemePreviewActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ThemePreviewActivity.java @@ -257,7 +257,6 @@ public class ThemePreviewActivity extends BaseFragment implements DownloadContro public ThemePreviewActivity(Theme.ThemeInfo themeInfo, boolean deleteFile, int screenType, boolean edit, boolean night) { super(); this.screenType = screenType; - swipeBackEnabled = false; nightTheme = night; applyingTheme = themeInfo; deleteOnCancel = deleteFile; @@ -1962,6 +1961,11 @@ public class ThemePreviewActivity extends BaseFragment implements DownloadContro } } + @Override + public boolean isSwipeBackEnabled(MotionEvent event) { + return false; + } + @Override public void onFailedDownload(String fileName, boolean canceled) { updateButtonState( true, canceled); @@ -3475,11 +3479,13 @@ public class ThemePreviewActivity extends BaseFragment implements DownloadContro items.add(new ThemeDescription(listView2, 0, new Class[]{ChatMessageCell.class}, null, new Drawable[]{Theme.chat_msgInDrawable, Theme.chat_msgInMediaDrawable}, null, Theme.key_chat_inBubble)); items.add(new ThemeDescription(listView2, 0, new Class[]{ChatMessageCell.class}, null, new Drawable[]{Theme.chat_msgInSelectedDrawable, Theme.chat_msgInMediaSelectedDrawable}, null, Theme.key_chat_inBubbleSelected)); - items.add(new ThemeDescription(listView2, 0, new Class[]{ChatMessageCell.class}, null, new Drawable[]{Theme.chat_msgInDrawable.getShadowDrawable(), Theme.chat_msgInMediaDrawable.getShadowDrawable()}, null, Theme.key_chat_inBubbleShadow)); + items.add(new ThemeDescription(listView2, 0, new Class[]{ChatMessageCell.class}, null, Theme.chat_msgInDrawable.getShadowDrawables(), null, Theme.key_chat_inBubbleShadow)); + items.add(new ThemeDescription(listView2, 0, new Class[]{ChatMessageCell.class}, null, Theme.chat_msgInMediaDrawable.getShadowDrawables(), null, Theme.key_chat_inBubbleShadow)); items.add(new ThemeDescription(listView2, 0, new Class[]{ChatMessageCell.class}, null, new Drawable[]{Theme.chat_msgOutDrawable, Theme.chat_msgOutMediaDrawable}, null, Theme.key_chat_outBubble)); items.add(new ThemeDescription(listView2, 0, new Class[]{ChatMessageCell.class}, null, new Drawable[]{Theme.chat_msgOutDrawable, Theme.chat_msgOutMediaDrawable}, null, Theme.key_chat_outBubbleGradient)); items.add(new ThemeDescription(listView2, 0, new Class[]{ChatMessageCell.class}, null, new Drawable[]{Theme.chat_msgOutSelectedDrawable, Theme.chat_msgOutMediaSelectedDrawable}, null, Theme.key_chat_outBubbleSelected)); - items.add(new ThemeDescription(listView2, 0, new Class[]{ChatMessageCell.class}, null, new Drawable[]{Theme.chat_msgOutDrawable.getShadowDrawable(), Theme.chat_msgOutMediaDrawable.getShadowDrawable()}, null, Theme.key_chat_outBubbleShadow)); + items.add(new ThemeDescription(listView2, 0, new Class[]{ChatMessageCell.class}, null, Theme.chat_msgOutDrawable.getShadowDrawables(), null, Theme.key_chat_outBubbleShadow)); + items.add(new ThemeDescription(listView2, 0, new Class[]{ChatMessageCell.class}, null, Theme.chat_msgOutMediaDrawable.getShadowDrawables(), null, Theme.key_chat_outBubbleShadow)); items.add(new ThemeDescription(listView2, 0, new Class[]{ChatMessageCell.class}, null, null, null, Theme.key_chat_messageTextIn)); items.add(new ThemeDescription(listView2, 0, new Class[]{ChatMessageCell.class}, null, null, null, Theme.key_chat_messageTextOut)); items.add(new ThemeDescription(listView2, 0, new Class[]{ChatMessageCell.class}, null, new Drawable[]{Theme.chat_msgOutCheckDrawable}, null, Theme.key_chat_outSentCheck)); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ThemeSetUrlActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ThemeSetUrlActivity.java index f749a1841..058d1745a 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ThemeSetUrlActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ThemeSetUrlActivity.java @@ -683,11 +683,13 @@ public class ThemeSetUrlActivity extends BaseFragment implements NotificationCen new ThemeDescription(messagesCell, 0, null, null, new Drawable[]{Theme.chat_msgInDrawable, Theme.chat_msgInMediaDrawable}, null, Theme.key_chat_inBubble), new ThemeDescription(messagesCell, 0, null, null, new Drawable[]{Theme.chat_msgInSelectedDrawable, Theme.chat_msgInMediaSelectedDrawable}, null, Theme.key_chat_inBubbleSelected), - new ThemeDescription(messagesCell, 0, null, null, new Drawable[]{Theme.chat_msgInDrawable.getShadowDrawable(), Theme.chat_msgInMediaDrawable.getShadowDrawable()}, null, Theme.key_chat_inBubbleShadow), + new ThemeDescription(messagesCell, 0, null, null, Theme.chat_msgInDrawable.getShadowDrawables(), null, Theme.key_chat_inBubbleShadow), + new ThemeDescription(messagesCell, 0, null, null, Theme.chat_msgInMediaDrawable.getShadowDrawables(), null, Theme.key_chat_inBubbleShadow), new ThemeDescription(messagesCell, 0, null, null, new Drawable[]{Theme.chat_msgOutDrawable, Theme.chat_msgOutMediaDrawable}, null, Theme.key_chat_outBubble), new ThemeDescription(messagesCell, 0, null, null, new Drawable[]{Theme.chat_msgOutDrawable, Theme.chat_msgOutMediaDrawable}, null, Theme.key_chat_outBubbleGradient), new ThemeDescription(messagesCell, 0, null, null, new Drawable[]{Theme.chat_msgOutSelectedDrawable, Theme.chat_msgOutMediaSelectedDrawable}, null, Theme.key_chat_outBubbleSelected), - new ThemeDescription(messagesCell, 0, null, null, new Drawable[]{Theme.chat_msgOutDrawable.getShadowDrawable(), Theme.chat_msgOutMediaDrawable.getShadowDrawable()}, null, Theme.key_chat_outBubbleShadow), + new ThemeDescription(messagesCell, 0, null, null, Theme.chat_msgOutDrawable.getShadowDrawables(), null, Theme.key_chat_outBubbleShadow), + new ThemeDescription(messagesCell, 0, null, null, Theme.chat_msgOutMediaDrawable.getShadowDrawables(), null, Theme.key_chat_outBubbleShadow), new ThemeDescription(messagesCell, 0, null, null, null, null, Theme.key_chat_messageTextIn), new ThemeDescription(messagesCell, 0, null, null, null, null, Theme.key_chat_messageTextOut), new ThemeDescription(messagesCell, 0, null, null, new Drawable[]{Theme.chat_msgOutCheckDrawable}, null, Theme.key_chat_outSentCheck), diff --git a/TMessagesProj/src/main/java/org/telegram/ui/WebviewActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/WebviewActivity.java index 3cfe8c374..9282ca194 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/WebviewActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/WebviewActivity.java @@ -21,6 +21,7 @@ import android.content.SharedPreferences; import android.net.Uri; import android.os.Build; import android.text.TextUtils; +import android.view.MotionEvent; import android.view.View; import android.view.ViewParent; import android.webkit.CookieManager; @@ -154,7 +155,6 @@ public class WebviewActivity extends BaseFragment { @SuppressLint({"SetJavaScriptEnabled", "AddJavascriptInterface"}) @Override public View createView(Context context) { - swipeBackEnabled = false; actionBar.setBackButtonImage(R.drawable.ic_ab_back); actionBar.setAllowOverlayTitle(true); @@ -326,6 +326,11 @@ public class WebviewActivity extends BaseFragment { } } + @Override + public boolean isSwipeBackEnabled(MotionEvent event) { + return false; + } + public static boolean supportWebview() { String manufacturer = Build.MANUFACTURER; String model = Build.MODEL; diff --git a/TMessagesProj/src/main/res/drawable-hdpi/actions_nearby_off.png b/TMessagesProj/src/main/res/drawable-hdpi/actions_nearby_off.png new file mode 100644 index 000000000..a13f8f8e3 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/actions_nearby_off.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/actions_nearby_on.png b/TMessagesProj/src/main/res/drawable-hdpi/actions_nearby_on.png new file mode 100644 index 000000000..fbcfb126d Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/actions_nearby_on.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/heart_confetti.png b/TMessagesProj/src/main/res/drawable-hdpi/heart_confetti.png new file mode 100644 index 000000000..a95725758 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/heart_confetti.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/menu_bookmarks_14.png b/TMessagesProj/src/main/res/drawable-hdpi/menu_bookmarks_14.png new file mode 100644 index 000000000..83d26d3a7 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/menu_bookmarks_14.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/menu_broadcast_14.png b/TMessagesProj/src/main/res/drawable-hdpi/menu_broadcast_14.png new file mode 100644 index 000000000..8c868385b Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/menu_broadcast_14.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/menu_calls_14.png b/TMessagesProj/src/main/res/drawable-hdpi/menu_calls_14.png new file mode 100644 index 000000000..981f01222 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/menu_calls_14.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/menu_contacts_14.png b/TMessagesProj/src/main/res/drawable-hdpi/menu_contacts_14.png new file mode 100644 index 000000000..df99943a9 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/menu_contacts_14.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/menu_groups_14.png b/TMessagesProj/src/main/res/drawable-hdpi/menu_groups_14.png new file mode 100644 index 000000000..a2af54ab4 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/menu_groups_14.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/menu_secret_14.png b/TMessagesProj/src/main/res/drawable-hdpi/menu_secret_14.png new file mode 100644 index 000000000..476e2a125 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/menu_secret_14.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/menu_settings_14.png b/TMessagesProj/src/main/res/drawable-hdpi/menu_settings_14.png new file mode 100644 index 000000000..76cd00449 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/menu_settings_14.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/msg_start_secret.png b/TMessagesProj/src/main/res/drawable-hdpi/msg_start_secret.png new file mode 100644 index 000000000..da7248aa3 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/msg_start_secret.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/actions_nearby_off.png b/TMessagesProj/src/main/res/drawable-mdpi/actions_nearby_off.png new file mode 100644 index 000000000..b1375eac9 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/actions_nearby_off.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/actions_nearby_on.png b/TMessagesProj/src/main/res/drawable-mdpi/actions_nearby_on.png new file mode 100644 index 000000000..162f1d45c Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/actions_nearby_on.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/heart_confetti.png b/TMessagesProj/src/main/res/drawable-mdpi/heart_confetti.png new file mode 100644 index 000000000..7b3eb49a9 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/heart_confetti.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/menu_bookmarks_14.png b/TMessagesProj/src/main/res/drawable-mdpi/menu_bookmarks_14.png new file mode 100644 index 000000000..1f6e8259f Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/menu_bookmarks_14.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/menu_broadcast_14.png b/TMessagesProj/src/main/res/drawable-mdpi/menu_broadcast_14.png new file mode 100644 index 000000000..72b3cc564 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/menu_broadcast_14.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/menu_calls_14.png b/TMessagesProj/src/main/res/drawable-mdpi/menu_calls_14.png new file mode 100644 index 000000000..c861fb064 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/menu_calls_14.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/menu_contacts_14.png b/TMessagesProj/src/main/res/drawable-mdpi/menu_contacts_14.png new file mode 100644 index 000000000..1f22cc90c Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/menu_contacts_14.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/menu_groups_14.png b/TMessagesProj/src/main/res/drawable-mdpi/menu_groups_14.png new file mode 100644 index 000000000..0a0b949d7 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/menu_groups_14.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/menu_secret_14.png b/TMessagesProj/src/main/res/drawable-mdpi/menu_secret_14.png new file mode 100644 index 000000000..ff63df78b Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/menu_secret_14.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/menu_settings_4.png b/TMessagesProj/src/main/res/drawable-mdpi/menu_settings_4.png new file mode 100644 index 000000000..0852f0892 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/menu_settings_4.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/msg_start_secret.png b/TMessagesProj/src/main/res/drawable-mdpi/msg_start_secret.png new file mode 100644 index 000000000..633c5cff3 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/msg_start_secret.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/actions_nearby_off.png b/TMessagesProj/src/main/res/drawable-xhdpi/actions_nearby_off.png new file mode 100644 index 000000000..97ee6c6be Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/actions_nearby_off.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/actions_nearby_on.png b/TMessagesProj/src/main/res/drawable-xhdpi/actions_nearby_on.png new file mode 100644 index 000000000..517396a2a Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/actions_nearby_on.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/heart_confetti.png b/TMessagesProj/src/main/res/drawable-xhdpi/heart_confetti.png new file mode 100644 index 000000000..bf707d8dd Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/heart_confetti.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/menu_bookmarks_14.png b/TMessagesProj/src/main/res/drawable-xhdpi/menu_bookmarks_14.png new file mode 100644 index 000000000..1e775bd4a Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/menu_bookmarks_14.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/menu_broadcast_14.png b/TMessagesProj/src/main/res/drawable-xhdpi/menu_broadcast_14.png new file mode 100644 index 000000000..eb68c5b9d Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/menu_broadcast_14.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/menu_calls_14.png b/TMessagesProj/src/main/res/drawable-xhdpi/menu_calls_14.png new file mode 100644 index 000000000..c1d677242 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/menu_calls_14.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/menu_contacts_14.png b/TMessagesProj/src/main/res/drawable-xhdpi/menu_contacts_14.png new file mode 100644 index 000000000..578acba73 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/menu_contacts_14.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/menu_groups_14.png b/TMessagesProj/src/main/res/drawable-xhdpi/menu_groups_14.png new file mode 100644 index 000000000..6f1c07618 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/menu_groups_14.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/menu_secret_14.png b/TMessagesProj/src/main/res/drawable-xhdpi/menu_secret_14.png new file mode 100644 index 000000000..b34681da6 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/menu_secret_14.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/menu_settings_14.png b/TMessagesProj/src/main/res/drawable-xhdpi/menu_settings_14.png new file mode 100644 index 000000000..05653b1ec Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/menu_settings_14.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/msg_start_secret.png b/TMessagesProj/src/main/res/drawable-xhdpi/msg_start_secret.png new file mode 100644 index 000000000..ba68009f9 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/msg_start_secret.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/actions_nearby_off.png b/TMessagesProj/src/main/res/drawable-xxhdpi/actions_nearby_off.png new file mode 100644 index 000000000..86f71988e Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/actions_nearby_off.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/actions_nearby_on.png b/TMessagesProj/src/main/res/drawable-xxhdpi/actions_nearby_on.png new file mode 100644 index 000000000..6ccab068c Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/actions_nearby_on.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/heart_confetti.png b/TMessagesProj/src/main/res/drawable-xxhdpi/heart_confetti.png new file mode 100644 index 000000000..15bfa2271 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/heart_confetti.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/menu_bookmarks_14.png b/TMessagesProj/src/main/res/drawable-xxhdpi/menu_bookmarks_14.png new file mode 100644 index 000000000..390f4606b Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/menu_bookmarks_14.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/menu_broadcast_14.png b/TMessagesProj/src/main/res/drawable-xxhdpi/menu_broadcast_14.png new file mode 100644 index 000000000..faf5867c1 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/menu_broadcast_14.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/menu_calls_14.png b/TMessagesProj/src/main/res/drawable-xxhdpi/menu_calls_14.png new file mode 100644 index 000000000..e8e61094c Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/menu_calls_14.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/menu_contacts_14.png b/TMessagesProj/src/main/res/drawable-xxhdpi/menu_contacts_14.png new file mode 100644 index 000000000..87ee57b14 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/menu_contacts_14.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/menu_groups_14.png b/TMessagesProj/src/main/res/drawable-xxhdpi/menu_groups_14.png new file mode 100644 index 000000000..c7c8fa3d9 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/menu_groups_14.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/menu_secret_14.png b/TMessagesProj/src/main/res/drawable-xxhdpi/menu_secret_14.png new file mode 100644 index 000000000..46890dcbd Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/menu_secret_14.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/menu_settings_14.png b/TMessagesProj/src/main/res/drawable-xxhdpi/menu_settings_14.png new file mode 100644 index 000000000..1c3a2bd98 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/menu_settings_14.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/msg_start_secret.png b/TMessagesProj/src/main/res/drawable-xxhdpi/msg_start_secret.png new file mode 100644 index 000000000..b42c9909e Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/msg_start_secret.png differ diff --git a/TMessagesProj/src/main/res/values-ar/strings.xml b/TMessagesProj/src/main/res/values-ar/strings.xml index 3fe0b0323..bcb49046f 100644 --- a/TMessagesProj/src/main/res/values-ar/strings.xml +++ b/TMessagesProj/src/main/res/values-ar/strings.xml @@ -115,7 +115,7 @@ سيتم إرسال رقم الهاتف والبريد الإلكتروني إلى %1$s كمعلومات دفع. محادثة جديدة - Auto-Night Mode is off + الوضع الليلي الآلي معطَّل الإعدادات جهات الاتصال مجموعة جديدة @@ -236,7 +236,7 @@ هل ترغب حقًا في مغادرة **%1$s**؟ المعذرة، لا يمكنك إضافة هذا المستخدم للمجموعات. المعذرة، المجموعة ممتلئة. - المعذرة، إذا غادر شخص ما المجموعة، تحتاج أن تكون في قائمة جهات اتصاله كي تتمكن من إعادة إضافته إليها.\n\nيرجى الملاحظة أنه مازال بإمكانه الانضمام عبر رابط الدعوة الخاص بالمجموعة طالما أنه ليس في قائمة المستخدمين الذين تمت إزالتهم. + عذرًا، إذا لم يعد شخص جزءًا من مجموعة؛ يجب أن تكون في جهات اتصاله في تيليجرام لإضافته مرة أخرى إليها.\n\nلاحظ أنه لا يزال بإمكان هذا الشخص الانضمام عبر رابط دعوة المجموعة طالما أنه ليس في قائمة المستخدمين الذين تمت إزالتهم. المعذرة، يوجد الكثير من المشرفين في هذه المجموعة. المعذرة، يملك هذا المستخدم الكثير من المجموعات أو القنوات العامة. دعه يجعل بعض مجموعاته أو قنواته الحالية خاصة أولًا. المعذرة، يملك هذا المستخدم الكثير من المجموعات المحلية. دعه يحذف أو ينقل ملكية بعض منها أولًا. @@ -245,7 +245,7 @@ ثبت un1 «%1$s» ثبت un1 رسالة ثبت un1 استفتاءًا - un1 pinned a quiz + ثبت un1 اختبارًا un1 ثبت صورة ثبت un1 مقطعًا مرئيًا ثبت un1 ملفًا @@ -358,7 +358,7 @@ للأسف، تم حظرك من المشاركة في المجموعات العامة. المعذرة، لا يمكن الوصول إلى هذه المحادثة. هل ترغب بإضافة %1$s للقناة؟ - المعذرة، قرر هذا المستخدم مغادرة القناة، لا يمكنك إضافته مرة أخرى إليها. + عذرًا، إذا لم يعد شخص جزءًا من قناة؛ يجب أن تكون في جهات اتصاله في تيليجرام لإضافته مرة أخرى إليها.\n\nلاحظ أنه لا يزال بإمكان هذا الشخص الانضمام عبر رابط دعوة القناة طالما أنه ليس في قائمة المستخدمين الذين تمت إزالتهم. المعذرة، لا يمكنك إضافة هذا المستخدم للقنوات. المعذرة، يوجد الكثير من المشرفين في هذه القناة. المعذرة، يوجد الكثير من حسابات البوت في هذه القناة. @@ -378,7 +378,7 @@ نشرت %1$s مقطعًا مرئيًا نشرت %1$s جهة اتصال %2$s نشرت %1$s الاستفتاء %2$s - %1$s posted the quiz \"%2$s\" + نشرت %1$s الاختبار «%2$s» نشرت %1$s موقعًا نشرت %1$s موقعًا حيًا نشرت %1$s ملفًا @@ -525,29 +525,29 @@ المعذرة، هذا النص طويل للغاية ولا يمكن إرساله برسالة واحدة.\n\nتم تفعيل الوضع البطيء. لا يمكنك إرسال عدة رسائل مرةً واحدة. استفتاء جديد - New Quiz + اختبار جديد استفتاء السؤال اطرح سؤالًا خيارات الاستفتاء - Quiz answers + إجابات الاختبار نتائج الاستفتاء - Anonymous Voting + استفتاء سري وضع الاختبار - Select an option first - Collapse - Expand - المعذرة، لا يمكن تحويل الاستفتاءات العلنية للقنوات. + حدد خيارًا أولًا + طيّ + توسيع + المعذرة، لا يمكن تحويل استفتاءات الإجابات العلنية للقنوات. المعذرة، لا يمكن تحويل الاستفتاءات للمحادثات السرية. إجابات متعددة اضغط لاختيار الإجابة الصحيحة - Polls in Quiz Mode have one correct answer. Users can\'t revoke their answers. + تملك الاختبارات إجابة واحدة صحيحة. لا يمكن للمستخدمين تغيير إجاباتهم. إضافة خيار... يمكنك إضافة %1$s. لقد قمت بإضافة العدد الأقصى من الخيارات. استفتاء سري إجابة خاطئة! - You missed the correct option. + لم تختر الإجابة الصحيحة. أحسنت! لقد اخترت الإجابة الصحيحة. استفتاء @@ -559,26 +559,26 @@ إيقاف الاستفتاء؟ إذا قمت بإيقاف الاستفتاء الآنَ فلن يتمكن أي أحد من التصويت عليه، لا يمكنك التراجع عن هذا القرار. إيقاف الاختبار - Stop quiz? - If you stop this quiz now, nobody will be able to submit answers. This action cannot be undone. + إيقاف الاختبار؟ + إذا أوقفت هذا الاختبار الآن فلن يتمكن أحد من تقديم الإجابات. لا يمكنك التراجع عن هذا الإجراء. تجاهل الاستفتاء؟ هل ترغب حقًا في تجاهل هذا الاستفتاء؟ سحب الصوت النتائج النهائية ما من أصوات - Nobody answered + لم يُجب أحد %1$d صوت صوت واحد صوتان %1$d أصوات %1$d صوتًا %1$d صوت - %1$d answers - %1$d answer - %1$d answers - %1$d answers - %1$d answers - %1$d answers + %1$d إجابة + إجابة واحدة + إجابتين + %1$d إجابات + %1$d إجابةً + %1$d إجابة عرض المزيد (%1$d) عرض المزيد (%1$d) عرض المزيد (%1$d) @@ -627,7 +627,7 @@ un1 ثبت هذه رسالة: ألغى un1 تثبيت رسالة أوقف un1 الاستفتاء: - un1 stopped the quiz: + أوقف un1 الاختبار: حذف un1 هذه الرسالة: غيّرَ un1 موقع المجموعة ليصبح «%1$s» أزال un1 موقع المجموعة @@ -795,6 +795,7 @@ لقد قمت بمغادرة المجموعة حذف هذه المحادثة حذف هذه المحادثة + حذف المحادثات اسحب للإلغاء حفظ في الجهاز حفظ في الصور المتحركة @@ -957,11 +958,13 @@ المعذرة، لا يمكنك جدولة أكثر من 100 رسالة. سيكون من الممكن القيام بهذا الإجراء بعد نشر الرسالة. سيكون من الممكن التصويت بعد نشر الرسالة. - Poll results will become available after the message is published. + ستصبح نتائج الاستفتاء متاحة بعد نشر الرسالة. 📅 تذكير نتيجة واحدة جودة المقطع المرئي أقل مما ينبغي لتغيير إعدادات الضغط. اضغط باستمرار على **كلمة** ما، ثم حرّك المؤشر لتحديد المزيد والنسخ. + Card number copied to clipboard + نسخ عيّن %1$s عداد التدمير الذاتي ليصبح %2$s قمت بتعيين عداد التدمير الذاتي ليصبح %1$s @@ -982,7 +985,7 @@ أرسل لك %1$s مقطعًا مرئيًا ذاتي التدمير أرسل لك %1$s جهة اتصال %2$s أرسل لك %1$s استفتاء %2$s - %1$s sent you the quiz \"%2$s\" + أرسل لك %1$s الاستفتاء «%2$s» أرسل لك %1$s موقعًا أرسل لك %1$s موقعًا حيًا %1$s دعاك للعب %2$s @@ -999,7 +1002,7 @@ أرسل %1$s صورةً لمجموعة %2$s أرسل %1$s مقطعًا مرئيًا لمجموعة %2$s أرسل %1$s استفتاء %3$s في مجموعة %2$s - %1$s sent the quiz \"%3$s\" to the group %2$s + أرسل %1$s الاستفتاء «%3$s» لمجموعة %2$s أرسل %1$s جهة اتصال %3$s لمجموعة %2$s أرسل %1$s موقعًا حيًا لمجموعة %2$s شارك %1$s موقعه الحي مع مجموعة %2$s @@ -1041,7 +1044,7 @@ ثبّتَ %1$s «%2$s» في مجموعة %3$s ثبّتَ %1$s رسالةً في مجموعة %2$s ثبّتَ %1$s استفتاء %3$s في مجموعة %2$s - %1$s pinned the quiz \"%3$s\" in the group %2$s + أرسل %1$s الاختبار «%3$s» لمجموعة %2$s ثبّتَ %1$s صورةً في مجموعة %2$s ثبّتَ %1$s لعبةً في مجموعة %2$s ثبّتَ %1$s نتيجة لعبة في مجموعة %2$s @@ -1060,7 +1063,7 @@ ثبت %1$s «%2$s» ثبت %1$s رسالة ثبّتَت %1$s استفتاء %2$s - %1$s pinned the quiz \"%2$s\" + ثبت %1$s الاختبار «%2$s» %1$s ثبت صورة %1$s ثبت لعبة ثبّتَت %1$s نتيجة لعبة @@ -1116,7 +1119,6 @@ ستتمكن من إضافة أعضاء أكثر إذا انتهيت من إنشاء المجموعة وقمت بتحويلها إلى مجموعة خارقة. أدخل اسم للمجموعة اسم المجموعة - تم اختيار %1$d من %2$d حتى %1$s المعذرة، هذه المجموعة ممتلئة. المعذرة، هذه المحادثة غير موجودة. @@ -1168,6 +1170,9 @@ دعوة حظر المستخدم حظر مستخدم جديد + Block users + Do you want to block **%1$s** from messaging and calling you on Telegram? + Do you want to block **%1$s** from messaging and calling you on Telegram? تم حظر المستخدم تم إلغاء حظر المستخدم تعديل جهة الاتصال @@ -1212,6 +1217,8 @@ الصور والمقاطع المرئية الروابط الصوتيات + Send Message + Report اسم المستخدم اسم المستخدم الخاص بك @@ -1305,7 +1312,7 @@ حذف النمط هل ترغب حقًا في حذف هذا النمط؟ ملف النمط غير صحيح - Tap **Create** if you want to share your theme with others or customize each color manually.\n\nPlease enter theme name: + اضغط على **إنشاء** إذا كنت ترغب في مشاركة نمطك مع الآخرين أو تخصيص كل لون يدويًّا.\n\nيرجى إدخال اسم النمط: أدخل اسم النمط أغلق المحرر حفظ النمط @@ -1675,6 +1682,10 @@ إعادة تنزيل جهات الاتصال إعادة تعيين المحادثات "قراءة كافة المحادثات " + Enable pause music on record + Disable pause music on record + Enable smooth keyboard + Disable smooth keyboard تفعيل الكاميرا الداخلية للتطبيق تعطيل الكاميرا الداخلية للتطبيق إعادة ضبط جهات الاتصال المستوردة @@ -1764,14 +1775,14 @@ ميل مسح رمز QR مسح رمز QR - Token invalid or already expired. - No auth token found - Auth successfull + رمز غير صالح أو منتهي الصلاحية. + لم يتم العثور على رمز مصادقة + تمّت المصادقة بنجاح https://desktop.telegram.org - Download Telegram on your computer from *desktop.telegram.org*. + قم بتنزيل تيليجرام على حاسوبك من *desktop.telegram.org*. افتح تيليجرام على سطح المكتب للحصول على رمز QR. امسح رمز الـ QR لربط حسابك. - This code can be used to allow someone to log in to your Telegram account.\n\nTo confirm Telegram login, please go to Settings > Devices > Scan QR and scan the code. + يمكن استخدام هذا الرمز للسماح لشخص ما بتسجيل الدخول إلى حسابك في تيليجرام.\n\nلتأكيد عملية تسجيل الدخول؛ يرجى الذهاب إلى الإعدادات > الأجهزة > مسح QR وامسح الرمز. قاعدة البيانات على الجهاز مسح قاعدة البيانات المحلية @@ -2049,11 +2060,13 @@ أكتوبر نوفمبر ديسمبر - ملفات - وسائط - روابط - صوتيات - تسجيلات + ملفات + وسائط + Shared Media + مجموعات + روابط + صوتيات + Voice Messages الملفات المتبادلة الوسائط المتبادلة الروابط المتبادلة @@ -2096,7 +2109,7 @@ أو اختر مكانًا انقر لإرسال هذا الموقع المواقع الحية - Live Location + الموقع المباشر لمدة 15 دقيقة لمدة ساعة لمدة 8 ساعات @@ -2111,6 +2124,10 @@ اختر المدة التي سيتمكن خلالها أعضاء هذه المحادثة من مشاهدة موقعك الحي. تفعيل خدمات الموقع يرجى تفعيل خدمات الموقع لاستخدام ميزات تيليجرام التي تحتاجها. + إظهار نفسي + إظهار ملفك الشخصي + Users nearby will be able to view your profile and send you messages. This may help you find new friends, but could also attract excessive attention. You can stop sharing your profile at any time.\n\nYour phone number will remain hidden. + إيقاف إظهاري الأشخاص القريبون إضافة الأشخاص القريبين أضف الأشخاص القريبين الذين يستعرضون هذا القسم أيضًا واكتشف المجموعات المحلية بكل سهولة.\n\nاسمح بالوصول إلى موقعك لتفعيل هذه الميزة. @@ -2119,7 +2136,7 @@ أضف الأشخاص القريبين الذين يستعرضون هذا القسم أيضًا واكتشف المجموعات المحلية بكل سهولة.\n\nقم بتشغيل خدمات الموقع لتفعيل هذه الميزة. تشغيل المجموعات القريبة منك - اطلب من أصدقائك فتح هذه الصفحة لتبادل أرقام الهواتف. + Exchange contact info with people nearby and find new friends. يتم البحث عن مستخدمين قريبين منك... إنشاء مجموعة محلية إنشاء مجموعة @@ -2131,7 +2148,7 @@ الأماكن في هذه المنطقة عرض في لائحة - Show as grid + عرض كمصفوفة عرض كافة الوسائط عرض جميع الملفات انقر للتحميل @@ -2150,8 +2167,8 @@ هذا المقطع ليس معالَجا ليتم عرضُه فورَ تشغيله، قد تحتاج لتنزيله بالكامل قبل مشاهدته. لم يتمكن التطبيق من تشغيل هذا المقطع المرئي، هل ترغب في تشغيله بمشغل خارجي؟ ما من عمليات بحث تمت مؤخرًا - الصور - الصور المتحركة + Images + GIFs لا يوجد صور متحركة حديثة بحث الصور البحث في الويب @@ -2281,9 +2298,9 @@ استخدام التخزين والشبكة استخدام التخزين استهلاك البيانات - الخلوية - WI-FI - التجوال + Mobile + Wi-Fi + Roaming الرسائل والبيانات الأخرى المرسلة الواردة @@ -2754,10 +2771,10 @@ %1$d مستقبلًا %1$d مستقبل %1$d متصل - %1$d متصل - %1$d متصل - %1$d متصل - %1$d متصل + متصل واحد + متصلان + %1$d متصلين + %1$d متصلا %1$d متصل لا يوجد جهات اتصال على تيليجرام جهة اتصال واحدة على تيليجرام @@ -2849,6 +2866,12 @@ %1$d عناصر %1$d عنصرًا %1$d عنصر + + + + + + من %1$d محادثة من محادثة واحدة من محادثتين @@ -3006,12 +3029,36 @@ %1$d ملفات %1$d ملفًا %1$d ملف + %1$d music files + %1$d music file + %1$d music files + %1$d music files + %1$d music files + %1$d music files + %1$d groups in common + %1$d group in common + %1$d groups in common + %1$d groups in common + %1$d groups in common + %1$d groups in common %1$d ملف ملف واحد ملفان %1$d ملفات %1$d ملفًا %1$d ملف + %1$d voice messages + %1$d voice message + %1$d voice messages + %1$d voice messages + %1$d voice messages + %1$d voice messages + %1$d links + %1$d link + %1$d links + %1$d links + %1$d links + %1$d links %1$d مستخدم محظور مستخدم واحد محظور مستخدمان محظوران @@ -3108,12 +3155,30 @@ %1$d أشخاص يستخدمون هذا النمط %1$d شخصًا يستخدم هذا النمط %1$d شخص يستخدم هذا النمط - %1$d of %2$d results - %1$d of %2$d results - %1$d of %2$d results - %1$d of %2$d results - %1$d of %2$d results - %1$d of %2$d results + %1$d من %2$d + "%1$d من %2$d " + %1$d من %2$d + %1$d من %2$d + %1$d من %2$d + "%1$d من %2$d " + %1$d users + %1$d user + %1$d users + %1$d users + %1$d users + %1$d users + %1$d users + %1$d user + %1$d users + %1$d users + %1$d users + %1$d users + %1$d of %2$d selected + %1$d of %2$d selected + %1$d of %2$d selected + %1$d of %2$d selected + %1$d of %2$d selected + %1$d of %2$d selected مجموعة قناة diff --git a/TMessagesProj/src/main/res/values-de/strings.xml b/TMessagesProj/src/main/res/values-de/strings.xml index 9f25388b9..ed275b579 100644 --- a/TMessagesProj/src/main/res/values-de/strings.xml +++ b/TMessagesProj/src/main/res/values-de/strings.xml @@ -525,12 +525,12 @@ Dieser Text ist für eine einzelne Nachricht leider zu lang.\n\nLangsamer Modus ist aktiv, du kannst nicht mehr als eine gleichzeitig senden. Neue Umfrage - New Quiz + Neues Quiz Umfrage Frage Stelle eine Frage Umfrageoptionen - Quiz answers + Quiz-Antworten Umfrageergebnis Anonyme Stimmabgabe Quiz-Modus @@ -795,6 +795,7 @@ Du hast die Gruppe verlassen Diese Gruppe löschen Diesen Chat löschen + Chats löschen WISCHEN UM ABZUBRECHEN In Downloads speichern GIF hinzufügen @@ -962,6 +963,8 @@ 1 Ergebnis Die Videoqualität ist zu niedrig, um die Komprimierung zu ändern. **Wort** gedrückt halten und Cursor bewegen, um noch mehr Text zu markieren. + Card number copied to clipboard + Copy %1$s hat den Selbstzerstörungs-Timer auf %2$s gesetzt Du hast den Selbstzerstörungs-Timer auf %1$s gesetzt @@ -1116,7 +1119,6 @@ Sobald du diese Gruppe zu einer Supergruppe erweitert hast, kannst du mehr Nutzer einladen. Gruppenname Gruppenname - %1$d von %2$d ausgewählt bis zu %1$s Leider ist diese Gruppe schon voll. Leider gibt es diesen Chat nicht. @@ -1168,6 +1170,9 @@ Einladen Nutzer blockieren Nutzer blockieren + Nutzer blockieren + Do you want to block **%1$s** from messaging and calling you on Telegram? + Möchtest du **%1$s** blockieren, so dass sie dich bei Telegram weder anschreiben noch anrufen dürfen? Nutzer blockiert Nutzer freigegeben Kontakt bearbeiten @@ -1212,6 +1217,8 @@ Bilder und Videos Links Audiodateien + Send Message + Report Benutzername Dein Benutzername @@ -1675,6 +1682,10 @@ Kontakte neu laden Chats zurücksetzen Alle Chats lesen + Enable pause music on record + Disable pause music on record + Enable smooth keyboard + Disable smooth keyboard In-App Kamera aktivieren In-App Kamera deaktivieren Importierte Kontakte zurücksetzen @@ -2049,11 +2060,13 @@ Oktober November Dezember - DATEIEN - MEDIEN - LINKS - AUDIOS - SPRACHE + Files + Media + Shared Media + Groups + Links + Audio + Voice Messages Geteilte Dateien Geteilte Inhalte Geteilte Links @@ -2111,6 +2124,10 @@ Wähle, wie lange Leute in diesem Chat deinen Live-Standort sehen dürfen. GPS aktivieren Bitte aktiviere GPS, um auf ortsbezogene Funktionen zuzugreifen. + Make Myself Visible + Show Your Profile? + Users nearby will be able to view your profile and send you messages. This may help you find new friends, but could also attract excessive attention. You can stop sharing your profile at any time.\n\nYour phone number will remain hidden. + Stop Showing Me Leute in der Nähe Leute in der Nähe Füge schnell Leute aus der Nähe hinzu, \ndie diesen Bereich ebenfalls ansehen,\nund entdecke lokale Gruppen-Chats.\n\nBitte aktiviere den Standortzugriff,\num diese Funktion nutzen zu können. @@ -2119,7 +2136,7 @@ Füge schnell Leute aus der Nähe hinzu, \ndie diesen Bereich ebenfalls ansehen,\nund entdecke lokale Gruppen-Chats.\n\nBitte aktiviere die Standortdienste,\num diese Funktion nutzen zu können. Einschalten Gruppen in der Nähe - Bitte deinen Freund in der Nähe, diese Seite zu öffnen, um Nummern auszutauschen. + Exchange contact info with people nearby and find new friends. Prüfe, wer bei dir in der Nähe ist... Erstelle eine lokale Gruppe Gruppe erstellen @@ -2150,8 +2167,8 @@ Dieses Video ist nicht für Streaming optimiert. Du musst es vollständig herunterladen, um es abzuspielen. App konnte dieses Video nicht abspielen. Möchtest du es mit einem externen Player abspielen? Keine kürzliche Suche - BILDER - GIFS + Bilder + GIFs Suchverlauf BILDERSUCHE SUCHE IM WEB @@ -2281,9 +2298,9 @@ Daten- und Speichernutzung Speichernutzung Datenbenutzung - MOBIL - WLAN - ROAMING + Mobil + Wi-Fi + Roaming Nachrichten und sonstige Daten Gesendet Empfangen @@ -2849,6 +2866,12 @@ %1$d Objekte %1$d Objekte %1$d Objekte + + + + + + von %1$d Chats von %1$d Chat von %1$d Chats @@ -3006,12 +3029,36 @@ %1$d Dateien %1$d Dateien %1$d Dateien + %1$d music files + %1$d music file + %1$d music files + %1$d music files + %1$d music files + %1$d music files + %1$d groups in common + %1$d group in common + %1$d groups in common + %1$d groups in common + %1$d groups in common + %1$d groups in common %1$d Medien %1$d Medium %1$d Medien %1$d Medien %1$d Medien %1$d Medien + %1$d voice messages + %1$d voice message + %1$d voice messages + %1$d voice messages + %1$d voice messages + %1$d voice messages + %1$d links + %1$d link + %1$d links + %1$d links + %1$d links + %1$d links %1$d blockierte Nutzer %1$d blockierter Nutzer %1$d blockierte Nutzer @@ -3114,6 +3161,24 @@ %1$d von %2$d Ergebnissen %1$d von %2$d Ergebnissen %1$d von %2$d Ergebnissen + %1$d Nutzer + %1$d Nutzer + %1$d Nutzer + %1$d Nutzer + %1$d Nutzer + %1$d Nutzer + %1$d Nutzer + %1$d Nutzer + %1$d Nutzer + %1$d Nutzer + %1$d Nutzer + %1$d Nutzer + %1$d of %2$d selected + %1$d of %2$d selected + %1$d of %2$d selected + %1$d of %2$d selected + %1$d of %2$d selected + %1$d of %2$d selected Gruppe Kanal diff --git a/TMessagesProj/src/main/res/values-es/strings.xml b/TMessagesProj/src/main/res/values-es/strings.xml index 8c4c8eb74..cae62038d 100644 --- a/TMessagesProj/src/main/res/values-es/strings.xml +++ b/TMessagesProj/src/main/res/values-es/strings.xml @@ -337,7 +337,7 @@ Foto del canal cambiada Foto del canal eliminada Nombre del canal cambiado a un2 - Lo sentimos, tienes demasiados alias públicos. Puedes anular el enlace de uno de tus grupos o canales anteriores, o crear uno privado. + Lo sentimos, tienes demasiados nombres de usuario públicos. Puedes anular el enlace de uno de tus grupos o canales anteriores, o crear uno privado. Propietario Administrador Administrador @@ -525,12 +525,12 @@ Lo sentimos, este texto es muy largo para ser enviado en un mensaje.\n\nEl modo lento está activado. No puedes enviar más de un mensaje a la vez. Nueva encuesta - New Quiz + Nuevo cuestionario Encuesta Pregunta Haz una pregunta Opciones de encuesta - Quiz answers + Respuestas del cuestionario Resultados de la encuesta Voto anónimo Cuestionario @@ -795,6 +795,7 @@ Saliste de este grupo Eliminar este grupo Eliminar este chat + Eliminar chats DESLIZA PARA CANCELAR Guardar en Descargas Guardar GIF @@ -962,6 +963,8 @@ 1 resultado La calidad del video es demasiado baja para cambiar los ajustes de compresión. Mantén en la **palabra**, luego mueve el cursor para seleccionar más texto para copiar. + Número de tarjeta copiado al portapapeles + Copiar %1$s activó la autodestrucción en %2$s Activaste la autodestrucción en %1$s @@ -1116,7 +1119,6 @@ Podrás añadir más usuarios después de crear el grupo y convertirlo en un supergrupo. Nombre del grupo Nombre del grupo - %1$d de %2$d seleccionados hasta %1$s Lo sentimos, este grupo está lleno. Lo sentimos, este chat no existe. @@ -1168,6 +1170,9 @@ Invitar Bloquear Bloquear + Bloquear usuarios + ¿Quieres bloquear los mensajes y llamadas de **%1$s** en Telegram? + ¿Quieres bloquear los mensajes y llamadas de **%1$s** en Telegram? Usuario bloqueado Usuario desbloqueado Editar contacto @@ -1212,17 +1217,19 @@ Fotos y videos Enlaces Audios + Enviar mensaje + Reportar - Alias - Tu alias - Lo sentimos, este alias ya está ocupado. - Lo sentimos, este alias no es válido. - Un alias debe tener al menos 5 caracteres. - El alias no debe exceder los 32 caracteres. - Lo sentimos, un alias no puede comenzar con un número. - Puedes elegir un alias en **Telegram**. Si lo haces, otras personas te podrán encontrar por ese alias y contactarte sin saber tu número de teléfono.\n\nPuedes usar **a–z**, **0–9** y guiones bajos.\nLa longitud mínima es de **5** caracteres. + Nombre de usuario + Tu nombre de usuario + Lo sentimos, este nombre de usuario ya está ocupado. + Lo sentimos, este nombre de usuario no es válido. + Un nombre de usuario debe tener al menos 5 caracteres. + El nombre de usuario no debe exceder los 32 caracteres. + Lo sentimos, un nombre de usuario no puede comenzar con un número. + Puedes elegir un nombre de usuario en **Telegram**. Si lo haces, otras personas te podrán encontrar por ese nombre y contactarte sin saber tu número de teléfono.\n\nPuedes usar **a–z**, **0–9** y guiones bajos.\nLa longitud mínima es de **5** caracteres. Este enlace abre un chat contigo:\n%1$s - Verificando alias... + Verificando nombre de usuario... %1$s está disponible. Ninguno Ocurrió un error. @@ -1675,6 +1682,10 @@ Recargar contactos Restablecer chats Leer todos los chats + Activar pausar música al grabar + Desactivar pausar música al grabar + Activar la animación del teclado + Desactivar la animación del teclado Activar cámara interna Desactivar cámara interna Restablecer contactos importados @@ -2049,11 +2060,13 @@ Octubre Noviembre Diciembre - ARCHIVOS - MEDIA - ENLACES - AUDIO - VOZ + Archivos + Media + Multimedia compartida + Grupos + Enlaces + Audio + Mensajes de voz Archivos Contenido compartido Enlaces @@ -2111,6 +2124,10 @@ Elige durante cuánto tiempo las personas de este chat verán tu ubicación en tiempo real. Activar GPS Por favor, activa tu GPS para acceder a las características de ubicación. + Hacerme visible + ¿Mostrar tu perfil? + Los usuarios que estén cerca podrán ver tu perfil y enviarte mensajes. Esto puede ayudarte a encontrar nuevos amigos, pero también podría atraer atención excesiva. Puedes dejar de compartir tu perfil cuando quieras.\n\nTu número permanecerá oculto. + Dejar de mostrarme Personas cerca Añadir personas cerca Añade rápidamente a personas cerca que también están viendo esta sección y descubre grupos locales.\n\nPor favor, activa el acceso a la ubicación para usar esta característica. @@ -2119,7 +2136,7 @@ Añade rápidamente a personas cerca que también están viendo esta sección y descubre grupos locales.\n\nPor favor, activa los servicios de ubicación para usar esta característica. Activar Grupos cerca - Para intercambiar números de teléfono, pide a alguien que esté cerca que abra esta pantalla. + Intercambia información de contacto con personas cerca y encuentra nuevos amigos. Buscando personas a tu alrededor… Crear un grupo local Iniciar grupo @@ -2150,8 +2167,8 @@ Este video no está optimizado para streaming. Tendrás que descargarlo completamente para reproducirlo. La app no logró reproducir este video. ¿Quieres intentarlo con un reproductor externo? Sin búsquedas recientes - IMÁGENES - GIF + Imágenes + GIF No hay GIF recientes BUSCAR FOTOS BÚSQUEDA WEB @@ -2281,9 +2298,9 @@ Uso de almacenamiento y red Uso de almacenamiento Uso de datos - MÓVIL - WI-FI - ITINERANCIA + Móvil + Wi-Fi + Itinerancia Mensajes y otros datos Enviados Recibidos @@ -2604,10 +2621,10 @@ ¿Quieres enviar este mensaje a **%1$s**? ¿Quieres compartir este juego en **%1$s**? ¿Quieres enviar este contacto a **%1$s**? - No hay ninguna cuenta de Telegram con este alias. + No hay ninguna cuenta de Telegram con este nombre de usuario. Este bot no puede unirse a grupos. ¿Quieres permitir las vistas previas ampliadas en chats secretos? Ten en cuenta que son generadas en los servidores de Telegram. - Ten en cuenta que los bots integrados son hechos por terceros. Para que funcione, los símbolos escritos después del alias del bot, son enviados al desarrollador respectivo. + Ten en cuenta que los bots integrados son hechos por terceros. Para que funcione, los símbolos escritos después del nombre de usuario del bot son enviados al desarrollador respectivo. Lo sentimos, no puedes editar este mensaje. Por favor, permite a Telegram recibir llamadas para que podamos ingresar automáticamente el código por ti. Por favor, permite a Telegram recibir llamadas y leer el registro de llamadas para que podamos poner automáticamente el código por ti. @@ -2849,6 +2866,12 @@ %1$d ítems %1$d ítems %1$d ítems + + + + + + en %1$d chats en %1$d chat en %1$d chats @@ -3006,12 +3029,36 @@ %1$d archivos %1$d archivos %1$d archivos + %1$d archivos de música + %1$d archivo de música + %1$d archivos de música + %1$d archivos de música + %1$d archivos de música + %1$d archivos de música + %1$d grupos en común + %1$d grupo en común + %1$d grupos en común + %1$d grupos en común + %1$d grupos en común + %1$d grupos en común %1$d archivos multimedia %1$d archivo multimedia %1$d archivos multimedia %1$d archivos multimedia %1$d archivos multimedia %1$d archivos multimedia + %1$d mensajes de voz + %1$d mensaje de voz + %1$d mensajes de voz + %1$d mensajes de voz + %1$d mensajes de voz + %1$d mensajes de voz + %1$d enlaces + %1$d enlace + %1$d enlaces + %1$d enlaces + %1$d enlaces + %1$d enlaces %1$d usuarios bloqueados %1$d usuario bloqueado %1$d usuarios bloqueados @@ -3114,6 +3161,24 @@ Resultado %1$d de %2$d Resultado %1$d de %2$d Resultado %1$d de %2$d + %1$d usuarios + %1$d usuario + %1$d usuarios + %1$d usuarios + %1$d usuarios + %1$d usuarios + %1$d usuarios + %1$d usuario + %1$d usuarios + %1$d usuarios + %1$d usuarios + %1$d usuarios + %1$d de %2$d seleccionados + %1$d de %2$d seleccionado + %1$d de %2$d seleccionados + %1$d de %2$d seleccionados + %1$d de %2$d seleccionados + %1$d de %2$d seleccionados Grupo Canal diff --git a/TMessagesProj/src/main/res/values-it/strings.xml b/TMessagesProj/src/main/res/values-it/strings.xml index 782926515..456415064 100644 --- a/TMessagesProj/src/main/res/values-it/strings.xml +++ b/TMessagesProj/src/main/res/values-it/strings.xml @@ -795,6 +795,7 @@ Hai lasciato il gruppo Elimina questo gruppo Elimina questa chat + Elimina chat ANNULLA Salva nei download Salva nelle GIF @@ -962,6 +963,8 @@ 1 risultato Qualità video troppo bassa per cambiare le impostazioni di compressione. Tieni premuta la **parola**, quindi muovi il cursore per selezionare altro testo da copiare. + Numero carta copiato negli appunti + Copia %1$s ha impostato il timer di autodistruzione a %2$s Hai impostato il timer di autodistruzione a %1$s @@ -1116,7 +1119,6 @@ Potrai aggiungere più utenti dopo aver creato il gruppo e averlo convertito in supergruppo. Inserisci il nome del gruppo Nome del gruppo - %1$d di %2$d fino a %1$s Spiacenti, questo gruppo è già pieno. Spiacenti, sembra che questa chat non esista. @@ -1168,6 +1170,9 @@ Invita Blocca utente Blocca utente + Blocca utenti + Vuoi impedire a **%1$s** di scriverti e chiamarti su Telegram? + Vuoi impedire a **%1$s** di scriverti e chiamarti su Telegram? Utente bloccato Utente sbloccato Modifica contatto @@ -1212,6 +1217,8 @@ Foto e video Link File audio + Invia messaggio + Segnala Username Il tuo username @@ -1675,6 +1682,10 @@ Ricarica contatti Ripristina chat Leggi tutte le chat + Enable pause music on record + Disable pause music on record + Attiva tastiera fluida + Disattiva tastiera fluida Attiva fotocamera in-app Disattiva fotocamera in-app Ripristina contatti importati @@ -1743,7 +1754,7 @@ Connetti altri account Telegram e passa facilmente da uno all\'altro. Imposta un codice di blocco Blocca l\'app con un codice, così gli altri non potranno aprirla. - Vuota la cache + Svuota cache Libera spazio sul tuo dispositivo; i tuoi media rimarranno nel cloud. Cambia numero di telefono Sposta il tuo account, le chat e i media su un nuovo numero. @@ -1777,7 +1788,7 @@ Cancella database locale Sei sicuro di voler eliminare i messaggi di testo nella cache? Cancellando il database locale, verranno eliminati i messaggi nella cache e il database verrà compresso per risparmiare spazio. Telegram ha bisogno di alcuni dati per funzionare, quindi il database non sarà azzerato.\n\nQuesta operazione può richiedere alcuni minuti. - Vuota la cache + Svuota cache Svuota Calcolo... Documenti @@ -2049,11 +2060,13 @@ Ottobre Novembre Dicembre - FILE - MEDIA - LINK - AUDIO - MESSAGGI VOCALI + File + Media + Media condivisi + Gruppi + Link + Audio + Messaggi vocali File condivisi Contenuto condiviso Link condivisi @@ -2082,8 +2095,8 @@ Invia la mia posizione corrente Condividi posizione attuale per... Condividi posizione attuale - Arresta condivisione - Arresta condivisione posizione + Termina condivisione + Termina condivisione posizione Vuoi interrompere la condivisione della tua posizione attuale con **%1$s**? Vuoi interrompere la condivisione della tua posizione attuale con **%1$s**? Vuoi interrompere la condivisione della tua posizione attuale? @@ -2111,6 +2124,10 @@ Scegli per quanto tempo le persone in questa chat vedranno la tua posizione attuale. Attiva GPS Per favore attiva il tuo GPS per accedere alle funzioni basate sulla posizione. + Rendimi visibile + Mostrare il tuo profilo? + Gli utenti nelle vicinanze potranno visualizzare il tuo profilo e inviarti messaggi. Questo può aiutarti a trovare nuovi amici, ma potrebbe anche attirare un\'eccessiva attenzione. Puoi interrompere la condivisione del tuo profilo in qualsiasi momento.\n\nIl tuo numero di telefono rimarrà nascosto. + Interrompi visibilità Persone vicine Aggiungi persone vicine Aggiungi rapidamente persone vicine che stanno guardando questa sezione e scopri chat di gruppo locali.\n\nPer favore concedi l\'accesso alla posizione per abilitare questa funzione. @@ -2119,7 +2136,7 @@ Aggiungi rapidamente persone vicine che stanno guardando questa sezione e scopri chat di gruppo locali.\n\nPer favore attiva i servizi di localizzazione per abilitare questa funzione. Attiva Gruppi vicini - Chiedi al tuo amico vicino di aprire questa pagina per scambiare i numeri di telefono. + Scambia info di contatto con le persone vicine e trova nuovi amici. Cerco utenti attorno a te... Crea un gruppo locale Avvia gruppo @@ -2150,8 +2167,8 @@ Questo video non è ottimizzato per lo streaming. Potresti doverlo scaricare completamente per riprodurlo. L\'app non è in grado di riprodurre questo video. Vuoi provare con un player esterno? Nessuna ricerca recente - IMMAGINI - GIF + Immagini + GIF Nessuna GIF recente CERCA IMMAGINI RICERCA WEB @@ -2281,9 +2298,9 @@ Utilizzo disco e rete Utilizzo archivio Utilizzo dati - CELLULARE - WI-FI - ROAMING + Cellulare + Wi-Fi + Roaming Messaggi e altri dati Inviati Ricevuti @@ -2552,7 +2569,7 @@ Sei sicuro di voler uscire?\n\nNota che puoi usare Telegram su tutti i tuoi dispositivi contemporaneamente.\n\nRicorda, uscendo eliminerai tutte le chat segrete. Elimina %1$s Svuota %1$s - Svuota la cache per %1$s + Svuota cache per %1$s Sei sicuro di voler eliminare le chat selezionate? Sei sicuro di voler eliminare la cronologia nelle chat selezionate? Eliminare tutti i testi e i media dalle chat selezionate? @@ -2572,7 +2589,7 @@ Questo bot vorrebbe sapere la tua posizione ogni volta che invii una richiesta. Questo può essere usato per fornire risultati specifici in base alla posizione. Condividere il tuo numero di telefono? Il bot saprà il tuo numero di telefono. Questo può essere utile per l\'integrazione con altri servizi. - Sei sicuro di voler condividere il tuo numero %1$s con **%2$s**? + Vuoi condividere il tuo numero %1$s con **%2$s**? Sei sicuro di voler condividere il tuo numero? Sei sicuro di voler bloccare **%1$s**? Sei sicuro di voler sbloccare questo contatto? @@ -2849,6 +2866,12 @@ %1$d oggetti %1$d oggetti %1$d oggetti + + + + + + da %1$d chat da %1$d chat da %1$d chat @@ -3006,12 +3029,36 @@ %1$d file %1$d file %1$d file + %1$d file musicali + %1$d file musicale + %1$d file musicali + %1$d file musicali + %1$d file musicali + %1$d file musicali + %1$d gruppi in comune + %1$d gruppo in comune + %1$d gruppi in comune + %1$d gruppi in comune + %1$d gruppi in comune + %1$d gruppi in comune %1$d media %1$d media %1$d media %1$d media %1$d media %1$d media + %1$d messaggi vocali + %1$d messaggio vocale + %1$d messaggi vocali + %1$d messaggi vocali + %1$d messaggi vocali + %1$d messaggi vocali + %1$d link + %1$d link + %1$d link + %1$d link + %1$d link + %1$d link %1$d utenti bloccati %1$d utente bloccato %1$d utenti bloccati @@ -3114,6 +3161,24 @@ Risultato %1$d di %2$d Risultato %1$d di %2$d Risultato %1$d di %2$d + %1$d utenti + %1$d utente + %1$d utenti + %1$d utenti + %1$d utenti + %1$d utenti + %1$d utenti + %1$d utente + %1$d utenti + %1$d utenti + %1$d utenti + %1$d utenti + %1$d di %2$d selezionati + %1$d di %2$d selezionato + %1$d di %2$d selezionati + %1$d di %2$d selezionati + %1$d di %2$d selezionati + %1$d di %2$d selezionati Gruppo Canale @@ -3162,7 +3227,7 @@ Ripeti, una Chiudi lettore musicale Riproduzione a velocità doppia - Arresta condivisione posizione attuale + Termina condivisione posizione attuale Fotocamera istantanea Pulsante di scatto Cambia fotocamera diff --git a/TMessagesProj/src/main/res/values-ko/strings.xml b/TMessagesProj/src/main/res/values-ko/strings.xml index de9ae50dc..a5750c635 100644 --- a/TMessagesProj/src/main/res/values-ko/strings.xml +++ b/TMessagesProj/src/main/res/values-ko/strings.xml @@ -21,7 +21,7 @@ 기기에 있는 연락처를 계정과 계속 동기화하려면 켜 주세요. 기기에 있는 연락처가 계정에 추가되었습니다. - 휴대폰 인증 + 휴대전화 인증 **%1$s** 번호로 인증 코드가 담긴 SMS를 보냈습니다. 회원님의 다른 기기에 설치된 **텔레그램** 앱으로 코드를 보냈습니다. 텔레그램 메시지를 확인하세요 @@ -71,7 +71,7 @@ 전화번호 이메일 배송 정보 저장 - 향후 사용을 대비하여 배송 정보를 저장하실 수 있습니다. + 나중에 이용할 수 있도록 배송 정보를 저장하실 수 있습니다. 결제 정보 결제 카드 카드 번호 @@ -80,7 +80,7 @@ 결제 주소 성명 결제 정보 저장 - 향후 사용을 위하여 결제 정보를 저장할 수 있습니다. + 나중에 이용할 수 있도록 결제 정보를 저장하실 수 있습니다. 이 기능을 사용하려면 *2단계 인증을 활성화*해 주세요. 거래내역 확인 %3$s에 대한 %1$s 금액을 %2$s 봇에게 전송하시겠습니까? @@ -99,7 +99,7 @@ %1$s 카드가 파일에 보관되어 있습니다. 이 카드로 결제하려면 2단계 인증 비밀번호를 입력해 주세요. 죄송합니다. 봇에 의해 결제가 취소되었습니다. 죄송합니다. 결제가 거절됐습니다. - 결제 서버로 연결을 할 수 없습니다. 인터넷 연결을 확인해주시고 다시 시도해주세요. + 결제 서버로 연결할 수 없습니다. 인터넷 연결을 확인하고 다시 시도해 주세요. 경고 텔레그램이나 %1$s은(는) 회원님의 신용카드 정보에 접근할 수 없습니다. 신용카드 정보는 %2$s 결제 시스템에서만 처리됩니다.\n\n결제는 %1$s 개발자에게 직접 됩니다. 텔레그램은 그 어떠한 보장도 하지 않음으로 진행시 위험을 감수하셔야 합니다. 문제 발생 시, %1$s 개발자나 사용하시는 은행에게 문의해 주세요. 비밀번호 및 이메일 @@ -137,7 +137,7 @@ 프록시 연결 갱신 중... 비밀 대화 시작 - %s 님을 기다리고 있습니다... + %s 님의 접속을 기다리고 있습니다... 비밀 대화가 취소되었습니다 암호화 키 교환 중... %s 님이 비밀 대화에 들어왔습니다. @@ -194,7 +194,7 @@ 미리보기에 대한 의견 남기기 스티커 보내기 GIF 보내기 - 묶음 들여다보기 + 묶음 보기 맨 위에 고정 죄송합니다. %1$s까지 메인 목록에 고정하실 수 있습니다. 아직 분류할 것이 남았다면, 대화방들을 보관해 보세요 - 보관한 대화방 폴더에서는 무한정 고정하실 수 있습니다. 맨 위 고정 해제 @@ -231,7 +231,7 @@ 그룹을 관리하는 데 도움을 줄 관리자를 추가하실 수 있습니다. 관리자를 제명하려면 길게 누르세요. 잠깐! 그룹을 삭제하시면 참가자와 메시지가 모두 사라집니다. 그래도 그룹을 삭제할까요? 그룹 만들어짐 - un1 님이 회원님을 이 그룹에 초대했습니다 + un1 님이 나를 이 그룹에 추가했습니다 정말 그룹에서 나가시겠습니까? 정말 **%1$s** 그룹에서 나가시겠습니까? 죄송합니다. 이 사용자를 그룹에 추가하실 수 없습니다. @@ -366,30 +366,30 @@ 커뮤니티가 너무 많습니다 죄송합니다. 너무 많은 그룹과 채널에 들어가 계십니다. 몇 곳에서 나온 뒤 새로 만들어 주세요. 죄송합니다. 너무 많은 그룹과 채널에 들어가 계십니다. 몇 곳에서 나온 뒤 새로 들어가 주세요. - un1 님이 회원님을 이 채널에 추가했습니다 + un1 님이 나를 이 채널에 추가했습니다 채널에 들어오셨습니다 그룹에 들어오셨습니다 채널에서 추방 죄송합니다. 이 채널에 메시지를 보내실 수 없습니다. - %1$s님이 %2$s 채널에 초대했습니다 - %1$s 채널 사진이 업데이트됐습니다 - %1$s 채널이 메시지를 게시했습니다 - %1$s 채널이 사진을 게시했습니다 + %1$s 님이 나를 %2$s 채널에 초대했습니다 + %1$s 채널 사진이 업데이트되었습니다 + %1$s에서 메시지를 게시했습니다 + %1$s에서 사진을 게시했습니다 %1$s 채널이 동영상을 게시했습니다 %1$s 님이 연락처를 게시했습니다 %2$s - %1$s 님이 %2$s 설문을 게시했습니다 - %1$s 님이 %2$s 퀴즈를 게시했습니다 - %1$s 채널이 위치를 게시했습니다 - %1$s 채널이 실시간 위치를 게시했습니다 - %1$s 채널이 파일을 게시했습니다 - %1$s 채널에서 GIF를 게시했습니다 - %1$s 님이 %2$s을(를) 게시했습니다 - %1$s 님이 앨범을 게시했습니다 - %1$s 채널에 음성 메시지를 게시했습니다 - %1$s 채널이 동영상 메시지를 게시했습니다 - %1$s 채널이 오디오 파일을 게시했습니다 - %1$s 채널이 스티커를 게시했습니다 - %1$s 채널이 %2$s 스티커를 올렸습니다 + %1$s에서 %2$s 설문을 게시했습니다 + %1$s 님이 \"%2$s\" 퀴즈를 게시했습니다 + %1$s에서 위치를 게시했습니다 + %1$s에서 실시간 위치를 게시했습니다 + %1$s에서 파일을 게시했습니다 + %1$s에서 GIF를 게시했습니다 + %1$s에서 %2$s을 게시했습니다 + %1$s에서 사진첩을 게시했습니다 + %1$s에서 음성 메시지를 게시했습니다 + %1$s에서 동영상 메시지를 게시했습니다 + %1$s에서 오디오 파일을 게시했습니다 + %1$s에서 스티커를 게시했습니다 + %1$s에서 %2$s 스티커를 게시했습니다 참가자를 추가할 수 있는 사람 모든 참가자 관리자만 @@ -499,7 +499,7 @@ 채널에 게시하시는 모든 것이 이 그룹으로 전달됩니다. **%1$s** 링크가 모든 구독자에게 바닥 패널에서 보입니다. **%1$s** 채널이 그룹을 토론 게시판으로 삼아 잇고 있습니다. - 이 채널에 새로 게시되는 대화가 모두 그룹에 전달됩니다. + 이 채널에 새로 게시되는 메시지가 모두 그룹으로 전달됩니다. 새로운 그룹 만들기 그룹 끊어내기 채널 끊어내기 @@ -525,31 +525,31 @@ 죄송합니다. 이 글은 한 메시지로 치기에 너무 깁니다.\n\n저속 모드가 켜져 있습니다. 한 번에 메시지를 하나 이상 보내실 수 없습니다. 새로운 설문 - New Quiz + 새로운 퀴즈 설문 질문 질문을 작성하세요 - 보기 답안 - Quiz answers + 설문 선택지 + 퀴즈 답 설문 결과 익명 투표 퀴즈 모드 - Select an option first + 먼저 선택지를 고르세요 줄이기 늘이기 - 죄송합니다. 공개 설문은 채널로 전달하실 수 없습니다. + 죄송합니다. 공개 투표 설문은 채널로 전달하실 수 없습니다. 죄송합니다. 설문을 비밀 대화로 전달하실 수 없습니다. - 선다형 - 짧게 눌러 올바른 답을 선택하세요 - 한 퀴즈에는 하나의 올바른 답이 있습니다. 사용자는 본인의 답을 철회할 수 없습니다. - 보기를 추가합니다... + 다중 선택 + 올바른 답을 눌러 정하세요 + 설문이 퀴즈 모드일 때는 올바른 답이 하나만 있습니다. 사용자는 한 번 고른 답을 무를 수 없습니다. + 선택지를 추가합니다... %1$s 추가하실 수 있습니다. - 추가하신 보기 개수가 최대치입니다. + 추가하신 선택지 수가 최대입니다. 익명 투표 정답이 아니에요! - 잘못된 보기를 선택하셨습니다. + 틀린 답을 고르셨습니다. 참 잘했어요! - 올바른 답을 선택하셨습니다. + 올바른 답을 고르셨습니다. 설문 퀴즈 투표 @@ -560,13 +560,13 @@ 지금 이 설문을 마감하시면, 더 이상 다른 사람이 투표할 수 없습니다. 이 작업은 되돌릴 수 없습니다. 퀴즈 마감 퀴즈를 마감할까요? - 이 퀴즈를 마감하면, 더 이상 사람들이 답을 제출할 수 없습니디. 이 작업은 되돌릴 수 없습니다. + 이 퀴즈를 마감하시면, 더 이상 다른 사람이 퀴즈에 답을 제출할 수 없습니다. 이 작업은 되돌릴 수 없습니다. 설문 삭제 정말 이 설문을 삭제하시겠습니까? 투표 취소 최종 결과 투표자 없음 - 답변한 사람이 없습니다 + 답한 사람이 없습니다 %1$d명 투표함 %1$d명 투표함 %1$d명 투표함 @@ -585,13 +585,13 @@ 더 보기 (%1$d) 더 보기 (%1$d) 더 보기 (%1$d) - 보기를 %1$d개 더 - 보기를 %1$d개 더 - 보기를 %1$d개 더 - 보기를 %1$d개 더 - 보기를 %1$d개 더 - 보기를 %1$d개 더 - 보기 + 선택지를 %1$d개 더 + 선택지를 %1$d개 더 + 선택지를 %1$d개 더 + 선택지를 %1$d개 더 + 선택지를 %1$d개 더 + 선택지를 %1$d개 더 + 선택지 최근 활동 모든 활동 @@ -627,7 +627,7 @@ un1 님이 아래 메시지를 고정했습니다: un1 님이 메시지를 고정했습니다. un1 님이 설문을 마감했습니다: - un1 stopped the quiz: + un1 님이 퀴즈를 마감했습니다: un1 님이 아래 메시지를 삭제했습니다: un1 님이 그룹 위치를 \"%1$s\"(으)로 바꿨습니다 un1 님이 그룹 위치를 제거했습니다 @@ -746,7 +746,7 @@ %1$s 님이 음성 메시지 녹음 중... %1$s 님이 동영상 메시지 녹화 중... %1$s 님이 녹음을 보내는 중... - %1$s 님이 사진을 보내는 중... + %1$s 님이 사진 보내는 중... 즉시 보기 그룹 보기 배경 보기 @@ -784,7 +784,7 @@ 내 전화번호 공유 내 연락처 공유 연락처에 추가 - %s 님이 회원님을 비밀 대화에 초대했습니다. + %s 님이 나를 비밀 대화에 초대했습니다. %s 님을 비밀 대화에 초대하셨습니다. 비밀 대화는 단대단 암호화를 사용합니다 @@ -795,6 +795,7 @@ 그룹에서 나오셨습니다 이 그룹 삭제 대화방 삭제 + Delete chats 밀어서 취소 다운로드 폴더에 저장 GIF에 저장 @@ -820,7 +821,7 @@ 보내기 취소 %1$s이(가) 앞으로 여실 페이지로 회원님의 텔레그램 이름과 아이디(전화번호 아님)를 전달할 수 있도록 허락할까요? 이 장소와 관련 없는 그룹인가요? - 그룹이 관련 없음 신고 + 관련 없는 그룹 신고 그룹이 이 장소와 관련 없는 경우 알려 주세요:\n\n**%1$s** 그룹이 이 장소와 관련 없는 경우 알려 주세요. 스팸 신고 @@ -829,7 +830,7 @@ 사용자 차단 스팸 신고하고 나가기 연락처에 추가 - 연락처에 %1$s 님 추가 + %1$s 님을 연락처에 추가하기 연락처 보기 텔레그램 메시지와 전화 수신에서 **%1$s** 님을 차단하시겠습니까? 정말 이 사용자가 보낸 스팸을 신고하시겠습니까? @@ -962,6 +963,8 @@ 1건의 결과 압축 설정을 바꾸기엔 동영상 품질이 너무 낮습니다. **낱말**을 꾹 잡고선, 커서를 움직여 복사할 글을 늘리세요. + Card number copied to clipboard + Copy %1$s 님이 자동 삭제 타이머를 %2$s(으)로 맞췄습니다 자동 삭제 타이머를 %1$s(으)로 맞추셨습니다 @@ -972,17 +975,17 @@ 📅 나 %1$s: %2$s %1$s 님이 회원님에게 %2$s을(를) 보냈습니다 - %1$s 님이 나에게 앨범을 보냈습니다 + %1$s 님이 나에게 사진첩을 보냈습니다 %1$s 님이 회원님에게 %2$s을(를) 전달했습니다 %1$s님이 메시지를 보냈습니다 - %1$s님이 사진을 보냈습니다 + %1$s 님이 나에게 사진을 보냈습니다 %1$s님이 동영상을 보냈습니다 %1$s 님이 회원님에게 %2$s에 대한 인보이스를 보냈습니다 %1$s 님이 자동 삭제되는 사진을 보냈습니다 %1$s 님이 자동 삭제되는 동영상을 보냈습니다 %1$s 님이 %2$s 연락처를 공유했습니다 %1$s 님이 %2$s 설문을 보냈습니다 - %1$s 님이 %2$s 퀴즈를 보냈습니다 + %1$s 님이 나에게 \"%2$s\" 퀴즈를 보냈습니다 %1$s님이 위치를 보냈습니다 %1$s 님이 실시간 위치를 보냈습니다 %1$s님이 %2$s 게임으로 초대했습니다 @@ -993,13 +996,13 @@ %1$s 님이 동영상 메시지를 보냈습니다 %1$s 님이 오디오 파일을 보냈습니다 %1$s 님이 스티커를 보냈습니다 - %1$s 님이 %2$s 스티커를 보냈습니다 + %1$s 님이 나에게 %2$s 스티커를 보냈습니다 %1$s @ %2$s: %3$s %1$s님이 %2$s 그룹에 메시지를 보냈습니다 %1$s 님이 %2$s 그룹에 사진을 보냈습니다 %1$s님이 %2$s 그룹에 동영상을 보냈습니다 %1$s 님이 %3$s 설문을 %2$s 그룹에 보냈습니다 - %1$s 님이 %3$s 퀴즈를 %2$s 그룹에 보냈습니다 + %1$s 님이 \"%3$s\" 퀴즈를 %2$s 그룹에 보냈습니다 %1$s 님이 %3$s 연락처를 %2$s 그룹에서 공유했습니다 %1$s님이 %2$s 그룹에 위치를 보냈습니다 %1$s 님이 %2$s 그룹과 실시간 위치를 공유했습니다 @@ -1020,14 +1023,14 @@ %1$s 님이 %2$s 그룹에 돌아왔습니다 %1$s 님이 %2$s 그룹에 들어왔습니다 %1$s 님이 %3$s 님을 %2$s 그룹에서 추방했습니다 - %1$s 님이 회원님을 %2$s 그룹에서 추방했습니다 + %1$s 님이 나를 %2$s 그룹에서 추방했습니다 %1$s 님이 %2$s 그룹에서 나갔습니다 %1$s 님이 텔레그램에 가입했습니다! %1$s 님,\n%2$s에 새로운 기기가 회원님의 계정에 로그인한 것을 감지했습니다.\n\n기기: %3$s\n위치: %4$s\n\n본인이 아니라면 설정 — 모든 세션 보기에서 그 세션을 종료하실 수 있습니다.\n\n누군가가 회원님의 뜻과 달리 계정에 접속했다고 생각하시면, 설정에서 2단계 인증을 활성화하실 수 있습니다.\n\n감사합니다.\n\n텔레그램 팀 %1$s 님이 프로필 사진을 업데이트했습니다 초대 링크를 통해 %1$s 님이 %2$s 그룹에 들어왔습니다. %1$s 님이 %2$s 그룹에 %3$s을(를) 보냈습니다 - %1$s 님이 앨범을 %2$s 그룹에 보냈습니다 + %1$s 님이 사진첩을 %2$s 그룹에 보냈습니다 %1$s 님이 %2$s 그룹에 %3$s을(를) 전달했습니다 텔레그램 텔레그램 @@ -1041,7 +1044,7 @@ %1$s 님이 %3$s 그룹에 \"%2$s\"을(를) 고정했습니다 %1$s 님이 %2$s 그룹에 메시지를 고정했습니다 %1$s 님이 %3$s 설문을 %2$s 그룹에 고정했습니다 - %1$s 님이 %3$s 퀴즈를 %2$s 그룹에 고정했습니다 + %1$s 님이 \"%3$s\" 퀴즈를 %2$s 그룹에 고정했습니다 %1$s 님이 %2$s 그룹에 사진을 고정했습니다 %1$s 님이 %2$s 그룹에 게임을 고정함 %1$s 님이 게임 점수를 %2$s 그룹에 고정했습니다 @@ -1060,7 +1063,7 @@ %1$s 님이 \"%2$s\"을(를) 고정했습니다 %1$s 님이 메시지를 고정했습니다 %1$s 님이 %2$s 설문을 고정했습니다 - %1$s 님이 %2$s 퀴즈를 고정했습니다 + %1$s 님이 \"%2$s\" 퀴즈를 고정했습니다 %1$s 님이 사진을 고정했습니다 %1$s 님이 게임을 고정했습니다 %1$s 님이 게임 점수를 고정했습니다 @@ -1116,9 +1119,8 @@ 이 그룹을 마저 만들고 슈퍼그룹으로 변환한 뒤에 사용자를 더 추가하실 수 있습니다. 그룹명 입력 그룹명 - %2$d명 중 %1$d명 선택 최대 %1$s - 죄송합니다. 그룹이 가득 차 있습니다. + 죄송합니다. 이 그룹은 이미 가득 찼습니다. 죄송하지만, 대화방이 없어진 모양입니다. 링크를 클립보드에 복사했습니다 링크가 클립보드에 복사되었습니다.\n이 링크는 이 대화방의 참가자에게만 작동합니다. @@ -1168,6 +1170,9 @@ 초대 사용자 차단 사용자 차단 + Block users + Do you want to block **%1$s** from messaging and calling you on Telegram? + Do you want to block **%1$s** from messaging and calling you on Telegram? 사용자가 차단되었습니다 사용자가 차단 해제되었습니다 연락처 수정 @@ -1197,12 +1202,12 @@ 타이머를 맞추시면, 사진이 열람된 뒤 자동으로 삭제됩니다. 타이머를 맞추시면, 동영상이 열람된 뒤 자동으로 삭제됩니다. - 이 이미지와 문자는 **%1$s** 님과의 비밀 대화에 사용된 암호화 키에서 파생되었습니다.\n\n이 이미지와 문자가 **%2$s** 님 기기에서도 똑같이 보인다면, 단대단 암호화에 문제가 없음이 보장됩니다.\n\n자세한 내용은 telegram.org를 참조하세요. + 이 이미지와 문자는 **%1$s** 님과의 비밀 대화에 사용된 암호화 키에서 파생되었습니다.\n\n이 이미지와 문자가 **%2$s** 님의 기기에서 똑같이 보인다면, 단대단 암호화가 보장됩니다.\n\ntelegram.org에서 자세히 알아보세요. https://telegram.org/faq#secret-chats 알 수 없음 알 수 없음 전화번호 숨김 - 전화번호는 %1$s 님이 회원님을 연락처로 추가하는 즉시 보입니다. + 전화번호는 %1$s 님이 회원님을 연락처에 추가하는 즉시 보입니다. **완료**를 누르시면, 회원님의 전화번호가 %1$s 님에게 보입니다. %1$s 님과 내 전화번호 공유 %1$s 님이 연락처 목록에 등록되었습니다. @@ -1212,6 +1217,8 @@ 사진과 동영상 링크 오디오 파일 + Send Message + Report 사용자명 사용자명 @@ -1243,7 +1250,7 @@ 그룹 스티커 즐겨찾기에서 삭제 마스크에 추가 - 스티커를 찾지 못함 + 스티커를 찾지 못했습니다 스티커가 제거되었습니다 마스크가 제거되었습니다 새로운 스티커가 추가되었습니다 @@ -1270,10 +1277,10 @@ 이 스티커들이 텔레그램에서 한창 인기를 끌고 있습니다. @sticker 봇으로 맞춤 스티커를 추가하실 수 있습니다. 보관된 스티커 보관된 마스크 - 보관된 스티커 없음 + 보관된 스티커가 없습니다 보관된 마스크 없음 스티커 묶음을 200개까지 추가하실 수 있습니다. 사용하지 않은 스티커는 새로운 묶음을 추가하실 때 보관됩니다. - 마스크를 200 묶음까지 저장하실 수 있습니다. 사용하지 않은 마스크는 새로운 묶음을 추가하실 때 보관됩니다. + 마스크 묶음을 200개까지 보유하실 수 있습니다. 사용하지 않은 마스크는 새로운 묶음을 추가하실 때 보관됩니다. 스티커 보내기 보관된 스티커 몇몇 오래된 스티커 묶음이 보관되었습니다. 스티커 설정에서 다시 활성화하실 수 있습니다. @@ -1444,7 +1451,7 @@ 보라색 주황색 LED는 몇몇 기기에 있는 반짝이는 작은 빛으로 새로운 메시지가 왔음을 나타냅니다. - 우선순위가 높은 알림은 휴대폰이 방해 금지 상태이더라도 작동합니다. + 우선순위가 높은 알림은 휴대전화가 방해 금지 상태이더라도 작동합니다. 일반 음소거됨 음소거 해제 @@ -1452,7 +1459,7 @@ %1$s까지 끔 기본 (켬) - 기본 (꺼짐) + 기본 (끔) 켜기 끄기 차단된 사용자 @@ -1525,7 +1532,7 @@ 데이터가 부족합니다 비공식 언어 해당 언어가 없습니다. - 이미 이 언어 묶음(**%1$s**)을 사용하고 계십니다. 설정에서 언제든 언어를 바꾸실 수 있습니다. + 이미 이 언어 묶음(**%1$s**)을 사용하고 계십니다. 언제든 설정에서 언어를 바꾸실 수 있습니다. 안타깝게도 이 맞춤 언어 묶음(**%1$s**)에는 Android 텔레그램용 데이터가 들어 있지 않습니다. 텔레그램 지원 사항은 자원봉사자들이 처리합니다. 신속하게 응답해 드리고자 노력하지만, 다소 시간이 걸릴 수 있습니다.\n\n 자주 묻는 질문]]>을 확인해 보세요. 잦은 질문에 대한 답과 문제 해결]]>을 위한 중요한 조언이 있습니다. 봉사자에게 질문하기 @@ -1641,7 +1648,7 @@ 대화 중 소리 기본 - 기본 + 기본값 스마트 알림 예외 예외 추가 @@ -1675,6 +1682,10 @@ 연락처 재동기화 대화 초기화 모든 대화 읽기 + Enable pause music on record + Disable pause music on record + Enable smooth keyboard + Disable smooth keyboard 앱 안 카메라 사용 앱 안 카메라 사용 안 함 가져온 연락처 초기화 @@ -1775,7 +1786,7 @@ 로컬 데이터베이스 로컬 데이터베이스 비우기 - 정말 문자 메시지 캐시를 비우시겠습니까? + 정말 캐시된 문자 메시지 비우시겠습니까? 로컬 데이터베이스를 비우면 캐시된 메시지의 글을 지우고 데이터베이스를 압축해 내장 디스크 공간을 절약합니다. 텔레그램이 작동하는데 데이터가 어느 정도 필요하므로 데이터베이스 크기는 0이 되지 않습니다.\n\n이 작업은 완료되기까지 몇 분 정도 걸릴 수 있습니다. 캐시 비우기 비우기 @@ -1789,7 +1800,7 @@ 다른 파일 비어 있음 미디어 저장 기간 - 회원님이 이 기간 동안 **접근하시지 않은** 클라우드 대화방의 사진, 동영상과 그 밖의 파일들이 디스크 공간을 절약하기 위해 이 기기에서 제거됩니다.\n\n모든 미디어는 텔레그램 클라우드에 남으며 언제든지 다시 다운로드하실 수 있습니다. + 이 기간 동안 회원님이 **접근하지 않으신** 클라우드 대화방의 사진, 동영상과 그 밖의 파일들이 디스크 공간을 절약하기 위해 이 기기에서 제거됩니다.\n\n모든 미디어는 텔레그램 클라우드에 남으며 언제든지 다시 다운로드하실 수 있습니다. 영원히 음성 메시지 동영상 메시지 @@ -1798,7 +1809,7 @@ "요청 받은 정보 " 제공한 정보 텔레그램 패스포트가 무엇인가요? - 텔레그램 패스포트와 함께라면, 신분 인증이 필요한 여러 웹 사이트와 서비스에 손쉽게 로그인하실 수 있습니다.\n\n회원님의 정보와 개인 데이터, 서류들은 단대단 암호화로 보호됩니다. 텔레그램을 포함하여, 그 누구도 회원님의 허가 없이 이들에 접근할 수 없습니다. + 텔레그램 패스포트와 함께라면, 신분 인증이 필요한 여러 웹 사이트와 서비스에 손쉽게 로그인하실 수 있습니다.\n\n회원님의 정보와 개인 데이터, 서류들은 단대단 암호화로 보호됩니다. 텔레그램을 포함하여, 그 누구도 회원님의 허가 없이 이들에 접근할 수 없습니다.\n\n*FAQ*를 방문하여 자세히 알아보실 수 있습니다. https://telegram.org/faq#passport 단대단 암호화로 개인 데이터를 보호하려면 비밀번호를 만드셔야 합니다.\n\n새로운 기기로 텔레그램에 로그인할 때 이 비밀번호가 필요할 것입니다. 비밀번호 만들기 @@ -1887,7 +1898,7 @@ 생년월일 성별 서류 번호 - 만기 + 만료일 시민권 거주지 본인 사진 @@ -1900,12 +1911,12 @@ 서류 뒷면의 사진을 업로드하세요 주요 면 서류 주요 면의 사진을 업로드하세요 - 만기일을 선택하세요 + 만료일을 선택하세요 만기되지 않음 없음 생년월일을 선택하세요 본인 사진을 삭제할까요? - 서류에 회원님의 사진과 성명, 생년월일, 서류 번호, 발급 국가, 만기일이 포함되어야 합니다. + 서류에 회원님의 사진과 성명, 생년월일, 서류 번호, 발급 국가, 만료일이 포함되어야 합니다. 정말 입력한 정보를 모두 삭제하시겠습니까? 삭제 스캔 @@ -1986,7 +1997,7 @@ 활성화된 다른 세션이 없습니다 동일한 전화번호를 사용하여 다른 모바일, 태블릿, 데스크탑 장치에서 텔레그램에 로그인하실 수 있습니다. 모든 데이터가 즉시 동기화됩니다. 활성 세션 - 다른 기기의 세션을 관리하세요. + 다른 기기의 세션을 제어하세요. 세션을 종료하려면 짧게 누르세요. 이 세션을 종료할까요? 정말 이 세션을 종료하시겠습니까? @@ -2003,19 +2014,19 @@ 텔레그램으로 로그인된 웹 사이트 텔레그램 계정과 연결을 끊으려면 짧게 누르세요. 정말 %1$s과(와) 연결을 끊으시겠습니까? - 웹사이트 연결 끊기 - 웹사이트 연결 끊기 + 웹 사이트 연결 끊기 + 웹 사이트 연결 끊기 연결 끊기 %1$s 차단 모든 웹 사이트 연결 끊기 - 정말로 텔레그램을 사용하여 로그인한 모든 웹사이트의 연결을 해제하시겠습니까? + 정말 텔레그램을 사용하여 로그인한 모든 웹 사이트와 연결을 끊으시겠습니까? 텔레그램으로 로그인하기를 지원하는 웹 사이트에 로그인하실 수 있습니다. 완료되지 않은 로그인 시도 위 기기가 메시지에 접근할 수 없습니다. 코드는 알맞게 입력하셨으나, 비밀번호가 잘못되었습니다. 암호 잠금 암호 바꾸기 - 암호를 설정하면, 대화 페이지에 잠금 아이콘이 나타납니다. 이 아이콘을 눌러 텔레그램을 잠그거나 잠금 해제하실 수 있습니다.\n\n주의: 암호를 잊어버리면 앱을 삭제하고 다시 설치하셔야 합니다. 비밀 대화는 모두 사라집니다. + 암호를 설정하시면, 대화 페이지에 잠금 아이콘이 나타납니다. 이 아이콘을 눌러 텔레그램을 잠그거나 잠금 해제하실 수 있습니다.\n\n주의: 암호를 잊어버리면 앱을 삭제하고 다시 설치하셔야 합니다. 비밀 대화는 모두 사라집니다. PIN 암호 현재 암호를 입력하세요 @@ -2049,11 +2060,13 @@ 10월 11월 12월 - 파일 - 미디어 - 링크 - 오디오 - 음성 + Files + Media + Shared Media + Groups + Links + Audio + Voice Messages 공유한 파일 공유하는 콘텐츠 공유한 링크 @@ -2111,6 +2124,10 @@ 이 대화방 사람들에게 회원님의 실시간 위치를 얼마 동안 보일지 선택하세요. GPS 켜기 위치 기반 기능에 접근하려면 GPS를 켜 주세요. + Make Myself Visible + Show Your Profile? + Users nearby will be able to view your profile and send you messages. This may help you find new friends, but could also attract excessive attention. You can stop sharing your profile at any time.\n\nYour phone number will remain hidden. + Stop Showing Me 주변 사람 주변 사람 추가 손쉽게 이 페이지를 열고 있는 사람들을 추가하고 지역 그룹 대화방을 찾으세요.\n\n이 기능을 켜려면 위치 접근을 켜 주세요. @@ -2119,7 +2136,7 @@ 이 페이지를 보고 있는 주변 사람들을 손쉽게 추가하거나 지역 그룹 대화방을 발견해 보세요.\n\n이 기능을 사용하려면 위치 서비스를 켜셔야 합니다. 켜기 주변 그룹 - 친구에게 이 페이지를 열자고 하여 전화번호를 교환하세요. + Exchange contact info with people nearby and find new friends. 주변에 있는 사용자 찾는 중... 지역 그룹 만들기 그룹하기 @@ -2127,7 +2144,7 @@ 이 위치와 관계 없는 그룹을 만들 경우, 앞으로 위치 기반 그룹을 만들지 못하실 수 있습니다. 위치 설정 이 위치로 설정하기 - 사람들이 회원님의 그룹을 \"주변 사람\" 구역에서 찾을 수 있습니다. + 사람들이 회원님의 그룹을 \"주변 사람\" 섹션에서 찾을 수 있습니다. 지역에 있는 장소 목록으로 보기 @@ -2150,8 +2167,8 @@ 이 동영상은 스트리밍에 최적화되어 있지 않습니다. 재생하려면 완전히 다운로드하셔야 합니다. 앱에서 동영상을 재생할 수 없습니다. 외부 플레이어로 재생할까요? 최근 검색 기록이 없습니다 - 이미지 - GIF + Images + GIFs 최근 GIF 없음 이미지 찾기 웹 검색 @@ -2212,7 +2229,7 @@ 2단계 인증 2단계 인증 - 개별 비밀번호 설정 + 추가 비밀번호 설정 새로운 기기에 로그인할 때 SMS로 받는 코드와 별개로 입력해야 하는 비밀번호를 설정하실 수 있습니다. 비밀번호 비밀번호를 입력하세요 @@ -2229,7 +2246,7 @@ 경고 비밀번호 분실시\n\n텔레그램에 대한 모든 접속 권한을 상실하시게 됩니다.\n비밀번호 분실시 복구는 불가능 합니다. 거의 다 됐어요! - 2단계 인증 설정을 완료하시려면 이메일을 (스팸 폴더도 잊지 않고) 확인해 주세요. + 2단계 인증 설정을 완료하려면 이메일을 (스팸 메일함도 잊지 않고) 확인해 주세요. 성공! 2단계 인증 비밀번호가 활성화되었습니다. 2단계 인증용 복구 이메일이 이제 작동합니다. @@ -2281,9 +2298,9 @@ 디스크 및 네트워크 사용량 저장 공간 사용량 데이터 사용량 - 모바일 - 와이파이 - 로밍 + Mobile + Wi-Fi + Roaming 메시지 및 기타 데이터 보냄 받음 @@ -2369,7 +2386,7 @@ 사용자를 삭제하려면 길게 누르세요. 그룹 나를 그룹 대화방에 추가할 수 있는 사람 - 회원님을 그룹과 채널에 추가할 수 있는 사람을 세세하게 정하실 수 있습니다. + 회원님을 그룹과 채널에 추가할 수 있는 사람을 세세하게 제한하실 수 있습니다. 항상 허용 항상 거부 위 사용자는 앞선 설정과 무관하게 회원님을 그룹과 채널에 추가하지 못합니다. @@ -2380,7 +2397,7 @@ 단대단을 끄시면, 회원님의 IP 주소를 노출시키지 않도록 모든 전화가 텔레그램 서버를 통해 전달됩니다. 다만 음성 품질이 약간 저하될 수 있습니다. 동기화된 연락처 삭제 자주 이용하는 연락처 추천 - "신속한 연락을 위해 검색 구역 위쪽에 자주 대화하는 사람을 내보이세요. " + 신속한 연락을 위해 검색 구역 위쪽에 자주 대화하는 사람을 표시합니다. 추천 사용 안 함 즐겨 사용하시는 인라인 봇과 자주 메시지하시는 대화 상대들의 데이터가 삭제됩니다. 사용자 또는 그룹 추가 @@ -2464,8 +2481,8 @@ 그룹 사진을 바꾸셨습니다 그룹명을 un2(으)로 바꾸셨습니다 그룹을 만드셨습니다 - un1 님이 회원님을 추방했습니다 - un1 님을 추가하셨습니다 + un1 님이 나를 추방했습니다 + un1 님이 나를 추가했습니다 un1 님이 그룹에 돌아왔습니다 un1 님이 그룹에 들어왔습니다 그룹에 돌아오셨습니다 @@ -2489,7 +2506,7 @@ 동영상 자동 삭제되는 사진 자동 삭제되는 동영상 - 사진이 만료했습니다 + 사진이 만료되었습니다 동영상이 만료했습니다 GIF 위치 @@ -2549,7 +2566,7 @@ **%1$s** 님에게 이 메시지를 보내시겠습니까? **%1$s** 님에게 이 게임을 공유하시겠습니까? **%1$s** 님에게 이 연락처를 보내시겠습니까? - 정말 로그아웃하시겠습니까?\n\n텔레그램은 회원님의 모든 기기에서 동시에 끊김 없이 이용하실 수 있습니다.\n\n로그아웃 시 모든 비밀 대화가 사라지는 점을 유의하시기 바랍니다. + 정말 로그아웃하시겠습니까?\n\n텔레그램은 회원님의 모든 기기에서 동시에 끊김 없이 이용하실 수 있습니다.\n\n로그아웃하면 모든 비밀 대화가 사라진다는 점을 기억하세요. %1$s 삭제 %1$s 비우기 %1$s에서 캐시 비우기 @@ -2637,7 +2654,7 @@ 음성 메시지를 보내려면 텔레그램에게 마이크 접근 권한을 부여하셔야 합니다. 동영상을 녹화하려면 텔레그램에게 마이크 접근 권한을 부여하셔야 합니다. 사진과 동영상을 촬영하려면 텔레그램에게 카메라 접근 권한을 부여하셔야 합니다. 설정에서 권한을 켜 주세요. - 회원님의 위치를 친구들과 공유하려면 텔레그램에게 위치 접근 권한을 부여하셔야 합니다. + 회원님의 위치를 친구들과 공유하려면 텔레그램에게 위치 접근 권한이 필요합니다. 텔레그램에게 위치 접근 권한이 필요합니다. 화면속화면 모드로 동영상을 재생하려면 텔레그램에게 다른 앱 위에 그릴 수 있는 권한을 부여하셔야 합니다. 설정 @@ -2708,7 +2725,7 @@ 코멘트를 입력하실 수 있습니다 답신 전화 다시 전화 걸기 - 기본 + 기본값 정말 이 통화 기록을 삭제하시겠습니까? 텔레그램 전화 이어폰 @@ -2849,6 +2866,12 @@ %1$d개 아이템 %1$d개 아이템 %1$d개 아이템 + + + + + + %1$d개의 대화로부터 받음 %1$d개의 대화로부터 받음 %1$d개의 대화로부터 받음 @@ -2915,12 +2938,12 @@ %1$d 미터 %1$d 미터 %1$d 미터 - 스티커 %1$d개 - 스티커 %1$d개 - 스티커 %1$d개 - 스티커 %1$d개 - 스티커 %1$d개 - 스티커 %1$d개 + 스티커 %1$d장 + 스티커 %1$d장 + 스티커 %1$d장 + 스티커 %1$d장 + 스티커 %1$d장 + 스티커 %1$d장 마스크 %1$d개 마스크 %1$d개 마스크 %1$d개 @@ -2988,12 +3011,12 @@ 전달할 메시지 %1$d개 전달할 메시지 %1$d개 전달할 메시지 %1$d개 - 사진 %1$d개 - 사진 %1$d개 - 사진 %1$d개 - 사진 %1$d개 - 사진 %1$d개 - 사진 %1$d개 + 사진 %1$d장 + 사진 %1$d장 + 사진 %1$d장 + 사진 %1$d장 + 사진 %1$d장 + 사진 %1$d장 동영상 %1$d개 동영상 %1$d개 동영상 %1$d개 @@ -3006,12 +3029,36 @@ 파일 %1$d개 파일 %1$d개 파일 %1$d개 + %1$d music files + %1$d music file + %1$d music files + %1$d music files + %1$d music files + %1$d music files + %1$d groups in common + %1$d group in common + %1$d groups in common + %1$d groups in common + %1$d groups in common + %1$d groups in common 미디어 %1$d개 미디어 %1$d개 미디어 %1$d개 미디어 %1$d개 미디어 %1$d개 미디어 %1$d개 + %1$d voice messages + %1$d voice message + %1$d voice messages + %1$d voice messages + %1$d voice messages + %1$d voice messages + %1$d links + %1$d link + %1$d links + %1$d links + %1$d links + %1$d links 차단된 사용자 %1$d명 차단된 사용자 %1$d명 차단된 사용자 %1$d명 @@ -3024,12 +3071,12 @@ 전달할 파일 %1$d개 전달할 파일 %1$d개 전달할 파일 %1$d개 - 전달할 사진 %1$d개 - 전달할 사진 %1$d개 - 전달할 사진 %1$d개 - 전달할 사진 %1$d개 - 전달할 사진 %1$d개 - 전달할 사진 %1$d개 + 전달할 사진 %1$d장 + 전달할 사진 %1$d장 + 전달할 사진 %1$d장 + 전달할 사진 %1$d장 + 전달할 사진 %1$d장 + 전달할 사진 %1$d장 전달할 동영상 %1$d개 전달할 동영상 %1$d개 전달할 동영상 %1$d개 @@ -3066,12 +3113,12 @@ 전달할 연락처 %1$d개 전달할 연락처 %1$d개 전달할 연락처 %1$d개 - 전달할 스티커 %1$d개 - 전달할 스티커 %1$d개 - 전달할 스티커 %1$d개 - 전달할 스티커 %1$d개 - 전달할 스티커 %1$d개 - 전달할 스티커 %1$d개 + 전달할 스티커 %1$d장 + 전달할 스티커 %1$d장 + 전달할 스티커 %1$d장 + 전달할 스티커 %1$d장 + 전달할 스티커 %1$d장 + 전달할 스티커 %1$d장 전달할 설문 %1$d개 전달할 설문 %1$d개 전달할 설문 %1$d개 @@ -3114,6 +3161,24 @@ %1$d /%2$d의 결과 %1$d /%2$d의 결과 %1$d /%2$d의 결과 + %1$d users + %1$d user + %1$d users + %1$d users + %1$d users + %1$d users + %1$d users + %1$d user + %1$d users + %1$d users + %1$d users + %1$d users + %1$d of %2$d selected + %1$d of %2$d selected + %1$d of %2$d selected + %1$d of %2$d selected + %1$d of %2$d selected + %1$d of %2$d selected 그룹 채널 @@ -3201,8 +3266,8 @@ 더 작은 크기 나은 품질 - yyyy년 MMM dd일, a h:mm - yyyy년 MM dd일, HH:mm + yyyy년 MMM dd일 h:mm a + yyyy년 MMM dd일 HH:mm yyyy.MM.dd, a h:mm yyyy.MMM.dd, HH:mm MMM dd, a h:mm @@ -3225,5 +3290,5 @@ yyyy\'년\' M\'월\' d\'일\' HH:mm\'에 보냄\' \'오늘\' HH:mm\'에 알리기\' MMM d HH:mm\'에 알리기\' - yyyy MMM d \'이날\' HH:mm\'에 알림\' + yyyy\'년\' M\'월\' d\'일\' HH:mm\'에 알림\' diff --git a/TMessagesProj/src/main/res/values-nl/strings.xml b/TMessagesProj/src/main/res/values-nl/strings.xml index 19dec23c8..4dd245fe0 100644 --- a/TMessagesProj/src/main/res/values-nl/strings.xml +++ b/TMessagesProj/src/main/res/values-nl/strings.xml @@ -219,7 +219,7 @@ Stille chats blijven gearchiveerd bij nieuwe berichten. Vastgezette chats Je kunt een ongelimteerd aantal gearchiveerde chats vastzetten. - Hold this button to schedule your message or send it without sound. + Hou deze knop ingedrukt om je bericht te plannen of zonder geluid te sturen. Promoveren tot beheerder Beheerdersrechten aanpassen @@ -245,7 +245,7 @@ un1 heeft \"%1$s\" vastgezet un1 heeft bericht vastgezet un1 heeft een poll vastgezet - un1 pinned a quiz + un1 heeft een quiz vastgezet un1 heeft foto vastgezet un1 heeft een video vastgezet un1 heeft bestand vastgezet @@ -378,7 +378,7 @@ %1$s plaatste een video %1$s plaatste een contact %2$s %1$s plaatste een poll %2$s - %1$s posted the quiz \"%2$s\" + %1$s plaatste de quiz \"%2$s\" %1$s plaatste een locatie %1$ plaatste een live-locatie %1$s plaatste een bestand @@ -525,48 +525,48 @@ Sorry, deze tekst is te lang om als 1 bericht te sturen.\n\nTempolimiet is ingeschakeld, je kunt niet meer dan 1 bericht tegelijkertijd sturen. Nieuwe poll - New Quiz + Nieuwe Quiz Poll Vraag Stel een vraag Pollopties - Quiz answers - Poll Results - Anonymous Voting + Quiz antwoorden + Poll resultaten + Anoniem stemmen Quizmode - Select an option first - Collapse - Expand - Sorry, polls with visible votes can’t be forwarded to channels. - Sorry, polls can’t be forwarded to secret chats. - Multiple Answers - Tap to choose the correct answer - Polls in Quiz Mode have one correct answer. Users can\'t revoke their answers. - Optie toevoegen + Kies eerst een optie + Inklappen + Uitklappen + Sorry, polls met zichtbare stemmen kunnen niet naar kanalen worden doorgestuurd. + Sorry, polls kunnen niet worden doorgestuurd naar geheime chats + Meerdere antwoorden + Tik om het juiste antwoord te kiezen + Polls in quiz-modus hebben 1 correct antwoord. Gebruikers kunnen hun antwoord niet intrekken. + Optie toevoegen... Je kan nog %1$s. Maximaal aantal opties zijn toegevoegd. Anonieme poll - Wrong answer! - You missed the correct option. + Fout antwoord! + Je hebt de juiste optie gemist. Goed gedaan! - You chose the right answer. + Je hebt het goede antwoord gekozen. Poll Quiz STEMMEN - VIEW RESULTS + RESULTATEN WEERGEVEN Anonieme quiz Poll stoppen Poll stoppen? Als je deze poll nu stopt kan niemand meer stemmen. Deze actie kan niet ongedaan worden gemaakt. Quiz stoppen? Quiz stoppen? - If you stop this quiz now, nobody will be able to submit answers. This action cannot be undone. + Als je deze quiz nu stopt kan niemand antwoorden insturen, je kunt dit niet ongedaan maken. Poll verwijderen? Deze poll echt weggooien? Stem intrekken Eindresultaat Geen stemmen - Nobody answered + Niemand heeft geantwoord %1$d stemmen %1$d stem %1$d stemmen @@ -627,7 +627,7 @@ bericht door un1 vastgezet: bericht door un1 losgemaakt un1 heeft de poll gestopt: - un1 stopped the quiz: + un1 stopte de quiz: bericht door un1 verwijderd: un1 wijzigde de groepslocatie naar \"%1$s\" un1 verwijderde de groepslocatie @@ -795,6 +795,7 @@ Je hebt deze groep verlaten Deze groep verwijderen Chat verwijderen + Delete chats SLEEP OM TE ANNULEREN Opslaan in Downloads GIF opslaan @@ -957,11 +958,13 @@ Sorry, je kunt niet meer dan 100 berichten plannen. Deze actie is beschikbaar na publicatie van het bericht. Stemmen is beschikbaar naar publicatie van het bericht. - Poll results will become available after the message is published. + Poll-resultaten zijn zichtbaar na het publiceren van het bericht. 📅 Herinnering 1 resultaat Videokwaliteit is te laag om de compressie-instellingen te wijzigen. Hou het **woord** vast, beweeg de cursor om meer tekst te selecteren om te kopiëren. + Card number copied to clipboard + Kopiëren %1$s heeft de zelfvernietigingstimer ingesteld op %2$s Je hebt de zelfvernietigingstimer ingesteld op %1$s @@ -982,7 +985,7 @@ %1$s heeft je een zelfvernietigende video gestuurd %1$s deelde een contact %2$s met je %1$s stuurde je een poll %2$s - %1$s sent you the quiz \"%2$s\" + %1$s stuude je de quiz \"%2$s\" %1$s heeft je een locatie gestuurd %1$s deelt een live-locatie met je %1$s wil %2$s met je spelen @@ -999,7 +1002,7 @@ %1$s heeft een foto gestuurd naar de groep %2$s %1$s heeft een video gestuurd naar de groep %2$s %1$s stuurde een poll %3$s naar de groep %2$s - %1$s sent the quiz \"%3$s\" to the group %2$s + %1$s stuurde de quiz \"%3$s\" naar de groep %2$s %1$s deelde een contact %3$s in de groep %2$s %1$s heeft een locatie gestuurd naar de groep %2$s %1$s deelt een live-locatie met groep %2$s @@ -1041,7 +1044,7 @@ %1$s heeft \"%2$s\" vastgezet in de groep %3$s %1$s heeft bericht vastgezet in de groep %2$s %1$s heeft een poll %3$s vastgezet in de groep %2$s - %1$s pinned the quiz \"%3$s\" in the group %2$s + %1$s heeft de quiz \"%3$s\" vastgezet in de groep %2$s %1$s heeft foto vastgezet in de groep %2$s %1$s heeft een spel in de groep %2$s vastgezet %1$s heeft een score vastgezet in de groep %2$s @@ -1060,7 +1063,7 @@ %1$s heeft \"%2$s\" vastgezet %1$s heeft bericht vastgezet %1$s heeft een poll vastgezet %2$s - %1$s pinned the quiz \"%2$s\" + %1$s heeft quiz \"%2$s\" vastgezet %1$s heeft foto vastgezet %1$s heeft een spel vastgezet %1$s heeft een score vastgezet @@ -1116,7 +1119,6 @@ Nadat je de groep hebt aangemaakt kun je meer gebruikers toevoegen en omzetten naar een supergroep. Groepsnaam Groepsnaam - %1$d van %2$d geselecteerd tot aan %1$s Sorry, deze groep is al vol. Sorry, deze groep bestaat niet. @@ -1168,6 +1170,9 @@ Nodig uit Blokkeer Blokkeer gebruiker + Block users + Do you want to block **%1$s** from messaging and calling you on Telegram? + Do you want to block **%1$s** from messaging and calling you on Telegram? Gebruiker geblokkeerd Gebruiker gedeblokkeerd Wijzig @@ -1212,6 +1217,8 @@ Foto\'s en video\'s Links Audiobestanden + Send Message + Report Gebruikersnaam Kies een naam @@ -1317,7 +1324,7 @@ Aangepaste thema\'s Link instellen Themalink - Message corners + Berichthoeken Weergave chatoverzicht Twee regels Drie regels @@ -1675,6 +1682,10 @@ Contacten verversen Chats herstellen Alles als gelezen + Enable pause music on record + Disable pause music on record + Enable smooth keyboard + Disable smooth keyboard In-app camera inschakelen In-app camera uitschakelen Reset geimporteerde contacten @@ -1953,7 +1964,7 @@ Hongaars Armeens Indonesisch - Ijslands + IJslands Italiaans Japans Georgisch @@ -1978,7 +1989,7 @@ Turkmeens Turks Oekraïens - Oesbeeks + Oezbeeks Vietnamees Actieve sessies @@ -2049,11 +2060,13 @@ oktober november december - BESTANDEN - MEDIA - LINKS - AUDIO - SPRAAK + Bestanden + Media + Shared Media + Groepen + Links + Audio + Voice Messages Gedeelde bestanden Gedeelde content Gedeelde links @@ -2111,6 +2124,10 @@ Kies hoelang je je Live-locatie met mensen in deze chat wilt delen. GPS inschakelen Activeer je GPS voor locatie-gebaseerde diensten. + Make Myself Visible + Show Your Profile? + Users nearby will be able to view your profile and send you messages. This may help you find new friends, but could also attract excessive attention. You can stop sharing your profile at any time.\n\nYour phone number will remain hidden. + Stop Showing Me Mensen dichtbij Voeg mensen dichtbij toe Gebruik deze sectie om makkelijk mensen dichtbij toe te voegen die deze sectie open hebben en lokale groepschats te ontdekken.\n\nSta locatie-toegang toe om deze functie in te schakelen. @@ -2119,7 +2136,7 @@ Voeg snel mensen dichtbij toe die deze sectie open hebben en ontdek lokale groepschats.\n\nSta locatietoegang toe om deze functie te gebruiken. Inschakelen Groepen dichtbij - Vraag je vriend die bij je is om deze pagina te openen en zo telefoonnummers uit te wisselen. + Exchange contact info with people nearby and find new friends. Zoeken naar gebruikers in de buurt Maak een lokale groep Groep starten @@ -2150,8 +2167,8 @@ Deze video is niet geoptimaliseerd om te streamen, een volledige download kan nodig zijn om deze af te spelen. De app kon deze video niet afspelen. Afspelen proberen met externe speler? Geen recente zoekopdrachten - AFBEELDINGEN - GIF\'S + Images + GIFs Niets recents ONLINE ZOEKEN ZOEK OP HET WEB @@ -2281,9 +2298,9 @@ Opslag- en datagebruik Opslaggebruik Datagebruik - MOBIEL - WI-FI - ROAMEN + Mobile + Wi-Fi + Roaming Berichten en andere gegevens Verzonden Ontvangen @@ -2849,6 +2866,12 @@ %1$d items %1$d items %1$d items + + + + + + van %1$d chats van %1$d chat van %1$d chats @@ -3006,12 +3029,36 @@ %1$d bestanden %1$d bestanden %1$d bestanden + %1$d music files + %1$d music file + %1$d music files + %1$d music files + %1$d music files + %1$d music files + %1$d groups in common + %1$d group in common + %1$d groups in common + %1$d groups in common + %1$d groups in common + %1$d groups in common %1$d media %1$d media %1$d media %1$d media %1$d media %1$d media + %1$d voice messages + %1$d voice message + %1$d voice messages + %1$d voice messages + %1$d voice messages + %1$d voice messages + %1$d links + %1$d link + %1$d links + %1$d links + %1$d links + %1$d links %1$d geblokkeerde gebruikers %1$d geblokkeerde gebruiker %1$d geblokkeerde gebruikers @@ -3114,6 +3161,24 @@ %1$d van %2$d resultaten %1$d van %2$d resultaten %1$d van %2$d resultaten + %1$d gebruikers + %1$d gebruiker + %1$d gebruikers + %1$d gebruikers + %1$d gebruikers + %1$d gebruikers + %1$d users + %1$d user + %1$d users + %1$d users + %1$d users + %1$d users + %1$d of %2$d selected + %1$d of %2$d selected + %1$d of %2$d selected + %1$d of %2$d selected + %1$d of %2$d selected + %1$d of %2$d selected Groep Kanaal diff --git a/TMessagesProj/src/main/res/values-pt-rBR/strings.xml b/TMessagesProj/src/main/res/values-pt-rBR/strings.xml index c2336c048..8fda4210f 100644 --- a/TMessagesProj/src/main/res/values-pt-rBR/strings.xml +++ b/TMessagesProj/src/main/res/values-pt-rBR/strings.xml @@ -378,7 +378,7 @@ %1$s postou um vídeo %1$s postou um contato %2$s %1$s postou uma enquete %2$s - %1$s postou um quiz %2$s + %1$s postou o quiz \"%2$s\" %1$s postou uma localização %1$@ postou uma localização em tempo real %1$s postou um arquivo @@ -525,12 +525,12 @@ Desculpe, este texto é muito longo para ser enviado em uma só mensagem.\n\nO Modo Lento está ativado. Você não pode enviar mais de uma mensagem por vez. Nova Enquete - New Quiz + Novo Quiz Enquete Pergunta Faça uma pergunta Opções da enquete - Quiz answers + Respostas do quiz Resultados da Enquete Votação Anônima Modo Quiz @@ -744,7 +744,7 @@ %1$s está escrevendo... %1$s estão escrevendo... %1$s está gravando voz... - %1$s está gravando mensagem de vídeo... + %1$s está gravando msg. de vídeo... %1$s está enviando um áudio... %1$s está enviando uma foto... LEITURA RÁPIDA @@ -758,8 +758,8 @@ %1$s está jogando... %1$s está enviando um vídeo... %1$s está enviando um arquivo... - gravando mensagem de voz... - gravando mensagem de vídeo... + gravando voz... + gravando msg. de vídeo... enviando áudio... enviando uma foto... jogando... @@ -795,6 +795,7 @@ Você saiu deste grupo Apagar este grupo Apagar este chat + Apagar chats DESLIZE PARA CANCELAR Salvar em downloads Salvar em GIFs @@ -924,7 +925,7 @@ GIFs não são permitidos neste grupo. Não é permitido enviar mensagens neste grupo. admin - A instalação de APKs está restrita nesse aplicativo. Você pode ativar nas configurações de sistema. + A instalação de APKs está restrita nesse aplicativo. Você pode ativar nas configurações do sistema. Mensagens não lidas Buscar pacotes de sticker Pesquisar emoji @@ -962,6 +963,8 @@ 1 resultado A qualidade do vídeo é muito baixa para mudar a compressão. Segure na **palavra** e depois mova o cursor para selecionar mais texto para copiar. + Número do cartão copiado. + Copiar "%1$s alterou o timer de autodestruição para %2$s " Você alterou o timer de autodestruição para %1$s @@ -982,7 +985,7 @@ %1$s te enviou um video autodestrutivo %1$s compartilhou um contato %2$s com você %1$s te enviou uma enquete %2$s - %1$s te enviou um quiz %2$s + %1$s te enviou o quiz \"%2$s\" %1$s te enviou uma localização %1$s te enviou uma localização em tempo real %1$s te convidou para jogar %2$s @@ -999,7 +1002,7 @@ %1$s enviou uma foto para o grupo %2$s %1$s enviou um vídeo para o grupo %2$s %1$s enviou uma enquete %3$s no grupo %2$s - %1$s enviou um quiz %3$s ao grupo %2$s + %1$s enviou o quiz \"%3$s\" ao grupo %2$s %1$s compartilhou um contato %3$s no grupo %2$s %1$s enviou uma localização para o grupo %2$s %1$s compartilhou a localização em tempo real com o grupo %2$s @@ -1041,7 +1044,7 @@ %1$s fixou \"%2$s\" no grupo %3$s %1$s fixou uma mensagem no grupo %2$s %1$s fixou uma enquete %3$s no grupo %2$s - %1$s fixou um quiz %3$s no grupo %2$s + %1$s fixou o quiz \"%3$s\" no grupo %2$s %1$s fixou uma foto no grupo %2$s %1$s fixou um jogo no grupo %2$s %1$s fixou um placar de jogo no grupo %2$s @@ -1060,7 +1063,7 @@ %1$s fixou \"%2$s\" %1$s fixou uma mensagem %1$s fixou uma enquete %2$s - %1$s fixou um quiz %2$s + %1$s fixou o quiz \"%2$s\" %1$s fixou uma foto %1$s fixou um jogo %1$s fixou um placar de jogo @@ -1088,7 +1091,7 @@ às ontem às às %1$s - ontem às %1$s + ontem, %1$s online visto visto @@ -1116,7 +1119,6 @@ Você poderá adicionar mais usuários após finalizar a criação do grupo e convertê-lo em supergrupo. Digite o nome do grupo Nome do grupo - %1$d de %2$d selecionados até %1$s Desculpe, esse grupo já está lotado. Desculpe, parece que esse chat não existe. @@ -1168,6 +1170,9 @@ Convidar Bloquear usuário Bloquear usuário + Bloquear usuários + Deseja bloquear as mensagens e chamadas de **%1$s** no Telegram? + Deseja bloquear as mensagens e chamadas de **%1$s** no Telegram? Usuário bloqueado Usuário desbloqueado Editar contato @@ -1212,6 +1217,8 @@ Fotos e vídeos Links Arquivos de áudio + Enviar Mensagem + Denunciar Nome de Usuário Seu nome de usuário @@ -1675,6 +1682,10 @@ Recarregar Contatos Redefinir Chats Ler Todos os Chats + Ativar pausa na música ao gravar + Desativar pausa na música ao gravar + Ativar teclado suave + Desativar teclado suave Ativar câmera no app Desativar câmera no app Restaurar Contatos Importados @@ -1766,12 +1777,12 @@ Escanear Código QR Token inválido ou já expirado. Token de autenticação não encontrado - Autenticado com sucesso + Autenticação concluída https://desktop.telegram.org/ Baixe o Telegram em *desktop.telegram.org* no seu computador. Use o Telegram Desktop para obter o código QR. Escaneie o código QR para conectar à sua conta. - Esse código pode ser usado para permitir que alguém faça login em sua conta do Telegram.\n\nPara confirmar o login no Telegram, acesse Configurações > Dispositivos > Escanear Código QR e escaneie o código. + Esse código pode ser usado para permitir que alguém faça login em sua conta do Telegram.\n\nPara confirmar o login no Telegram, acesse Configurações > Dispositivos > Ler Código QR e escaneie o código. Banco de Dados Local Limpar base de dados local @@ -2049,11 +2060,13 @@ outubro novembro dezembro - ARQUIVOS - MÍDIA - LINKS - ÁUDIO - VOZ + Arquivos + Mídia + Mídia Compartilhada + Grupos + Links + Áudios + Mensagens de Voz Arquivos Compartilhados Conteúdo Compartilhado Links Compartilhados @@ -2111,6 +2124,10 @@ Escolha por quanto tempo as pessoas nesse chat irão ver a sua localização em tempo real. Ativar GPS Por favor, ative seu GPS para acessar as funções com base em localização. + Ficar Visível + Mostrar o Seu Perfil? + Pessoas próximas poderão ver seu perfil e te enviar mensagens. Isso pode ajudar a encontrar novos amigos, mas também pode chamar muita atenção. Você pode parar de compartilhar o seu perfil a qualquer momento.\n\nSeu número de telefone continuará oculto. + Parar de Me Mostrar Pessoas Próximas Adicionar Pessoas Próximas Adicione rapidamente pessoas próximas que estejam visualizando esta seção e descubra grupos locais.\n\nPor favor, ative o acesso à localização para ativar este recurso. @@ -2119,7 +2136,7 @@ Adicione rapidamente pessoas próximas que estejam visualizando esta seção e descubra grupos locais.\n\nPor favor, ative os serviços de localização para ativar este recurso. Ativar Grupos próximos - Peça ao seu amigo por perto para abrir esta página para trocar números de telefone. + Troque informações de contato com pessoas próximas e faça novos amigos. Buscando por pessoas nas proximidades... Criar um Grupo Local Iniciar Grupo @@ -2150,8 +2167,8 @@ Este vídeo não está otimizado para streaming. Talvez você precise baixá-lo para assistir. O app não conseguiu reproduzir o vídeo. Deseja abrir em um player externo? Sem buscas recentes - IMAGENS - GIFS + Imagens + GIFs Nenhum GIF recente BUSCAR IMAGENS BUSCA GLOBAL @@ -2281,9 +2298,9 @@ Uso de disco e de rede Uso de Armazenamento Uso de Dados - DADOS MÓVEIS - WI-FI - ROAMING + Móvel + Wi-Fi + Roaming Mensagens e outros dados Enviados Recebidos @@ -2565,14 +2582,14 @@ Tem certeza de que deseja apagar o histórico do chat **%1$s**? Apagar rascunhos da nuvem Deseja mesmo apagar todos os seus rascunhos da nuvem? - Compartilhar sua localização? + Compartilhar a Sua Localização? Isso irá enviar sua localização atual ao bot. O app não conseguiu determinar a sua localização atual. Escolher manualmente Esse bot gostaria de saber sua localização todas as vezes que você enviá-lo uma mensagem. Isso pode ser utilizado para providenciar resultados específicos de localização. Compartilhar seu número de telefone? O bot saberá seu número de telefone. Isso pode ser útil para a integração com outros serviços. - Tem certeza de que deseja compartilhar seu número de telefone %1$s com **%2$s**? + Deseja compartilhar o seu número de telefone %1$s com **%2$s**? Tem certeza de que deseja compartilhar seu número de telefone? Deseja mesmo bloquear **%1$s**? Tem certeza de que deseja desbloquear este contato? @@ -2849,6 +2866,12 @@ %1$d itens %1$d itens %1$d itens + + + + + + de %1$d chats de %1$d chat de %1$d chats @@ -3006,12 +3029,36 @@ %1$d arquivos %1$d arquivos %1$d arquivos + %1$d músicas + %1$d música + %1$d músicas + %1$d músicas + %1$d músicas + %1$d músicas + %1$d grupos em comum + %1$d grupo em comum + %1$d grupos em comum + %1$d grupos em comum + %1$d grupos em comum + %1$d grupos em comum %1$d media %1$d mídia %1$d media %1$d media %1$d media %1$d media + %1$d mensagens de voz + %1$d mensagem de voz + %1$d mensagens de voz + %1$d mensagens de voz + %1$d mensagens de voz + %1$d mensagens de voz + %1$d links + %1$d link + %1$d links + %1$d links + %1$d links + %1$d links %1$d usuários bloqueados %1$d usuário bloqueado %1$d usuários bloqueados @@ -3114,6 +3161,24 @@ %1$d de %2$d resultados %1$d de %2$d resultados %1$d de %2$d resultados + %1$d usuários + %1$d usuário + %1$d usuários + %1$d usuários + %1$d usuários + %1$d usuários + %1$d usuários + %1$d usuário + %1$d usuários + %1$d usuários + %1$d usuários + %1$d usuários + %1$d de %2$d selecionados + %1$d de %2$d selecionado + %1$d de %2$d selecionados + %1$d de %2$d selecionados + %1$d de %2$d selecionados + %1$d de %2$d selecionados Grupo Canal @@ -3217,7 +3282,7 @@ EEE HH:mm h:mm a - %1$s às %2$s + %1$s, %2$s d \'de\' MMM d \'de\' MMM \'de\' yyyy \'Enviar hoje às\' HH:mm diff --git a/TMessagesProj/src/main/res/values/strings.xml b/TMessagesProj/src/main/res/values/strings.xml index 192b3213e..9e1a102be 100644 --- a/TMessagesProj/src/main/res/values/strings.xml +++ b/TMessagesProj/src/main/res/values/strings.xml @@ -795,6 +795,7 @@ You left this group Delete this group Delete this chat + Delete chats SLIDE TO CANCEL Save to downloads Save to GIFs @@ -962,6 +963,8 @@ 1 result Video quality is too low to change compression settings. Hold the **word**, then move the cursor to select more text to copy. + Card number copied to clipboard + Copy %1$s set the self-destruct timer to %2$s You set the self-destruct timer to %1$s @@ -1116,7 +1119,6 @@ You will be able to add more users after you finish creating the group and convert it to a supergroup. Enter group name Group name - %1$d of %2$d selected up to %1$s Sorry, this group is already full. Sorry, this chat does not seem to exist. @@ -1168,6 +1170,9 @@ Invite Block user Block user + Block users + Do you want to block **%1$s** from messaging and calling you on Telegram? + Do you want to block **%1$s** from messaging and calling you on Telegram? User blocked User unblocked Edit contact @@ -1212,6 +1217,8 @@ Photos and videos Links Audio files + Send Message + Report Username Your Username @@ -1675,6 +1682,10 @@ Reload Contacts Reset Dialogs Read all Chats + Enable pause music on record + Disable pause music on record + Enable smooth keyboard + Disable smooth keyboard Enable in-app camera Disable in-app camera Reset Imported Contacts @@ -2049,11 +2060,13 @@ October November December - FILES - MEDIA - LINKS - AUDIO - VOICE + Files + Media + Shared Media + Groups + Links + Audio + Voice Messages Shared Files Shared Content Shared Links @@ -2111,15 +2124,19 @@ Choose for how long people in this chat will see your live location. Enable GPS Please enable your GPS to access location-based features. + Make Myself Visible + Show Your Profile? + Users nearby will be able to view your profile and send you messages. This may help you find new friends, but could also attract excessive attention. You can stop sharing your profile at any time.\n\nYour phone number will remain hidden. + Stop Showing Me People Nearby Add People Nearby - Quickly add people nearby who are viewing this section and discover local group chats. \n\nPlease switch on location access to enable this feature. + Quickly add people nearby who are viewing this section and discover local group chats.\n\nPlease switch on location access to enable this feature. People nearby Allow Access Quickly add people nearby who are also viewing this section and discover local group chats.\n\nPlease turn on location services to enable this feature. Turn On Groups nearby - Ask your friend nearby to open this page to exchange phone numbers. + Exchange contact info with people nearby and find new friends. Looking for users around you... Create a Local Group Start Group @@ -2150,8 +2167,8 @@ This video is not optimized for streaming. You may need to download it in full to play it. App was unable to play this video. Try to play it with external player? No recent searches - IMAGES - GIFS + Images + GIFs No recent GIFs FIND IMAGES WEB SEARCH @@ -2281,9 +2298,9 @@ Disk and network usage Storage Usage Data Usage - MOBILE - WI-FI - ROAMING + Mobile + Wi-Fi + Roaming Messages and other data Sent Received @@ -3170,12 +3187,36 @@ %1$d files %1$d files %1$d files + %1$d music files + %1$d music file + %1$d music files + %1$d music files + %1$d music files + %1$d music files + %1$d groups in common + %1$d group in common + %1$d groups in common + %1$d groups in common + %1$d groups in common + %1$d groups in common %1$d media %1$d media %1$d media %1$d media %1$d media %1$d media + %1$d voice messages + %1$d voice message + %1$d voice messages + %1$d voice messages + %1$d voice messages + %1$d voice messages + %1$d links + %1$d link + %1$d links + %1$d links + %1$d links + %1$d links %1$d blocked users %1$d blocked user %1$d blocked users @@ -3278,6 +3319,24 @@ %1$d of %2$d results %1$d of %2$d results %1$d of %2$d results + %1$d users + %1$d user + %1$d users + %1$d users + %1$d users + %1$d users + %1$d users + %1$d user + %1$d users + %1$d users + %1$d users + %1$d users + %1$d of %2$d selected + %1$d of %2$d selected + %1$d of %2$d selected + %1$d of %2$d selected + %1$d of %2$d selected + %1$d of %2$d selected Group Channel