update to 9.7.6 (3721)

This commit is contained in:
xaxtix 2023-08-05 11:32:46 +04:00
parent 6c1e8c1cf7
commit 0bcf4fe556
62 changed files with 1594 additions and 667 deletions

View file

@ -368,22 +368,25 @@ import com.google.common.collect.ImmutableList;
newPeriodInfo.copyWithRequestedContentPositionUs( newPeriodInfo.copyWithRequestedContentPositionUs(
oldPeriodInfo.requestedContentPositionUs); oldPeriodInfo.requestedContentPositionUs);
if (!areDurationsCompatible(oldPeriodInfo.durationUs, newPeriodInfo.durationUs)) { //@xaxtix
// The period duration changed. Remove all subsequent periods and check whether we read //comment cause lead to infinit seek loop in end of video
// beyond the new duration.
periodHolder.updateClipping(); // if (!areDurationsCompatible(oldPeriodInfo.durationUs, newPeriodInfo.durationUs)) {
long newDurationInRendererTime = // // The period duration changed. Remove all subsequent periods and check whether we read
newPeriodInfo.durationUs == C.TIME_UNSET // // beyond the new duration.
? Long.MAX_VALUE // periodHolder.updateClipping();
: periodHolder.toRendererTime(newPeriodInfo.durationUs); // long newDurationInRendererTime =
boolean isReadingAndReadBeyondNewDuration = // newPeriodInfo.durationUs == C.TIME_UNSET
periodHolder == reading // ? Long.MAX_VALUE
&& !periodHolder.info.isFollowedByTransitionToSameStream // : periodHolder.toRendererTime(newPeriodInfo.durationUs);
&& (maxRendererReadPositionUs == C.TIME_END_OF_SOURCE // boolean isReadingAndReadBeyondNewDuration =
|| maxRendererReadPositionUs >= newDurationInRendererTime); // periodHolder == reading
boolean readingPeriodRemoved = removeAfter(periodHolder); // && !periodHolder.info.isFollowedByTransitionToSameStream
return !readingPeriodRemoved && !isReadingAndReadBeyondNewDuration; // && (maxRendererReadPositionUs == C.TIME_END_OF_SOURCE
} // || maxRendererReadPositionUs >= newDurationInRendererTime);
// boolean readingPeriodRemoved = removeAfter(periodHolder);
// return !readingPeriodRemoved && !isReadingAndReadBeyondNewDuration;
// }
previousPeriodHolder = periodHolder; previousPeriodHolder = periodHolder;
periodHolder = periodHolder.getNext(); periodHolder = periodHolder.getNext();

View file

@ -97,19 +97,19 @@ public final class DefaultMediaCodecAdapterFactory implements MediaCodecAdapter.
@Override @Override
public MediaCodecAdapter createAdapter(MediaCodecAdapter.Configuration configuration) public MediaCodecAdapter createAdapter(MediaCodecAdapter.Configuration configuration)
throws IOException { throws IOException {
// if (Util.SDK_INT >= 23 if (Util.SDK_INT >= 23
// && (asynchronousMode == MODE_ENABLED && (asynchronousMode == MODE_ENABLED
// || (asynchronousMode == MODE_DEFAULT && Util.SDK_INT >= 31))) { || (asynchronousMode == MODE_DEFAULT && Util.SDK_INT >= 31))) {
// int trackType = MimeTypes.getTrackType(configuration.format.sampleMimeType); int trackType = MimeTypes.getTrackType(configuration.format.sampleMimeType);
// Log.i( Log.i(
// TAG, TAG,
// "Creating an asynchronous MediaCodec adapter for track type " "Creating an asynchronous MediaCodec adapter for track type "
// + Util.getTrackTypeString(trackType)); + Util.getTrackTypeString(trackType));
// AsynchronousMediaCodecAdapter.Factory factory = AsynchronousMediaCodecAdapter.Factory factory =
// new AsynchronousMediaCodecAdapter.Factory( new AsynchronousMediaCodecAdapter.Factory(
// trackType, enableSynchronizeCodecInteractionsWithQueueing); trackType, enableSynchronizeCodecInteractionsWithQueueing);
// return factory.createAdapter(configuration); return factory.createAdapter(configuration);
// } }
return new SynchronousMediaCodecAdapter.Factory().createAdapter(configuration); return new SynchronousMediaCodecAdapter.Factory().createAdapter(configuration);
} }
} }

View file

@ -174,6 +174,7 @@ import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.RandomAccessFile; import java.io.RandomAccessFile;
import java.lang.ref.WeakReference;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.net.IDN; import java.net.IDN;
@ -247,9 +248,6 @@ public class AndroidUtilities {
private static int adjustOwnerClassGuid = 0; private static int adjustOwnerClassGuid = 0;
private static int altFocusableClassGuid = 0; private static int altFocusableClassGuid = 0;
private static Paint roundPaint;
private static RectF bitmapRect;
public static final RectF rectTmp = new RectF(); public static final RectF rectTmp = new RectF();
public static final Rect rectTmp2 = new Rect(); public static final Rect rectTmp2 = new Rect();
@ -513,9 +511,17 @@ public class AndroidUtilities {
return; return;
} }
if (bitmapToRecycle != null && !bitmapToRecycle.isEmpty()) { if (bitmapToRecycle != null && !bitmapToRecycle.isEmpty()) {
ArrayList<WeakReference<Bitmap>> bitmapsToRecycleRef = new ArrayList<>();
for (int i = 0; i < bitmapToRecycle.size(); i++) {
Bitmap bitmap = bitmapToRecycle.get(i);
if (bitmap != null && !bitmap.isRecycled()) {
bitmapsToRecycleRef.add(new WeakReference<>(bitmap));
}
}
AndroidUtilities.runOnUIThread(() -> Utilities.globalQueue.postRunnable(() -> { AndroidUtilities.runOnUIThread(() -> Utilities.globalQueue.postRunnable(() -> {
for (int i = 0; i < bitmapToRecycle.size(); i++) { for (int i = 0; i < bitmapsToRecycleRef.size(); i++) {
Bitmap bitmap = bitmapToRecycle.get(i); Bitmap bitmap = bitmapsToRecycleRef.get(i).get();
bitmapsToRecycleRef.get(i).clear();
if (bitmap != null && !bitmap.isRecycled()) { if (bitmap != null && !bitmap.isRecycled()) {
try { try {
bitmap.recycle(); bitmap.recycle();
@ -3202,10 +3208,10 @@ public class AndroidUtilities {
} }
public static String formatFileSize(long size) { public static String formatFileSize(long size) {
return formatFileSize(size, false); return formatFileSize(size, false, false);
} }
public static String formatFileSize(long size, boolean removeZero) { public static String formatFileSize(long size, boolean removeZero, boolean makeShort) {
if (size == 0) { if (size == 0) {
return String.format("%d KB", 0); return String.format("%d KB", 0);
} else if (size < 1024) { } else if (size < 1024) {
@ -3228,6 +3234,8 @@ public class AndroidUtilities {
float value = (int) (size / 1024L / 1024L) / 1000.0f; float value = (int) (size / 1024L / 1024L) / 1000.0f;
if (removeZero && (value - (int) value) * 10 == 0) { if (removeZero && (value - (int) value) * 10 == 0) {
return String.format("%d GB", (int) value); return String.format("%d GB", (int) value);
} else if (makeShort) {
return String.format("%.1f GB", value);
} else { } else {
return String.format("%.2f GB", value); return String.format("%.2f GB", value);
} }
@ -5370,10 +5378,12 @@ public class AndroidUtilities {
System.gc(); System.gc();
clone = ByteBuffer.allocate(original.capacity()); clone = ByteBuffer.allocate(original.capacity());
} }
int position = original.position();
original.rewind(); original.rewind();
clone.put(original); clone.put(original);
original.rewind(); original.rewind();
clone.flip(); clone.flip();
clone.position(position);
return clone; return clone;
} }
} }

View file

@ -24,8 +24,8 @@ public class BuildVars {
public static boolean USE_CLOUD_STRINGS = true; public static boolean USE_CLOUD_STRINGS = true;
public static boolean CHECK_UPDATES = true; public static boolean CHECK_UPDATES = true;
public static boolean NO_SCOPED_STORAGE = Build.VERSION.SDK_INT <= 29; public static boolean NO_SCOPED_STORAGE = Build.VERSION.SDK_INT <= 29;
public static int BUILD_VERSION = 3712; public static int BUILD_VERSION = 3721;
public static String BUILD_VERSION_STRING = "9.7.4"; public static String BUILD_VERSION_STRING = "9.7.6";
public static int APP_ID = 4; public static int APP_ID = 4;
public static String APP_HASH = "014b35b6184100b085b0d0572f9b5103"; public static String APP_HASH = "014b35b6184100b085b0d0572f9b5103";

View file

@ -0,0 +1,32 @@
package org.telegram.messenger;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
public class ChatMessageSharedResources {
public Context context;
public Drawable chat_msgAvatarLiveLocationDrawable;
public Drawable chat_redLocationIcon;
public ChatMessageSharedResources(Context context) {
this.context = context;
}
public Drawable getRedLocationIcon() {
if (chat_redLocationIcon == null) {
Resources resources = context.getResources();
chat_redLocationIcon = resources.getDrawable(R.drawable.map_pin).mutate();
}
return chat_redLocationIcon;
}
public Drawable getAvatarLiveLocation() {
if (chat_msgAvatarLiveLocationDrawable == null) {
Resources resources = context.getResources();
chat_msgAvatarLiveLocationDrawable = resources.getDrawable(R.drawable.livepin).mutate();
}
return chat_msgAvatarLiveLocationDrawable;
}
}

View file

@ -25,7 +25,7 @@ public class DispatchQueue extends Thread {
private long lastTaskTime; private long lastTaskTime;
private static int indexPointer = 0; private static int indexPointer = 0;
public final int index = indexPointer++; public final int index = indexPointer++;
private int priority = THREAD_PRIORITY_DEFAULT; private int threadPriority = THREAD_PRIORITY_DEFAULT;
public DispatchQueue(final String threadName) { public DispatchQueue(final String threadName) {
this(threadName, true); this(threadName, true);
@ -39,7 +39,7 @@ public class DispatchQueue extends Thread {
} }
public DispatchQueue(final String threadName, boolean start, int priority) { public DispatchQueue(final String threadName, boolean start, int priority) {
this.priority = priority; this.threadPriority = priority;
setName(threadName); setName(threadName);
if (start) { if (start) {
start(); start();
@ -126,8 +126,8 @@ public class DispatchQueue extends Thread {
return true; return true;
}); });
syncLatch.countDown(); syncLatch.countDown();
if (priority != THREAD_PRIORITY_DEFAULT) { if (threadPriority != THREAD_PRIORITY_DEFAULT) {
Process.setThreadPriority(priority); Process.setThreadPriority(threadPriority);
} }
Looper.loop(); Looper.loop();
} }

View file

@ -708,7 +708,12 @@ public class FileLoadOperation {
final CountDownLatch countDownLatch = new CountDownLatch(1); final CountDownLatch countDownLatch = new CountDownLatch(1);
final long[] result = new long[2]; final long[] result = new long[2];
Utilities.stageQueue.postRunnable(() -> { Utilities.stageQueue.postRunnable(() -> {
result[0] = getDownloadedLengthFromOffsetInternal(notLoadedBytesRanges, offset, length); try {
result[0] = getDownloadedLengthFromOffsetInternal(notLoadedBytesRanges, offset, length);
} catch (Throwable e) {
FileLog.e(e);
result[0] = 0;
}
if (state == stateFinished) { if (state == stateFinished) {
result[1] = 1; result[1] = 1;
} }

View file

@ -165,6 +165,7 @@ public class FileLog {
privateFields.add("networkType"); privateFields.add("networkType");
privateFields.add("disableFree"); privateFields.add("disableFree");
privateFields.add("mContext"); privateFields.add("mContext");
privateFields.add("priority");
//exclude file loading //exclude file loading
excludeRequests = new HashSet<>(); excludeRequests = new HashSet<>();
@ -183,7 +184,7 @@ public class FileLog {
@Override @Override
public boolean shouldSkipClass(Class<?> clazz) { public boolean shouldSkipClass(Class<?> clazz) {
return clazz.isInstance(AnimatedFileDrawable.class) || clazz.isInstance(ColorStateList.class) || clazz.isInstance(Context.class); return clazz.isInstance(DispatchQueue.class) || clazz.isInstance(AnimatedFileDrawable.class) || clazz.isInstance(ColorStateList.class) || clazz.isInstance(Context.class);
} }
}; };
gson = new GsonBuilder().addSerializationExclusionStrategy(strategy).registerTypeAdapterFactory(RuntimeClassNameTypeAdapterFactory.of(TLObject.class, "type_", strategy)).create(); gson = new GsonBuilder().addSerializationExclusionStrategy(strategy).registerTypeAdapterFactory(RuntimeClassNameTypeAdapterFactory.of(TLObject.class, "type_", strategy)).create();

View file

@ -71,6 +71,7 @@ public class FileStreamLoadOperation extends BaseDataSource implements FileLoadO
@Override @Override
public long open(DataSpec dataSpec) throws IOException { public long open(DataSpec dataSpec) throws IOException {
uri = dataSpec.uri; uri = dataSpec.uri;
transferInitializing(dataSpec);
currentAccount = Utilities.parseInt(uri.getQueryParameter("account")); currentAccount = Utilities.parseInt(uri.getQueryParameter("account"));
parentObject = FileLoader.getInstance(currentAccount).getParentObject(Utilities.parseInt(uri.getQueryParameter("rid"))); parentObject = FileLoader.getInstance(currentAccount).getParentObject(Utilities.parseInt(uri.getQueryParameter("rid")));
document = new TLRPC.TL_document(); document = new TLRPC.TL_document();
@ -124,6 +125,7 @@ public class FileStreamLoadOperation extends BaseDataSource implements FileLoadO
return C.RESULT_END_OF_INPUT; return C.RESULT_END_OF_INPUT;
} else { } else {
int availableLength = 0; int availableLength = 0;
int bytesRead;
try { try {
if (bytesRemaining < readLength) { if (bytesRemaining < readLength) {
readLength = (int) bytesRemaining; readLength = (int) bytesRemaining;
@ -165,14 +167,16 @@ public class FileStreamLoadOperation extends BaseDataSource implements FileLoadO
if (!opened) { if (!opened) {
return 0; return 0;
} }
file.readFully(buffer, offset, availableLength); bytesRead = file.read(buffer, offset, availableLength);
currentOffset += availableLength; if (bytesRead > 0) {
bytesRemaining -= availableLength; currentOffset += bytesRead;
bytesTransferred(availableLength); bytesRemaining -= bytesRead;
bytesTransferred(bytesRead);
}
} catch (Exception e) { } catch (Exception e) {
throw new IOException(e); throw new IOException(e);
} }
return availableLength; return bytesRead;
} }
} }

View file

@ -52,7 +52,6 @@ import org.telegram.ui.Components.BackgroundGradientDrawable;
import org.telegram.ui.Components.MotionBackgroundDrawable; import org.telegram.ui.Components.MotionBackgroundDrawable;
import org.telegram.ui.Components.Point; import org.telegram.ui.Components.Point;
import org.telegram.ui.Components.RLottieDrawable; import org.telegram.ui.Components.RLottieDrawable;
import org.telegram.ui.Components.Reactions.HwEmojis;
import org.telegram.ui.Components.SlotsDrawable; import org.telegram.ui.Components.SlotsDrawable;
import org.telegram.ui.Components.ThemePreviewDrawable; import org.telegram.ui.Components.ThemePreviewDrawable;
@ -103,6 +102,8 @@ import java.util.zip.GZIPInputStream;
*/ */
public class ImageLoader { public class ImageLoader {
private static final boolean DEBUG_MODE = false;
private HashMap<String, Integer> bitmapUseCounts = new HashMap<>(); private HashMap<String, Integer> bitmapUseCounts = new HashMap<>();
private LruCache<BitmapDrawable> smallImagesMemCache; private LruCache<BitmapDrawable> smallImagesMemCache;
private LruCache<BitmapDrawable> memCache; private LruCache<BitmapDrawable> memCache;
@ -1822,7 +1823,9 @@ public class ImageLoader {
data[164] = photoBytes[1]; data[164] = photoBytes[1];
data[166] = photoBytes[2]; data[166] = photoBytes[2];
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, len); BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = SharedConfig.deviceIsHigh() ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, len, options);
if (bitmap != null && !TextUtils.isEmpty(filter) && filter.contains("b")) { if (bitmap != null && !TextUtils.isEmpty(filter) && filter.contains("b")) {
Utilities.blurBitmap(bitmap, 3, 1, bitmap.getWidth(), bitmap.getHeight(), bitmap.getRowBytes()); Utilities.blurBitmap(bitmap, 3, 1, bitmap.getWidth(), bitmap.getHeight(), bitmap.getRowBytes());
} }
@ -2060,15 +2063,15 @@ public class ImageLoader {
} else { } else {
maxSize = 15; maxSize = 15;
} }
int cacheSize = Math.min(maxSize, memoryClass / 7) * 1024 * 1024; int cacheSize = DEBUG_MODE ? 1 : Math.min(maxSize, memoryClass / 7) * 1024 * 1024;
int commonCacheSize = (int) (cacheSize * 0.8f); int commonCacheSize = DEBUG_MODE ? 1 : (int) (cacheSize * 0.8f);
int smallImagesCacheSize = (int) (cacheSize * 0.2f); int smallImagesCacheSize = DEBUG_MODE ? 1 : (int) (cacheSize * 0.2f);
memCache = new LruCache<BitmapDrawable>(commonCacheSize) { memCache = new LruCache<BitmapDrawable>(commonCacheSize) {
@Override @Override
protected int sizeOf(String key, BitmapDrawable value) { protected int sizeOf(String key, BitmapDrawable value) {
return value.getBitmap().getByteCount(); return sizeOfBitmapDrawable(value);
} }
@Override @Override
@ -2090,7 +2093,7 @@ public class ImageLoader {
smallImagesMemCache = new LruCache<BitmapDrawable>(smallImagesCacheSize) { smallImagesMemCache = new LruCache<BitmapDrawable>(smallImagesCacheSize) {
@Override @Override
protected int sizeOf(String key, BitmapDrawable value) { protected int sizeOf(String key, BitmapDrawable value) {
return value.getBitmap().getByteCount(); return sizeOfBitmapDrawable(value);
} }
@Override @Override
@ -2109,18 +2112,18 @@ public class ImageLoader {
} }
} }
}; };
wallpaperMemCache = new LruCache<BitmapDrawable>(cacheSize / 4) { wallpaperMemCache = new LruCache<BitmapDrawable>(DEBUG_MODE ? 1 : cacheSize / 4) {
@Override @Override
protected int sizeOf(String key, BitmapDrawable value) { protected int sizeOf(String key, BitmapDrawable value) {
return value.getBitmap().getByteCount(); return sizeOfBitmapDrawable(value);
} }
}; };
lottieMemCache = new LruCache<BitmapDrawable>(512 * 512 * 2 * 4 * 5) { lottieMemCache = new LruCache<BitmapDrawable>(DEBUG_MODE ? 1 : 512 * 512 * 2 * 4 * 5) {
@Override @Override
protected int sizeOf(String key, BitmapDrawable value) { protected int sizeOf(String key, BitmapDrawable value) {
return value.getIntrinsicWidth() * value.getIntrinsicHeight() * 4 * 2; return sizeOfBitmapDrawable(value);
} }
@Override @Override
@ -2327,6 +2330,18 @@ public class ImageLoader {
checkMediaPaths(); checkMediaPaths();
} }
private int sizeOfBitmapDrawable(BitmapDrawable value) {
if (value instanceof AnimatedFileDrawable) {
AnimatedFileDrawable animatedFileDrawable = (AnimatedFileDrawable) value;
int maxSize = animatedFileDrawable.getRenderingHeight() * animatedFileDrawable.getRenderingWidth() * 4 * 3;
maxSize = Math.max(animatedFileDrawable.getIntrinsicHeight() * value.getIntrinsicWidth() * 4 * 3, maxSize);
return maxSize;
} if (value instanceof RLottieDrawable) {
return value.getIntrinsicWidth() * value.getIntrinsicHeight() * 4 * 2;
}
return value.getBitmap().getByteCount();
}
public void checkMediaPaths() { public void checkMediaPaths() {
checkMediaPaths(null); checkMediaPaths(null);
} }

View file

@ -12,6 +12,7 @@ import android.graphics.Bitmap;
import android.graphics.BitmapShader; import android.graphics.BitmapShader;
import android.graphics.BlendMode; import android.graphics.BlendMode;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter; import android.graphics.ColorFilter;
import android.graphics.ComposeShader; import android.graphics.ComposeShader;
import android.graphics.Matrix; import android.graphics.Matrix;
@ -49,13 +50,15 @@ import java.util.List;
public class ImageReceiver implements NotificationCenter.NotificationCenterDelegate { public class ImageReceiver implements NotificationCenter.NotificationCenterDelegate {
List<ImageReceiver> preloadReceivers; List<ImageReceiver> preloadReceivers;
private boolean allowCrossfadeWithImage = true;
public boolean updateThumbShaderMatrix() { public boolean updateThumbShaderMatrix() {
if (currentThumbDrawable != null && thumbShader != null) { if (currentThumbDrawable != null && thumbShader != null) {
drawDrawable(null, currentThumbDrawable, 255, thumbShader, 0, 0, 0, null); drawDrawable(null, currentThumbDrawable, 255, thumbShader, 0, 0, 0, null);
return true; return true;
} }
if (staticThumbDrawable != null && thumbShader != null) { if (staticThumbDrawable != null && staticThumbShader != null) {
drawDrawable(null, staticThumbDrawable, 255, thumbShader, 0, 0, 0, null); drawDrawable(null, staticThumbDrawable, 255, staticThumbShader, 0, 0, 0, null);
return true; return true;
} }
return false; return false;
@ -239,6 +242,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
private int thumbTag; private int thumbTag;
private Drawable currentThumbDrawable; private Drawable currentThumbDrawable;
public BitmapShader thumbShader; public BitmapShader thumbShader;
public BitmapShader staticThumbShader;
private int thumbOrientation, thumbInvert; private int thumbOrientation, thumbInvert;
private ImageLocation currentMediaLocation; private ImageLocation currentMediaLocation;
@ -284,21 +288,20 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
private float imageX, imageY, imageW, imageH; private float imageX, imageY, imageW, imageH;
private float sideClip; private float sideClip;
private RectF drawRegion = new RectF(); private final RectF drawRegion = new RectF();
private boolean isVisible = true; private boolean isVisible = true;
private boolean isAspectFit; private boolean isAspectFit;
private boolean forcePreview; private boolean forcePreview;
private boolean forceCrossfade; private boolean forceCrossfade;
private int[] roundRadius = new int[4]; private final int[] roundRadius = new int[4];
private boolean isRoundRect = true; private boolean isRoundRect = true;
private Object mark; private Object mark;
private Paint roundPaint; private Paint roundPaint;
private RectF roundRect = new RectF(); private final RectF roundRect = new RectF();
private RectF bitmapRect = new RectF(); private final Matrix shaderMatrix = new Matrix();
private Matrix shaderMatrix = new Matrix(); private final Path roundPath = new Path();
private Path roundPath = new Path(); private static final float[] radii = new float[8];
private static float[] radii = new float[8];
private float overrideAlpha = 1.0f; private float overrideAlpha = 1.0f;
private int isPressed; private int isPressed;
private boolean centerRotation; private boolean centerRotation;
@ -661,7 +664,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
recycleBitmap(thumbKey, TYPE_THUMB); recycleBitmap(thumbKey, TYPE_THUMB);
recycleBitmap(null, TYPE_CROSSFDADE); recycleBitmap(null, TYPE_CROSSFDADE);
recycleBitmap(mediaKey, TYPE_MEDIA); recycleBitmap(mediaKey, TYPE_MEDIA);
crossfadeShader = thumbShader; crossfadeShader = staticThumbShader;
crossfadeImage = staticThumbDrawable; crossfadeImage = staticThumbDrawable;
crossfadingWithThumb = false; crossfadingWithThumb = false;
crossfadeKey = null; crossfadeKey = null;
@ -700,6 +703,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
imageShader = null; imageShader = null;
composeShader = null; composeShader = null;
thumbShader = null; thumbShader = null;
staticThumbShader = null;
mediaShader = null; mediaShader = null;
legacyShader = null; legacyShader = null;
legacyCanvas = null; legacyCanvas = null;
@ -819,7 +823,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
recycleBitmap(null, TYPE_THUMB); recycleBitmap(null, TYPE_THUMB);
recycleBitmap(null, TYPE_CROSSFDADE); recycleBitmap(null, TYPE_CROSSFDADE);
recycleBitmap(null, TYPE_MEDIA); recycleBitmap(null, TYPE_MEDIA);
crossfadeShader = thumbShader; crossfadeShader = staticThumbShader;
crossfadeImage = staticThumbDrawable; crossfadeImage = staticThumbDrawable;
crossfadingWithThumb = true; crossfadingWithThumb = true;
crossfadeKey = null; crossfadeKey = null;
@ -863,6 +867,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
} }
fileDrawable.setAllowDecodeSingleFrame(true); fileDrawable.setAllowDecodeSingleFrame(true);
} }
staticThumbShader = null;
thumbShader = null; thumbShader = null;
roundPaint.setShader(null); roundPaint.setShader(null);
setStaticDrawable(bitmap); setStaticDrawable(bitmap);
@ -937,8 +942,10 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
} }
private void setDrawableShader(Drawable drawable, BitmapShader shader) { private void setDrawableShader(Drawable drawable, BitmapShader shader) {
if (drawable == currentThumbDrawable || drawable == staticThumbDrawable) { if (drawable == currentThumbDrawable) {
thumbShader = shader; thumbShader = shader;
} else if (drawable == staticThumbDrawable) {
staticThumbShader = shader;
} else if (drawable == currentMediaDrawable) { } else if (drawable == currentMediaDrawable) {
mediaShader = shader; mediaShader = shader;
} else if (drawable == currentImageDrawable) { } else if (drawable == currentImageDrawable) {
@ -1040,10 +1047,10 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
if (staticThumbDrawable != null) { if (staticThumbDrawable != null) {
setStaticDrawable(null); setStaticDrawable(null);
thumbShader = null; staticThumbShader = null;
roundPaint.setShader(null);
} }
clearImage(); clearImage();
roundPaint.setShader(null);
if (isPressed == 0) { if (isPressed == 0) {
pressedProgress = 0f; pressedProgress = 0f;
} }
@ -1768,23 +1775,6 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
// lottieDrawable.updateCurrentFrame(); // lottieDrawable.updateCurrentFrame();
// } // }
} }
protected boolean customDraw(
Canvas canvas,
AnimatedFileDrawable animation,
RLottieDrawable lottieAnimation,
Drawable currentMediaDrawable, BitmapShader currentMediaShader,
Drawable currentImageDrawable, BitmapShader currentImageShader,
Drawable currentThumbDrawable, BitmapShader currentThumbShader,
boolean crossfadeWithOldImage, boolean crossfadingWithThumb,
Drawable crossfadeImage, BitmapShader crossfadeShader,
Drawable staticThumbDrawable,
float currentAlpha, float previousAlpha, float overrideAlpha,
int[] roundRadius,
BackgroundThreadDrawHolder backgroundThreadDrawHolder
) {
return false;
}
public boolean draw(Canvas canvas) { public boolean draw(Canvas canvas) {
return draw(canvas, null); return draw(canvas, null);
@ -1807,6 +1797,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
BitmapShader imageShader; BitmapShader imageShader;
Drawable currentThumbDrawable; Drawable currentThumbDrawable;
BitmapShader thumbShader; BitmapShader thumbShader;
BitmapShader staticThumbShader;
boolean crossfadeWithOldImage; boolean crossfadeWithOldImage;
boolean crossfadingWithThumb; boolean crossfadingWithThumb;
@ -1830,6 +1821,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
currentImageDrawable = backgroundThreadDrawHolder.imageDrawable; currentImageDrawable = backgroundThreadDrawHolder.imageDrawable;
imageShader = backgroundThreadDrawHolder.imageShader; imageShader = backgroundThreadDrawHolder.imageShader;
thumbShader = backgroundThreadDrawHolder.thumbShader; thumbShader = backgroundThreadDrawHolder.thumbShader;
staticThumbShader = backgroundThreadDrawHolder.staticThumbShader;
crossfadeImage = backgroundThreadDrawHolder.crossfadeImage; crossfadeImage = backgroundThreadDrawHolder.crossfadeImage;
crossfadeWithOldImage = backgroundThreadDrawHolder.crossfadeWithOldImage; crossfadeWithOldImage = backgroundThreadDrawHolder.crossfadeWithOldImage;
crossfadingWithThumb = backgroundThreadDrawHolder.crossfadingWithThumb; crossfadingWithThumb = backgroundThreadDrawHolder.crossfadingWithThumb;
@ -1851,6 +1843,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
imageShader = this.imageShader; imageShader = this.imageShader;
currentThumbDrawable = this.currentThumbDrawable; currentThumbDrawable = this.currentThumbDrawable;
thumbShader = this.thumbShader; thumbShader = this.thumbShader;
staticThumbShader = this.staticThumbShader;
crossfadeWithOldImage = this.crossfadeWithOldImage; crossfadeWithOldImage = this.crossfadeWithOldImage;
crossfadingWithThumb = this.crossfadingWithThumb; crossfadingWithThumb = this.crossfadingWithThumb;
crossfadeImage = this.crossfadeImage; crossfadeImage = this.crossfadeImage;
@ -1862,21 +1855,6 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
animationNotReady = animation != null && !animation.hasBitmap() || lottieDrawable != null && !lottieDrawable.hasBitmap(); animationNotReady = animation != null && !animation.hasBitmap() || lottieDrawable != null && !lottieDrawable.hasBitmap();
colorFilter = this.colorFilter; colorFilter = this.colorFilter;
} }
if (customDraw(
canvas,
animation, lottieDrawable,
currentMediaDrawable, mediaShader,
currentImageDrawable, imageShader,
currentThumbDrawable, thumbShader,
crossfadeWithOldImage, crossfadingWithThumb,
crossfadeImage, crossfadeShader,
staticThumbDrawable,
currentAlpha, previousAlpha, overrideAlpha,
roundRadius, backgroundThreadDrawHolder
)) {
return true;
}
if (animation != null) { if (animation != null) {
animation.setRoundRadius(roundRadius); animation.setRoundRadius(roundRadius);
@ -1908,20 +1886,20 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
shaderToUse = crossfadeShader; shaderToUse = crossfadeShader;
orientation = imageOrientation; orientation = imageOrientation;
invert = imageInvert; invert = imageInvert;
} else if (staticThumbDrawable instanceof BitmapDrawable) {
drawable = staticThumbDrawable;
if (useRoundForThumb && thumbShader == null) {
updateDrawableRadius(staticThumbDrawable);
thumbShader = this.thumbShader;
}
shaderToUse = thumbShader;
orientation = thumbOrientation;
invert = thumbInvert;
} else if (currentThumbDrawable != null) { } else if (currentThumbDrawable != null) {
drawable = currentThumbDrawable; drawable = currentThumbDrawable;
shaderToUse = thumbShader; shaderToUse = thumbShader;
orientation = thumbOrientation; orientation = thumbOrientation;
invert = thumbInvert; invert = thumbInvert;
} else if (staticThumbDrawable instanceof BitmapDrawable) {
drawable = staticThumbDrawable;
if (useRoundForThumb && staticThumbShader == null) {
updateDrawableRadius(staticThumbDrawable);
staticThumbShader = this.staticThumbShader;
}
shaderToUse = staticThumbShader;
orientation = thumbOrientation;
invert = thumbInvert;
} }
float crossfadeProgress = currentAlpha; float crossfadeProgress = currentAlpha;
@ -1932,17 +1910,17 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
if (drawable != null) { if (drawable != null) {
if (crossfadeAlpha != 0) { if (crossfadeAlpha != 0) {
if (previousAlpha != 1f && (drawable == currentImageDrawable || drawable == currentMediaDrawable) && staticThumbDrawable != null) { if (previousAlpha != 1f && (drawable == currentImageDrawable || drawable == currentMediaDrawable) && staticThumbDrawable != null) {
if (useRoundForThumb && thumbShader == null) { if (useRoundForThumb && staticThumbShader == null) {
updateDrawableRadius(staticThumbDrawable); updateDrawableRadius(staticThumbDrawable);
thumbShader = this.thumbShader; staticThumbShader = this.staticThumbShader;
} }
drawDrawable(canvas, staticThumbDrawable, (int) (overrideAlpha * 255), thumbShader, orientation, invert, backgroundThreadDrawHolder); drawDrawable(canvas, staticThumbDrawable, (int) (overrideAlpha * 255), staticThumbShader, orientation, invert, backgroundThreadDrawHolder);
} }
if (crossfadeWithThumb && animationNotReady) { if (crossfadeWithThumb && animationNotReady) {
drawDrawable(canvas, drawable, (int) (overrideAlpha * 255), shaderToUse, orientation, invert, backgroundThreadDrawHolder); drawDrawable(canvas, drawable, (int) (overrideAlpha * 255), shaderToUse, orientation, invert, backgroundThreadDrawHolder);
} else { } else {
Drawable thumbDrawable = null;
if (crossfadeWithThumb && currentAlpha != 1.0f) { if (crossfadeWithThumb && currentAlpha != 1.0f) {
Drawable thumbDrawable = null;
BitmapShader thumbShaderToUse = null; BitmapShader thumbShaderToUse = null;
if (drawable == currentImageDrawable || drawable == currentMediaDrawable) { if (drawable == currentImageDrawable || drawable == currentMediaDrawable) {
if (crossfadeImage != null) { if (crossfadeImage != null) {
@ -1953,20 +1931,20 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
thumbShaderToUse = thumbShader; thumbShaderToUse = thumbShader;
} else if (staticThumbDrawable != null) { } else if (staticThumbDrawable != null) {
thumbDrawable = staticThumbDrawable; thumbDrawable = staticThumbDrawable;
if (useRoundForThumb && thumbShader == null) { if (useRoundForThumb && staticThumbShader == null) {
updateDrawableRadius(staticThumbDrawable); updateDrawableRadius(staticThumbDrawable);
thumbShader = this.thumbShader; staticThumbShader = this.staticThumbShader;
} }
thumbShaderToUse = thumbShader; thumbShaderToUse = staticThumbShader;
} }
} else if (drawable == currentThumbDrawable || drawable == crossfadeImage) { } else if (drawable == currentThumbDrawable || drawable == crossfadeImage) {
if (staticThumbDrawable != null) { if (staticThumbDrawable != null) {
thumbDrawable = staticThumbDrawable; thumbDrawable = staticThumbDrawable;
if (useRoundForThumb && thumbShader == null) { if (useRoundForThumb && staticThumbShader == null) {
updateDrawableRadius(staticThumbDrawable); updateDrawableRadius(staticThumbDrawable);
thumbShader = this.thumbShader; staticThumbShader = this.staticThumbShader;
} }
thumbShaderToUse = thumbShader; thumbShaderToUse = staticThumbShader;
} }
} else if (drawable == staticThumbDrawable) { } else if (drawable == staticThumbDrawable) {
if (crossfadeImage != null) { if (crossfadeImage != null) {
@ -3019,6 +2997,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
currentThumbKey = null; currentThumbKey = null;
currentThumbDrawable = null; currentThumbDrawable = null;
thumbShader = null; thumbShader = null;
staticThumbShader = null;
roundPaint.setShader(null); roundPaint.setShader(null);
setStaticDrawable(thumb); setStaticDrawable(thumb);
crossfadeWithThumb = true; crossfadeWithThumb = true;
@ -3123,6 +3102,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
holder.imageShader = imageShader; holder.imageShader = imageShader;
holder.thumbDrawable = currentThumbDrawable; holder.thumbDrawable = currentThumbDrawable;
holder.thumbShader = thumbShader; holder.thumbShader = thumbShader;
holder.staticThumbShader = staticThumbShader;
holder.staticThumbDrawable = staticThumbDrawable; holder.staticThumbDrawable = staticThumbDrawable;
holder.crossfadeImage = crossfadeImage; holder.crossfadeImage = crossfadeImage;
holder.colorFilter = colorFilter; holder.colorFilter = colorFilter;
@ -3145,6 +3125,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
public float overrideAlpha; public float overrideAlpha;
public long time; public long time;
public int threadIndex; public int threadIndex;
public BitmapShader staticThumbShader;
private AnimatedFileDrawable animation; private AnimatedFileDrawable animation;
private RLottieDrawable lottieDrawable; private RLottieDrawable lottieDrawable;
private int[] roundRadius = new int[4]; private int[] roundRadius = new int[4];
@ -3179,6 +3160,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
imageShader = null; imageShader = null;
thumbDrawable = null; thumbDrawable = null;
thumbShader = null; thumbShader = null;
staticThumbShader = null;
staticThumbDrawable = null; staticThumbDrawable = null;
crossfadeImage = null; crossfadeImage = null;
colorFilter = null; colorFilter = null;

View file

@ -2090,9 +2090,9 @@ public class MediaDataController extends BaseController {
} }
public static long calcHash(long hash, long id) { public static long calcHash(long hash, long id) {
hash ^= id >> 21; hash ^= hash >> 21;
hash ^= id << 35; hash ^= hash << 35;
hash ^= id >> 4; hash ^= hash >> 4;
return hash + id; return hash + id;
} }

View file

@ -0,0 +1,54 @@
package org.telegram.messenger;
public class MessageLoaderLogger {
final long dialogId;
final int count;
final int loadIndex;
final long startTime;
long moveToStorageQueueTime;
long getFromDatabaseTime;
long moveToStageQueueTime;
long stageQueueProccessing;
boolean reload;
public MessageLoaderLogger(long dialogId, int loadIndex, int count) {
this.dialogId = dialogId;
this.count = count;
this.loadIndex = loadIndex;
startTime = System.currentTimeMillis();
}
public void logStorageQueuePost() {
moveToStorageQueueTime = System.currentTimeMillis() - startTime;
}
public void logStorageProccessing() {
getFromDatabaseTime = System.currentTimeMillis() - startTime;
}
public void logStageQueuePost() {
moveToStageQueueTime = System.currentTimeMillis() - startTime;
}
public void reload() {
reload = true;
}
public void logStageQueueProcessing() {
stageQueueProccessing = System.currentTimeMillis() - startTime;
}
public void finish() {
long totalTime = System.currentTimeMillis() - startTime;
FileLog.d("MessageLoaderLogger dialogId=" + dialogId + " index=" + loadIndex + " count=" + count + " " +
" moveToStorageQueueTime=" + moveToStorageQueueTime +
" getFromDatabaseTime=" + getFromDatabaseTime +
" moveToStageQueueTime=" + moveToStageQueueTime +
" stageQueueProccessing=" + stageQueueProccessing +
" wasReload=" + reload + " totalTime=" + totalTime
);
}
}

View file

@ -1354,7 +1354,7 @@ public class MessageObject {
} }
public void createStrippedThumb() { public void createStrippedThumb() {
if (photoThumbs == null || !canCreateStripedThubms() && !hasExtendedMediaPreview()) { if (photoThumbs == null || !canCreateStripedThubms() && !hasExtendedMediaPreview() || strippedThumb != null) {
return; return;
} }
try { try {
@ -4835,7 +4835,15 @@ public class MessageObject {
} }
String text = messageOwner.message; String text = messageOwner.message;
ArrayList<TLRPC.MessageEntity> entities = messageOwner.entities; ArrayList<TLRPC.MessageEntity> entities = messageOwner.entities;
if (hasExtendedMedia()) { if (type == TYPE_STORY) {
if (messageOwner.media != null && messageOwner.media.storyItem != null) {
text = messageOwner.media.storyItem.caption;
entities = messageOwner.media.storyItem.entities;
} else {
text = "";
entities = new ArrayList<>();
}
} else if (hasExtendedMedia()) {
text = messageOwner.message = messageOwner.media.description; text = messageOwner.message = messageOwner.media.description;
} }
if (captionTranslated = translated) { if (captionTranslated = translated) {
@ -4844,7 +4852,7 @@ public class MessageObject {
} }
if (!isMediaEmpty() && !(getMedia(messageOwner) instanceof TLRPC.TL_messageMediaGame) && !TextUtils.isEmpty(text)) { if (!isMediaEmpty() && !(getMedia(messageOwner) instanceof TLRPC.TL_messageMediaGame) && !TextUtils.isEmpty(text)) {
caption = Emoji.replaceEmoji(text, Theme.chat_msgTextPaint.getFontMetricsInt(), AndroidUtilities.dp(20), false); caption = Emoji.replaceEmoji(text, Theme.chat_msgTextPaint.getFontMetricsInt(), AndroidUtilities.dp(20), false);
caption = replaceAnimatedEmoji(caption, Theme.chat_msgTextPaint.getFontMetricsInt()); caption = replaceAnimatedEmoji(caption, entities, Theme.chat_msgTextPaint.getFontMetricsInt(), false);
boolean hasEntities; boolean hasEntities;
if (messageOwner.send_state != MESSAGE_SEND_STATE_SENT) { if (messageOwner.send_state != MESSAGE_SEND_STATE_SENT) {

View file

@ -7964,21 +7964,24 @@ public class MessagesController extends BaseController implements NotificationCe
} }
public void loadMessages(long dialogId, long mergeDialogId, boolean loadInfo, int count, int max_id, int offset_date, boolean fromCache, int midDate, int classGuid, int load_type, int last_message_id, int mode, int threadMessageId, int loadIndex, int first_unread, int unread_count, int last_date, boolean queryFromServer, int mentionsCount, boolean isTopic) { public void loadMessages(long dialogId, long mergeDialogId, boolean loadInfo, int count, int max_id, int offset_date, boolean fromCache, int midDate, int classGuid, int load_type, int last_message_id, int mode, int threadMessageId, int loadIndex, int first_unread, int unread_count, int last_date, boolean queryFromServer, int mentionsCount, boolean isTopic) {
loadMessagesInternal(dialogId, mergeDialogId, loadInfo, count, max_id, offset_date, fromCache, midDate, classGuid, load_type, last_message_id, mode, threadMessageId, loadIndex, first_unread, unread_count, last_date, queryFromServer, mentionsCount, true, true, isTopic); loadMessagesInternal(dialogId, mergeDialogId, loadInfo, count, max_id, offset_date, fromCache, midDate, classGuid, load_type, last_message_id, mode, threadMessageId, loadIndex, first_unread, unread_count, last_date, queryFromServer, mentionsCount, true, true, isTopic, null);
} }
private void loadMessagesInternal(long dialogId, long mergeDialogId, boolean loadInfo, int count, int max_id, int offset_date, boolean fromCache, int minDate, int classGuid, int load_type, int last_message_id, int mode, int threadMessageId, int loadIndex, int first_unread, int unread_count, int last_date, boolean queryFromServer, int mentionsCount, boolean loadDialog, boolean processMessages, boolean isTopic) { private void loadMessagesInternal(long dialogId, long mergeDialogId, boolean loadInfo, int count, int max_id, int offset_date, boolean fromCache, int minDate, int classGuid, int load_type, int last_message_id, int mode, int threadMessageId, int loadIndex, int first_unread, int unread_count, int last_date, boolean queryFromServer, int mentionsCount, boolean loadDialog, boolean processMessages, boolean isTopic, MessageLoaderLogger loaderLogger) {
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.d("load messages in chat " + dialogId + " topic_id " + threadMessageId + " count " + count + " max_id " + max_id + " cache " + fromCache + " mindate = " + minDate + " guid " + classGuid + " load_type " + load_type + " last_message_id " + last_message_id + " mode " + mode + " index " + loadIndex + " firstUnread " + first_unread + " unread_count " + unread_count + " last_date " + last_date + " queryFromServer " + queryFromServer + " isTopic " + isTopic); FileLog.d("load messages in chat " + dialogId + " topic_id " + threadMessageId + " count " + count + " max_id " + max_id + " cache " + fromCache + " mindate = " + minDate + " guid " + classGuid + " load_type " + load_type + " last_message_id " + last_message_id + " mode " + mode + " index " + loadIndex + " firstUnread " + first_unread + " unread_count " + unread_count + " last_date " + last_date + " queryFromServer " + queryFromServer + " isTopic " + isTopic);
} }
if (BuildVars.LOGS_ENABLED && loaderLogger == null && mode == 0) {
loaderLogger = new MessageLoaderLogger(dialogId, loadIndex, count);
}
if ((threadMessageId == 0 || isTopic) && mode != 2 && (fromCache || DialogObject.isEncryptedDialog(dialogId))) { if ((threadMessageId == 0 || isTopic) && mode != 2 && (fromCache || DialogObject.isEncryptedDialog(dialogId))) {
getMessagesStorage().getMessages(dialogId, mergeDialogId, loadInfo, count, max_id, offset_date, minDate, classGuid, load_type, mode == 1, threadMessageId, loadIndex, processMessages, isTopic); getMessagesStorage().getMessages(dialogId, mergeDialogId, loadInfo, count, max_id, offset_date, minDate, classGuid, load_type, mode == 1, threadMessageId, loadIndex, processMessages, isTopic, loaderLogger);
} else { } else {
if (threadMessageId != 0) { if (threadMessageId != 0) {
if (loadDialog && isTopic && load_type == 2 && last_message_id == 0) { if (loadDialog && isTopic && load_type == 2 && last_message_id == 0) {
TLRPC.TL_forumTopic topic = topicsController.findTopic(-dialogId, threadMessageId); TLRPC.TL_forumTopic topic = topicsController.findTopic(-dialogId, threadMessageId);
if (topic != null) { if (topic != null) {
loadMessagesInternal(dialogId, mergeDialogId, loadInfo, count, max_id, offset_date, false, minDate, classGuid, load_type, topic.top_message, 0, threadMessageId, loadIndex, first_unread, topic.unread_count, last_date, queryFromServer, topic.unread_mentions_count, false, processMessages, isTopic); loadMessagesInternal(dialogId, mergeDialogId, loadInfo, count, max_id, offset_date, false, minDate, classGuid, load_type, topic.top_message, 0, threadMessageId, loadIndex, first_unread, topic.unread_count, last_date, queryFromServer, topic.unread_mentions_count, false, processMessages, isTopic, loaderLogger);
return; return;
} }
} }
@ -8036,7 +8039,7 @@ public class MessagesController extends BaseController implements NotificationCe
} }
} }
} }
processLoadedMessages(res, res.messages.size(), dialogId, mergeDialogId, count, mid, offset_date, false, classGuid, fnid, last_message_id, unread_count, last_date, load_type, false, 0, threadMessageId, loadIndex, queryFromServer, mentionsCount, processMessages, isTopic); processLoadedMessages(res, res.messages.size(), dialogId, mergeDialogId, count, mid, offset_date, false, classGuid, fnid, last_message_id, unread_count, last_date, load_type, false, 0, threadMessageId, loadIndex, queryFromServer, mentionsCount, processMessages, isTopic, null);
} else { } else {
AndroidUtilities.runOnUIThread(() -> getNotificationCenter().postNotificationName(NotificationCenter.loadingMessagesFailed, classGuid, req, error)); AndroidUtilities.runOnUIThread(() -> getNotificationCenter().postNotificationName(NotificationCenter.loadingMessagesFailed, classGuid, req, error));
} }
@ -8064,7 +8067,7 @@ public class MessagesController extends BaseController implements NotificationCe
} }
} }
} }
processLoadedMessages(res, res.messages.size(), dialogId, mergeDialogId, count, mid, offset_date, false, classGuid, first_unread, last_message_id, unread_count, last_date, load_type, false, mode, threadMessageId, loadIndex, queryFromServer, mentionsCount, processMessages, isTopic); processLoadedMessages(res, res.messages.size(), dialogId, mergeDialogId, count, mid, offset_date, false, classGuid, first_unread, last_message_id, unread_count, last_date, load_type, false, mode, threadMessageId, loadIndex, queryFromServer, mentionsCount, processMessages, isTopic, null);
} }
}); });
getConnectionsManager().bindRequestToGuid(reqId, classGuid); getConnectionsManager().bindRequestToGuid(reqId, classGuid);
@ -8091,7 +8094,7 @@ public class MessagesController extends BaseController implements NotificationCe
getMessagesStorage().putDialogs(dialogs, 2); getMessagesStorage().putDialogs(dialogs, 2);
} }
loadMessagesInternal(dialogId, mergeDialogId, loadInfo, count, max_id, offset_date, false, minDate, classGuid, load_type, dialog.top_message, 0, threadMessageId, loadIndex, first_unread, dialog.unread_count, last_date, queryFromServer, dialog.unread_mentions_count, false, processMessages, isTopic); loadMessagesInternal(dialogId, mergeDialogId, loadInfo, count, max_id, offset_date, false, minDate, classGuid, load_type, dialog.top_message, 0, threadMessageId, loadIndex, first_unread, dialog.unread_count, last_date, queryFromServer, dialog.unread_mentions_count, false, processMessages, isTopic, null);
} }
} else { } else {
AndroidUtilities.runOnUIThread(() -> getNotificationCenter().postNotificationName(NotificationCenter.loadingMessagesFailed, classGuid, req, error)); AndroidUtilities.runOnUIThread(() -> getNotificationCenter().postNotificationName(NotificationCenter.loadingMessagesFailed, classGuid, req, error));
@ -8139,7 +8142,7 @@ public class MessagesController extends BaseController implements NotificationCe
} }
} }
} }
processLoadedMessages(res, res.messages.size(), dialogId, mergeDialogId, count, mid, offset_date, false, classGuid, first_unread, last_message_id, unread_count, last_date, load_type, false, 0, threadMessageId, loadIndex, queryFromServer, mentionsCount, processMessages, isTopic); processLoadedMessages(res, res.messages.size(), dialogId, mergeDialogId, count, mid, offset_date, false, classGuid, first_unread, last_message_id, unread_count, last_date, load_type, false, 0, threadMessageId, loadIndex, queryFromServer, mentionsCount, processMessages, isTopic, null);
} else { } else {
AndroidUtilities.runOnUIThread(() -> getNotificationCenter().postNotificationName(NotificationCenter.loadingMessagesFailed, classGuid, req, error)); AndroidUtilities.runOnUIThread(() -> getNotificationCenter().postNotificationName(NotificationCenter.loadingMessagesFailed, classGuid, req, error));
} }
@ -8198,7 +8201,7 @@ public class MessagesController extends BaseController implements NotificationCe
} }
public void processLoadedMessages(TLRPC.messages_Messages messagesRes, int resCount, long dialogId, long mergeDialogId, int count, int max_id, int offset_date, boolean isCache, int classGuid, public void processLoadedMessages(TLRPC.messages_Messages messagesRes, int resCount, long dialogId, long mergeDialogId, int count, int max_id, int offset_date, boolean isCache, int classGuid,
int first_unread, int last_message_id, int unread_count, int last_date, int load_type, boolean isEnd, int mode, int threadMessageId, int loadIndex, boolean queryFromServer, int mentionsCount, boolean needProcess, boolean isTopic) { int first_unread, int last_message_id, int unread_count, int last_date, int load_type, boolean isEnd, int mode, int threadMessageId, int loadIndex, boolean queryFromServer, int mentionsCount, boolean needProcess, boolean isTopic, MessageLoaderLogger loaderLogger) {
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.d("processLoadedMessages size " + messagesRes.messages.size() + " in chat " + dialogId + " topic_id " + threadMessageId + " count " + count + " max_id " + max_id + " cache " + isCache + " guid " + classGuid + " load_type " + load_type + " last_message_id " + last_message_id + " index " + loadIndex + " firstUnread " + first_unread + " unread_count " + unread_count + " last_date " + last_date + " queryFromServer " + queryFromServer + " isTopic" + isTopic); FileLog.d("processLoadedMessages size " + messagesRes.messages.size() + " in chat " + dialogId + " topic_id " + threadMessageId + " count " + count + " max_id " + max_id + " cache " + isCache + " guid " + classGuid + " load_type " + load_type + " last_message_id " + last_message_id + " index " + loadIndex + " firstUnread " + first_unread + " unread_count " + unread_count + " last_date " + last_date + " queryFromServer " + queryFromServer + " isTopic" + isTopic);
} }
@ -8242,16 +8245,16 @@ public class MessagesController extends BaseController implements NotificationCe
reload = ((SystemClock.elapsedRealtime() - lastScheduledServerQueryTime.get(dialogId, 0L)) > 60 * 1000); reload = ((SystemClock.elapsedRealtime() - lastScheduledServerQueryTime.get(dialogId, 0L)) > 60 * 1000);
} else { } else {
reload = resCount == 0 && (!isInitialLoading || (SystemClock.elapsedRealtime() - lastServerQueryTime.get(dialogId, 0L)) > 60 * 1000 || (isCache && isTopic)); reload = resCount == 0 && (!isInitialLoading || (SystemClock.elapsedRealtime() - lastServerQueryTime.get(dialogId, 0L)) > 60 * 1000 || (isCache && isTopic));
if (isCache && dialogId < 0) { // if (isCache && dialogId < 0) {
TLRPC.Chat chat = getChat(-dialogId); // TLRPC.Chat chat = getChat(-dialogId);
if (chat == null) { // if (chat == null) {
chat = chatsDict.get(-dialogId); // chat = chatsDict.get(-dialogId);
} // }
if (chat != null && mode == 0 && ChatObject.isNotInChat(chat) && (SystemClock.elapsedRealtime() - lastServerQueryTime.get(dialogId, 0L)) > 24 * 60 * 60 * 1000) { // if (chat != null && mode == 0 && ChatObject.isNotInChat(chat) && (SystemClock.elapsedRealtime() - lastServerQueryTime.get(dialogId, 0L)) > 24 * 60 * 60 * 1000) {
messagesRes.messages.clear(); // messagesRes.messages.clear();
reload = true; // reload = true;
} // }
} // }
} }
if (!DialogObject.isEncryptedDialog(dialogId) && isCache && reload) { if (!DialogObject.isEncryptedDialog(dialogId) && isCache && reload) {
int hash; int hash;
@ -8274,7 +8277,10 @@ public class MessagesController extends BaseController implements NotificationCe
lastServerQueryTime.put(dialogId, SystemClock.elapsedRealtime()); lastServerQueryTime.put(dialogId, SystemClock.elapsedRealtime());
hash = 0; hash = 0;
} }
AndroidUtilities.runOnUIThread(() -> loadMessagesInternal(dialogId, mergeDialogId, false, count, load_type == 2 && queryFromServer ? first_unread : max_id, offset_date, false, hash, classGuid, load_type, last_message_id, mode, threadMessageId, loadIndex, first_unread, unread_count, last_date, queryFromServer, mentionsCount, true, needProcess, isTopic)); if (loaderLogger != null) {
loaderLogger.reload();
}
AndroidUtilities.runOnUIThread(() -> loadMessagesInternal(dialogId, mergeDialogId, false, count, load_type == 2 && queryFromServer ? first_unread : max_id, offset_date, false, hash, classGuid, load_type, last_message_id, mode, threadMessageId, loadIndex, first_unread, unread_count, last_date, queryFromServer, mentionsCount, true, needProcess, isTopic, loaderLogger));
if (messagesRes.messages.isEmpty()) { if (messagesRes.messages.isEmpty()) {
return; return;
} }
@ -8367,10 +8373,16 @@ public class MessagesController extends BaseController implements NotificationCe
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.d("process time=" + (SystemClock.elapsedRealtime() - startProcessTime) + " count=" + objects.size() + " for dialog " + dialogId); FileLog.d("process time=" + (SystemClock.elapsedRealtime() - startProcessTime) + " count=" + objects.size() + " for dialog " + dialogId);
} }
if (loaderLogger != null) {
loaderLogger.logStageQueueProcessing();
}
AndroidUtilities.runOnUIThread(() -> { AndroidUtilities.runOnUIThread(() -> {
putUsers(messagesRes.users, isCache); putUsers(messagesRes.users, isCache);
putChats(messagesRes.chats, isCache); putChats(messagesRes.chats, isCache);
if (loaderLogger != null) {
loaderLogger.finish();
}
if (messagesRes.animatedEmoji != null && needProcess) { if (messagesRes.animatedEmoji != null && needProcess) {
AnimatedEmojiDrawable.getDocumentFetcher(currentAccount).processDocuments(messagesRes.animatedEmoji); AnimatedEmojiDrawable.getDocumentFetcher(currentAccount).processDocuments(messagesRes.animatedEmoji);
} }
@ -12183,6 +12195,9 @@ public class MessagesController extends BaseController implements NotificationCe
} }
public void startShortPoll(TLRPC.Chat chat, int guid, boolean stop) { public void startShortPoll(TLRPC.Chat chat, int guid, boolean stop) {
startShortPoll(chat, guid, stop, null);
}
public void startShortPoll(TLRPC.Chat chat, int guid, boolean stop, Consumer<Boolean> needPollConsumer) {
if (chat == null) { if (chat == null) {
return; return;
} }
@ -12212,9 +12227,17 @@ public class MessagesController extends BaseController implements NotificationCe
if (!guids.contains(guid)) { if (!guids.contains(guid)) {
guids.add(guid); guids.add(guid);
} }
boolean needGetDifference = false;
if (shortPollChannels.indexOfKey(chat.id) < 0) { if (shortPollChannels.indexOfKey(chat.id) < 0) {
needGetDifference = true;
getChannelDifference(chat.id, 3, 0, null); getChannelDifference(chat.id, 3, 0, null);
} }
boolean finalNeedGetDifference = needGetDifference;
if (needPollConsumer != null) {
AndroidUtilities.runOnUIThread(() -> {
needPollConsumer.accept(finalNeedGetDifference);
});
}
if (chat.megagroup) { if (chat.megagroup) {
if (onlineGuids == null) { if (onlineGuids == null) {
onlineGuids = new ArrayList<>(); onlineGuids = new ArrayList<>();
@ -12259,6 +12282,9 @@ public class MessagesController extends BaseController implements NotificationCe
if (newDialogType == 1) { if (newDialogType == 1) {
channelPts = channelsPts.get(channelId); channelPts = channelsPts.get(channelId);
if (channelPts != 0) { if (channelPts != 0) {
AndroidUtilities.runOnUIThread(() -> {
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.onReceivedChannelDifference, channelId);
});
return; return;
} }
channelPts = 1; channelPts = 1;
@ -12271,10 +12297,16 @@ public class MessagesController extends BaseController implements NotificationCe
channelsPts.put(channelId, channelPts); channelsPts.put(channelId, channelPts);
} }
if (channelPts == 0 && (newDialogType == 2 || newDialogType == 3)) { if (channelPts == 0 && (newDialogType == 2 || newDialogType == 3)) {
AndroidUtilities.runOnUIThread(() -> {
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.onReceivedChannelDifference, channelId);
});
return; return;
} }
} }
if (channelPts == 0) { if (channelPts == 0) {
AndroidUtilities.runOnUIThread(() -> {
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.onReceivedChannelDifference, channelId);
});
return; return;
} }
} }
@ -12293,6 +12325,9 @@ public class MessagesController extends BaseController implements NotificationCe
if (taskId != 0) { if (taskId != 0) {
getMessagesStorage().removePendingTask(taskId); getMessagesStorage().removePendingTask(taskId);
} }
AndroidUtilities.runOnUIThread(() -> {
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.onReceivedChannelDifference, channelId);
});
return; return;
} }
long newTaskId; long newTaskId;
@ -12382,6 +12417,7 @@ public class MessagesController extends BaseController implements NotificationCe
} }
Utilities.stageQueue.postRunnable(() -> { Utilities.stageQueue.postRunnable(() -> {
boolean notifyAbountDifference = true;
if (res instanceof TLRPC.TL_updates_channelDifference || res instanceof TLRPC.TL_updates_channelDifferenceEmpty) { if (res instanceof TLRPC.TL_updates_channelDifference || res instanceof TLRPC.TL_updates_channelDifferenceEmpty) {
if (!res.new_messages.isEmpty()) { if (!res.new_messages.isEmpty()) {
LongSparseArray<ArrayList<MessageObject>> messages = new LongSparseArray<>(); LongSparseArray<ArrayList<MessageObject>> messages = new LongSparseArray<>();
@ -12464,7 +12500,10 @@ public class MessagesController extends BaseController implements NotificationCe
message.dialog_id = -channelId; message.dialog_id = -channelId;
message.unread = !(message.action instanceof TLRPC.TL_messageActionChannelCreate || channelFinal != null && channelFinal.left || (message.out ? outboxValue : inboxValue) >= message.id); message.unread = !(message.action instanceof TLRPC.TL_messageActionChannelCreate || channelFinal != null && channelFinal.left || (message.out ? outboxValue : inboxValue) >= message.id);
} }
getMessagesStorage().overwriteChannel(channelId, (TLRPC.TL_updates_channelDifferenceTooLong) res, newDialogType); getMessagesStorage().overwriteChannel(channelId, (TLRPC.TL_updates_channelDifferenceTooLong) res, newDialogType, () -> AndroidUtilities.runOnUIThread(() -> {
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.onReceivedChannelDifference, channelId);
}));
notifyAbountDifference = false;
} }
gettingDifferenceChannels.delete(channelId); gettingDifferenceChannels.delete(channelId);
channelsPts.put(channelId, res.pts); channelsPts.put(channelId, res.pts);
@ -12483,10 +12522,18 @@ public class MessagesController extends BaseController implements NotificationCe
if (newTaskId != 0) { if (newTaskId != 0) {
getMessagesStorage().removePendingTask(newTaskId); getMessagesStorage().removePendingTask(newTaskId);
} }
if (notifyAbountDifference) {
AndroidUtilities.runOnUIThread(() -> {
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.onReceivedChannelDifference, channelId);
});
}
}); });
}); });
} else if (error != null) { } else if (error != null) {
AndroidUtilities.runOnUIThread(() -> checkChannelError(error.text, channelId)); AndroidUtilities.runOnUIThread(() -> {
checkChannelError(error.text, channelId);
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.onReceivedChannelDifference, channelId);
});
gettingDifferenceChannels.delete(channelId); gettingDifferenceChannels.delete(channelId);
if (newTaskId != 0) { if (newTaskId != 0) {
getMessagesStorage().removePendingTask(newTaskId); getMessagesStorage().removePendingTask(newTaskId);
@ -17672,9 +17719,9 @@ public class MessagesController extends BaseController implements NotificationCe
int lastMessageId = (int) args[4]; int lastMessageId = (int) args[4];
if ((size < count / 2 && !isEnd) && isCache) { if ((size < count / 2 && !isEnd) && isCache) {
if (finalMessageId != 0) { if (finalMessageId != 0) {
loadMessagesInternal(dialogId, 0, false, count, finalMessageId, 0, false, 0, classGuid, 3, lastMessageId, 0, 0, -1, 0, 0, 0, false, 0, true, false, false); loadMessagesInternal(dialogId, 0, false, count, finalMessageId, 0, false, 0, classGuid, 3, lastMessageId, 0, 0, -1, 0, 0, 0, false, 0, true, false, false, null);
} else { } else {
loadMessagesInternal(dialogId, 0, false, count, finalMessageId, 0, false, 0, classGuid, 2, lastMessageId, 0, 0, -1, 0, 0, 0, false, 0, true, false, false); loadMessagesInternal(dialogId, 0, false, count, finalMessageId, 0, false, 0, classGuid, 2, lastMessageId, 0, 0, -1, 0, 0, 0, false, 0, true, false, false, null);
} }
} else { } else {
getNotificationCenter().removeObserver(this, NotificationCenter.messagesDidLoadWithoutProcess); getNotificationCenter().removeObserver(this, NotificationCenter.messagesDidLoadWithoutProcess);
@ -17698,9 +17745,9 @@ public class MessagesController extends BaseController implements NotificationCe
getNotificationCenter().addObserver(delegate, NotificationCenter.loadingMessagesFailed); getNotificationCenter().addObserver(delegate, NotificationCenter.loadingMessagesFailed);
if (messageId != 0) { if (messageId != 0) {
loadMessagesInternal(dialogId, 0, true, count, finalMessageId, 0, true, 0, classGuid, 3, 0, 0, 0, -1, 0, 0, 0, false, 0, true, false, false); loadMessagesInternal(dialogId, 0, true, count, finalMessageId, 0, true, 0, classGuid, 3, 0, 0, 0, -1, 0, 0, 0, false, 0, true, false, false, null);
} else { } else {
loadMessagesInternal(dialogId, 0, true, count, finalMessageId, 0, true, 0, classGuid, 2, 0, 0, 0, -1, 0, 0, 0, false, 0, true, false, false); loadMessagesInternal(dialogId, 0, true, count, finalMessageId, 0, true, 0, classGuid, 2, 0, 0, 0, -1, 0, 0, 0, false, 0, true, false, false, null);
} }
} }

View file

@ -7729,7 +7729,7 @@ public class MessagesStorage extends BaseController {
}); });
} }
public Runnable getMessagesInternal(long dialogId, long mergeDialogId, int count, int max_id, int offset_date, int minDate, int classGuid, int load_type, boolean scheduled, int threadMessageId, int loadIndex, boolean processMessages, boolean isTopic) { public Runnable getMessagesInternal(long dialogId, long mergeDialogId, int count, int max_id, int offset_date, int minDate, int classGuid, int load_type, boolean scheduled, int threadMessageId, int loadIndex, boolean processMessages, boolean isTopic, MessageLoaderLogger loaderLogger) {
TLRPC.TL_messages_messages res = new TLRPC.TL_messages_messages(); TLRPC.TL_messages_messages res = new TLRPC.TL_messages_messages();
long currentUserId = getUserConfig().clientUserId; long currentUserId = getUserConfig().clientUserId;
int count_unread = 0; int count_unread = 0;
@ -8623,7 +8623,7 @@ public class MessagesStorage extends BaseController {
}; };
} else {*/ } else {*/
int finalMessagesCount = scheduled ? res.messages.size() : messagesCount; int finalMessagesCount = scheduled ? res.messages.size() : messagesCount;
return () -> getMessagesController().processLoadedMessages(res, finalMessagesCount, dialogId, mergeDialogId, countQueryFinal, maxIdOverrideFinal, offset_date, true, classGuid, minUnreadIdFinal, lastMessageIdFinal, countUnreadFinal, maxUnreadDateFinal, load_type, isEndFinal, scheduled ? 1 : 0, threadMessageId, loadIndex, queryFromServerFinal, mentionsUnreadFinal, processMessages, isTopic); return () -> getMessagesController().processLoadedMessages(res, finalMessagesCount, dialogId, mergeDialogId, countQueryFinal, maxIdOverrideFinal, offset_date, true, classGuid, minUnreadIdFinal, lastMessageIdFinal, countUnreadFinal, maxUnreadDateFinal, load_type, isEndFinal, scheduled ? 1 : 0, threadMessageId, loadIndex, queryFromServerFinal, mentionsUnreadFinal, processMessages, isTopic, loaderLogger);
//} //}
} }
@ -8654,10 +8654,19 @@ public class MessagesStorage extends BaseController {
} }
} }
public void getMessages(long dialogId, long mergeDialogId, boolean loadInfo, int count, int max_id, int offset_date, int minDate, int classGuid, int load_type, boolean scheduled, int replyMessageId, int loadIndex, boolean processMessages, boolean isTopic) { public void getMessages(long dialogId, long mergeDialogId, boolean loadInfo, int count, int max_id, int offset_date, int minDate, int classGuid, int load_type, boolean scheduled, int replyMessageId, int loadIndex, boolean processMessages, boolean isTopic, MessageLoaderLogger loaderLogger) {
storageQueue.postRunnable(() -> { storageQueue.postRunnable(() -> {
Runnable processMessagesRunnable = getMessagesInternal(dialogId, mergeDialogId, count, max_id, offset_date, minDate, classGuid, load_type, scheduled, replyMessageId, loadIndex, processMessages, isTopic); if (loaderLogger != null) {
loaderLogger.logStorageQueuePost();
}
Runnable processMessagesRunnable = getMessagesInternal(dialogId, mergeDialogId, count, max_id, offset_date, minDate, classGuid, load_type, scheduled, replyMessageId, loadIndex, processMessages, isTopic, loaderLogger);
if (loaderLogger != null) {
loaderLogger.logStorageProccessing();
}
Utilities.stageQueue.postRunnable(() -> { Utilities.stageQueue.postRunnable(() -> {
if (loaderLogger != null) {
loaderLogger.logStageQueuePost();
}
processMessagesRunnable.run(); processMessagesRunnable.run();
}); });
}); });
@ -9908,7 +9917,7 @@ public class MessagesStorage extends BaseController {
}); });
} }
public void overwriteChannel(long channelId, TLRPC.TL_updates_channelDifferenceTooLong difference, int newDialogType) { public void overwriteChannel(long channelId, TLRPC.TL_updates_channelDifferenceTooLong difference, int newDialogType, Runnable onDone) {
storageQueue.postRunnable(() -> { storageQueue.postRunnable(() -> {
SQLiteCursor cursor = null; SQLiteCursor cursor = null;
try { try {
@ -9978,6 +9987,9 @@ public class MessagesStorage extends BaseController {
cursor.dispose(); cursor.dispose();
} }
} }
if (onDone != null) {
onDone.run();
}
}); });
} }

View file

@ -288,6 +288,8 @@ public class NotificationCenter {
public static final int uploadStoryProgress = totalEvents++; public static final int uploadStoryProgress = totalEvents++;
public static final int uploadStoryEnd = totalEvents++; public static final int uploadStoryEnd = totalEvents++;
public static final int customTypefacesLoaded = totalEvents++; public static final int customTypefacesLoaded = totalEvents++;
public static final int stealthModeChanged = totalEvents++;
public static final int onReceivedChannelDifference = totalEvents++;
public static boolean alreadyLogged; public static boolean alreadyLogged;

View file

@ -4325,7 +4325,7 @@ public class NotificationsController extends BaseController {
notificationBuilder.setChannelId(validateChannelId(lastDialogId, lastTopicId, chatName, vibrationPattern, ledColor, sound, importance, isDefault, isInApp, isSilent, chatType)); notificationBuilder.setChannelId(validateChannelId(lastDialogId, lastTopicId, chatName, vibrationPattern, ledColor, sound, importance, isDefault, isInApp, isSilent, chatType));
} }
Notification mainNotification = notificationBuilder.build(); Notification mainNotification = notificationBuilder.build();
if (Build.VERSION.SDK_INT < 18) { if (Build.VERSION.SDK_INT <= 19) {
notificationManager.notify(notificationId, mainNotification); notificationManager.notify(notificationId, mainNotification);
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.d("show summary notification by SDK check"); FileLog.d("show summary notification by SDK check");

View file

@ -206,7 +206,7 @@ public class SaveToGallerySettingsHelper {
} }
builder.append(LocaleController.getString("SaveToGalleryVideos", R.string.SaveToGalleryVideos)); builder.append(LocaleController.getString("SaveToGalleryVideos", R.string.SaveToGalleryVideos));
if (limitVideo > 0 && limitVideo < 4L * 1000 * 1024 * 1024) { if (limitVideo > 0 && limitVideo < 4L * 1000 * 1024 * 1024) {
builder.append(" (").append(AndroidUtilities.formatFileSize(limitVideo, true)).append(")"); builder.append(" (").append(AndroidUtilities.formatFileSize(limitVideo, true, false)).append(")");
} }
} }
} else { } else {
@ -244,7 +244,7 @@ public class SaveToGallerySettingsHelper {
} }
if (limitVideo > 0 && limitVideo < 4L * 1000 * 1024 * 1024) { if (limitVideo > 0 && limitVideo < 4L * 1000 * 1024 * 1024) {
builder.append(LocaleController.formatString("SaveToGalleryVideosUpTo", R.string.SaveToGalleryVideosUpTo, AndroidUtilities.formatFileSize(limitVideo, true))); builder.append(LocaleController.formatString("SaveToGalleryVideosUpTo", R.string.SaveToGalleryVideosUpTo, AndroidUtilities.formatFileSize(limitVideo, true, false)));
} else { } else {
builder.append(LocaleController.formatString("SaveToGalleryVideos", R.string.SaveToGalleryVideos)); builder.append(LocaleController.formatString("SaveToGalleryVideos", R.string.SaveToGalleryVideos));
} }

View file

@ -43,6 +43,8 @@ import android.util.SparseArray;
import androidx.core.graphics.ColorUtils; import androidx.core.graphics.ColorUtils;
import com.google.android.exoplayer2.util.Log;
import org.telegram.ui.ActionBar.Theme; import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.DrawingInBackgroundThreadDrawable; import org.telegram.ui.Components.DrawingInBackgroundThreadDrawable;
import org.xml.sax.Attributes; import org.xml.sax.Attributes;
@ -109,19 +111,19 @@ public class SvgHelper {
private Paint backgroundPaint; private Paint backgroundPaint;
protected int width; protected int width;
protected int height; protected int height;
private static int[] parentPosition = new int[2]; private static final int[] parentPosition = new int[2];
private Bitmap[] backgroundBitmap = new Bitmap[1 + DrawingInBackgroundThreadDrawable.THREAD_COUNT]; private final Bitmap[] backgroundBitmap = new Bitmap[1 + DrawingInBackgroundThreadDrawable.THREAD_COUNT];
private Canvas[] backgroundCanvas = new Canvas[1 + DrawingInBackgroundThreadDrawable.THREAD_COUNT]; private final Canvas[] backgroundCanvas = new Canvas[1 + DrawingInBackgroundThreadDrawable.THREAD_COUNT];
private LinearGradient[] placeholderGradient = new LinearGradient[1 + DrawingInBackgroundThreadDrawable.THREAD_COUNT]; private final LinearGradient[] placeholderGradient = new LinearGradient[1 + DrawingInBackgroundThreadDrawable.THREAD_COUNT];
private Matrix[] placeholderMatrix = new Matrix[1 + DrawingInBackgroundThreadDrawable.THREAD_COUNT]; private final Matrix[] placeholderMatrix = new Matrix[1 + DrawingInBackgroundThreadDrawable.THREAD_COUNT];
private static float totalTranslation; private static float totalTranslation;
private static float gradientWidth; private static float gradientWidth;
private static long lastUpdateTime; private static long lastUpdateTime;
private static Runnable shiftRunnable; private static Runnable shiftRunnable;
private static WeakReference<Drawable> shiftDrawable; private static WeakReference<Drawable> shiftDrawable;
private ImageReceiver parentImageReceiver; private ImageReceiver parentImageReceiver;
private int[] currentColor = new int[2]; private final int[] currentColor = new int[2];
private int currentColorKey; private int currentColorKey;
private Integer overrideColor; private Integer overrideColor;
private Theme.ResourcesProvider currentResourcesProvider; private Theme.ResourcesProvider currentResourcesProvider;
@ -441,6 +443,7 @@ public class SvgHelper {
SAXParser sp = spf.newSAXParser(); SAXParser sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader(); XMLReader xr = sp.getXMLReader();
SVGHandler handler = new SVGHandler(width, height, color, false, scale); SVGHandler handler = new SVGHandler(width, height, color, false, scale);
///handler.alphaOnly = true;
xr.setContentHandler(handler); xr.setContentHandler(handler);
xr.parse(new InputSource(stream)); xr.parse(new InputSource(stream));
return handler.getBitmap(); return handler.getBitmap();
@ -456,6 +459,9 @@ public class SvgHelper {
SAXParser sp = spf.newSAXParser(); SAXParser sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader(); XMLReader xr = sp.getXMLReader();
SVGHandler handler = new SVGHandler(width, height, white ? 0xffffffff : null, false, 1f); SVGHandler handler = new SVGHandler(width, height, white ? 0xffffffff : null, false, 1f);
if (!white) {
handler.alphaOnly = true;
}
xr.setContentHandler(handler); xr.setContentHandler(handler);
xr.parse(new InputSource(stream)); xr.parse(new InputSource(stream));
return handler.getBitmap(); return handler.getBitmap();
@ -1116,6 +1122,7 @@ public class SvgHelper {
boolean pushed = false; boolean pushed = false;
private HashMap<String, StyleSet> globalStyles = new HashMap<>(); private HashMap<String, StyleSet> globalStyles = new HashMap<>();
private boolean alphaOnly;
private SVGHandler(int dw, int dh, Integer color, boolean asDrawable, float scale) { private SVGHandler(int dw, int dh, Integer color, boolean asDrawable, float scale) {
globalScale = scale; globalScale = scale;
@ -1275,7 +1282,7 @@ public class SvgHelper {
height *= scale; height *= scale;
} }
if (drawable == null) { if (drawable == null) {
bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); bitmap = Bitmap.createBitmap(width, height, alphaOnly ? Bitmap.Config.ALPHA_8 : Bitmap.Config.ARGB_8888);
bitmap.eraseColor(0); bitmap.eraseColor(0);
canvas = new Canvas(bitmap); canvas = new Canvas(bitmap);
if (scale != 0) { if (scale != 0) {

View file

@ -0,0 +1,57 @@
package org.telegram.ui.ActionBar;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.drawable.Drawable;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.telegram.messenger.AndroidUtilities;
public class RoundVideoShadow extends Drawable {
Paint eraserPaint;
Paint paint;
public RoundVideoShadow() {
// eraserPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
// eraserPaint.setColor(0);
// eraserPaint.setStyle(Paint.Style.FILL);
// eraserPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setShadowLayer(AndroidUtilities.dp(4), 0, 0, 0x5f000000);
}
@Override
public void draw(@NonNull Canvas canvas) {
float cx = getBounds().centerX();
float cy = getBounds().centerY();
// for (int a = 0; a < 2; a++) {
// canvas.drawCircle(cx, cy, AndroidUtilities.roundMessageSize / 2f - AndroidUtilities.dp(1), a == 0 ? paint : eraserPaint);
// }
float r = (getBounds().width() - AndroidUtilities.dp(8)) / 2f;
canvas.drawCircle(cx, cy - AndroidUtilities.dp(1), r, paint);
}
@Override
public void setAlpha(int alpha) {
paint.setAlpha(alpha);
// eraserPaint.setAlpha(alpha);
}
@Override
public void setColorFilter(@Nullable ColorFilter colorFilter) {
}
@Override
public int getOpacity() {
return 0;
}
}

View file

@ -3197,7 +3197,6 @@ public class Theme {
public static Drawable chat_inlineResultFile; public static Drawable chat_inlineResultFile;
public static Drawable chat_inlineResultAudio; public static Drawable chat_inlineResultAudio;
public static Drawable chat_inlineResultLocation; public static Drawable chat_inlineResultLocation;
public static Drawable chat_redLocationIcon;
public static Drawable chat_msgOutLocationDrawable; public static Drawable chat_msgOutLocationDrawable;
public static Drawable chat_contextResult_shadowUnderSwitchDrawable; public static Drawable chat_contextResult_shadowUnderSwitchDrawable;
public static Drawable chat_shareIconDrawable; public static Drawable chat_shareIconDrawable;
@ -3226,7 +3225,6 @@ public class Theme {
public static Drawable chat_msgCallDownRedDrawable; public static Drawable chat_msgCallDownRedDrawable;
public static Drawable chat_msgCallDownGreenDrawable; public static Drawable chat_msgCallDownGreenDrawable;
public static Drawable chat_msgAvatarLiveLocationDrawable;
public static Drawable chat_attachEmptyDrawable; public static Drawable chat_attachEmptyDrawable;
public static RLottieDrawable[] chat_attachButtonDrawables = new RLottieDrawable[6]; public static RLottieDrawable[] chat_attachButtonDrawables = new RLottieDrawable[6];
public static Drawable[] chat_locationDrawable = new Drawable[2]; public static Drawable[] chat_locationDrawable = new Drawable[2];
@ -7670,11 +7668,17 @@ public class Theme {
options.inSampleSize *= 2; options.inSampleSize *= 2;
} while (options.inSampleSize < scale); } while (options.inSampleSize < scale);
} }
options.inPreferredConfig = Bitmap.Config.ALPHA_8;
options.inJustDecodeBounds = false; options.inJustDecodeBounds = false;
Bitmap wallpaper = BitmapFactory.decodeFile(wallpaperPath, options); Bitmap wallpaper = BitmapFactory.decodeFile(wallpaperPath, options);
if (wallpaper != null) { if (wallpaper != null) {
if (color2 != 0 && accent != null) { if (color2 != 0 && accent != null) {
MotionBackgroundDrawable wallpaperDrawable = new MotionBackgroundDrawable(backColor, color1, color2, color3, true); MotionBackgroundDrawable wallpaperDrawable = new MotionBackgroundDrawable(backColor, color1, color2, color3, true);
if (bitmap != null && bitmap.getConfig() != Bitmap.Config.ALPHA_8) {
Bitmap toRecycle = bitmap;
bitmap = bitmap.copy(Bitmap.Config.ALPHA_8, false);
toRecycle.recycle();
}
wallpaperDrawable.setPatternBitmap((int) (accent.patternIntensity * 100), wallpaper); wallpaperDrawable.setPatternBitmap((int) (accent.patternIntensity * 100), wallpaper);
wallpaperDrawable.setBounds(0, 0, bitmap.getWidth(), bitmap.getHeight()); wallpaperDrawable.setBounds(0, 0, bitmap.getWidth(), bitmap.getHeight());
wallpaperDrawable.draw(canvas); wallpaperDrawable.draw(canvas);
@ -8466,12 +8470,10 @@ public class Theme {
calllog_msgCallUpGreenDrawable = resources.getDrawable(R.drawable.ic_call_made_green_18dp).mutate(); calllog_msgCallUpGreenDrawable = resources.getDrawable(R.drawable.ic_call_made_green_18dp).mutate();
calllog_msgCallDownRedDrawable = resources.getDrawable(R.drawable.ic_call_received_green_18dp).mutate(); calllog_msgCallDownRedDrawable = resources.getDrawable(R.drawable.ic_call_received_green_18dp).mutate();
calllog_msgCallDownGreenDrawable = resources.getDrawable(R.drawable.ic_call_received_green_18dp).mutate(); calllog_msgCallDownGreenDrawable = resources.getDrawable(R.drawable.ic_call_received_green_18dp).mutate();
chat_msgAvatarLiveLocationDrawable = resources.getDrawable(R.drawable.livepin).mutate();
chat_inlineResultFile = resources.getDrawable(R.drawable.bot_file); chat_inlineResultFile = resources.getDrawable(R.drawable.bot_file);
chat_inlineResultAudio = resources.getDrawable(R.drawable.bot_music); chat_inlineResultAudio = resources.getDrawable(R.drawable.bot_music);
chat_inlineResultLocation = resources.getDrawable(R.drawable.bot_location); chat_inlineResultLocation = resources.getDrawable(R.drawable.bot_location);
chat_redLocationIcon = resources.getDrawable(R.drawable.map_pin).mutate();
chat_botLinkDrawable = resources.getDrawable(R.drawable.bot_link); chat_botLinkDrawable = resources.getDrawable(R.drawable.bot_link);
chat_botInlineDrawable = resources.getDrawable(R.drawable.bot_lines); chat_botInlineDrawable = resources.getDrawable(R.drawable.bot_lines);
@ -8545,29 +8547,7 @@ public class Theme {
chat_composeShadowDrawable = context.getResources().getDrawable(R.drawable.compose_panel_shadow).mutate(); chat_composeShadowDrawable = context.getResources().getDrawable(R.drawable.compose_panel_shadow).mutate();
chat_composeShadowRoundDrawable = context.getResources().getDrawable(R.drawable.sheet_shadow_round).mutate(); chat_composeShadowRoundDrawable = context.getResources().getDrawable(R.drawable.sheet_shadow_round).mutate();
try { chat_roundVideoShadow = new RoundVideoShadow();
int bitmapSize = AndroidUtilities.roundMessageSize + AndroidUtilities.dp(6);
Bitmap bitmap = Bitmap.createBitmap(bitmapSize, bitmapSize, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
Paint eraserPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
eraserPaint.setColor(0);
eraserPaint.setStyle(Paint.Style.FILL);
eraserPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setShadowLayer(AndroidUtilities.dp(4), 0, 0, 0x5f000000);
for (int a = 0; a < 2; a++) {
canvas.drawCircle(bitmapSize / 2, bitmapSize / 2, AndroidUtilities.roundMessageSize / 2 - AndroidUtilities.dp(1), a == 0 ? paint : eraserPaint);
}
try {
canvas.setBitmap(null);
} catch (Exception ignore) {
}
chat_roundVideoShadow = new BitmapDrawable(bitmap);
} catch (Throwable ignore) {
}
defaultChatDrawables.clear(); defaultChatDrawables.clear();
defaultChatDrawableColorKeys.clear(); defaultChatDrawableColorKeys.clear();
@ -9590,7 +9570,15 @@ public class Theme {
try { try {
if (backgroundColor != 0 && gradientToColor1 != 0 && gradientToColor2 != 0) { if (backgroundColor != 0 && gradientToColor1 != 0 && gradientToColor2 != 0) {
MotionBackgroundDrawable motionBackgroundDrawable = new MotionBackgroundDrawable(backgroundColor, gradientToColor1, gradientToColor2, gradientToColor3, false); MotionBackgroundDrawable motionBackgroundDrawable = new MotionBackgroundDrawable(backgroundColor, gradientToColor1, gradientToColor2, gradientToColor3, false);
motionBackgroundDrawable.setPatternBitmap(intensity, BitmapFactory.decodeFile(wallpaperFile.getAbsolutePath())); BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ALPHA_8;
Bitmap patternBitmap = BitmapFactory.decodeFile(wallpaperFile.getAbsolutePath(), options);
if (patternBitmap != null && patternBitmap.getConfig() != Bitmap.Config.ALPHA_8) {
Bitmap toRecycle = patternBitmap;
patternBitmap = patternBitmap.copy(Bitmap.Config.ALPHA_8, false);
toRecycle.recycle();
}
motionBackgroundDrawable.setPatternBitmap(intensity, patternBitmap);
motionBackgroundDrawable.setPatternColorFilter(motionBackgroundDrawable.getPatternColor()); motionBackgroundDrawable.setPatternColorFilter(motionBackgroundDrawable.getPatternColor());
settings.wallpaper = motionBackgroundDrawable; settings.wallpaper = motionBackgroundDrawable;
} else { } else {
@ -9932,6 +9920,7 @@ public class Theme {
photoH /= 2; photoH /= 2;
} }
} }
opts.inPreferredConfig = Bitmap.Config.ALPHA_8;
opts.inJustDecodeBounds = false; opts.inJustDecodeBounds = false;
opts.inSampleSize = scaleFactor; opts.inSampleSize = scaleFactor;
Bitmap bitmap = BitmapFactory.decodeStream(stream, null, opts); Bitmap bitmap = BitmapFactory.decodeStream(stream, null, opts);
@ -9943,6 +9932,11 @@ public class Theme {
} else { } else {
intensity = 100; intensity = 100;
} }
if (bitmap != null && bitmap.getConfig() != Bitmap.Config.ALPHA_8) {
Bitmap toRecycle = bitmap;
bitmap = bitmap.copy(Bitmap.Config.ALPHA_8, false);
toRecycle.recycle();
}
motionBackgroundDrawable.setPatternBitmap(intensity, bitmap); motionBackgroundDrawable.setPatternBitmap(intensity, bitmap);
motionBackgroundDrawable.setPatternColorFilter(motionBackgroundDrawable.getPatternColor()); motionBackgroundDrawable.setPatternColorFilter(motionBackgroundDrawable.getPatternColor());
return motionBackgroundDrawable; return motionBackgroundDrawable;

View file

@ -92,6 +92,7 @@ import android.widget.Toast;
import androidx.annotation.Keep; import androidx.annotation.Keep;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.collection.LongSparseArray; import androidx.collection.LongSparseArray;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.DefaultItemAnimator; import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.GridLayoutManagerFixed; import androidx.recyclerview.widget.GridLayoutManagerFixed;
@ -309,6 +310,7 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg
@SuppressLint("StaticFieldLeak") @SuppressLint("StaticFieldLeak")
private static volatile ArticleViewer Instance = null; private static volatile ArticleViewer Instance = null;
private Drawable chat_redLocationIcon;
public static ArticleViewer getInstance() { public static ArticleViewer getInstance() {
ArticleViewer localInstance = Instance; ArticleViewer localInstance = Instance;
@ -757,7 +759,7 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg
MotionEvent textSelectionEv = MotionEvent.obtain(ev); MotionEvent textSelectionEv = MotionEvent.obtain(ev);
textSelectionEv.offsetLocation(-containerView.getX(), -containerView.getY()); textSelectionEv.offsetLocation(-containerView.getX(), -containerView.getY());
if (textSelectionHelper.isSelectionMode() && textSelectionHelper.getOverlayView(getContext()).onTouchEvent(textSelectionEv)) { if (textSelectionHelper.isInSelectionMode() && textSelectionHelper.getOverlayView(getContext()).onTouchEvent(textSelectionEv)) {
return true; return true;
} }
@ -765,7 +767,7 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg
ev.setAction(MotionEvent.ACTION_CANCEL); ev.setAction(MotionEvent.ACTION_CANCEL);
} }
if (ev.getAction() == MotionEvent.ACTION_DOWN && textSelectionHelper.isSelectionMode() && (ev.getY() < containerView.getTop() || ev.getY() > containerView.getBottom())) { if (ev.getAction() == MotionEvent.ACTION_DOWN && textSelectionHelper.isInSelectionMode() && (ev.getY() < containerView.getTop() || ev.getY() > containerView.getBottom())) {
if (textSelectionHelper.getOverlayView(getContext()).onTouchEvent(textSelectionEv)) { if (textSelectionHelper.getOverlayView(getContext()).onTouchEvent(textSelectionEv)) {
return super.dispatchTouchEvent(ev); return super.dispatchTouchEvent(ev);
} else { } else {
@ -906,7 +908,7 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg
} }
public boolean handleTouchEvent(MotionEvent event) { public boolean handleTouchEvent(MotionEvent event) {
if (pageSwitchAnimation == null && !closeAnimationInProgress && fullscreenVideoContainer.getVisibility() != VISIBLE && !textSelectionHelper.isSelectionMode()) { if (pageSwitchAnimation == null && !closeAnimationInProgress && fullscreenVideoContainer.getVisibility() != VISIBLE && !textSelectionHelper.isInSelectionMode()) {
if (event != null && event.getAction() == MotionEvent.ACTION_DOWN && !startedTracking && !maybeStartTracking) { if (event != null && event.getAction() == MotionEvent.ACTION_DOWN && !startedTracking && !maybeStartTracking) {
startedTrackingPointerId = event.getPointerId(0); startedTrackingPointerId = event.getPointerId(0);
maybeStartTracking = true; maybeStartTracking = true;
@ -1035,7 +1037,7 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg
tracker.recycle(); tracker.recycle();
tracker = null; tracker = null;
} }
if (textSelectionHelper != null && !textSelectionHelper.isSelectionMode()) { if (textSelectionHelper != null && !textSelectionHelper.isInSelectionMode()) {
textSelectionHelper.clear(); textSelectionHelper.clear();
} }
} }
@ -1134,7 +1136,7 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg
} else { } else {
textSelectionHelper.trySelect(pressedLinkOwnerView); textSelectionHelper.trySelect(pressedLinkOwnerView);
} }
if (textSelectionHelper.isSelectionMode()) { if (textSelectionHelper.isInSelectionMode()) {
windowView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING); windowView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
} }
} else if (pressedLinkOwnerLayout != null && pressedLinkOwnerView != null) { } else if (pressedLinkOwnerLayout != null && pressedLinkOwnerView != null) {
@ -1733,7 +1735,7 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg
TextSelectionHelper.TextSelectionOverlay selectionOverlay = textSelectionHelperBottomSheet.getOverlayView(getContext()); TextSelectionHelper.TextSelectionOverlay selectionOverlay = textSelectionHelperBottomSheet.getOverlayView(getContext());
MotionEvent textSelectionEv = MotionEvent.obtain(ev); MotionEvent textSelectionEv = MotionEvent.obtain(ev);
textSelectionEv.offsetLocation(-linearLayout.getX(), -linearLayout.getY()); textSelectionEv.offsetLocation(-linearLayout.getX(), -linearLayout.getY());
if (textSelectionHelperBottomSheet.isSelectionMode() && textSelectionHelperBottomSheet.getOverlayView(getContext()).onTouchEvent(textSelectionEv)) { if (textSelectionHelperBottomSheet.isInSelectionMode() && textSelectionHelperBottomSheet.getOverlayView(getContext()).onTouchEvent(textSelectionEv)) {
return true; return true;
} }
@ -1741,7 +1743,7 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg
ev.setAction(MotionEvent.ACTION_CANCEL); ev.setAction(MotionEvent.ACTION_CANCEL);
} }
if (ev.getAction() == MotionEvent.ACTION_DOWN && textSelectionHelperBottomSheet.isSelectionMode() && (ev.getY() < linearLayout.getTop() || ev.getY() > linearLayout.getBottom())) { if (ev.getAction() == MotionEvent.ACTION_DOWN && textSelectionHelperBottomSheet.isInSelectionMode() && (ev.getY() < linearLayout.getTop() || ev.getY() > linearLayout.getBottom())) {
if (textSelectionHelperBottomSheet.getOverlayView(getContext()).onTouchEvent(textSelectionEv)) { if (textSelectionHelperBottomSheet.getOverlayView(getContext()).onTouchEvent(textSelectionEv)) {
return super.dispatchTouchEvent(ev); return super.dispatchTouchEvent(ev);
} else { } else {
@ -1762,7 +1764,7 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg
builder.setDelegate(new BottomSheet.BottomSheetDelegate() { builder.setDelegate(new BottomSheet.BottomSheetDelegate() {
@Override @Override
public boolean canDismiss() { public boolean canDismiss() {
if (textSelectionHelperBottomSheet != null && textSelectionHelperBottomSheet.isSelectionMode()){ if (textSelectionHelperBottomSheet != null && textSelectionHelperBottomSheet.isInSelectionMode()){
textSelectionHelperBottomSheet.clear(); textSelectionHelperBottomSheet.clear();
return false; return false;
} }
@ -1773,7 +1775,7 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg
frameLayout.addView(linearLayout, LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT); frameLayout.addView(linearLayout, LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT);
frameLayout.addView(overlayView, LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT); frameLayout.addView(overlayView, LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT);
builder.setCustomView(frameLayout); builder.setCustomView(frameLayout);
if (textSelectionHelper.isSelectionMode()) { if (textSelectionHelper.isInSelectionMode()) {
textSelectionHelper.clear(); textSelectionHelper.clear();
} }
showDialog(linkSheet = builder.create()); showDialog(linkSheet = builder.create());
@ -3186,7 +3188,7 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg
}); });
listView[i].setOnItemClickListener((view, position, x, y) -> { listView[i].setOnItemClickListener((view, position, x, y) -> {
if (textSelectionHelper != null) { if (textSelectionHelper != null) {
if (textSelectionHelper.isSelectionMode()) { if (textSelectionHelper.isInSelectionMode()) {
textSelectionHelper.clear(); textSelectionHelper.clear();
return; return;
} }
@ -4580,7 +4582,7 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg
return; return;
} }
} }
if (textSelectionHelper.isSelectionMode()) { if (textSelectionHelper.isInSelectionMode()) {
textSelectionHelper.clear(); textSelectionHelper.clear();
return; return;
} }
@ -7541,7 +7543,7 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg
pressedLinkOwnerView = null; pressedLinkOwnerView = null;
} }
updateChildTextPositions(); updateChildTextPositions();
if (textSelectionHelper != null && textSelectionHelper.isSelectionMode()) { if (textSelectionHelper != null && textSelectionHelper.isInSelectionMode()) {
textSelectionHelper.invalidate(); textSelectionHelper.invalidate();
} }
} }
@ -10394,13 +10396,16 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg
imageView.draw(canvas); imageView.draw(canvas);
if (currentMapProvider == 2 && imageView.hasNotThumb()) { if (currentMapProvider == 2 && imageView.hasNotThumb()) {
int w = (int) (Theme.chat_redLocationIcon.getIntrinsicWidth() * 0.8f); if (chat_redLocationIcon == null) {
int h = (int) (Theme.chat_redLocationIcon.getIntrinsicHeight() * 0.8f); chat_redLocationIcon = ContextCompat.getDrawable(getContext(), R.drawable.map_pin).mutate();
}
int w = (int) (chat_redLocationIcon.getIntrinsicWidth() * 0.8f);
int h = (int) (chat_redLocationIcon.getIntrinsicHeight() * 0.8f);
int x = (int) (imageView.getImageX() + (imageView.getImageWidth() - w) / 2); int x = (int) (imageView.getImageX() + (imageView.getImageWidth() - w) / 2);
int y = (int) (imageView.getImageY() + (imageView.getImageHeight() / 2 - h)); int y = (int) (imageView.getImageY() + (imageView.getImageHeight() / 2 - h));
Theme.chat_redLocationIcon.setAlpha((int) (255 * imageView.getCurrentAlpha())); chat_redLocationIcon.setAlpha((int) (255 * imageView.getCurrentAlpha()));
Theme.chat_redLocationIcon.setBounds(x, y, x + w, y + h); chat_redLocationIcon.setBounds(x, y, x + w, y + h);
Theme.chat_redLocationIcon.draw(canvas); chat_redLocationIcon.draw(canvas);
} }
int count = 0; int count = 0;
if (captionLayout != null) { if (captionLayout != null) {
@ -11059,7 +11064,7 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg
if (Build.VERSION.SDK_INT >= 23) { if (Build.VERSION.SDK_INT >= 23) {
scrollView.setOnScrollChangeListener((v, scrollX, scrollY, oldScrollX, oldScrollY) -> { scrollView.setOnScrollChangeListener((v, scrollX, scrollY, oldScrollX, oldScrollY) -> {
if (textSelectionHelper != null && textSelectionHelper.isSelectionMode()) { if (textSelectionHelper != null && textSelectionHelper.isInSelectionMode()) {
textSelectionHelper.invalidate(); textSelectionHelper.invalidate();
} }
}); });

View file

@ -149,7 +149,7 @@ public class CacheControlActivity extends BaseFragment implements NotificationCe
private LinearLayoutManager layoutManager; private LinearLayoutManager layoutManager;
AlertDialog progressDialog; AlertDialog progressDialog;
private boolean[] selected = new boolean[] { true, true, true, true, true, true, true, true, true }; private boolean[] selected = new boolean[] { true, true, true, true, true, true, true, true, true, true };
private long databaseSize = -1; private long databaseSize = -1;
private long cacheSize = -1, cacheEmojiSize = -1, cacheTempSize = -1; private long cacheSize = -1, cacheEmojiSize = -1, cacheTempSize = -1;
private long documentsSize = -1; private long documentsSize = -1;
@ -374,7 +374,7 @@ public class CacheControlActivity extends BaseFragment implements NotificationCe
if (canceled) { if (canceled) {
return; return;
} }
totalSize = lastTotalSizeCalculated = cacheSize + cacheTempSize + videoSize + audioSize + photoSize + documentsSize + musicSize + stickersCacheSize; totalSize = lastTotalSizeCalculated = cacheSize + cacheTempSize + videoSize + audioSize + photoSize + documentsSize + musicSize + storiesSize + stickersCacheSize;
lastTotalSizeCalculatedTime = System.currentTimeMillis(); lastTotalSizeCalculatedTime = System.currentTimeMillis();
File path; File path;
@ -441,13 +441,13 @@ public class CacheControlActivity extends BaseFragment implements NotificationCe
private void updateChart() { private void updateChart() {
if (cacheChart != null) { if (cacheChart != null) {
if (!calculating && totalSize > 0) { if (!calculating && totalSize > 0) {
CacheChart.SegmentSize[] segments = new CacheChart.SegmentSize[9]; CacheChart.SegmentSize[] segments = new CacheChart.SegmentSize[10];
for (int i = 0; i < itemInners.size(); ++i) { for (int i = 0; i < itemInners.size(); ++i) {
ItemInner item = itemInners.get(i); ItemInner item = itemInners.get(i);
if (item.viewType == VIEW_TYPE_SECTION) { if (item.viewType == VIEW_TYPE_SECTION) {
if (item.index < 0) { if (item.index < 0) {
if (collapsed) { if (collapsed) {
segments[8] = CacheChart.SegmentSize.of(item.size, selected[8]); segments[9] = CacheChart.SegmentSize.of(item.size, selected[9]);
} }
} else { } else {
segments[item.index] = CacheChart.SegmentSize.of(item.size, selected[item.index]); segments[item.index] = CacheChart.SegmentSize.of(item.size, selected[item.index]);
@ -716,13 +716,13 @@ public class CacheControlActivity extends BaseFragment implements NotificationCe
sections.add(ItemInner.asCheckBox(LocaleController.getString(R.string.LocalDocumentCache), 2, documentsSize, Theme.key_statisticChartLine_green)); sections.add(ItemInner.asCheckBox(LocaleController.getString(R.string.LocalDocumentCache), 2, documentsSize, Theme.key_statisticChartLine_green));
} }
if (musicSize > 0) { if (musicSize > 0) {
sections.add(ItemInner.asCheckBox(LocaleController.getString(R.string.LocalMusicCache), 3, musicSize, Theme.key_statisticChartLine_red)); sections.add(ItemInner.asCheckBox(LocaleController.getString(R.string.LocalMusicCache), 3, musicSize, Theme.key_statisticChartLine_purple));
} }
if (audioSize > 0) { if (audioSize > 0) {
sections.add(ItemInner.asCheckBox(LocaleController.getString(R.string.LocalAudioCache), 4, audioSize, Theme.key_statisticChartLine_lightgreen)); sections.add(ItemInner.asCheckBox(LocaleController.getString(R.string.LocalAudioCache), 4, audioSize, Theme.key_statisticChartLine_lightgreen));
} }
if (storiesSize > 0) { if (storiesSize > 0) {
sections.add(ItemInner.asCheckBox(LocaleController.getString(R.string.LocalStoriesCache), 5, storiesSize, Theme.key_statisticChartLine_indigo)); sections.add(ItemInner.asCheckBox(LocaleController.getString(R.string.LocalStoriesCache), 5, storiesSize, Theme.key_statisticChartLine_red));
} }
if (stickersCacheSize > 0) { if (stickersCacheSize > 0) {
sections.add(ItemInner.asCheckBox(LocaleController.getString(R.string.LocalStickersCache), 6, stickersCacheSize, Theme.key_statisticChartLine_orange)); sections.add(ItemInner.asCheckBox(LocaleController.getString(R.string.LocalStickersCache), 6, stickersCacheSize, Theme.key_statisticChartLine_orange));
@ -739,13 +739,13 @@ public class CacheControlActivity extends BaseFragment implements NotificationCe
hasCache = true; hasCache = true;
if (tempSizes == null) { if (tempSizes == null) {
tempSizes = new float[9]; tempSizes = new float[10];
} }
for (int i = 0; i < tempSizes.length; ++i) { for (int i = 0; i < tempSizes.length; ++i) {
tempSizes[i] = (float) size(i); tempSizes[i] = (float) size(i);
} }
if (percents == null) { if (percents == null) {
percents = new int[9]; percents = new int[10];
} }
AndroidUtilities.roundPercents(tempSizes, percents); AndroidUtilities.roundPercents(tempSizes, percents);
@ -759,7 +759,7 @@ public class CacheControlActivity extends BaseFragment implements NotificationCe
sum += sections.get(i).size; sum += sections.get(i).size;
sumPercents += percents[sections.get(i).index]; sumPercents += percents[sections.get(i).index];
} }
percents[8] = sumPercents; percents[9] = sumPercents;
itemInners.add(ItemInner.asCheckBox(LocaleController.getString(R.string.LocalOther), -1, sum, Theme.key_statisticChartLine_golden)); itemInners.add(ItemInner.asCheckBox(LocaleController.getString(R.string.LocalOther), -1, sum, Theme.key_statisticChartLine_golden));
if (!collapsed) { if (!collapsed) {
itemInners.addAll(sections.subList(MAX_NOT_COLLAPSED, sections.size())); itemInners.addAll(sections.subList(MAX_NOT_COLLAPSED, sections.size()));
@ -963,7 +963,7 @@ public class CacheControlActivity extends BaseFragment implements NotificationCe
long clearedSize = 0; long clearedSize = 0;
boolean allItemsClear = true; boolean allItemsClear = true;
final int[] clearDirI = new int[] { 0 }; final int[] clearDirI = new int[] { 0 };
int clearDirCount = (selected[0] ? 2 : 0) + (selected[1] ? 2 : 0) + (selected[2] ? 2 : 0) + (selected[3] ? 2 : 0) + (selected[4] ? 1 : 0) + (selected[5] ? 2 : 0) + (selected[6] ? 1 : 0) + (selected[7] ? 1 : 0); int clearDirCount = (selected[0] ? 2 : 0) + (selected[1] ? 2 : 0) + (selected[2] ? 2 : 0) + (selected[3] ? 2 : 0) + (selected[4] ? 1 : 0) + (selected[5] ? 2 : 0) + (selected[6] ? 1 : 0) + (selected[7] ? 1 : 0) + (selected[8] ? 1 : 0);
long time = System.currentTimeMillis(); long time = System.currentTimeMillis();
Utilities.Callback<Float> updateProgress = t -> { Utilities.Callback<Float> updateProgress = t -> {
onProgress.run(clearDirI[0] / (float) clearDirCount + (1f / clearDirCount) * MathUtils.clamp(t, 0, 1), false); onProgress.run(clearDirI[0] / (float) clearDirCount + (1f / clearDirCount) * MathUtils.clamp(t, 0, 1), false);
@ -1001,7 +1001,7 @@ public class CacheControlActivity extends BaseFragment implements NotificationCe
clearedSize += storiesSize; clearedSize += storiesSize;
} else if (a == 6) { } else if (a == 6) {
type = 100; type = 100;
clearedSize += stickersCacheSize + cacheEmojiSize; clearedSize += stickersCacheSize;
} else if (a == 7) { } else if (a == 7) {
clearedSize += cacheSize; clearedSize += cacheSize;
documentsMusicType = 5; documentsMusicType = 5;
@ -1088,7 +1088,7 @@ public class CacheControlActivity extends BaseFragment implements NotificationCe
} }
} }
final boolean imagesClearedFinal = imagesCleared; final boolean imagesClearedFinal = imagesCleared;
totalSize = lastTotalSizeCalculated = cacheSize + cacheTempSize + videoSize + audioSize + photoSize + documentsSize + musicSize + stickersCacheSize; totalSize = lastTotalSizeCalculated = cacheSize + cacheTempSize + videoSize + audioSize + photoSize + documentsSize + musicSize + stickersCacheSize + storiesSize;
lastTotalSizeCalculatedTime = System.currentTimeMillis(); lastTotalSizeCalculatedTime = System.currentTimeMillis();
Arrays.fill(selected, true); Arrays.fill(selected, true);
@ -1176,16 +1176,17 @@ public class CacheControlActivity extends BaseFragment implements NotificationCe
case 2: return documentsSize; case 2: return documentsSize;
case 3: return musicSize; case 3: return musicSize;
case 4: return audioSize; case 4: return audioSize;
case 5: return stickersCacheSize; case 5: return storiesSize;
case 6: return cacheSize; case 6: return stickersCacheSize;
case 7: return cacheTempSize; case 7: return cacheSize;
case 8: return cacheTempSize;
default: return 0; default: return 0;
} }
} }
private int sectionsSelected() { private int sectionsSelected() {
int count = 0; int count = 0;
for (int i = 0; i < 8; ++i) { for (int i = 0; i < 9; ++i) {
if (selected[i] && size(i) > 0) { if (selected[i] && size(i) > 0) {
count++; count++;
} }

View file

@ -84,6 +84,7 @@ import org.telegram.PhoneFormat.PhoneFormat;
import org.telegram.messenger.AccountInstance; import org.telegram.messenger.AccountInstance;
import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.ChatMessageSharedResources;
import org.telegram.messenger.ChatObject; import org.telegram.messenger.ChatObject;
import org.telegram.messenger.ContactsController; import org.telegram.messenger.ContactsController;
import org.telegram.messenger.DialogObject; import org.telegram.messenger.DialogObject;
@ -1287,6 +1288,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
private Theme.ResourcesProvider resourcesProvider; private Theme.ResourcesProvider resourcesProvider;
private final boolean canDrawBackgroundInParent; private final boolean canDrawBackgroundInParent;
private ChatMessageSharedResources sharedResources;
// Public for enter transition // Public for enter transition
public List<SpoilerEffect> replySpoilers = new ArrayList<>(); public List<SpoilerEffect> replySpoilers = new ArrayList<>();
@ -1298,13 +1300,17 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
public boolean isBlurred; public boolean isBlurred;
public ChatMessageCell(Context context) { public ChatMessageCell(Context context) {
this(context, false, null); this(context, false, null, null);
} }
public ChatMessageCell(Context context, boolean canDrawBackgroundInParent, Theme.ResourcesProvider resourcesProvider) { public ChatMessageCell(Context context, boolean canDrawBackgroundInParent, ChatMessageSharedResources sharedResources, Theme.ResourcesProvider resourcesProvider) {
super(context); super(context);
this.resourcesProvider = resourcesProvider; this.resourcesProvider = resourcesProvider;
this.canDrawBackgroundInParent = canDrawBackgroundInParent; this.canDrawBackgroundInParent = canDrawBackgroundInParent;
this.sharedResources = sharedResources;
if (this.sharedResources == null) {
this.sharedResources = new ChatMessageSharedResources(context);
}
backgroundDrawable = new MessageBackgroundDrawable(this); backgroundDrawable = new MessageBackgroundDrawable(this);
avatarImage = new ImageReceiver(); avatarImage = new ImageReceiver();
@ -10293,13 +10299,14 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} }
} }
if (currentMessageObject.type == MessageObject.TYPE_GEO && !(MessageObject.getMedia(currentMessageObject.messageOwner) instanceof TLRPC.TL_messageMediaGeoLive) && currentMapProvider == 2 && photoImage.hasNotThumb()) { if (currentMessageObject.type == MessageObject.TYPE_GEO && !(MessageObject.getMedia(currentMessageObject.messageOwner) instanceof TLRPC.TL_messageMediaGeoLive) && currentMapProvider == 2 && photoImage.hasNotThumb()) {
int w = (int) (Theme.chat_redLocationIcon.getIntrinsicWidth() * 0.8f); Drawable redLocationIcon = sharedResources.getRedLocationIcon();
int h = (int) (Theme.chat_redLocationIcon.getIntrinsicHeight() * 0.8f); int w = (int) (redLocationIcon.getIntrinsicWidth() * 0.8f);
int h = (int) (redLocationIcon.getIntrinsicHeight() * 0.8f);
int x = (int) (photoImage.getImageX() + (photoImage.getImageWidth() - w) / 2); int x = (int) (photoImage.getImageX() + (photoImage.getImageWidth() - w) / 2);
int y = (int) (photoImage.getImageY() + (photoImage.getImageHeight() / 2 - h) - AndroidUtilities.dp(16) * (1f - CubicBezierInterpolator.EASE_OUT_BACK.getInterpolation(photoImage.getCurrentAlpha()))); int y = (int) (photoImage.getImageY() + (photoImage.getImageHeight() / 2 - h) - AndroidUtilities.dp(16) * (1f - CubicBezierInterpolator.EASE_OUT_BACK.getInterpolation(photoImage.getCurrentAlpha())));
Theme.chat_redLocationIcon.setAlpha((int) (255 * Math.min(1, photoImage.getCurrentAlpha() * 5))); redLocationIcon.setAlpha((int) (255 * Math.min(1, photoImage.getCurrentAlpha() * 5)));
Theme.chat_redLocationIcon.setBounds(x, y, x + w, y + h); redLocationIcon.setBounds(x, y, x + w, y + h);
Theme.chat_redLocationIcon.draw(canvas); redLocationIcon.draw(canvas);
if (photoImage.getCurrentAlpha() < 1) { if (photoImage.getCurrentAlpha() < 1) {
invalidate(); invalidate();
} }
@ -17192,9 +17199,10 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
int cx = (int) (photoImage.getImageX() + photoImage.getImageWidth() / 2 - AndroidUtilities.dp(31)); int cx = (int) (photoImage.getImageX() + photoImage.getImageWidth() / 2 - AndroidUtilities.dp(31));
cy = (int) (photoImage.getImageY() + photoImage.getImageHeight() / 2 - AndroidUtilities.dp(38) - AndroidUtilities.dp(16) * (1f - CubicBezierInterpolator.EASE_OUT_BACK.getInterpolation(progress))); cy = (int) (photoImage.getImageY() + photoImage.getImageHeight() / 2 - AndroidUtilities.dp(38) - AndroidUtilities.dp(16) * (1f - CubicBezierInterpolator.EASE_OUT_BACK.getInterpolation(progress)));
setDrawableBounds(Theme.chat_msgAvatarLiveLocationDrawable, cx, cy); Drawable msgAvatarLiveLocation = sharedResources.getAvatarLiveLocation();
Theme.chat_msgAvatarLiveLocationDrawable.setAlpha((int) (255 * Math.min(1, progress * 5))); setDrawableBounds(msgAvatarLiveLocation, cx, cy);
Theme.chat_msgAvatarLiveLocationDrawable.draw(canvas); msgAvatarLiveLocation.setAlpha((int) (255 * Math.min(1, progress * 5)));
msgAvatarLiveLocation.draw(canvas);
locationImageReceiver.setImageCoords(cx + AndroidUtilities.dp(5.0f), cy + AndroidUtilities.dp(5.0f), AndroidUtilities.dp(52), AndroidUtilities.dp(52)); locationImageReceiver.setImageCoords(cx + AndroidUtilities.dp(5.0f), cy + AndroidUtilities.dp(5.0f), AndroidUtilities.dp(52), AndroidUtilities.dp(52));
locationImageReceiver.setAlpha(Math.min(1, progress * 5)); locationImageReceiver.setAlpha(Math.min(1, progress * 5));

View file

@ -104,6 +104,7 @@ import org.telegram.ui.Components.VectorAvatarThumbDrawable;
import org.telegram.ui.Components.spoilers.SpoilerEffect; import org.telegram.ui.Components.spoilers.SpoilerEffect;
import org.telegram.ui.DialogsActivity; import org.telegram.ui.DialogsActivity;
import org.telegram.ui.RightSlidingDialogContainer; import org.telegram.ui.RightSlidingDialogContainer;
import org.telegram.ui.Stories.StoriesController;
import org.telegram.ui.Stories.StoriesListPlaceProvider; import org.telegram.ui.Stories.StoriesListPlaceProvider;
import org.telegram.ui.Stories.StoriesUtilities; import org.telegram.ui.Stories.StoriesUtilities;
import org.telegram.ui.Stories.StoryViewer; import org.telegram.ui.Stories.StoryViewer;
@ -185,7 +186,7 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
} }
}; };
private Path thumbPath = new Path(); private Path thumbPath;
private SpoilerEffect thumbSpoiler = new SpoilerEffect(); private SpoilerEffect thumbSpoiler = new SpoilerEffect();
public void setMoving(boolean moving) { public void setMoving(boolean moving) {
@ -708,6 +709,7 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
AnimatedEmojiSpan.release(this, animatedEmojiStack3); AnimatedEmojiSpan.release(this, animatedEmojiStack3);
AnimatedEmojiSpan.release(this, animatedEmojiStackName); AnimatedEmojiSpan.release(this, animatedEmojiStackName);
storyParams.onDetachFromWindow(); storyParams.onDetachFromWindow();
canvasButton = null;
} }
@Override @Override
@ -3765,7 +3767,11 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
); );
thumbImage[i].draw(canvas); thumbImage[i].draw(canvas);
if (drawSpoiler[i]) { if (drawSpoiler[i]) {
thumbPath.rewind(); if (thumbPath == null) {
thumbPath = new Path();
} else {
thumbPath.rewind();
}
thumbPath.addRoundRect(AndroidUtilities.rectTmp, thumbImage[i].getRoundRadius()[0], thumbImage[i].getRoundRadius()[1], Path.Direction.CW); thumbPath.addRoundRect(AndroidUtilities.rectTmp, thumbImage[i].getRoundRadius()[0], thumbImage[i].getRoundRadius()[1], Path.Direction.CW);
canvas.save(); canvas.save();
@ -4383,7 +4389,10 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
} else { } else {
archivedChatsDrawable.outCy = storyParams.originalAvatarRect.centerY(); archivedChatsDrawable.outCy = storyParams.originalAvatarRect.centerY();
archivedChatsDrawable.outCx = storyParams.originalAvatarRect.centerX(); archivedChatsDrawable.outCx = storyParams.originalAvatarRect.centerX();
archivedChatsDrawable.outRadius = avatarImage.getImageWidth() / 2.0f; archivedChatsDrawable.outRadius = storyParams.originalAvatarRect.width() / 2.0f;
if (MessagesController.getInstance(currentAccount).getStoriesController().hasHiddenStories()) {
archivedChatsDrawable.outRadius -= AndroidUtilities.dpf2(3.5f);
}
archivedChatsDrawable.outImageSize = avatarImage.getBitmapWidth(); archivedChatsDrawable.outImageSize = avatarImage.getBitmapWidth();
} }
archivedChatsDrawable.startOutAnimation(); archivedChatsDrawable.startOutAnimation();

View file

@ -37,6 +37,7 @@ import org.telegram.messenger.UserConfig;
import org.telegram.messenger.UserObject; import org.telegram.messenger.UserObject;
import org.telegram.tgnet.ConnectionsManager; import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.TLRPC; import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.ActionBar.Theme; import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.AnimatedEmojiDrawable; import org.telegram.ui.Components.AnimatedEmojiDrawable;
import org.telegram.ui.Components.AvatarDrawable; import org.telegram.ui.Components.AvatarDrawable;
@ -45,14 +46,17 @@ import org.telegram.ui.Components.CheckBox2;
import org.telegram.ui.Components.CombinedDrawable; import org.telegram.ui.Components.CombinedDrawable;
import org.telegram.ui.Components.Premium.PremiumGradient; import org.telegram.ui.Components.Premium.PremiumGradient;
import org.telegram.ui.Components.RecyclerListView; import org.telegram.ui.Components.RecyclerListView;
import org.telegram.ui.LaunchActivity;
import org.telegram.ui.NotificationsSettingsActivity; import org.telegram.ui.NotificationsSettingsActivity;
import org.telegram.ui.Stories.StoriesListPlaceProvider;
import org.telegram.ui.Stories.StoriesUtilities;
import java.util.Locale; import java.util.Locale;
public class ProfileSearchCell extends BaseCell implements NotificationCenter.NotificationCenterDelegate { public class ProfileSearchCell extends BaseCell implements NotificationCenter.NotificationCenterDelegate {
private CharSequence currentName; private CharSequence currentName;
private ImageReceiver avatarImage; public ImageReceiver avatarImage;
private AvatarDrawable avatarDrawable; private AvatarDrawable avatarDrawable;
private CharSequence subLabel; private CharSequence subLabel;
private Theme.ResourcesProvider resourcesProvider; private Theme.ResourcesProvider resourcesProvider;
@ -102,6 +106,7 @@ public class ProfileSearchCell extends BaseCell implements NotificationCenter.No
private int statusLeft; private int statusLeft;
private StaticLayout statusLayout; private StaticLayout statusLayout;
private AnimatedEmojiDrawable.SwapAnimatedEmojiDrawable statusDrawable; private AnimatedEmojiDrawable.SwapAnimatedEmojiDrawable statusDrawable;
public StoriesUtilities.AvatarStoryParams avatarStoryParams = new StoriesUtilities.AvatarStoryParams(false);
private RectF rect = new RectF(); private RectF rect = new RectF();
@ -503,8 +508,7 @@ public class ProfileSearchCell extends BaseCell implements NotificationCenter.No
} else { } else {
avatarLeft = AndroidUtilities.dp(11) + getPaddingLeft(); avatarLeft = AndroidUtilities.dp(11) + getPaddingLeft();
} }
avatarStoryParams.originalAvatarRect.set(avatarLeft, AndroidUtilities.dp(7), avatarLeft + AndroidUtilities.dp(46), AndroidUtilities.dp(7) + AndroidUtilities.dp(46));
avatarImage.setImageCoords(avatarLeft, AndroidUtilities.dp(7), AndroidUtilities.dp(46), AndroidUtilities.dp(46));
double widthpx; double widthpx;
float left; float left;
@ -745,7 +749,7 @@ public class ProfileSearchCell extends BaseCell implements NotificationCenter.No
actionLayout.draw(canvas); actionLayout.draw(canvas);
canvas.restore(); canvas.restore();
} }
avatarImage.draw(canvas); StoriesUtilities.drawAvatarWithStory(dialog_id, canvas, avatarImage, avatarStoryParams);
} }
@Override @Override
@ -790,6 +794,9 @@ public class ProfileSearchCell extends BaseCell implements NotificationCenter.No
@Override @Override
public boolean onTouchEvent(MotionEvent event) { public boolean onTouchEvent(MotionEvent event) {
if (avatarStoryParams.checkOnTouchEvent(event, this)) {
return true;
}
if (actionButton != null && actionButton.checkTouchEvent(event)) { if (actionButton != null && actionButton.checkTouchEvent(event)) {
return true; return true;
} }

View file

@ -38,6 +38,7 @@ import android.widget.Magnifier;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.core.widget.NestedScrollView;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.AndroidUtilities;
@ -281,6 +282,9 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
} }
}; };
protected Theme.ResourcesProvider resourcesProvider;
public boolean useMovingOffset = true;
private boolean invalidateParent;
public TextSelectionHelper() { public TextSelectionHelper() {
longpressDelay = ViewConfiguration.getLongPressTimeout(); longpressDelay = ViewConfiguration.getLongPressTimeout();
@ -288,6 +292,11 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
selectionPaint.setPathEffect(new CornerPathEffect(cornerRadius = AndroidUtilities.dp(6))); selectionPaint.setPathEffect(new CornerPathEffect(cornerRadius = AndroidUtilities.dp(6)));
} }
public void setInvalidateParent() {
invalidateParent = true;
}
public interface OnTranslateListener { public interface OnTranslateListener {
public void run(CharSequence text, String fromLang, String toLang, Runnable onAlertDismiss); public void run(CharSequence text, String fromLang, String toLang, Runnable onAlertDismiss);
} }
@ -381,7 +390,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
int offset = movingHandleStart ? selectionStart : selectionEnd; int offset = movingHandleStart ? selectionStart : selectionEnd;
fillLayoutForOffset(offset, layoutBlock); fillLayoutForOffset(offset, layoutBlock);
StaticLayout layout = layoutBlock.layout; Layout layout = layoutBlock.layout;
if (layout == null) { if (layout == null) {
return; return;
} }
@ -389,17 +398,18 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
int line = layout.getLineForOffset(offset); int line = layout.getLineForOffset(offset);
int lineHeight = layout.getLineBottom(line) - layout.getLineTop(line); int lineHeight = layout.getLineBottom(line) - layout.getLineTop(line);
int newY = (int) (layout.getLineTop(line) + textY + selectedView.getY()) - lineHeight - AndroidUtilities.dp(8); int[] coordsInParent = getCoordsInParent();
int newY = (int) (layout.getLineTop(line) + textY + coordsInParent[1]) - lineHeight - AndroidUtilities.dp(8);
newY += layoutBlock.yOffset; newY += layoutBlock.yOffset;
int startLine; int startLine;
int endLine; int endLine;
if (selectedView instanceof ArticleViewer.BlockTableCell) { if (selectedView instanceof ArticleViewer.BlockTableCell) {
startLine = (int) selectedView.getX(); startLine = (int) coordsInParent[0];
endLine = (int) selectedView.getX() + selectedView.getMeasuredWidth(); endLine = (int) coordsInParent[0] + selectedView.getMeasuredWidth();
} else { } else {
startLine = (int) (selectedView.getX() + textX + layout.getLineLeft(line)); startLine = (int) (coordsInParent[0] + textX + layout.getLineLeft(line));
endLine = (int) (selectedView.getX() + textX + layout.getLineRight(line)); endLine = (int) (coordsInParent[0] + textX + layout.getLineRight(line));
} }
if (x < startLine) { if (x < startLine) {
x = startLine; x = startLine;
@ -467,7 +477,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
handleViewAnimator.start(); handleViewAnimator.start();
} }
public boolean isSelectionMode() { public boolean isInSelectionMode() {
return selectionStart >= 0 && selectionEnd >= 0; return selectionStart >= 0 && selectionEnd >= 0;
} }
@ -481,7 +491,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
return; return;
} }
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!movingHandle && isSelectionMode() && canShowActions()) { if (!movingHandle && isInSelectionMode() && canShowActions()) {
if (!actionsIsShowing) { if (!actionsIsShowing) {
if (actionMode == null) { if (actionMode == null) {
FloatingToolbar floatingToolbar = new FloatingToolbar(textSelectionOverlay.getContext(), textSelectionOverlay, STYLE_THEME, getResourcesProvider()); FloatingToolbar floatingToolbar = new FloatingToolbar(textSelectionOverlay.getContext(), textSelectionOverlay, STYLE_THEME, getResourcesProvider());
@ -496,11 +506,11 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
} }
} else { } else {
if (!showActionsAsPopupAlways) { if (!showActionsAsPopupAlways) {
if (actionMode == null && isSelectionMode()) { if (actionMode == null && isInSelectionMode()) {
actionMode = textSelectionOverlay.startActionMode(textSelectActionCallback); actionMode = textSelectionOverlay.startActionMode(textSelectActionCallback);
} }
} else { } else {
if (!movingHandle && isSelectionMode() && canShowActions()) { if (!movingHandle && isInSelectionMode() && canShowActions()) {
if (popupLayout == null) { if (popupLayout == null) {
popupRect = new android.graphics.Rect(); popupRect = new android.graphics.Rect();
popupLayout = new ActionBarPopupWindow.ActionBarPopupWindowLayout(textSelectionOverlay.getContext()); popupLayout = new ActionBarPopupWindow.ActionBarPopupWindowLayout(textSelectionOverlay.getContext());
@ -544,7 +554,8 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
if (selectedView != null) { if (selectedView != null) {
int lineHeight = -getLineHeight(); int lineHeight = -getLineHeight();
int[] coords = offsetToCord(selectionStart); int[] coords = offsetToCord(selectionStart);
y = (int) (coords[1] + textY + selectedView.getY()) + lineHeight / 2 - AndroidUtilities.dp(4); int[] coordsInParent = getCoordsInParent();
y = (int) (coords[1] + textY + coordsInParent[1]) + lineHeight / 2 - AndroidUtilities.dp(4);
if (y < 0) y = 0; if (y < 0) y = 0;
} }
@ -580,7 +591,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
} }
actionsIsShowing = false; actionsIsShowing = false;
} }
if (!isSelectionMode() && actionMode != null) { if (!isInSelectionMode() && actionMode != null) {
actionMode.finish(); actionMode.finish();
actionMode = null; actionMode = null;
} }
@ -658,7 +669,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
} }
public void onParentScrolled() { public void onParentScrolled() {
if (isSelectionMode() && textSelectionOverlay != null) { if (isInSelectionMode() && textSelectionOverlay != null) {
parentIsScrolling = true; parentIsScrolling = true;
textSelectionOverlay.invalidate(); textSelectionOverlay.invalidate();
hideActions(); hideActions();
@ -695,7 +706,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
public boolean checkOnTap(MotionEvent event) { public boolean checkOnTap(MotionEvent event) {
if (!isSelectionMode() || movingHandle) return false; if (!isInSelectionMode() || movingHandle) return false;
switch (event.getAction()) { switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_DOWN:
pressedX = event.getX(); pressedX = event.getX();
@ -717,7 +728,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
@Override @Override
public boolean onTouchEvent(MotionEvent event) { public boolean onTouchEvent(MotionEvent event) {
if (!isSelectionMode()) return false; if (!isInSelectionMode()) return false;
if (event.getPointerCount() > 1) { if (event.getPointerCount() > 1) {
return movingHandle; return movingHandle;
} }
@ -747,8 +758,13 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
float textSizeHalf = getLineHeight() / 2; float textSizeHalf = getLineHeight() / 2;
movingOffsetX = cords[0] + textX + selectedView.getX() - x; int[] coordsInParent = getCoordsInParent();
movingOffsetY = cords[1] + textY + selectedView.getTop() - y - textSizeHalf; if (useMovingOffset) {
movingOffsetX = cords[0] + textX + coordsInParent[0] - x;
} else {
movingOffsetX = 0;
}
movingOffsetY = cords[1] + textY + coordsInParent[1] - y - textSizeHalf;
hideActions(); hideActions();
return true; return true;
} }
@ -763,8 +779,9 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
int[] cords = offsetToCord(selectionEnd); int[] cords = offsetToCord(selectionEnd);
float textSizeHalf = getLineHeight() / 2; float textSizeHalf = getLineHeight() / 2;
movingOffsetX = cords[0] + textX + selectedView.getX() - x; int[] coordsInParent = getCoordsInParent();
movingOffsetY = cords[1] + textY + selectedView.getTop() - y - textSizeHalf; movingOffsetX = cords[0] + textX + coordsInParent[0] - x;
movingOffsetY = cords[1] + textY + coordsInParent[1] - y - textSizeHalf;
showMagnifier(lastX); showMagnifier(lastX);
hideActions(); hideActions();
return true; return true;
@ -799,15 +816,16 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
fillLayoutForOffset(selectionEnd, layoutBlock); fillLayoutForOffset(selectionEnd, layoutBlock);
} }
StaticLayout oldTextLayout = layoutBlock.layout; Layout oldTextLayout = layoutBlock.layout;
if (oldTextLayout == null) { if (oldTextLayout == null) {
return true; return true;
} }
float oldYoffset = layoutBlock.yOffset; float oldYoffset = layoutBlock.yOffset;
Cell oldSelectedView = selectedView; Cell oldSelectedView = selectedView;
y -= selectedView.getTop(); int[] coordsInParent = getCoordsInParent();
x -= selectedView.getX(); y -= coordsInParent[1];
x -= coordsInParent[0];
boolean canScrollDown = event.getY() - touchSlop > parentView.getMeasuredHeight() - getParentBottomPadding() && (multiselect || selectedView.getBottom() > parentView.getMeasuredHeight() - getParentBottomPadding()); boolean canScrollDown = event.getY() - touchSlop > parentView.getMeasuredHeight() - getParentBottomPadding() && (multiselect || selectedView.getBottom() > parentView.getMeasuredHeight() - getParentBottomPadding());
boolean canScrollUp = event.getY() < ((View) parentView.getParent()).getTop() + getParentTopPadding() && (multiselect || selectedView.getTop() < getParentTopPadding()); boolean canScrollUp = event.getY() < ((View) parentView.getParent()).getTop() + getParentTopPadding() && (multiselect || selectedView.getTop() < getParentTopPadding());
@ -852,10 +870,10 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
CharSequence text = getText(selectedView, false); CharSequence text = getText(selectedView, false);
fillLayoutForOffset(newSelection, layoutBlock); fillLayoutForOffset(newSelection, layoutBlock);
StaticLayout layoutOld = layoutBlock.layout; Layout layoutOld = layoutBlock.layout;
fillLayoutForOffset(selectionStart, layoutBlock); fillLayoutForOffset(selectionStart, layoutBlock);
StaticLayout layoutNew = layoutBlock.layout; Layout layoutNew = layoutBlock.layout;
if (layoutOld == null || layoutNew == null) { if (layoutOld == null || layoutNew == null) {
return true; return true;
@ -954,10 +972,10 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
fillLayoutForOffset(newSelection, layoutBlock); fillLayoutForOffset(newSelection, layoutBlock);
StaticLayout layoutOld = layoutBlock.layout; Layout layoutOld = layoutBlock.layout;
fillLayoutForOffset(selectionEnd, layoutBlock); fillLayoutForOffset(selectionEnd, layoutBlock);
StaticLayout layoutNew = layoutBlock.layout; Layout layoutNew = layoutBlock.layout;
if (layoutOld == null || layoutNew == null) { if (layoutOld == null || layoutNew == null) {
return true; return true;
@ -1037,7 +1055,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
movingHandle = false; movingHandle = false;
movingDirectionSettling = false; movingDirectionSettling = false;
isOneTouch = false; isOneTouch = false;
if (isSelectionMode()) { if (isInSelectionMode()) {
showActions(); showActions();
showHandleViews(); showHandleViews();
} }
@ -1053,7 +1071,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
@Override @Override
protected void onDraw(Canvas canvas) { protected void onDraw(Canvas canvas) {
if (!isSelectionMode()) return; if (!isInSelectionMode()) return;
int handleViewSize = AndroidUtilities.dp(22); int handleViewSize = AndroidUtilities.dp(22);
int count = 0; int count = 0;
@ -1061,8 +1079,10 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
pickEndView(); pickEndView();
if (selectedView != null) { if (selectedView != null) {
canvas.save(); canvas.save();
float yOffset = selectedView.getY() + textY; int[] coordsInParent = getCoordsInParent();
float xOffset = selectedView.getX() + textX; float yOffset = coordsInParent[1] + textY;
float xOffset = coordsInParent[0] + textX;
canvas.translate(xOffset, yOffset); canvas.translate(xOffset, yOffset);
MessageObject msg = selectedView instanceof ChatMessageCell ? ((ChatMessageCell) selectedView).getMessageObject() : null; MessageObject msg = selectedView instanceof ChatMessageCell ? ((ChatMessageCell) selectedView).getMessageObject() : null;
@ -1076,7 +1096,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
if (selectionEnd >= 0 && selectionEnd <= len) { if (selectionEnd >= 0 && selectionEnd <= len) {
fillLayoutForOffset(selectionEnd, layoutBlock); fillLayoutForOffset(selectionEnd, layoutBlock);
StaticLayout layout = layoutBlock.layout; Layout layout = layoutBlock.layout;
if (layout != null) { if (layout != null) {
int end = selectionEnd - layoutBlock.charOffset; int end = selectionEnd - layoutBlock.charOffset;
int textLen = layout.getText().length(); int textLen = layout.getText().length();
@ -1133,15 +1153,16 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
pickStartView(); pickStartView();
if (selectedView != null) { if (selectedView != null) {
canvas.save(); canvas.save();
float yOffset = selectedView.getY() + textY; int[] coordsInParent = getCoordsInParent();
float xOffset = selectedView.getX() + textX; float yOffset = coordsInParent[1] + textY;
float xOffset = coordsInParent[0] + textX;
canvas.translate(xOffset, yOffset); canvas.translate(xOffset, yOffset);
int len = getText(selectedView, false).length(); int len = getText(selectedView, false).length();
if (selectionStart >= 0 && selectionStart <= len) { if (selectionStart >= 0 && selectionStart <= len) {
fillLayoutForOffset(selectionStart, layoutBlock); fillLayoutForOffset(selectionStart, layoutBlock);
StaticLayout layout = layoutBlock.layout; Layout layout = layoutBlock.layout;
if (layout != null) { if (layout != null) {
int start = selectionStart - layoutBlock.charOffset; int start = selectionStart - layoutBlock.charOffset;
int line = layout.getLineForOffset(start); int line = layout.getLineForOffset(start);
@ -1222,6 +1243,67 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
invalidate(); invalidate();
} }
} }
public boolean isTouched() {
return movingHandle;
}
public void checkCancel(float lastMotionX, float lastMotionY, boolean inParent) {
if (!inParent) {
int[] coordsInParent = getCoordsInParent();
lastMotionY += coordsInParent[1] + textY;
}
if (!movingHandle && (lastMotionY < startArea.top - AndroidUtilities.dp(8) || lastMotionY > endArea.bottom + AndroidUtilities.dp(8))) {
clear();
}
}
float cancelPressedX, cancelPressedY;
public void checkCancelAction(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
cancelPressedX = ev.getX();
cancelPressedY = ev.getY();
} else if (Math.abs(ev.getX() - cancelPressedX) < AndroidUtilities.touchSlop && Math.abs(ev.getY() - cancelPressedY) < AndroidUtilities.touchSlop && (ev.getAction() == MotionEvent.ACTION_CANCEL || ev.getAction() == MotionEvent.ACTION_UP)) {
checkCancel(ev.getX(), ev.getY(), true);
}
}
@Override
public void invalidate() {
super.invalidate();
if (invalidateParent && parentView != null) {
parentView.invalidate();
}
}
}
private int[] getCoordsInParent() {
View child = (View) selectedView;
int yOffset = 0;
int xOffset = 0;
if (child != null && parentView != null) {
while (child != parentView) {
if (child == null) {
xOffset = 0;
yOffset = 0;
break;
}
yOffset += child.getY();
xOffset += child.getX();
if (child instanceof NestedScrollView) {
yOffset -= child.getScrollY();
xOffset -= child.getScrollX();
}
if (child.getParent() instanceof View) {
child = (View) child.getParent();
} else {
xOffset = 0;
yOffset = 0;
break;
}
}
}
return new int[] {xOffset, yOffset};
} }
protected void jumpToLine(int newSelection, int nextWhitespace, boolean viewChanged, float newYoffset, float oldYoffset, Cell oldSelectedView) { protected void jumpToLine(int newSelection, int nextWhitespace, boolean viewChanged, float newYoffset, float oldYoffset, Cell oldSelectedView) {
@ -1333,7 +1415,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
@Override @Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) { public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
if (!isSelectionMode()) { if (!isInSelectionMode()) {
return true; return true;
} }
switch (item.getItemId()) { switch (item.getItemId()) {
@ -1396,17 +1478,18 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
@Override @Override
public void onGetContentRect(ActionMode mode, View view, Rect outRect) { public void onGetContentRect(ActionMode mode, View view, Rect outRect) {
if (!isSelectionMode()) { if (!isInSelectionMode()) {
return; return;
} }
pickStartView(); pickStartView();
int x1 = 0; int x1 = 0;
int y1 = 1; int y1 = 1;
int[] coordsInParent = getCoordsInParent();
if (selectedView != null) { if (selectedView != null) {
int lineHeight = -getLineHeight(); int lineHeight = -getLineHeight();
int[] coords = offsetToCord(selectionStart); int[] coords = offsetToCord(selectionStart);
x1 = coords[0] + textX; x1 = coords[0] + textX;
y1 = (int) (coords[1] + textY + selectedView.getY()) + lineHeight / 2 - AndroidUtilities.dp(4); y1 = (int) (coords[1] + textY + coordsInParent[1]) + lineHeight / 2 - AndroidUtilities.dp(4);
if (y1 < 1) y1 = 1; if (y1 < 1) y1 = 1;
} }
@ -1428,7 +1511,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
} }
private void copyText() { private void copyText() {
if (!isSelectionMode()) { if (!isInSelectionMode()) {
return; return;
} }
CharSequence str = getSelectedText(); CharSequence str = getSelectedText();
@ -1444,7 +1527,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
} }
private void translateText() { private void translateText() {
if (!isSelectionMode()) { if (!isInSelectionMode()) {
return; return;
} }
CharSequence str = getSelectedText(); CharSequence str = getSelectedText();
@ -1464,7 +1547,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
protected int[] offsetToCord(int offset) { protected int[] offsetToCord(int offset) {
fillLayoutForOffset(offset, layoutBlock); fillLayoutForOffset(offset, layoutBlock);
StaticLayout layout = layoutBlock.layout; Layout layout = layoutBlock.layout;
int blockOffset = offset - layoutBlock.charOffset; int blockOffset = offset - layoutBlock.charOffset;
if (layout == null || blockOffset < 0 || blockOffset > layout.getText().length()) { if (layout == null || blockOffset < 0 || blockOffset > layout.getText().length()) {
return tmpCoord; return tmpCoord;
@ -1477,7 +1560,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
return tmpCoord; return tmpCoord;
} }
protected void drawSelection(Canvas canvas, StaticLayout layout, int selectionStart, int selectionEnd, boolean hasStart, boolean hasEnd) { protected void drawSelection(Canvas canvas, Layout layout, int selectionStart, int selectionEnd, boolean hasStart, boolean hasEnd) {
selectionPath.reset(); selectionPath.reset();
selectionHandlePath.reset(); selectionHandlePath.reset();
final float R = cornerRadius * 1.65f; final float R = cornerRadius * 1.65f;
@ -1574,7 +1657,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
} }
private final ScalablePath tempPath2 = new ScalablePath(); private final ScalablePath tempPath2 = new ScalablePath();
private void drawLine(StaticLayout layout, int line, int start, int end, boolean padAtStart, boolean padAtEnd) { private void drawLine(Layout layout, int line, int start, int end, boolean padAtStart, boolean padAtEnd) {
tempPath2.reset(); tempPath2.reset();
layout.getSelectionPath(start, end, tempPath2); layout.getSelectionPath(start, end, tempPath2);
@ -1607,11 +1690,11 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
} }
} }
private static class LayoutBlock { public static class LayoutBlock {
public int charOffset; public int charOffset;
StaticLayout layout; public Layout layout;
float yOffset; public float yOffset;
float xOffset; public float xOffset;
} }
@ -1634,6 +1717,109 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
protected abstract void onTextSelected(Cell newView, Cell oldView); protected abstract void onTextSelected(Cell newView, Cell oldView);
public static class SimpleTextSelectionHelper extends TextSelectionHelper<SimpleSelectabeleView> {
SimpleSelectabeleView selectabeleView;
public SimpleTextSelectionHelper(SimpleSelectabeleView selectabeleView, Theme.ResourcesProvider resourcesProvider) {
this.selectabeleView = selectabeleView;
this.resourcesProvider = resourcesProvider;
}
public void setSelectabeleView(SimpleSelectabeleView selectabeleView) {
this.selectabeleView = selectabeleView;
}
@Override
protected CharSequence getText(SimpleSelectabeleView view, boolean maybe) {
return view.getText();
}
@Override
protected int getCharOffsetFromCord(int x, int y, int offsetX, int offsetY, SimpleSelectabeleView view, boolean maybe) {
if (y < 0) {
y = 1;
}
float yOffset = 0;
Layout lastLayout = view.getStaticTextLayout();
if (y > yOffset + lastLayout.getLineBottom(lastLayout.getLineCount() - 1)) {
y = (int) (yOffset + lastLayout.getLineBottom(lastLayout.getLineCount() - 1) - 1);
}
if (layoutBlock.layout == null) {
return -1;
}
Layout layout = layoutBlock.layout;
x -= layoutBlock.xOffset;
int line = -1;
for (int i = 0; i < layout.getLineCount(); i++) {
if (y > layoutBlock.yOffset + layout.getLineTop(i) && y < layoutBlock.yOffset + layout.getLineBottom(i)) {
line = i;
break;
}
}
if (line >= 0) {
int k = layoutBlock.charOffset + layout.getOffsetForHorizontal(line, x);;
return k;
}
return -1;
}
@Override
protected void fillLayoutForOffset(int offset, LayoutBlock layoutBlock, boolean maybe) {
layoutBlock.layout = selectabeleView.getStaticTextLayout();
layoutBlock.xOffset = layoutBlock.yOffset = 0;
layoutBlock.charOffset = 0;
}
@Override
protected int getLineHeight() {
Layout layout = selectabeleView.getStaticTextLayout();
int lineHeight = layout.getLineBottom(0) - layout.getLineTop(0);
return lineHeight;
}
@Override
protected void onTextSelected(SimpleSelectabeleView newView, SimpleSelectabeleView oldView) {
}
public void update(float textX, float textY) {
Layout layout = selectabeleView.getStaticTextLayout();
if (layout == null) {
textArea.setEmpty();
maybeSelectedView = null;
} else {
maybeSelectedView = selectabeleView;
maybeTextX = (int) textX;
maybeTextY = (int) textY;
layoutBlock.layout = layout;
layoutBlock.xOffset = textX;
layoutBlock.yOffset = textY;
layoutBlock.charOffset = 0;
textArea.set(
(int) textX, (int) textY,
(int) (textX + layout.getWidth()), (int) (textY + layout.getHeight())
);
}
}
public void draw(Canvas canvas) {
Layout layout = selectabeleView.getStaticTextLayout();
int color = Theme.getColor(Theme.key_chat_textSelectBackground, resourcesProvider);
selectionPaint.setColor(color);
selectionHandlePaint.setColor(color);
drawSelection(canvas, layout, selectionStart, selectionEnd, true, true);
}
public boolean isCurrent(SimpleSelectabeleView view) {
return this.selectabeleView == view;
}
}
public static class ChatListTextSelectionHelper extends TextSelectionHelper<ChatMessageCell> { public static class ChatListTextSelectionHelper extends TextSelectionHelper<ChatMessageCell> {
SparseArray<Animator> animatorSparseArray = new SparseArray<>(); SparseArray<Animator> animatorSparseArray = new SparseArray<>();
@ -1817,7 +2003,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
return -1; return -1;
} }
StaticLayout layout = layoutBlock.layout; Layout layout = layoutBlock.layout;
x -= layoutBlock.xOffset; x -= layoutBlock.xOffset;
@ -2476,7 +2662,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
boolean startPeek; boolean startPeek;
protected void pickEndView() { protected void pickEndView() {
if (!isSelectionMode()) { if (!isInSelectionMode()) {
return; return;
} }
startPeek = false; startPeek = false;
@ -2518,7 +2704,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
} }
protected void pickStartView() { protected void pickStartView() {
if (!isSelectionMode()) { if (!isInSelectionMode()) {
return; return;
} }
startPeek = true; startPeek = true;
@ -2769,6 +2955,13 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
void fillTextLayoutBlocks(ArrayList<TextLayoutBlock> blocks); void fillTextLayoutBlocks(ArrayList<TextLayoutBlock> blocks);
} }
public interface SimpleSelectabeleView extends SelectableView {
CharSequence getText();
Layout getStaticTextLayout();
}
public interface SelectableView { public interface SelectableView {
int getBottom(); int getBottom();
@ -2886,10 +3079,10 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
} }
protected int getThemedColor(int key) { protected int getThemedColor(int key) {
return Theme.getColor(key); return Theme.getColor(key, resourcesProvider);
} }
protected Theme.ResourcesProvider getResourcesProvider() { protected Theme.ResourcesProvider getResourcesProvider() {
return null; return resourcesProvider;
} }
} }

View file

@ -121,6 +121,7 @@ import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.BotWebViewVibrationEffect; import org.telegram.messenger.BotWebViewVibrationEffect;
import org.telegram.messenger.BuildVars; import org.telegram.messenger.BuildVars;
import org.telegram.messenger.ChatMessageSharedResources;
import org.telegram.messenger.ChatMessagesMetadataController; import org.telegram.messenger.ChatMessagesMetadataController;
import org.telegram.messenger.ChatObject; import org.telegram.messenger.ChatObject;
import org.telegram.messenger.ChatThemeController; import org.telegram.messenger.ChatThemeController;
@ -746,6 +747,13 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
private boolean chatListViewAttached; private boolean chatListViewAttached;
public boolean forceDisallowApplyWallpeper; public boolean forceDisallowApplyWallpeper;
public boolean forceDisallowRedrawThemeDescriptions; public boolean forceDisallowRedrawThemeDescriptions;
private boolean waitingForGetDifference;
private int initialMessagesSize;
private boolean loadInfo;
private boolean historyPreloaded;
private int migrated_to;
private boolean firstMessagesLoaded;
private Runnable closeInstantCameraAnimation;
{ {
skeletonOutlinePaint.setStyle(Paint.Style.STROKE); skeletonOutlinePaint.setStyle(Paint.Style.STROKE);
@ -864,6 +872,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
private TextSelectionHint textSelectionHint; private TextSelectionHint textSelectionHint;
private boolean textSelectionHintWasShowed; private boolean textSelectionHintWasShowed;
private float lastTouchY; private float lastTouchY;
ContentPreviewViewer.ContentPreviewViewerDelegate contentPreviewViewerDelegate;
private ChatMessageCell dummyMessageCell; private ChatMessageCell dummyMessageCell;
private FireworksOverlay fireworksOverlay; private FireworksOverlay fireworksOverlay;
@ -1032,6 +1041,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
public float drawingChatLisViewYoffset; public float drawingChatLisViewYoffset;
public int blurredViewTopOffset; public int blurredViewTopOffset;
public int blurredViewBottomOffset; public int blurredViewBottomOffset;
public ChatMessageSharedResources sharedResources;
private ValueAnimator searchExpandAnimator; private ValueAnimator searchExpandAnimator;
private float searchExpandProgress; private float searchExpandProgress;
@ -1321,7 +1331,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
RecyclerListView.OnItemLongClickListenerExtended onItemLongClickListener = new RecyclerListView.OnItemLongClickListenerExtended() { RecyclerListView.OnItemLongClickListenerExtended onItemLongClickListener = new RecyclerListView.OnItemLongClickListenerExtended() {
@Override @Override
public boolean onItemClick(View view, int position, float x, float y) { public boolean onItemClick(View view, int position, float x, float y) {
if (textSelectionHelper.isTryingSelect() || textSelectionHelper.isSelectionMode() || inPreviewMode) { if (textSelectionHelper.isTryingSelect() || textSelectionHelper.isInSelectionMode() || inPreviewMode) {
return false; return false;
} }
wasManualScroll = true; wasManualScroll = true;
@ -2090,11 +2100,11 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
} }
reportType = arguments.getInt("report", -1); reportType = arguments.getInt("report", -1);
pulled = arguments.getBoolean("pulled", false); pulled = arguments.getBoolean("pulled", false);
boolean historyPreloaded = arguments.getBoolean("historyPreloaded", false); historyPreloaded = arguments.getBoolean("historyPreloaded", false);
if (highlightMessageId != 0 && highlightMessageId != Integer.MAX_VALUE) { if (highlightMessageId != 0 && highlightMessageId != Integer.MAX_VALUE) {
startLoadFromMessageId = highlightMessageId; startLoadFromMessageId = highlightMessageId;
} }
int migrated_to = arguments.getInt("migrated_to", 0); migrated_to = arguments.getInt("migrated_to", 0);
scrollToTopOnResume = arguments.getBoolean("scrollToTopOnResume", false); scrollToTopOnResume = arguments.getBoolean("scrollToTopOnResume", false);
needRemovePreviousSameChatActivity = arguments.getBoolean("need_remove_previous_same_chat_activity", true); needRemovePreviousSameChatActivity = arguments.getBoolean("need_remove_previous_same_chat_activity", true);
justCreatedChat = arguments.getBoolean("just_created_chat", false); justCreatedChat = arguments.getBoolean("just_created_chat", false);
@ -2121,7 +2131,17 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
} }
dialog_id = -chatId; dialog_id = -chatId;
if (ChatObject.isChannel(currentChat)) { if (ChatObject.isChannel(currentChat)) {
getMessagesController().startShortPoll(currentChat, classGuid, false); if (ChatObject.isNotInChat(currentChat)) {
waitingForGetDifference = true;
getMessagesController().startShortPoll(currentChat, classGuid, false, isGettingDifference -> {
waitingForGetDifference = isGettingDifference;
if (!waitingForGetDifference) {
firstLoadMessages();
}
});
} else {
getMessagesController().startShortPoll(currentChat, classGuid, false);
}
} }
} else if (userId != 0) { } else if (userId != 0) {
currentUser = getMessagesController().getUser(userId); currentUser = getMessagesController().getUser(userId);
@ -2301,6 +2321,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
getNotificationCenter().addObserver(this, NotificationCenter.dialogIsTranslatable); getNotificationCenter().addObserver(this, NotificationCenter.dialogIsTranslatable);
getNotificationCenter().addObserver(this, NotificationCenter.messageTranslated); getNotificationCenter().addObserver(this, NotificationCenter.messageTranslated);
getNotificationCenter().addObserver(this, NotificationCenter.messageTranslating); getNotificationCenter().addObserver(this, NotificationCenter.messageTranslating);
getNotificationCenter().addObserver(this, NotificationCenter.onReceivedChannelDifference);
super.onFragmentCreate(); super.onFragmentCreate();
@ -2351,7 +2372,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
} }
} }
boolean loadInfo = false; loadInfo = false;
if (currentChat != null) { if (currentChat != null) {
chatInfo = getMessagesController().getChatFull(currentChat.id); chatInfo = getMessagesController().getChatFull(currentChat.id);
groupCall = getMessagesController().getGroupCall(currentChat.id, true); groupCall = getMessagesController().getGroupCall(currentChat.id, true);
@ -2382,35 +2403,15 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
checkDispatchHideSkeletons(false); checkDispatchHideSkeletons(false);
} }
if (chatMode != MODE_PINNED && !forceHistoryEmpty) { if (chatMode != MODE_PINNED && !forceHistoryEmpty) {
waitingForLoad.add(lastLoadIndex);
int initialMessagesSize;
if (SharedConfig.deviceIsHigh()) { if (SharedConfig.deviceIsHigh()) {
initialMessagesSize = (isThreadChat() && !isTopic) ? 30 : 25; initialMessagesSize = (isThreadChat() && !isTopic) ? 30 : 25;
} else { } else {
initialMessagesSize = (isThreadChat() && !isTopic) ? 20 : 15; initialMessagesSize = (isThreadChat() && !isTopic) ? 20 : 15;
} }
if (startLoadFromDate != 0) { if (!waitingForGetDifference) {
getMessagesController().loadMessages(dialog_id, mergeDialogId, false, 30, 0, startLoadFromDate, true, 0, classGuid, 4, 0, chatMode, threadMessageId, replyMaxReadId, lastLoadIndex++, isTopic); firstLoadMessages();
} else if (startLoadFromMessageId != 0 && (!isThreadChat() || startLoadFromMessageId == highlightMessageId || isTopic)) {
startLoadFromMessageIdSaved = startLoadFromMessageId;
if (migrated_to != 0) {
mergeDialogId = migrated_to;
getMessagesController().loadMessages(mergeDialogId, 0, loadInfo, initialMessagesSize, startLoadFromMessageId, 0, true, 0, classGuid, 3, 0, chatMode, threadMessageId, replyMaxReadId, lastLoadIndex++, isTopic);
} else {
getMessagesController().loadMessages(dialog_id, mergeDialogId, loadInfo, initialMessagesSize, startLoadFromMessageId, 0, true, 0, classGuid, 3, 0, chatMode, threadMessageId, replyMaxReadId, lastLoadIndex++, isTopic);
}
} else {
if (historyPreloaded) {
lastLoadIndex++;
} else {
getMessagesController().loadMessages(dialog_id, mergeDialogId, loadInfo, initialMessagesSize, startLoadFromMessageId, 0, true, 0, classGuid, 2, 0, chatMode, threadMessageId, replyMaxReadId, lastLoadIndex++, isTopic);
}
} }
} }
if (chatMode == 0 && !isThreadChat()) {
waitingForLoad.add(lastLoadIndex);
getMessagesController().loadMessages(dialog_id, mergeDialogId, false, 1, 0, 0, true, 0, classGuid, 2, 0, MODE_SCHEDULED, threadMessageId, replyMaxReadId, lastLoadIndex++, isTopic);
}
if (chatMode == 0) { if (chatMode == 0) {
if (userId != 0 && currentUser.bot) { if (userId != 0 && currentUser.bot) {
@ -2439,7 +2440,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (chatInfo != null && chatInfo.linked_chat_id != 0) { if (chatInfo != null && chatInfo.linked_chat_id != 0) {
TLRPC.Chat chat = getMessagesController().getChat(chatInfo.linked_chat_id); TLRPC.Chat chat = getMessagesController().getChat(chatInfo.linked_chat_id);
if (chat != null && chat.megagroup) { if (chat != null && chat.megagroup) {
getMessagesController().startShortPoll(chat, classGuid, false); getMessagesController().startShortPoll(chat, classGuid, false, null);
} }
} }
@ -2483,6 +2484,35 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
return true; return true;
} }
private void firstLoadMessages() {
if (firstMessagesLoaded) {
return;
}
firstMessagesLoaded = true;
waitingForLoad.add(lastLoadIndex);
if (startLoadFromDate != 0) {
getMessagesController().loadMessages(dialog_id, mergeDialogId, false, 30, 0, startLoadFromDate, true, 0, classGuid, 4, 0, chatMode, threadMessageId, replyMaxReadId, lastLoadIndex++, isTopic);
} else if (startLoadFromMessageId != 0 && (!isThreadChat() || startLoadFromMessageId == highlightMessageId || isTopic)) {
startLoadFromMessageIdSaved = startLoadFromMessageId;
if (migrated_to != 0) {
mergeDialogId = migrated_to;
getMessagesController().loadMessages(mergeDialogId, 0, loadInfo, initialMessagesSize, startLoadFromMessageId, 0, true, 0, classGuid, 3, 0, chatMode, threadMessageId, replyMaxReadId, lastLoadIndex++, isTopic);
} else {
getMessagesController().loadMessages(dialog_id, mergeDialogId, loadInfo, initialMessagesSize, startLoadFromMessageId, 0, true, 0, classGuid, 3, 0, chatMode, threadMessageId, replyMaxReadId, lastLoadIndex++, isTopic);
}
} else {
if (historyPreloaded) {
lastLoadIndex++;
} else {
getMessagesController().loadMessages(dialog_id, mergeDialogId, loadInfo, initialMessagesSize, startLoadFromMessageId, 0, true, 0, classGuid, 2, 0, chatMode, threadMessageId, replyMaxReadId, lastLoadIndex++, isTopic);
}
}
if (chatMode == 0 && !isThreadChat()) {
waitingForLoad.add(lastLoadIndex);
getMessagesController().loadMessages(dialog_id, mergeDialogId, false, 1, 0, 0, true, 0, classGuid, 2, 0, MODE_SCHEDULED, threadMessageId, replyMaxReadId, lastLoadIndex++, isTopic);
}
}
private void fillInviterId(boolean load) { private void fillInviterId(boolean load) {
if (currentChat == null || chatInfo == null || ChatObject.isNotInChat(currentChat) || currentChat.creator) { if (currentChat == null || chatInfo == null || ChatObject.isNotInChat(currentChat) || currentChat.creator) {
return; return;
@ -2568,6 +2598,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (chatAttachAlert != null) { if (chatAttachAlert != null) {
chatAttachAlert.dismissInternal(); chatAttachAlert.dismissInternal();
} }
ContentPreviewViewer.getInstance().clearDelegate(contentPreviewViewerDelegate);
getNotificationCenter().onAnimationFinish(transitionAnimationIndex); getNotificationCenter().onAnimationFinish(transitionAnimationIndex);
NotificationCenter.getGlobalInstance().onAnimationFinish(transitionAnimationGlobalIndex); NotificationCenter.getGlobalInstance().onAnimationFinish(transitionAnimationGlobalIndex);
getNotificationCenter().onAnimationFinish(scrollAnimationIndex); getNotificationCenter().onAnimationFinish(scrollAnimationIndex);
@ -2656,6 +2687,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
getNotificationCenter().removeObserver(this, NotificationCenter.dialogIsTranslatable); getNotificationCenter().removeObserver(this, NotificationCenter.dialogIsTranslatable);
getNotificationCenter().removeObserver(this, NotificationCenter.messageTranslated); getNotificationCenter().removeObserver(this, NotificationCenter.messageTranslated);
getNotificationCenter().removeObserver(this, NotificationCenter.messageTranslating); getNotificationCenter().removeObserver(this, NotificationCenter.messageTranslating);
getNotificationCenter().removeObserver(this, NotificationCenter.onReceivedChannelDifference);
if (currentEncryptedChat != null) { if (currentEncryptedChat != null) {
getNotificationCenter().removeObserver(this, NotificationCenter.didVerifyMessagesStickers); getNotificationCenter().removeObserver(this, NotificationCenter.didVerifyMessagesStickers);
} }
@ -2762,10 +2794,11 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
actionBar.setSubtitleColor(getThemedColor(Theme.key_actionBarActionModeDefaultIcon)); actionBar.setSubtitleColor(getThemedColor(Theme.key_actionBarActionModeDefaultIcon));
} }
actionBarBackgroundPaint.setColor(getThemedColor(Theme.key_actionBarDefault)); actionBarBackgroundPaint.setColor(getThemedColor(Theme.key_actionBarDefault));
sharedResources = new ChatMessageSharedResources(context);
if (chatMessageCellsCache.isEmpty()) { if (chatMessageCellsCache.isEmpty()) {
for (int a = 0; a < 15; a++) { for (int a = 0; a < 15; a++) {
chatMessageCellsCache.add(new ChatMessageCell(context, true, themeDelegate)); chatMessageCellsCache.add(new ChatMessageCell(context, true, sharedResources, themeDelegate));
} }
} }
for (int a = 1; a >= 0; a--) { for (int a = 1; a >= 0; a--) {
@ -3574,7 +3607,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
} }
forceScrollToTop = false; forceScrollToTop = false;
if (textSelectionHelper != null && textSelectionHelper.isSelectionMode()) { if (textSelectionHelper != null && textSelectionHelper.isInSelectionMode()) {
textSelectionHelper.invalidate(); textSelectionHelper.invalidate();
} }
isSkeletonVisible(); isSkeletonVisible();
@ -3837,7 +3870,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
currentEncryptedChat == null && message.getId() < 0 || currentEncryptedChat == null && message.getId() < 0 ||
bottomOverlayChat != null && bottomOverlayChat.getVisibility() == View.VISIBLE && !(bottomOverlayChatWaitsReply && allowReplyOnOpenTopic || message.wasJustSent) || bottomOverlayChat != null && bottomOverlayChat.getVisibility() == View.VISIBLE && !(bottomOverlayChatWaitsReply && allowReplyOnOpenTopic || message.wasJustSent) ||
currentChat != null && (ChatObject.isNotInChat(currentChat) && !isThreadChat() || ChatObject.isChannel(currentChat) && !ChatObject.canPost(currentChat) && !currentChat.megagroup || !ChatObject.canSendMessages(currentChat)) || currentChat != null && (ChatObject.isNotInChat(currentChat) && !isThreadChat() || ChatObject.isChannel(currentChat) && !ChatObject.canPost(currentChat) && !currentChat.megagroup || !ChatObject.canSendMessages(currentChat)) ||
textSelectionHelper.isSelectionMode()) { textSelectionHelper.isInSelectionMode()) {
slidingView.setSlidingOffset(0); slidingView.setSlidingOffset(0);
slidingView = null; slidingView = null;
return; return;
@ -5798,7 +5831,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}; };
contentView.addView(mentionContainer, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 110, Gravity.LEFT | Gravity.BOTTOM)); contentView.addView(mentionContainer, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 110, Gravity.LEFT | Gravity.BOTTOM));
final ContentPreviewViewer.ContentPreviewViewerDelegate contentPreviewViewerDelegate = new ContentPreviewViewer.ContentPreviewViewerDelegate() { contentPreviewViewerDelegate = new ContentPreviewViewer.ContentPreviewViewerDelegate() {
@Override @Override
public void sendSticker(TLRPC.Document sticker, String query, Object parent, boolean notify, int scheduleDate) { public void sendSticker(TLRPC.Document sticker, String query, Object parent, boolean notify, int scheduleDate) {
chatActivityEnterView.onStickerSelected(sticker, query, parent, null, true, notify, scheduleDate); chatActivityEnterView.onStickerSelected(sticker, query, parent, null, true, notify, scheduleDate);
@ -10342,7 +10375,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
} }
private void checkScrollForLoad(boolean scroll) { private void checkScrollForLoad(boolean scroll) {
if (chatLayoutManager == null || paused || chatAdapter.isFrozen) { if (chatLayoutManager == null || paused || chatAdapter.isFrozen || waitingForGetDifference) {
return; return;
} }
int firstVisibleItem = RecyclerListView.NO_POSITION; int firstVisibleItem = RecyclerListView.NO_POSITION;
@ -10631,9 +10664,11 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
} }
final MessagesController messagesController = getMessagesController(); final MessagesController messagesController = getMessagesController();
Utilities.searchQueue.postRunnable(() -> { Utilities.searchQueue.postRunnable(() -> {
boolean requestAnyway = false;
if (linkSearchRequestId != 0) { if (linkSearchRequestId != 0) {
getConnectionsManager().cancelRequest(linkSearchRequestId, true); getConnectionsManager().cancelRequest(linkSearchRequestId, true);
linkSearchRequestId = 0; linkSearchRequestId = 0;
requestAnyway = true;
} }
ArrayList<CharSequence> urls = null; ArrayList<CharSequence> urls = null;
CharSequence textToCheck; CharSequence textToCheck;
@ -10668,7 +10703,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
clear = false; clear = false;
} }
} }
if (clear) { if (clear && !requestAnyway) {
return; return;
} }
} }
@ -12123,7 +12158,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
return 0; return 0;
} }
if (dummyMessageCell == null) { if (dummyMessageCell == null) {
dummyMessageCell = new ChatMessageCell(getParentActivity(), true, themeDelegate); dummyMessageCell = new ChatMessageCell(getParentActivity(), true, sharedResources, themeDelegate);
} }
dummyMessageCell.isChat = currentChat != null || UserObject.isUserSelf(currentUser); dummyMessageCell.isChat = currentChat != null || UserObject.isUserSelf(currentUser);
dummyMessageCell.isBot = currentUser != null && currentUser.bot; dummyMessageCell.isBot = currentUser != null && currentUser.bot;
@ -12188,6 +12223,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
} }
public void scrollToMessageId(int id, int fromMessageId, boolean select, int loadIndex, boolean forceScroll, int forcePinnedMessageId, Runnable inCaseLoading) { public void scrollToMessageId(int id, int fromMessageId, boolean select, int loadIndex, boolean forceScroll, int forcePinnedMessageId, Runnable inCaseLoading) {
if (waitingForGetDifference) {
return;
}
if (id == 0 || NotificationCenter.getInstance(currentAccount).isAnimationInProgress() || getParentActivity() == null) { if (id == 0 || NotificationCenter.getInstance(currentAccount).isAnimationInProgress() || getParentActivity() == null) {
if (NotificationCenter.getInstance(currentAccount).isAnimationInProgress()) { if (NotificationCenter.getInstance(currentAccount).isAnimationInProgress()) {
nextScrollToMessageId = id; nextScrollToMessageId = id;
@ -12393,7 +12431,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (pagedownButton == null) { if (pagedownButton == null) {
return; return;
} }
boolean show = canShowPagedownButton && !textSelectionHelper.isSelectionMode() && !chatActivityEnterView.isRecordingAudioVideo(); boolean show = canShowPagedownButton && !textSelectionHelper.isInSelectionMode() && !chatActivityEnterView.isRecordingAudioVideo();
if (show) { if (show) {
if (animated && (openAnimationStartTime == 0 || SystemClock.elapsedRealtime() < openAnimationStartTime + 150)) { if (animated && (openAnimationStartTime == 0 || SystemClock.elapsedRealtime() < openAnimationStartTime + 150)) {
animated = false; animated = false;
@ -12752,7 +12790,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
lastTouchY = ev.getY(); lastTouchY = ev.getY();
TextSelectionHelper.TextSelectionOverlay selectionOverlay = textSelectionHelper.getOverlayView(getContext()); TextSelectionHelper.TextSelectionOverlay selectionOverlay = textSelectionHelper.getOverlayView(getContext());
ev.offsetLocation(-selectionOverlay.getX(), -selectionOverlay.getY()); ev.offsetLocation(-selectionOverlay.getX(), -selectionOverlay.getY());
if (textSelectionHelper.isSelectionMode() && textSelectionHelper.getOverlayView(getContext()).onTouchEvent(ev)) { if (textSelectionHelper.isInSelectionMode() && textSelectionHelper.getOverlayView(getContext()).onTouchEvent(ev)) {
return true; return true;
} else { } else {
ev.offsetLocation(selectionOverlay.getX(), selectionOverlay.getY()); ev.offsetLocation(selectionOverlay.getX(), selectionOverlay.getY());
@ -12762,7 +12800,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
ev.setAction(MotionEvent.ACTION_CANCEL); ev.setAction(MotionEvent.ACTION_CANCEL);
} }
if (ev.getAction() == MotionEvent.ACTION_DOWN && textSelectionHelper.isSelectionMode() && (ev.getY() < chatListView.getTop() || ev.getY() > chatListView.getBottom())) { if (ev.getAction() == MotionEvent.ACTION_DOWN && textSelectionHelper.isInSelectionMode() && (ev.getY() < chatListView.getTop() || ev.getY() > chatListView.getBottom())) {
ev.offsetLocation(-selectionOverlay.getX(), -selectionOverlay.getY()); ev.offsetLocation(-selectionOverlay.getX(), -selectionOverlay.getY());
if (textSelectionHelper.getOverlayView(getContext()).onTouchEvent(ev)) { if (textSelectionHelper.getOverlayView(getContext()).onTouchEvent(ev)) {
ev.offsetLocation(selectionOverlay.getX(), selectionOverlay.getY()); ev.offsetLocation(selectionOverlay.getX(), selectionOverlay.getY());
@ -17897,10 +17935,12 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (newGroups != null) { if (newGroups != null) {
for (int b = 0, N = newGroups.size(); b < N; b++) { for (int b = 0, N = newGroups.size(); b < N; b++) {
MessageObject.GroupedMessages groupedMessages = newGroups.valueAt(b); MessageObject.GroupedMessages groupedMessages = newGroups.valueAt(b);
MessageObject messageObject = groupedMessages.messages.get(groupedMessages.messages.size() - 1); if (!groupedMessages.messages.isEmpty()) {
int index = messages.indexOf(messageObject); MessageObject messageObject = groupedMessages.messages.get(groupedMessages.messages.size() - 1);
if (index >= 0) { int index = messages.indexOf(messageObject);
chatAdapter.notifyItemRangeChanged(index + chatAdapter.messagesStartRow, groupedMessages.messages.size()); if (index >= 0) {
chatAdapter.notifyItemRangeChanged(index + chatAdapter.messagesStartRow, groupedMessages.messages.size());
}
} }
} }
} }
@ -18319,6 +18359,12 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
updateTopPanel(true); updateTopPanel(true);
updateTranslateItemVisibility(); updateTranslateItemVisibility();
} else if (id == NotificationCenter.onReceivedChannelDifference) {
final long channelId = (long) args[0];
if (-channelId == dialog_id) {
waitingForGetDifference = false;
firstLoadMessages();
}
} }
} }
@ -26240,7 +26286,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
return false; return false;
} else if (checkRecordLocked(false)) { } else if (checkRecordLocked(false)) {
return false; return false;
} else if (textSelectionHelper.isSelectionMode()) { } else if (textSelectionHelper.isInSelectionMode()) {
textSelectionHelper.clear(); textSelectionHelper.clear();
return false; return false;
} else if (actionBar != null && actionBar.isActionModeShowed()) { } else if (actionBar != null && actionBar.isActionModeShowed()) {
@ -26613,6 +26659,12 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (photoEntry == null) { if (photoEntry == null) {
return; return;
} }
if (videoEditedInfo != null && videoEditedInfo.roundVideo) {
AndroidUtilities.runOnUIThread(closeInstantCameraAnimation = () -> {
closeInstantCameraAnimation = null;
runCloseInstantCameraAnimation();
}, 3000);
}
fillEditingMediaWithCaption(photoEntry.caption, photoEntry.entities); fillEditingMediaWithCaption(photoEntry.caption, photoEntry.entities);
if (photoEntry.isVideo) { if (photoEntry.isVideo) {
if (videoEditedInfo != null) { if (videoEditedInfo != null) {
@ -26630,6 +26682,32 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
afterMessageSend(); afterMessageSend();
} }
private void runCloseInstantCameraAnimation() {
instantCameraView.cancelBlur();
final InstantCameraView.InstantViewCameraContainer cameraContainer = instantCameraView.getCameraContainer();
AnimatorSet allAnimators = new AnimatorSet();
allAnimators.playTogether(
ObjectAnimator.ofFloat(cameraContainer, View.SCALE_X, 0.5f),
ObjectAnimator.ofFloat(cameraContainer, View.SCALE_Y, 0.5f),
ObjectAnimator.ofFloat(cameraContainer, View.ALPHA, 0.0f),
ObjectAnimator.ofFloat(instantCameraView.getSwitchButtonView(), View.ALPHA, 0.0f),
ObjectAnimator.ofInt(instantCameraView.getPaint(), AnimationProperties.PAINT_ALPHA, 0),
ObjectAnimator.ofFloat(instantCameraView.getMuteImageView(), View.ALPHA, 0.0f)
);
allAnimators.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
if (instantCameraView != null) {
instantCameraView.setIsMessageTransition(false);
instantCameraView.hideCamera(true);
instantCameraView.setVisibility(View.INVISIBLE);
}
}
});
allAnimators.start();
}
public void sendAnimatedEmoji(TLRPC.Document emoji, boolean notify, int scheduleDate) { public void sendAnimatedEmoji(TLRPC.Document emoji, boolean notify, int scheduleDate) {
if (emoji == null) { if (emoji == null) {
return; return;
@ -26781,7 +26859,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}; };
NotificationCenter.getInstance(currentAccount).addObserver(observer, NotificationCenter.messagesDidLoad); NotificationCenter.getInstance(currentAccount).addObserver(observer, NotificationCenter.messagesDidLoad);
Utilities.stageQueue.postRunnable(() -> { Utilities.stageQueue.postRunnable(() -> {
getMessagesController().processLoadedMessages(historyFinal, historyFinal.messages.size(), dialogId, 0, 30, (highlightMsgId > 0 ? highlightMsgId : maxReadId), 0, false, commentsClassGuid, fnidFinal, 0, 0, 0, (highlightMsgId > 0 ? 3 : 2), true, 0, arrayList.get(arrayList.size() - 1).getId(), 1, false, 0, true, isTopic); getMessagesController().processLoadedMessages(historyFinal, historyFinal.messages.size(), dialogId, 0, 30, (highlightMsgId > 0 ? highlightMsgId : maxReadId), 0, false, commentsClassGuid, fnidFinal, 0, 0, 0, (highlightMsgId > 0 ? 3 : 2), true, 0, arrayList.get(arrayList.size() - 1).getId(), 1, false, 0, true, isTopic, null);
}); });
} else { } else {
openCommentsChat.run(); openCommentsChat.run();
@ -27757,7 +27835,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
view = chatMessageCellsCache.get(0); view = chatMessageCellsCache.get(0);
chatMessageCellsCache.remove(0); chatMessageCellsCache.remove(0);
} else { } else {
view = new ChatMessageCell(mContext, true, themeDelegate); view = new ChatMessageCell(mContext, true, sharedResources, themeDelegate);
} }
ChatMessageCell chatMessageCell = (ChatMessageCell) view; ChatMessageCell chatMessageCell = (ChatMessageCell) view;
chatMessageCell.setResourcesProvider(themeDelegate); chatMessageCell.setResourcesProvider(themeDelegate);
@ -28160,6 +28238,10 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
boolean applyAnimation = false; boolean applyAnimation = false;
if (message.type == MessageObject.TYPE_ROUND_VIDEO && instantCameraView != null && instantCameraView.getTextureView() != null) { if (message.type == MessageObject.TYPE_ROUND_VIDEO && instantCameraView != null && instantCameraView.getTextureView() != null) {
applyAnimation = true; applyAnimation = true;
if (closeInstantCameraAnimation != null) {
AndroidUtilities.cancelRunOnUIThread(closeInstantCameraAnimation);
closeInstantCameraAnimation = null;
}
messageCell.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { messageCell.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override @Override
public boolean onPreDraw() { public boolean onPreDraw() {

View file

@ -503,11 +503,11 @@ public class AnimatedEmojiDrawable extends Drawable {
} }
}; };
imageReceiver.setAllowLoadingOnAttachedOnly(true); imageReceiver.setAllowLoadingOnAttachedOnly(true);
if (cacheType == CACHE_TYPE_RENDERING_VIDEO) {
imageReceiver.ignoreNotifications = true;
}
}; };
if (cacheType == CACHE_TYPE_RENDERING_VIDEO) {
imageReceiver.ignoreNotifications = true;
}
if (colorFilterToSet != null && canOverrideColor()) { if (colorFilterToSet != null && canOverrideColor()) {
imageReceiver.setColorFilter(colorFilterToSet); imageReceiver.setColorFilter(colorFilterToSet);
} }

View file

@ -23,17 +23,18 @@ import android.graphics.Shader;
import android.graphics.drawable.Animatable; import android.graphics.drawable.Animatable;
import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.BitmapDrawable;
import android.os.Build; import android.os.Build;
import android.util.Log;
import android.view.View; import android.view.View;
import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.AnimatedFileDrawableStream; import org.telegram.messenger.AnimatedFileDrawableStream;
import org.telegram.messenger.BuildVars;
import org.telegram.messenger.DispatchQueue; import org.telegram.messenger.DispatchQueue;
import org.telegram.messenger.DispatchQueuePoolBackground; import org.telegram.messenger.DispatchQueuePoolBackground;
import org.telegram.messenger.FileLoader; import org.telegram.messenger.FileLoader;
import org.telegram.messenger.FileLog; import org.telegram.messenger.FileLog;
import org.telegram.messenger.ImageLocation; import org.telegram.messenger.ImageLocation;
import org.telegram.messenger.ImageReceiver; import org.telegram.messenger.ImageReceiver;
import org.telegram.messenger.SharedConfig;
import org.telegram.messenger.utils.BitmapsCache; import org.telegram.messenger.utils.BitmapsCache;
import org.telegram.tgnet.TLRPC; import org.telegram.tgnet.TLRPC;
@ -48,6 +49,11 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable,
public boolean skipFrameUpdate; public boolean skipFrameUpdate;
public long currentTime; public long currentTime;
// canvas.drawPath lead to glitches
// clipPath not use antialias
private final boolean USE_BITMAP_SHADER = Build.VERSION.SDK_INT < 29;
private boolean PRERENDER_FRAME = true;
private static native long createDecoder(String src, int[] params, int account, long streamFileSize, Object readCallback, boolean preview); private static native long createDecoder(String src, int[] params, int account, long streamFileSize, Object readCallback, boolean preview);
private static native void destroyDecoder(long ptr); private static native void destroyDecoder(long ptr);
@ -259,26 +265,34 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable,
} }
loadFrameTask = null; loadFrameTask = null;
if (nextRenderingBitmap == null && nextRenderingBitmap2 == null) { if (!PRERENDER_FRAME) {
nextRenderingBitmap = backgroundBitmap; nextRenderingBitmap = backgroundBitmap;
nextRenderingBitmapTime = backgroundBitmapTime; nextRenderingBitmapTime = backgroundBitmapTime;
for (int i = 0; i < backgroundShader.length; i++) { for (int i = 0; i < backgroundShader.length; i++) {
nextRenderingShader[i] = backgroundShader[i]; nextRenderingShader[i] = backgroundShader[i];
} }
} else if (nextRenderingBitmap == null) {
nextRenderingBitmap = nextRenderingBitmap2;
nextRenderingBitmapTime = nextRenderingBitmapTime2;
nextRenderingBitmap2 = backgroundBitmap;
nextRenderingBitmapTime2 = backgroundBitmapTime;
for (int i = 0; i < backgroundShader.length; i++) {
nextRenderingShader[i] = nextRenderingShader2[i];
nextRenderingShader2[i] = backgroundShader[i];
}
} else { } else {
nextRenderingBitmap2 = backgroundBitmap; if (nextRenderingBitmap == null && nextRenderingBitmap2 == null) {
nextRenderingBitmapTime2 = backgroundBitmapTime; nextRenderingBitmap = backgroundBitmap;
for (int i = 0; i < backgroundShader.length; i++) { nextRenderingBitmapTime = backgroundBitmapTime;
nextRenderingShader2[i] = backgroundShader[i]; for (int i = 0; i < backgroundShader.length; i++) {
nextRenderingShader[i] = backgroundShader[i];
}
} else if (nextRenderingBitmap == null) {
nextRenderingBitmap = nextRenderingBitmap2;
nextRenderingBitmapTime = nextRenderingBitmapTime2;
nextRenderingBitmap2 = backgroundBitmap;
nextRenderingBitmapTime2 = backgroundBitmapTime;
for (int i = 0; i < backgroundShader.length; i++) {
nextRenderingShader[i] = nextRenderingShader2[i];
nextRenderingShader2[i] = backgroundShader[i];
}
} else {
nextRenderingBitmap2 = backgroundBitmap;
nextRenderingBitmapTime2 = backgroundBitmapTime;
for (int i = 0; i < backgroundShader.length; i++) {
nextRenderingShader2[i] = backgroundShader[i];
}
} }
} }
backgroundBitmap = null; backgroundBitmap = null;
@ -394,7 +408,7 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable,
} catch (Throwable e) { } catch (Throwable e) {
FileLog.e(e); FileLog.e(e);
} }
if (backgroundShader[0] == null && backgroundBitmap != null && hasRoundRadius()) { if (USE_BITMAP_SHADER && backgroundShader[0] == null && backgroundBitmap != null && hasRoundRadius()) {
backgroundShader[0] = new BitmapShader(backgroundBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); backgroundShader[0] = new BitmapShader(backgroundBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
} }
} }
@ -467,6 +481,7 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable,
public AnimatedFileDrawable(File file, boolean createDecoder, long streamSize, int streamLoadingPriority, TLRPC.Document document, ImageLocation location, Object parentObject, long seekTo, int account, boolean preview, int w, int h, BitmapsCache.CacheOptions cacheOptions) { public AnimatedFileDrawable(File file, boolean createDecoder, long streamSize, int streamLoadingPriority, TLRPC.Document document, ImageLocation location, Object parentObject, long seekTo, int account, boolean preview, int w, int h, BitmapsCache.CacheOptions cacheOptions) {
path = file; path = file;
PRERENDER_FRAME = SharedConfig.deviceIsAboveAverage() && limitFps;
streamFileSize = streamSize; streamFileSize = streamSize;
this.streamLoadingPriority = streamLoadingPriority; this.streamLoadingPriority = streamLoadingPriority;
currentAccount = account; currentAccount = account;
@ -503,6 +518,7 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable,
public void setIsWebmSticker(boolean b) { public void setIsWebmSticker(boolean b) {
isWebmSticker = b; isWebmSticker = b;
PRERENDER_FRAME = false;
if (isWebmSticker) { if (isWebmSticker) {
useSharedQueue = true; useSharedQueue = true;
} }
@ -750,7 +766,7 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable,
} }
private void scheduleNextGetFrame() { private void scheduleNextGetFrame() {
if (loadFrameTask != null || (nextRenderingBitmap2 != null && nextRenderingBitmap != null) || !canLoadFrames() || destroyWhenDone || !isRunning && (!decodeSingleFrame || decodeSingleFrame && singleFrameDecoded) || parents.size() == 0 && !ignoreNoParent || generatingCache) { if (loadFrameTask != null || ((!PRERENDER_FRAME || nextRenderingBitmap2 != null) && nextRenderingBitmap != null) || !canLoadFrames() || destroyWhenDone || !isRunning && (!decodeSingleFrame || decodeSingleFrame && singleFrameDecoded) || parents.size() == 0 && !ignoreNoParent || generatingCache) {
return; return;
} }
long ms = 0; long ms = 0;
@ -874,33 +890,36 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable,
} }
if (hasRoundRadius()) { if (hasRoundRadius()) {
int index = drawInBackground ? threadIndex + 1 : 0; int index = drawInBackground ? threadIndex + 1 : 0;
if (renderingShader[index] == null) { if (USE_BITMAP_SHADER) {
renderingShader[index] = new BitmapShader(renderingBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); if (renderingShader[index] == null) {
} renderingShader[index] = new BitmapShader(renderingBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
paint.setShader(renderingShader[index]); }
Matrix matrix = shaderMatrix[index]; paint.setShader(renderingShader[index]);
if (matrix == null) { Matrix matrix = shaderMatrix[index];
matrix = shaderMatrix[index] = new Matrix(); if (matrix == null) {
matrix = shaderMatrix[index] = new Matrix();
}
matrix.reset();
matrix.setTranslate(rect.left, rect.top);
if (metaData[2] == 90) {
matrix.preRotate(90);
matrix.preTranslate(0, -rect.width());
} else if (metaData[2] == 180) {
matrix.preRotate(180);
matrix.preTranslate(-rect.width(), -rect.height());
} else if (metaData[2] == 270) {
matrix.preRotate(270);
matrix.preTranslate(-rect.height(), 0);
}
matrix.preScale(scaleX, scaleY);
renderingShader[index].setLocalMatrix(matrix);
} }
Path path = roundPath[index]; Path path = roundPath[index];
if (path == null) { if (path == null) {
path = roundPath[index] = new Path(); path = roundPath[index] = new Path();
} }
matrix.reset();
matrix.setTranslate(rect.left, rect.top);
if (metaData[2] == 90) {
matrix.preRotate(90);
matrix.preTranslate(0, -rect.width());
} else if (metaData[2] == 180) {
matrix.preRotate(180);
matrix.preTranslate(-rect.width(), -rect.height());
} else if (metaData[2] == 270) {
matrix.preRotate(270);
matrix.preTranslate(-rect.height(), 0);
}
matrix.preScale(scaleX, scaleY);
renderingShader[index].setLocalMatrix(matrix);
if (invalidatePath || drawInBackground) { if (invalidatePath || drawInBackground) {
if (!drawInBackground) { if (!drawInBackground) {
invalidatePath = false; invalidatePath = false;
@ -909,29 +928,39 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable,
radii[a * 2] = roundRadius[a]; radii[a * 2] = roundRadius[a];
radii[a * 2 + 1] = roundRadius[a]; radii[a * 2 + 1] = roundRadius[a];
} }
path.reset(); path.rewind();
path.addRoundRect(drawInBackground ? rect : actualDrawRect, radii, Path.Direction.CW); path.addRoundRect(drawInBackground ? rect : actualDrawRect, radii, Path.Direction.CW);
path.close();
} }
canvas.drawPath(path, paint); if (USE_BITMAP_SHADER) {
canvas.drawPath(path, paint);
} else {
canvas.save();
canvas.clipPath(path);
drawBitmap(rect, paint, canvas, scaleX, scaleY);
canvas.restore();
}
} else { } else {
canvas.translate(rect.left, rect.top); drawBitmap(rect, paint, canvas, scaleX, scaleY);
if (metaData[2] == 90) {
canvas.rotate(90);
canvas.translate(0, -rect.width());
} else if (metaData[2] == 180) {
canvas.rotate(180);
canvas.translate(-rect.width(), -rect.height());
} else if (metaData[2] == 270) {
canvas.rotate(270);
canvas.translate(-rect.height(), 0);
}
canvas.scale(scaleX, scaleY);
canvas.drawBitmap(renderingBitmap, 0, 0, paint);
} }
} }
} }
private void drawBitmap(RectF rect, Paint paint, Canvas canvas, float sx, float sy) {
canvas.translate(rect.left, rect.top);
if (metaData[2] == 90) {
canvas.rotate(90);
canvas.translate(0, -rect.width());
} else if (metaData[2] == 180) {
canvas.rotate(180);
canvas.translate(-rect.width(), -rect.height());
} else if (metaData[2] == 270) {
canvas.rotate(270);
canvas.translate(-rect.height(), 0);
}
canvas.scale(sx, sy);
canvas.drawBitmap(renderingBitmap, 0, 0, paint);
}
public long getLastFrameTimestamp() { public long getLastFrameTimestamp() {
return lastTimeStamp; return lastTimeStamp;
} }
@ -1067,6 +1096,9 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable,
public void setLimitFps(boolean limitFps) { public void setLimitFps(boolean limitFps) {
this.limitFps = limitFps; this.limitFps = limitFps;
if (limitFps) {
PRERENDER_FRAME = false;
}
} }
public ArrayList<ImageReceiver> getParents() { public ArrayList<ImageReceiver> getParents() {
@ -1225,4 +1257,12 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable,
public int getFps() { public int getFps() {
return metaData[5]; return metaData[5];
} }
public int getRenderingWidth() {
return renderingWidth;
}
public int getRenderingHeight() {
return renderingHeight;
}
} }

View file

@ -45,14 +45,14 @@ public class CacheChart extends View {
private RectF chartBounds = new RectF(); private RectF chartBounds = new RectF();
private RectF chartInnerBounds = new RectF(); private RectF chartInnerBounds = new RectF();
private static final int DEFAULT_SECTIONS_COUNT = 9; private static final int DEFAULT_SECTIONS_COUNT = 10;
private static final int[] DEFAULT_COLORS = new int[] { private static final int[] DEFAULT_COLORS = new int[] {
Theme.key_statisticChartLine_lightblue, Theme.key_statisticChartLine_lightblue,
Theme.key_statisticChartLine_blue, Theme.key_statisticChartLine_blue,
Theme.key_statisticChartLine_green, Theme.key_statisticChartLine_green,
Theme.key_statisticChartLine_red, Theme.key_statisticChartLine_purple,
Theme.key_statisticChartLine_lightgreen, Theme.key_statisticChartLine_lightgreen,
Theme.key_statisticChartLine_indigo, Theme.key_statisticChartLine_red,
Theme.key_statisticChartLine_orange, Theme.key_statisticChartLine_orange,
Theme.key_statisticChartLine_cyan, Theme.key_statisticChartLine_cyan,
Theme.key_statisticChartLine_purple, Theme.key_statisticChartLine_purple,
@ -65,7 +65,7 @@ public class CacheChart extends View {
R.raw.cache_documents, R.raw.cache_documents,
R.raw.cache_music, R.raw.cache_music,
R.raw.cache_videos, R.raw.cache_videos,
R.raw.cache_other, R.raw.cache_music,
R.raw.cache_stickers, R.raw.cache_stickers,
R.raw.cache_profile_photos, R.raw.cache_profile_photos,
R.raw.cache_other, R.raw.cache_other,
@ -705,7 +705,7 @@ public class CacheChart extends View {
k++; k++;
} }
String[] fileSize = AndroidUtilities.formatFileSize(segmentsSum).split(" "); String[] fileSize = AndroidUtilities.formatFileSize(segmentsSum, true, true).split(" ");
String top = fileSize.length > 0 ? fileSize[0] : ""; String top = fileSize.length > 0 ? fileSize[0] : "";
if (top.length() >= 4 && segmentsSum < 1024L * 1024L * 1024L) { if (top.length() >= 4 && segmentsSum < 1024L * 1024L * 1024L) {
top = top.split("\\.")[0]; top = top.split("\\.")[0];

View file

@ -5185,7 +5185,11 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
return; return;
} else { } else {
messageEditText.setEnabled(true); messageEditText.setEnabled(true);
messageEditText.setInputType(commonInputType); if (messageEditText.getInputType() != commonInputType) {
messageEditText.setInputType(commonInputType);
} else {
}
} }
if (replyingMessageObject != null && replyingMessageObject.messageOwner.reply_markup != null && !TextUtils.isEmpty(replyingMessageObject.messageOwner.reply_markup.placeholder)) { if (replyingMessageObject != null && replyingMessageObject.messageOwner.reply_markup != null && !TextUtils.isEmpty(replyingMessageObject.messageOwner.reply_markup.placeholder)) {
messageEditText.setHintText(replyingMessageObject.messageOwner.reply_markup.placeholder, animated); messageEditText.setHintText(replyingMessageObject.messageOwner.reply_markup.placeholder, animated);

View file

@ -5738,6 +5738,7 @@ public class EmojiView extends FrameLayout implements NotificationCenter.Notific
if (colorPickerView != null && colorPickerView.isShowing()) { if (colorPickerView != null && colorPickerView.isShowing()) {
colorPickerView.dismiss(); colorPickerView.dismiss();
} }
ContentPreviewViewer.getInstance().clearDelegate(contentPreviewViewerDelegate);
} }
private void checkDocuments(boolean isGif) { private void checkDocuments(boolean isGif) {

View file

@ -29,6 +29,7 @@ import androidx.recyclerview.widget.RecyclerView;
import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.BuildVars; import org.telegram.messenger.BuildVars;
import org.telegram.messenger.ChatMessageSharedResources;
import org.telegram.messenger.ChatObject; import org.telegram.messenger.ChatObject;
import org.telegram.messenger.ContactsController; import org.telegram.messenger.ContactsController;
import org.telegram.messenger.FileLog; import org.telegram.messenger.FileLog;
@ -91,6 +92,7 @@ public class ForwardingPreviewView extends FrameLayout {
ArrayList<ActionBarMenuSubItem> actionItems = new ArrayList<>(); ArrayList<ActionBarMenuSubItem> actionItems = new ArrayList<>();
Rect rect = new Rect(); Rect rect = new Rect();
ChatMessageSharedResources sharedResources;
private boolean firstLayout = true; private boolean firstLayout = true;
ValueAnimator offsetsAnimator; ValueAnimator offsetsAnimator;
@ -116,6 +118,7 @@ public class ForwardingPreviewView extends FrameLayout {
@SuppressLint("ClickableViewAccessibility") @SuppressLint("ClickableViewAccessibility")
public ForwardingPreviewView(@NonNull Context context, ForwardingMessagesParams params, TLRPC.User user, TLRPC.Chat chat, int currentAccount, ResourcesDelegate resourcesProvider) { public ForwardingPreviewView(@NonNull Context context, ForwardingMessagesParams params, TLRPC.User user, TLRPC.Chat chat, int currentAccount, ResourcesDelegate resourcesProvider) {
super(context); super(context);
sharedResources = new ChatMessageSharedResources(context);
this.currentAccount = currentAccount; this.currentAccount = currentAccount;
currentUser = user; currentUser = user;
currentChat = chat; currentChat = chat;
@ -976,10 +979,11 @@ public class ForwardingPreviewView extends FrameLayout {
} }
private class Adapter extends RecyclerView.Adapter { private class Adapter extends RecyclerView.Adapter {
@NonNull @NonNull
@Override @Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
ChatMessageCell chatMessageCell = new ChatMessageCell(parent.getContext(), false, resourcesProvider); ChatMessageCell chatMessageCell = new ChatMessageCell(parent.getContext(), false, sharedResources, resourcesProvider);
return new RecyclerListView.Holder(chatMessageCell); return new RecyclerListView.Holder(chatMessageCell);
} }

View file

@ -242,7 +242,7 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
@SuppressLint("ClickableViewAccessibility") @SuppressLint("ClickableViewAccessibility")
public InstantCameraView(Context context, Delegate delegate, Theme.ResourcesProvider resourcesProvider) { public InstantCameraView(Context context, Delegate delegate, Theme.ResourcesProvider resourcesProvider) {
super(context); super(context);
WRITE_TO_FILE_IN_BACKGROUND = SharedConfig.deviceIsAboveAverage(); WRITE_TO_FILE_IN_BACKGROUND = false;//SharedConfig.deviceIsAboveAverage();
this.resourcesProvider = resourcesProvider; this.resourcesProvider = resourcesProvider;
parentView = delegate.getFragmentView(); parentView = delegate.getFragmentView();
setWillNotDraw(false); setWillNotDraw(false);
@ -515,20 +515,6 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
canvas.drawArc(rect, -90, 360 * progress, false, paint); canvas.drawArc(rect, -90, 360 * progress, false, paint);
canvas.restore(); canvas.restore();
} }
if (Theme.chat_roundVideoShadow != null) {
int x1 = (int) x - AndroidUtilities.dp(3);
int y1 = (int) y - AndroidUtilities.dp(2);
canvas.save();
if (isMessageTransition) {
canvas.scale(cameraContainer.getScaleX(), cameraContainer.getScaleY(), x, y);
} else {
canvas.scale(cameraContainer.getScaleX(), cameraContainer.getScaleY(), x + textureViewSize / 2f, y + textureViewSize / 2f);
}
Theme.chat_roundVideoShadow.setAlpha((int) (cameraContainer.getAlpha() * 255));
Theme.chat_roundVideoShadow.setBounds(x1, y1, x1 + textureViewSize + AndroidUtilities.dp(6), y1 + textureViewSize + AndroidUtilities.dp(6));
Theme.chat_roundVideoShadow.draw(canvas);
canvas.restore();
}
} }
@Override @Override
@ -629,7 +615,7 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
AutoDeleteMediaTask.lockFile(cameraFile); AutoDeleteMediaTask.lockFile(cameraFile);
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.d("show round camera " + cameraFile.getAbsolutePath()); FileLog.d("InstantCamera show round camera " + cameraFile.getAbsolutePath());
} }
textureView = new TextureView(getContext()); textureView = new TextureView(getContext());
@ -637,14 +623,14 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
@Override @Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.d("camera surface available"); FileLog.d("InstantCamera camera surface available");
} }
if (cameraThread == null && surface != null) { if (cameraThread == null && surface != null) {
if (cancelled) { if (cancelled) {
return; return;
} }
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.d("start create thread"); FileLog.d("InstantCamera start create thread");
} }
cameraThread = new CameraGLThread(surface, width, height); cameraThread = new CameraGLThread(surface, width, height);
} }
@ -1014,7 +1000,7 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
} }
} }
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.d("preview w = " + previewSize.mWidth + " h = " + previewSize.mHeight); FileLog.d("InstantCamera preview w = " + previewSize.mWidth + " h = " + previewSize.mHeight);
} }
return true; return true;
} }
@ -1099,7 +1085,7 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
return; return;
} }
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.d("create camera session"); FileLog.d("InstantCamera create camera session");
} }
surfaceTexture.setDefaultBufferSize(previewSize.getWidth(), previewSize.getHeight()); surfaceTexture.setDefaultBufferSize(previewSize.getWidth(), previewSize.getHeight());
@ -1112,7 +1098,7 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
Camera.Size size = cameraSession.getCurrentPreviewSize(); Camera.Size size = cameraSession.getCurrentPreviewSize();
if (size.width != previewSize.getWidth() || size.height != previewSize.getHeight()) { if (size.width != previewSize.getWidth() || size.height != previewSize.getHeight()) {
previewSize = new Size(size.width, size.height); previewSize = new Size(size.width, size.height);
FileLog.d("change preview size to w = " + previewSize.getWidth() + " h = " + previewSize.getHeight()); FileLog.d("InstantCamera change preview size to w = " + previewSize.getWidth() + " h = " + previewSize.getHeight());
} }
} catch (Exception e) { } catch (Exception e) {
FileLog.e(e); FileLog.e(e);
@ -1122,14 +1108,14 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
Camera.Size size = cameraSession.getCurrentPictureSize(); Camera.Size size = cameraSession.getCurrentPictureSize();
if (size.width != pictureSize.getWidth() || size.height != pictureSize.getHeight()) { if (size.width != pictureSize.getWidth() || size.height != pictureSize.getHeight()) {
pictureSize = new Size(size.width, size.height); pictureSize = new Size(size.width, size.height);
FileLog.d("change picture size to w = " + pictureSize.getWidth() + " h = " + pictureSize.getHeight()); FileLog.d("InstantCamera change picture size to w = " + pictureSize.getWidth() + " h = " + pictureSize.getHeight());
updateScale = true; updateScale = true;
} }
} catch (Exception e) { } catch (Exception e) {
FileLog.e(e); FileLog.e(e);
} }
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.d("camera initied"); FileLog.d("InstantCamera camera initied");
} }
cameraSession.setInitied(); cameraSession.setInitied();
if (updateScale) { if (updateScale) {
@ -1298,20 +1284,20 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
scaleX = height / (float) surfaceWidth; scaleX = height / (float) surfaceWidth;
scaleY = 1.0f; scaleY = 1.0f;
} }
FileLog.d("camera scaleX = " + scaleX + " scaleY = " + scaleY); FileLog.d("InstantCamera camera scaleX = " + scaleX + " scaleY = " + scaleY);
} }
private boolean initGL() { private boolean initGL() {
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.d("start init gl"); FileLog.d("InstantCamera start init gl");
} }
egl10 = (EGL10) EGLContext.getEGL(); egl10 = (EGL10) EGLContext.getEGL();
eglDisplay = egl10.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); eglDisplay = egl10.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
if (eglDisplay == EGL10.EGL_NO_DISPLAY) { if (eglDisplay == EGL10.EGL_NO_DISPLAY) {
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.e("eglGetDisplay failed " + GLUtils.getEGLErrorString(egl10.eglGetError())); FileLog.e("InstantCamera eglGetDisplay failed " + GLUtils.getEGLErrorString(egl10.eglGetError()));
} }
finish(); finish();
return false; return false;
@ -1320,7 +1306,7 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
int[] version = new int[2]; int[] version = new int[2];
if (!egl10.eglInitialize(eglDisplay, version)) { if (!egl10.eglInitialize(eglDisplay, version)) {
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.e("eglInitialize failed " + GLUtils.getEGLErrorString(egl10.eglGetError())); FileLog.e("InstantCamera eglInitialize failed " + GLUtils.getEGLErrorString(egl10.eglGetError()));
} }
finish(); finish();
return false; return false;
@ -1341,7 +1327,7 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
EGLConfig eglConfig; EGLConfig eglConfig;
if (!egl10.eglChooseConfig(eglDisplay, configSpec, configs, 1, configsCount)) { if (!egl10.eglChooseConfig(eglDisplay, configSpec, configs, 1, configsCount)) {
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.e("eglChooseConfig failed " + GLUtils.getEGLErrorString(egl10.eglGetError())); FileLog.e("InstantCamera eglChooseConfig failed " + GLUtils.getEGLErrorString(egl10.eglGetError()));
} }
finish(); finish();
return false; return false;
@ -1349,7 +1335,7 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
eglConfig = configs[0]; eglConfig = configs[0];
} else { } else {
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.e("eglConfig not initialized"); FileLog.e("InstantCamera eglConfig not initialized");
} }
finish(); finish();
return false; return false;
@ -1359,7 +1345,7 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
eglContext = egl10.eglCreateContext(eglDisplay, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list); eglContext = egl10.eglCreateContext(eglDisplay, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list);
if (eglContext == null) { if (eglContext == null) {
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.e("eglCreateContext failed " + GLUtils.getEGLErrorString(egl10.eglGetError())); FileLog.e("InstantCamera eglCreateContext failed " + GLUtils.getEGLErrorString(egl10.eglGetError()));
} }
finish(); finish();
return false; return false;
@ -1374,14 +1360,14 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
if (eglSurface == null || eglSurface == EGL10.EGL_NO_SURFACE) { if (eglSurface == null || eglSurface == EGL10.EGL_NO_SURFACE) {
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.e("createWindowSurface failed " + GLUtils.getEGLErrorString(egl10.eglGetError())); FileLog.e("InstantCamera createWindowSurface failed " + GLUtils.getEGLErrorString(egl10.eglGetError()));
} }
finish(); finish();
return false; return false;
} }
if (!egl10.eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext)) { if (!egl10.eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext)) {
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.e("eglMakeCurrent failed " + GLUtils.getEGLErrorString(egl10.eglGetError())); FileLog.e("InstantCamera eglMakeCurrent failed " + GLUtils.getEGLErrorString(egl10.eglGetError()));
} }
finish(); finish();
return false; return false;
@ -1423,7 +1409,7 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
GLES20.glGetProgramiv(drawProgram, GLES20.GL_LINK_STATUS, linkStatus, 0); GLES20.glGetProgramiv(drawProgram, GLES20.GL_LINK_STATUS, linkStatus, 0);
if (linkStatus[0] == 0) { if (linkStatus[0] == 0) {
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.e("failed link shader"); FileLog.e("InstantCamera failed link shader");
} }
GLES20.glDeleteProgram(drawProgram); GLES20.glDeleteProgram(drawProgram);
drawProgram = 0; drawProgram = 0;
@ -1435,7 +1421,7 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
} }
} else { } else {
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.e("failed creating shader"); FileLog.e("InstantCamera failed creating shader");
} }
finish(); finish();
return false; return false;
@ -1454,7 +1440,7 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
cameraSurface.setOnFrameAvailableListener(surfaceTexture -> requestRender()); cameraSurface.setOnFrameAvailableListener(surfaceTexture -> requestRender());
createCamera(cameraSurface); createCamera(cameraSurface);
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.e("gl initied"); FileLog.e("InstantCamera gl initied");
} }
return true; return true;
@ -1469,6 +1455,19 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
} }
public void finish() { public void finish() {
if (cameraSurface != null) {
cameraSurface.release();
cameraSurface = null;
}
if (eglSurface != null && eglContext != null) {
if (!eglContext.equals(egl10.eglGetCurrentContext()) || !eglSurface.equals(egl10.eglGetCurrentSurface(EGL10.EGL_DRAW))) {
egl10.eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext);
}
if (cameraTexture[0] != 0) {
GLES20.glDeleteTextures(1, cameraTexture, 0);
cameraTexture[0] = 0;
}
}
if (eglSurface != null) { if (eglSurface != null) {
egl10.eglMakeCurrent(eglDisplay, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT); egl10.eglMakeCurrent(eglDisplay, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT);
egl10.eglDestroySurface(eglDisplay, eglSurface); egl10.eglDestroySurface(eglDisplay, eglSurface);
@ -1571,7 +1570,7 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
case DO_REINIT_MESSAGE: { case DO_REINIT_MESSAGE: {
if (!egl10.eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext)) { if (!egl10.eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext)) {
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.d("eglMakeCurrent failed " + GLUtils.getEGLErrorString(egl10.eglGetError())); FileLog.d("InstantCamera eglMakeCurrent failed " + GLUtils.getEGLErrorString(egl10.eglGetError()));
} }
return; return;
} }
@ -1618,7 +1617,7 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
} }
case DO_SETSESSION_MESSAGE: { case DO_SETSESSION_MESSAGE: {
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.d("set gl rednderer session"); FileLog.d("InstantCamera set gl rednderer session");
} }
CameraSession newSession = (CameraSession) inputMessage.obj; CameraSession newSession = (CameraSession) inputMessage.obj;
if (currentSession == newSession) { if (currentSession == newSession) {
@ -1676,7 +1675,7 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
case MSG_START_RECORDING: { case MSG_START_RECORDING: {
try { try {
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.e("start encoder"); FileLog.e("InstantCamera start encoder");
} }
encoder.prepareEncoder(); encoder.prepareEncoder();
} catch (Exception e) { } catch (Exception e) {
@ -1688,7 +1687,7 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
} }
case MSG_STOP_RECORDING: { case MSG_STOP_RECORDING: {
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.e("stop encoder"); FileLog.e("InstantCamera stop encoder");
} }
encoder.handleStopRecording(inputMessage.arg1); encoder.handleStopRecording(inputMessage.arg1);
break; break;
@ -1907,6 +1906,9 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
public void startRecording(File outputFile, android.opengl.EGLContext sharedContext) { public void startRecording(File outputFile, android.opengl.EGLContext sharedContext) {
int resolution = MessagesController.getInstance(currentAccount).roundVideoSize; int resolution = MessagesController.getInstance(currentAccount).roundVideoSize;
int bitrate = MessagesController.getInstance(currentAccount).roundVideoBitrate * 1024; int bitrate = MessagesController.getInstance(currentAccount).roundVideoBitrate * 1024;
AndroidUtilities.runOnUIThread(() -> {
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.stopAllHeavyOperations, 512);
});
videoFile = outputFile; videoFile = outputFile;
videoWidth = resolution; videoWidth = resolution;
@ -1931,8 +1933,10 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
} }
} }
fileWriteQueue = new DispatchQueue("IVR_FileWriteQueue"); if (WRITE_TO_FILE_IN_BACKGROUND) {
fileWriteQueue.setPriority(Thread.MAX_PRIORITY); fileWriteQueue = new DispatchQueue("IVR_FileWriteQueue");
fileWriteQueue.setPriority(Thread.MAX_PRIORITY);
}
keyframeThumbs.clear(); keyframeThumbs.clear();
frameCount = 0; frameCount = 0;
@ -1946,6 +1950,9 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
public void stopRecording(int send) { public void stopRecording(int send) {
handler.sendMessage(handler.obtainMessage(MSG_STOP_RECORDING, send, 0)); handler.sendMessage(handler.obtainMessage(MSG_STOP_RECORDING, send, 0));
AndroidUtilities.runOnUIThread(() -> {
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.stopAllHeavyOperations, 512);
});
} }
long prevTimestamp; long prevTimestamp;
@ -1961,7 +1968,7 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
zeroTimeStamps++; zeroTimeStamps++;
if (zeroTimeStamps > 1) { if (zeroTimeStamps > 1) {
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.d("fix timestamp enabled"); FileLog.d("InstantCamera fix timestamp enabled");
} }
timestamp = timestampInternal; timestamp = timestampInternal;
} else { } else {
@ -1997,7 +2004,7 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
if (audioFirst == -1) { if (audioFirst == -1) {
if (videoFirst == -1) { if (videoFirst == -1) {
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.d("video record not yet started"); FileLog.d("InstantCamera video record not yet started");
} }
return; return;
} }
@ -2009,7 +2016,7 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
audioFirst = input.offset[a]; audioFirst = input.offset[a];
ok = true; ok = true;
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.d("detected desync between audio and video " + desyncTime); FileLog.d("InstantCamera detected desync between audio and video " + desyncTime);
} }
break; break;
} }
@ -2018,18 +2025,18 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
audioFirst = input.offset[a]; audioFirst = input.offset[a];
ok = true; ok = true;
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.d("found first audio frame at " + a + " timestamp = " + input.offset[a]); FileLog.d("InstantCamera found first audio frame at " + a + " timestamp = " + input.offset[a]);
} }
break; break;
} else { } else {
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.d("ignore first audio frame at " + a + " timestamp = " + input.offset[a]); FileLog.d("InstantCamera ignore first audio frame at " + a + " timestamp = " + input.offset[a]);
} }
} }
} }
if (!ok) { if (!ok) {
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.d("first audio frame not found, removing buffers " + input.results); FileLog.d("InstantCamera first audio frame not found, removing buffers " + input.results);
} }
buffersToWrite.remove(input); buffersToWrite.remove(input);
} else { } else {
@ -2074,9 +2081,9 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
if (!running && (input.offset[a] >= videoLast - desyncTime || totalTime >= 60_000000)) { if (!running && (input.offset[a] >= videoLast - desyncTime || totalTime >= 60_000000)) {
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
if (totalTime >= 60_000000) { if (totalTime >= 60_000000) {
FileLog.d("stop audio encoding because recorded time more than 60s"); FileLog.d("InstantCamera stop audio encoding because recorded time more than 60s");
} else { } else {
FileLog.d("stop audio encoding because of stoped video recording at " + input.offset[a] + " last video " + videoLast); FileLog.d("InstantCamera stop audio encoding because of stoped video recording at " + input.offset[a] + " last video " + videoLast);
} }
} }
@ -2163,7 +2170,7 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
if (videoFirst == -1) { if (videoFirst == -1) {
videoFirst = timestampNanos / 1000; videoFirst = timestampNanos / 1000;
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.d("first video frame was at " + videoFirst); FileLog.d("InstantCamera first video frame was at " + videoFirst);
} }
} }
videoLast = timestampNanos; videoLast = timestampNanos;
@ -2172,7 +2179,7 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
FloatBuffer vertexBuffer = InstantCameraView.this.vertexBuffer; FloatBuffer vertexBuffer = InstantCameraView.this.vertexBuffer;
FloatBuffer oldTextureBuffer = oldTextureTextureBuffer; FloatBuffer oldTextureBuffer = oldTextureTextureBuffer;
if (textureBuffer == null || vertexBuffer == null) { if (textureBuffer == null || vertexBuffer == null) {
FileLog.d("handleVideoFrameAvailable skip frame " + textureBuffer + " " + vertexBuffer); FileLog.d("InstantCamera handleVideoFrameAvailable skip frame " + textureBuffer + " " + vertexBuffer);
return; return;
} }
@ -2272,11 +2279,13 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
private void handleStopRecording(final int send) { private void handleStopRecording(final int send) {
if (running) { if (running) {
FileLog.d("InstantCamera handleStopRecording running=false");
sendWhenDone = send; sendWhenDone = send;
running = false; running = false;
return; return;
} }
try { try {
FileLog.d("InstantCamera handleStopRecording drain encoders");
drainEncoder(true); drainEncoder(true);
} catch (Exception e) { } catch (Exception e) {
FileLog.e(e); FileLog.e(e);
@ -2301,30 +2310,40 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
FileLog.e(e); FileLog.e(e);
} }
} }
if (mediaMuxer != null) { if (mediaMuxer != null) {
CountDownLatch countDownLatch = new CountDownLatch(1); if (WRITE_TO_FILE_IN_BACKGROUND) {
fileWriteQueue.postRunnable(() -> { CountDownLatch countDownLatch = new CountDownLatch(1);
fileWriteQueue.postRunnable(() -> {
try {
mediaMuxer.finishMovie();
} catch (Exception e) {
e.printStackTrace();
}
countDownLatch.countDown();
});
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
try { try {
mediaMuxer.finishMovie(); mediaMuxer.finishMovie();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e(e);
} }
countDownLatch.countDown();
});
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
} }
FileLog.d("InstantCamera handleStopRecording finish muxer");
if (writingToDifferentFile) { if (writingToDifferentFile) {
if (!fileToWrite.renameTo(videoFile)) { if (!fileToWrite.renameTo(videoFile)) {
FileLog.e("unable to rename file, try move file"); FileLog.e("InstantCamera unable to rename file, try move file");
try { try {
AndroidUtilities.copyFile(fileToWrite, videoFile); AndroidUtilities.copyFile(fileToWrite, videoFile);
fileToWrite.delete(); fileToWrite.delete();
} catch (IOException e) { } catch (IOException e) {
FileLog.e(e); FileLog.e(e);
FileLog.e("unable to move file"); FileLog.e("InstantCamera unable to move file");
} }
} }
} }
@ -2334,6 +2353,7 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
generateKeyframeThumbsQueue.recycle(); generateKeyframeThumbsQueue.recycle();
generateKeyframeThumbsQueue = null; generateKeyframeThumbsQueue = null;
} }
FileLog.d("InstantCamera handleStopRecording send " + send);
if (send != 0) { if (send != 0) {
AndroidUtilities.runOnUIThread(() -> { AndroidUtilities.runOnUIThread(() -> {
videoEditedInfo = new VideoEditedInfo(); videoEditedInfo = new VideoEditedInfo();
@ -2486,7 +2506,7 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
audioRecorder = new AudioRecord(MediaRecorder.AudioSource.DEFAULT, audioSampleRate, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSize); audioRecorder = new AudioRecord(MediaRecorder.AudioSource.DEFAULT, audioSampleRate, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSize);
audioRecorder.startRecording(); audioRecorder.startRecording();
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.d("initied audio record with channels " + audioRecorder.getChannelCount() + " sample rate = " + audioRecorder.getSampleRate() + " bufferSize = " + bufferSize); FileLog.d("InstantCamera initied audio record with channels " + audioRecorder.getChannelCount() + " sample rate = " + audioRecorder.getSampleRate() + " bufferSize = " + bufferSize);
} }
Thread thread = new Thread(recorderRunnable); Thread thread = new Thread(recorderRunnable);
thread.setPriority(Thread.MAX_PRIORITY); thread.setPriority(Thread.MAX_PRIORITY);
@ -2796,7 +2816,6 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
if (Build.VERSION.SDK_INT < 21) { if (Build.VERSION.SDK_INT < 21) {
encoderOutputBuffers = audioEncoder.getOutputBuffers(); encoderOutputBuffers = audioEncoder.getOutputBuffers();
} }
boolean encoderOutputAvailable = true;
while (true) { while (true) {
int encoderStatus = audioEncoder.dequeueOutputBuffer(audioBufferInfo, 0); int encoderStatus = audioEncoder.dequeueOutputBuffer(audioBufferInfo, 0);
if (encoderStatus == MediaCodec.INFO_TRY_AGAIN_LATER) { if (encoderStatus == MediaCodec.INFO_TRY_AGAIN_LATER) {
@ -2844,13 +2863,17 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
didWriteData(videoFile, availableSize, false); didWriteData(videoFile, availableSize, false);
} }
}); });
audioEncoder.releaseOutputBuffer(encoderStatus, false); if (audioEncoder != null) {
audioEncoder.releaseOutputBuffer(encoderStatus, false);
}
} else { } else {
long availableSize = mediaMuxer.writeSampleData(audioTrackIndex, encodedData, audioBufferInfo, false); long availableSize = mediaMuxer.writeSampleData(audioTrackIndex, encodedData, audioBufferInfo, false);
if (availableSize != 0 && !writingToDifferentFile) { if (availableSize != 0 && !writingToDifferentFile) {
didWriteData(videoFile, availableSize, false); didWriteData(videoFile, availableSize, false);
} }
audioEncoder.releaseOutputBuffer(encoderStatus, false); if (audioEncoder != null) {
audioEncoder.releaseOutputBuffer(encoderStatus, false);
}
} }
} else if (audioEncoder != null) { } else if (audioEncoder != null) {
audioEncoder.releaseOutputBuffer(encoderStatus, false); audioEncoder.releaseOutputBuffer(encoderStatus, false);

View file

@ -30,6 +30,7 @@ public class PremiumLockIconView extends ImageView {
StarParticlesView.Drawable starParticles; StarParticlesView.Drawable starParticles;
private boolean locked; private boolean locked;
private Theme.ResourcesProvider resourcesProvider; private Theme.ResourcesProvider resourcesProvider;
boolean attachedToWindow;
public PremiumLockIconView(Context context, int type) { public PremiumLockIconView(Context context, int type) {
this(context, type, null); this(context, type, null);
@ -165,6 +166,9 @@ public class PremiumLockIconView extends ImageView {
} }
private void updateGradient() { private void updateGradient() {
if (!attachedToWindow) {
return;
}
if (getMeasuredHeight() != 0 && getMeasuredWidth() != 0) { if (getMeasuredHeight() != 0 && getMeasuredWidth() != 0) {
int c1 = currentColor; int c1 = currentColor;
int c2; int c2;
@ -192,6 +196,27 @@ public class PremiumLockIconView extends ImageView {
} }
} }
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
attachedToWindow = true;
if (type != TYPE_REACTIONS) {
updateGradient();
}
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
attachedToWindow = false;
if (paint != null) {
paint.setShader(null);
paint = null;
}
shader = null;
wasDrawn = false;
}
public void setWaitingImage() { public void setWaitingImage() {
waitingImage = true; waitingImage = true;
wasDrawn = false; wasDrawn = false;

View file

@ -2017,8 +2017,10 @@ public class ShareAlert extends BottomSheet implements NotificationCenter.Notifi
params = SendMessagesHelper.SendMessageParams.of(sendingText[num], key, null, replyTopMsg, null, true, null, null, null, withSound, 0, null, false); params = SendMessagesHelper.SendMessageParams.of(sendingText[num], key, null, replyTopMsg, null, true, null, null, null, withSound, 0, null, false);
} }
} else { } else {
if (frameLayout2.getTag() != null && commentTextView.length() > 0 && text[0] != null) {
SendMessagesHelper.getInstance(currentAccount).sendMessage(SendMessagesHelper.SendMessageParams.of(text[0].toString(), key, null, replyTopMsg, null, true, null, null, null, withSound, 0, null, false));
}
params = SendMessagesHelper.SendMessageParams.of(null, key, null, replyTopMsg, null, true, null, null, null, withSound, 0, null, false); params = SendMessagesHelper.SendMessageParams.of(null, key, null, replyTopMsg, null, true, null, null, null, withSound, 0, null, false);
params.caption = frameLayout2.getTag() != null && commentTextView.length() > 0 && text[0] != null ? text[0].toString() : null;
params.sendingStory = storyItem; params.sendingStory = storyItem;
} }
SendMessagesHelper.getInstance(currentAccount).sendMessage(params); SendMessagesHelper.getInstance(currentAccount).sendMessage(params);

View file

@ -298,7 +298,6 @@ public class SpoilerEffect extends Drawable {
int dt = (int) Math.min(curTime - lastDrawTime, renderDelayMs); int dt = (int) Math.min(curTime - lastDrawTime, renderDelayMs);
boolean hasAnimator = false; boolean hasAnimator = false;
lastDrawTime = curTime; lastDrawTime = curTime;
int left = getBounds().left, top = getBounds().top, right = getBounds().right, bottom = getBounds().bottom; int left = getBounds().left, top = getBounds().top, right = getBounds().right, bottom = getBounds().bottom;

View file

@ -39,17 +39,17 @@ public class SpoilerEffectBitmapFactory {
int size; int size;
private SpoilerEffectBitmapFactory() { private SpoilerEffectBitmapFactory() {
int maxSize = SharedConfig.getDevicePerformanceClass() == SharedConfig.PERFORMANCE_CLASS_HIGH ? AndroidUtilities.dp(200) : AndroidUtilities.dp(150); int maxSize = SharedConfig.getDevicePerformanceClass() == SharedConfig.PERFORMANCE_CLASS_HIGH ? AndroidUtilities.dp(150) : AndroidUtilities.dp(100);
size = (int) Math.min(Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y) * 0.5f, maxSize); size = (int) Math.min(Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y) * 0.5f, maxSize);
if (size < AndroidUtilities.dp(100)) { if (size < AndroidUtilities.dp(80)) {
size = AndroidUtilities.dp(100); size = AndroidUtilities.dp(80);
} }
} }
Paint getPaint() { Paint getPaint() {
if (shaderBitmap == null) { if (shaderBitmap == null) {
shaderBitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888); shaderBitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ALPHA_8);
shaderCanvas = new Canvas(shaderBitmap); shaderCanvas = new Canvas(shaderBitmap);
shaderPaint = new Paint(); shaderPaint = new Paint();
shaderSpoilerEffects = new ArrayList<>(10 * 10); shaderSpoilerEffects = new ArrayList<>(10 * 10);
@ -89,10 +89,10 @@ public class SpoilerEffectBitmapFactory {
dispatchQueue.postRunnable(() -> { dispatchQueue.postRunnable(() -> {
Bitmap bitmap = bufferBitmapFinall; Bitmap bitmap = bufferBitmapFinall;
if (bitmap == null) { if (bitmap == null) {
bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888); bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ALPHA_8);
} }
if (backgroundBitmap == null) { if (backgroundBitmap == null) {
backgroundBitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888); backgroundBitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ALPHA_8);
} else { } else {
backgroundBitmap.eraseColor(Color.TRANSPARENT); backgroundBitmap.eraseColor(Color.TRANSPARENT);
} }

View file

@ -10,16 +10,18 @@ import android.graphics.Rect;
import android.graphics.Region; import android.graphics.Region;
import android.text.Layout; import android.text.Layout;
import android.text.Spanned; import android.text.Spanned;
import android.text.StaticLayout;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.widget.TextView; import android.widget.TextView;
import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.AndroidUtilities;
import org.telegram.ui.Cells.TextSelectionHelper;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Stack; import java.util.Stack;
public class SpoilersTextView extends TextView { public class SpoilersTextView extends TextView implements TextSelectionHelper.SimpleSelectabeleView {
private SpoilersClickDetector clickDetector; private SpoilersClickDetector clickDetector;
protected List<SpoilerEffect> spoilers = new ArrayList<>(); protected List<SpoilerEffect> spoilers = new ArrayList<>();
private Stack<SpoilerEffect> spoilersPool = new Stack<>(); private Stack<SpoilerEffect> spoilersPool = new Stack<>();
@ -147,4 +149,9 @@ public class SpoilersTextView extends TextView {
} }
invalidate(); invalidate();
} }
@Override
public Layout getStaticTextLayout() {
return getLayout();
}
} }

View file

@ -704,7 +704,6 @@ public class ContentPreviewViewer {
public boolean onTouch(MotionEvent event, final RecyclerListView listView, final int height, final Object listener, ContentPreviewViewerDelegate contentPreviewViewerDelegate, Theme.ResourcesProvider resourcesProvider) { public boolean onTouch(MotionEvent event, final RecyclerListView listView, final int height, final Object listener, ContentPreviewViewerDelegate contentPreviewViewerDelegate, Theme.ResourcesProvider resourcesProvider) {
delegate = contentPreviewViewerDelegate; delegate = contentPreviewViewerDelegate;
this.resourcesProvider = resourcesProvider;
if (delegate != null && !delegate.can()) { if (delegate != null && !delegate.can()) {
return false; return false;
} }
@ -908,7 +907,6 @@ public class ContentPreviewViewer {
public boolean onInterceptTouchEvent(MotionEvent event, final RecyclerListView listView, final int height, ContentPreviewViewerDelegate contentPreviewViewerDelegate, Theme.ResourcesProvider resourcesProvider) { public boolean onInterceptTouchEvent(MotionEvent event, final RecyclerListView listView, final int height, ContentPreviewViewerDelegate contentPreviewViewerDelegate, Theme.ResourcesProvider resourcesProvider) {
delegate = contentPreviewViewerDelegate; delegate = contentPreviewViewerDelegate;
this.resourcesProvider = resourcesProvider;
if (delegate != null && !delegate.can()) { if (delegate != null && !delegate.can()) {
return false; return false;
} }
@ -1299,12 +1297,24 @@ public class ContentPreviewViewer {
currentQuery = null; currentQuery = null;
delegate = null; delegate = null;
isVisible = false; isVisible = false;
resourcesProvider = null;
if (unlockPremiumView != null) { if (unlockPremiumView != null) {
unlockPremiumView.animate().alpha(0).translationY(AndroidUtilities.dp(56)).setDuration(150).setInterpolator(CubicBezierInterpolator.DEFAULT).start(); unlockPremiumView.animate().alpha(0).translationY(AndroidUtilities.dp(56)).setDuration(150).setInterpolator(CubicBezierInterpolator.DEFAULT).start();
} }
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.startAllHeavyOperations, 8); NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.startAllHeavyOperations, 8);
} }
public void clearDelegate(ContentPreviewViewerDelegate contentPreviewViewerDelegate) {
if (delegate == contentPreviewViewerDelegate) {
currentDocument = null;
currentStickerSet = null;
currentQuery = null;
delegate = null;
resourcesProvider = null;
reset();
}
}
public void destroy() { public void destroy() {
isVisible = false; isVisible = false;
delegate = null; delegate = null;
@ -1494,20 +1504,10 @@ public class ContentPreviewViewer {
AndroidUtilities.makeGlobalBlurBitmap(bitmap -> { AndroidUtilities.makeGlobalBlurBitmap(bitmap -> {
blurrBitmap = bitmap; blurrBitmap = bitmap;
preparingBitmap = false; preparingBitmap = false;
if (containerView != null) {
containerView.invalidate();
}
}, 12); }, 12);
// View parentView = parentActivity.getWindow().getDecorView();
// int w = (int) (parentView.getMeasuredWidth() / 12.0f);
// int h = (int) (parentView.getMeasuredHeight() / 12.0f);
// Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
// Canvas canvas = new Canvas(bitmap);
// canvas.scale(1.0f / 12.0f, 1.0f / 12.0f);
// canvas.drawColor(Theme.getColor(Theme.key_windowBackgroundWhite));
// parentView.draw(canvas);
// if (parentActivity instanceof LaunchActivity && ((LaunchActivity) parentActivity).getActionBarLayout().getLastFragment().getVisibleDialog() != null) {
// ((LaunchActivity) parentActivity).getActionBarLayout().getLastFragment().getVisibleDialog().getWindow().getDecorView().draw(canvas);
// }
// Utilities.stackBlurBitmap(bitmap, Math.max(10, Math.max(w, h) / 180));
// blurrBitmap = bitmap;
} }
public boolean showMenuFor(View view) { public boolean showMenuFor(View view) {

View file

@ -836,14 +836,14 @@ public class DataSettingsActivity extends BaseFragment {
builder.append(", "); builder.append(", ");
} }
builder.append(LocaleController.getString("AutoDownloadVideosOn", R.string.AutoDownloadVideosOn)); builder.append(LocaleController.getString("AutoDownloadVideosOn", R.string.AutoDownloadVideosOn));
builder.append(String.format(" (%1$s)", AndroidUtilities.formatFileSize(preset.sizes[DownloadController.typeToIndex(DownloadController.AUTODOWNLOAD_TYPE_VIDEO)], true))); builder.append(String.format(" (%1$s)", AndroidUtilities.formatFileSize(preset.sizes[DownloadController.typeToIndex(DownloadController.AUTODOWNLOAD_TYPE_VIDEO)], true, false)));
} }
if (files) { if (files) {
if (builder.length() > 0) { if (builder.length() > 0) {
builder.append(", "); builder.append(", ");
} }
builder.append(LocaleController.getString("AutoDownloadFilesOn", R.string.AutoDownloadFilesOn)); builder.append(LocaleController.getString("AutoDownloadFilesOn", R.string.AutoDownloadFilesOn));
builder.append(String.format(" (%1$s)", AndroidUtilities.formatFileSize(preset.sizes[DownloadController.typeToIndex(DownloadController.AUTODOWNLOAD_TYPE_DOCUMENT)], true))); builder.append(String.format(" (%1$s)", AndroidUtilities.formatFileSize(preset.sizes[DownloadController.typeToIndex(DownloadController.AUTODOWNLOAD_TYPE_DOCUMENT)], true, false)));
} }
} else { } else {
builder.append(LocaleController.getString("NoMediaAutoDownload", R.string.NoMediaAutoDownload)); builder.append(LocaleController.getString("NoMediaAutoDownload", R.string.NoMediaAutoDownload));

View file

@ -45,6 +45,7 @@ import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.text.TextPaint; import android.text.TextPaint;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log;
import android.util.LongSparseArray; import android.util.LongSparseArray;
import android.util.Property; import android.util.Property;
import android.util.StateSet; import android.util.StateSet;
@ -1925,7 +1926,7 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
ignoreLayout = false; ignoreLayout = false;
} }
} else if (pos == RecyclerView.NO_POSITION && firstLayout) { } else if (pos == RecyclerView.NO_POSITION && firstLayout) {
parentPage.layoutManager.scrollToPositionWithOffset(hasHiddenArchive() ? 1 : 0, (int) scrollYOffset); parentPage.layoutManager.scrollToPositionWithOffset(parentPage.dialogsType == DIALOGS_TYPE_DEFAULT && hasHiddenArchive() ? 1 : 0, (int) scrollYOffset);
} }
if (!onlySelect || initialDialogsType == DIALOGS_TYPE_FORWARD) { if (!onlySelect || initialDialogsType == DIALOGS_TYPE_FORWARD) {
ignoreLayout = true; ignoreLayout = true;
@ -3718,7 +3719,7 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
if (firstView != null) { if (firstView != null) {
firstView.invalidate(); firstView.invalidate();
} }
if (viewPage.archivePullViewState == ARCHIVE_ITEM_STATE_SHOWED && usedDy == 0 && dy < 0 && isDragging && !rightSlidingDialogContainer.hasFragment() && hasStories) { if (viewPage.archivePullViewState == ARCHIVE_ITEM_STATE_SHOWED && usedDy == 0 && dy < 0 && isDragging && !rightSlidingDialogContainer.hasFragment() && hasStories && progressToActionMode == 0) {
float newOverScroll = storiesOverscroll - dy * AndroidUtilities.lerp( 0.2f, 0.5f, dialogStoriesCell.overscrollProgress()); float newOverScroll = storiesOverscroll - dy * AndroidUtilities.lerp( 0.2f, 0.5f, dialogStoriesCell.overscrollProgress());
setStoriesOvercroll(viewPage, newOverScroll); setStoriesOvercroll(viewPage, newOverScroll);
} }
@ -3726,7 +3727,7 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
} }
int scrolled = super.scrollVerticallyBy(measuredDy, recycler, state); int scrolled = super.scrollVerticallyBy(measuredDy, recycler, state);
if (scrolled == 0 && dy < 0 && isDragging && !rightSlidingDialogContainer.hasFragment() && hasStories) { if (scrolled == 0 && dy < 0 && isDragging && !rightSlidingDialogContainer.hasFragment() && hasStories && progressToActionMode == 0) {
float newOverScroll = storiesOverscroll - dy * AndroidUtilities.lerp(0.2f, 0.5f, dialogStoriesCell.overscrollProgress()); float newOverScroll = storiesOverscroll - dy * AndroidUtilities.lerp(0.2f, 0.5f, dialogStoriesCell.overscrollProgress());
setStoriesOvercroll(viewPage, newOverScroll); setStoriesOvercroll(viewPage, newOverScroll);
} }
@ -5359,7 +5360,7 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
// } // }
public void showSelectStatusDialog() { public void showSelectStatusDialog() {
if (selectAnimatedEmojiDialog != null || SharedConfig.appLocked || !dialogStoriesCell.isExpanded()) { if (selectAnimatedEmojiDialog != null || SharedConfig.appLocked || (hasStories && !dialogStoriesCell.isExpanded())) {
return; return;
} }
final SelectAnimatedEmojiDialog.SelectAnimatedEmojiDialogWindow[] popup = new SelectAnimatedEmojiDialog.SelectAnimatedEmojiDialogWindow[1]; final SelectAnimatedEmojiDialog.SelectAnimatedEmojiDialogWindow[] popup = new SelectAnimatedEmojiDialog.SelectAnimatedEmojiDialogWindow[1];
@ -6389,7 +6390,9 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
@Override @Override
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
dialogStoriesCell.onResume(); if (dialogStoriesCell != null) {
dialogStoriesCell.onResume();
}
if (rightSlidingDialogContainer != null) { if (rightSlidingDialogContainer != null) {
rightSlidingDialogContainer.onResume(); rightSlidingDialogContainer.onResume();
} }

View file

@ -186,6 +186,7 @@ import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Adapters.MentionsAdapter; import org.telegram.ui.Adapters.MentionsAdapter;
import org.telegram.ui.Cells.CheckBoxCell; import org.telegram.ui.Cells.CheckBoxCell;
import org.telegram.ui.Cells.PhotoPickerPhotoCell; import org.telegram.ui.Cells.PhotoPickerPhotoCell;
import org.telegram.ui.Cells.TextSelectionHelper;
import org.telegram.ui.Components.AlertsCreator; import org.telegram.ui.Components.AlertsCreator;
import org.telegram.ui.Components.AnimatedEmojiDrawable; import org.telegram.ui.Components.AnimatedEmojiDrawable;
import org.telegram.ui.Components.AnimatedEmojiSpan; import org.telegram.ui.Components.AnimatedEmojiSpan;
@ -297,6 +298,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
private PhotoViewerActionBarContainer actionBarContainer; private PhotoViewerActionBarContainer actionBarContainer;
private PhotoCountView countView; private PhotoCountView countView;
public boolean closePhotoAfterSelect = true; public boolean closePhotoAfterSelect = true;
private TextSelectionHelper.SimpleTextSelectionHelper textSelectionHelper;
private static class PhotoViewerActionBarContainer extends FrameLayout implements NotificationCenter.NotificationCenterDelegate { private static class PhotoViewerActionBarContainer extends FrameLayout implements NotificationCenter.NotificationCenterDelegate {
@ -4464,6 +4466,19 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
} }
}; };
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (textSelectionHelper.isInSelectionMode()) {
textSelectionHelper.getOverlayView(getContext()).checkCancelAction(ev);
if (textSelectionHelper.getOverlayView(getContext()).onTouchEvent(ev)) {
return true;
}
return true;
}
return super.dispatchTouchEvent(ev);
}
@Override @Override
protected void onAttachedToWindow() { protected void onAttachedToWindow() {
super.onAttachedToWindow(); super.onAttachedToWindow();
@ -4477,6 +4492,22 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
Bulletin.removeDelegate(this); Bulletin.removeDelegate(this);
} }
@Override
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
View overlay = textSelectionHelper.getOverlayView(windowView.getContext());
if (child == overlay) {
return false;
}
return super.drawChild(canvas, child, drawingTime);
}
@Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
View overlay = textSelectionHelper.getOverlayView(windowView.getContext());
overlay.draw(canvas);
}
}; };
containerView.setFocusable(false); containerView.setFocusable(false);
@ -6129,7 +6160,6 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
return false; return false;
}); });
captionLimitView = new TextView(parentActivity); captionLimitView = new TextView(parentActivity);
captionLimitView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15); captionLimitView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
captionLimitView.setTextColor(0xffEC7777); captionLimitView.setTextColor(0xffEC7777);
@ -7025,6 +7055,16 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
doneButtonFullWidth.setBackground(Theme.AdaptiveRipple.filledRect(getThemedColor(Theme.key_featuredStickers_addButton), 6)); doneButtonFullWidth.setBackground(Theme.AdaptiveRipple.filledRect(getThemedColor(Theme.key_featuredStickers_addButton), 6));
doneButtonFullWidth.setTextColor(getThemedColor(Theme.key_featuredStickers_buttonText)); doneButtonFullWidth.setTextColor(getThemedColor(Theme.key_featuredStickers_buttonText));
textSelectionHelper = new TextSelectionHelper.SimpleTextSelectionHelper(null, resourcesProvider);
textSelectionHelper.useMovingOffset = false;
View overlay = textSelectionHelper.getOverlayView(windowView.getContext());
if (overlay != null) {
AndroidUtilities.removeFromParent(overlay);
containerView.addView(overlay);
}
textSelectionHelper.setParentView(containerView);
textSelectionHelper.setInvalidateParent();
} }
public void showCaptionLimitBulletin(FrameLayout view) { public void showCaptionLimitBulletin(FrameLayout view) {
@ -7388,7 +7428,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
} }
private TextView createCaptionTextView() { private TextView createCaptionTextView() {
TextView textView = new SpoilersTextView(activityContext) { SpoilersTextView textView = new SpoilersTextView(activityContext) {
private LinkSpanDrawable<ClickableSpan> pressedLink; private LinkSpanDrawable<ClickableSpan> pressedLink;
private LinkSpanDrawable.LinkCollector links = new LinkSpanDrawable.LinkCollector(this); private LinkSpanDrawable.LinkCollector links = new LinkSpanDrawable.LinkCollector(this);
@ -7398,6 +7438,11 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
if (getLayout() == null) { if (getLayout() == null) {
return false; return false;
} }
if (textSelectionHelper != null && getStaticTextLayout() != null) {
textSelectionHelper.setSelectabeleView(this);
textSelectionHelper.update(getPaddingLeft(), getPaddingTop());
textSelectionHelper.onTouchEvent(event);
}
boolean linkResult = false; boolean linkResult = false;
if (event.getAction() == MotionEvent.ACTION_DOWN || pressedLink != null && event.getAction() == MotionEvent.ACTION_UP) { if (event.getAction() == MotionEvent.ACTION_DOWN || pressedLink != null && event.getAction() == MotionEvent.ACTION_UP) {
int x = (int) (event.getX() - getPaddingLeft()); int x = (int) (event.getX() - getPaddingLeft());
@ -7452,6 +7497,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
return bottomTouchEnabled && b; return bottomTouchEnabled && b;
} }
@Override @Override
public void setPressed(boolean pressed) { public void setPressed(boolean pressed) {
final boolean needsRefresh = pressed != isPressed(); final boolean needsRefresh = pressed != isPressed();
@ -7465,6 +7511,15 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
@Override @Override
protected void onDraw(Canvas canvas) { protected void onDraw(Canvas canvas) {
if (textSelectionHelper != null && textSelectionHelper.isInSelectionMode()) {
canvas.save();
canvas.translate(getPaddingLeft(), getPaddingTop());
if (textSelectionHelper != null && getStaticTextLayout() != null && textSelectionHelper.isCurrent(this)) {
textSelectionHelper.draw(canvas);
}
canvas.restore();
}
canvas.save(); canvas.save();
canvas.translate(getPaddingLeft(), 0); canvas.translate(getPaddingLeft(), 0);
if (links.draw(canvas)) { if (links.draw(canvas)) {
@ -7504,6 +7559,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
canvas.restore(); canvas.restore();
} }
}; };
ViewHelper.setPadding(textView, 16, 8, 16, 8); ViewHelper.setPadding(textView, 16, 8, 16, 8);
textView.setLinkTextColor(0xff79c4fc); textView.setLinkTextColor(0xff79c4fc);
textView.setTextColor(0xffffffff); textView.setTextColor(0xffffffff);

View file

@ -399,7 +399,7 @@ public class SaveToGallerySettingsActivity extends BaseFragment {
SelectableAnimatedTextView lowerTextView = new SelectableAnimatedTextView(getContext()); SelectableAnimatedTextView lowerTextView = new SelectableAnimatedTextView(getContext());
lowerTextView.setTextSize(AndroidUtilities.dp(13)); lowerTextView.setTextSize(AndroidUtilities.dp(13));
lowerTextView.setText(AndroidUtilities.formatFileSize(1024 * 512, true)); lowerTextView.setText(AndroidUtilities.formatFileSize(1024 * 512, true, false));
textContainer.addView(lowerTextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.BOTTOM)); textContainer.addView(lowerTextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.BOTTOM));
SelectableAnimatedTextView midTextView = new SelectableAnimatedTextView(getContext()); SelectableAnimatedTextView midTextView = new SelectableAnimatedTextView(getContext());
@ -409,7 +409,7 @@ public class SaveToGallerySettingsActivity extends BaseFragment {
SelectableAnimatedTextView topTextView = new SelectableAnimatedTextView(getContext()); SelectableAnimatedTextView topTextView = new SelectableAnimatedTextView(getContext());
topTextView.setTextSize(AndroidUtilities.dp(13)); topTextView.setTextSize(AndroidUtilities.dp(13));
topTextView.setText(AndroidUtilities.formatFileSize(SaveToGallerySettingsHelper.MAX_VIDEO_LIMIT, true)); topTextView.setText(AndroidUtilities.formatFileSize(SaveToGallerySettingsHelper.MAX_VIDEO_LIMIT, true, false));
textContainer.addView(topTextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.RIGHT | Gravity.BOTTOM)); textContainer.addView(topTextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.RIGHT | Gravity.BOTTOM));
@ -450,7 +450,7 @@ public class SaveToGallerySettingsActivity extends BaseFragment {
} else { } else {
midTextView.setText( midTextView.setText(
LocaleController.formatString("UpToFileSize", R.string.UpToFileSize, LocaleController.formatString("UpToFileSize", R.string.UpToFileSize,
AndroidUtilities.formatFileSize(value, true) AndroidUtilities.formatFileSize(value, true, false)
), false); ), false);
lowerTextView.setSelectedInternal(false, animated); lowerTextView.setSelectedInternal(false, animated);
midTextView.setSelectedInternal(true, animated); midTextView.setSelectedInternal(true, animated);

View file

@ -212,7 +212,7 @@ public class StatisticActivity extends BaseFragment implements NotificationCente
if (recentPostsAll.size() > 0) { if (recentPostsAll.size() > 0) {
int lastPostId = recentPostsAll.get(0).counters.msg_id; int lastPostId = recentPostsAll.get(0).counters.msg_id;
int count = recentPostsAll.size(); int count = recentPostsAll.size();
getMessagesStorage().getMessages(-chat.id, 0, false, count, lastPostId, 0, 0, classGuid, 0, false, 0, 0, true, false); getMessagesStorage().getMessages(-chat.id, 0, false, count, lastPostId, 0, 0, classGuid, 0, false, 0, 0, true, false, null);
} }
AndroidUtilities.runOnUIThread(() -> { AndroidUtilities.runOnUIThread(() -> {

View file

@ -138,6 +138,7 @@ public class DarkThemeResourceProvider implements Theme.ResourcesProvider {
sparseIntArray.put(Theme.key_chat_outBubbleGradient1, 0); sparseIntArray.put(Theme.key_chat_outBubbleGradient1, 0);
sparseIntArray.put(Theme.key_chat_outBubbleGradient2, 0); sparseIntArray.put(Theme.key_chat_outBubbleGradient2, 0);
sparseIntArray.put(Theme.key_chat_outBubbleGradient3, 0); sparseIntArray.put(Theme.key_chat_outBubbleGradient3, 0);
sparseIntArray.put(Theme.key_chat_textSelectBackground, ColorUtils.blendARGB(Color.BLACK, Color.WHITE, 0.6f));
appendColors(); appendColors();
dividerPaint.setColor(getColor(Theme.key_divider)); dividerPaint.setColor(getColor(Theme.key_divider));

View file

@ -14,9 +14,12 @@ import android.graphics.PorterDuffColorFilter;
import android.graphics.Rect; import android.graphics.Rect;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.text.Layout; import android.text.Layout;
import android.text.Spannable;
import android.text.SpannableString; import android.text.SpannableString;
import android.text.SpannableStringBuilder; import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextUtils; import android.text.TextUtils;
import android.text.style.ClickableSpan;
import android.view.Gravity; import android.view.Gravity;
import android.view.HapticFeedbackConstants; import android.view.HapticFeedbackConstants;
import android.view.View; import android.view.View;
@ -58,6 +61,7 @@ import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.ListView.AdapterWithDiffUtils; import org.telegram.ui.Components.ListView.AdapterWithDiffUtils;
import org.telegram.ui.Components.RadialProgress; import org.telegram.ui.Components.RadialProgress;
import org.telegram.ui.Components.RecyclerListView; import org.telegram.ui.Components.RecyclerListView;
import org.telegram.ui.Components.TypefaceSpan;
import org.telegram.ui.PremiumPreviewFragment; import org.telegram.ui.PremiumPreviewFragment;
import org.telegram.ui.Stories.recorder.HintView2; import org.telegram.ui.Stories.recorder.HintView2;
import org.telegram.ui.Stories.recorder.StoryRecorder; import org.telegram.ui.Stories.recorder.StoryRecorder;
@ -1273,6 +1277,7 @@ public class DialogStoriesCell extends FrameLayout implements NotificationCenter
params.progressToArc = getArcProgress(cx, radius); params.progressToArc = getArcProgress(cx, radius);
params.isLast = isLast; params.isLast = isLast;
params.isFirst = isFirst; params.isFirst = isFirst;
params.crossfadeToDialog = 0;
StoriesUtilities.drawAvatarWithStory(dialogId, canvas, avatarImage, storiesController.hasSelfStories(), params); StoriesUtilities.drawAvatarWithStory(dialogId, canvas, avatarImage, storiesController.hasSelfStories(), params);
// avatarImage.draw(canvas); // avatarImage.draw(canvas);
} }
@ -1292,6 +1297,12 @@ public class DialogStoriesCell extends FrameLayout implements NotificationCenter
params.progressToArc = getArcProgress(cx, radius); params.progressToArc = getArcProgress(cx, radius);
params.isLast = isLast; params.isLast = isLast;
params.isFirst = isFirst; params.isFirst = isFirst;
if (crossfadeToDialog) {
params.crossfadeToDialog = crossfadeToDialogId;
params.crossfadeToDialogProgress = progressToCollapsed2;
} else {
params.crossfadeToDialog = 0;
}
StoriesUtilities.drawAvatarWithStory(dialogId, canvas, avatarImage, storiesController.hasStories(dialogId), params); StoriesUtilities.drawAvatarWithStory(dialogId, canvas, avatarImage, storiesController.hasStories(dialogId), params);
// avatarImage.draw(canvas); // avatarImage.draw(canvas);
} }
@ -1475,6 +1486,7 @@ public class DialogStoriesCell extends FrameLayout implements NotificationCenter
public void setCrossfadeTo(long dialogId) { public void setCrossfadeTo(long dialogId) {
if (crossfadeToDialogId != dialogId) { if (crossfadeToDialogId != dialogId) {
this.crossfadeToDialogId = dialogId;
crossfadeToDialog = dialogId != -1; crossfadeToDialog = dialogId != -1;
if (crossfadeToDialog) { if (crossfadeToDialog) {
TLObject object; TLObject object;
@ -1604,12 +1616,18 @@ public class DialogStoriesCell extends FrameLayout implements NotificationCenter
.setMultilineText(true) .setMultilineText(true)
.setTextAlign(Layout.Alignment.ALIGN_CENTER) .setTextAlign(Layout.Alignment.ALIGN_CENTER)
.setJoint(0, 37 - 8); .setJoint(0, 37 - 8);
CharSequence text = AndroidUtilities.replaceSingleTag(LocaleController.getString("StoriesPremiumHint").replace('\n', ' '), Theme.key_undo_cancelColor, 0, () -> { Spannable text = AndroidUtilities.replaceSingleTag(LocaleController.getString("StoriesPremiumHint").replace('\n', ' '), Theme.key_undo_cancelColor, 0, () -> {
if (premiumHint != null) { if (premiumHint != null) {
premiumHint.hide(); premiumHint.hide();
} }
fragment.presentFragment(new PremiumPreviewFragment("stories")); fragment.presentFragment(new PremiumPreviewFragment("stories"));
}); });
ClickableSpan[] spans = text.getSpans(0, text.length(), ClickableSpan.class);
if (spans != null && spans.length >= 1) {
int start = text.getSpanStart(spans[0]);
int end = text.getSpanEnd(spans[0]);
text.setSpan(new TypefaceSpan(AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_ROBOTO_MEDIUM)), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
premiumHint.setMaxWidthPx(HintView2.cutInFancyHalf(text, premiumHint.getTextPaint())); premiumHint.setMaxWidthPx(HintView2.cutInFancyHalf(text, premiumHint.getTextPaint()));
premiumHint.setText(text); premiumHint.setText(text);
premiumHint.setPadding(AndroidUtilities.dp(8), AndroidUtilities.dp(24), AndroidUtilities.dp(8), 0); premiumHint.setPadding(AndroidUtilities.dp(8), AndroidUtilities.dp(24), AndroidUtilities.dp(8), 0);

View file

@ -92,6 +92,7 @@ import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.ActionBar.BottomSheet; import org.telegram.ui.ActionBar.BottomSheet;
import org.telegram.ui.ActionBar.SimpleTextView; import org.telegram.ui.ActionBar.SimpleTextView;
import org.telegram.ui.ActionBar.Theme; import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Cells.TextSelectionHelper;
import org.telegram.ui.ChatActivity; import org.telegram.ui.ChatActivity;
import org.telegram.ui.Components.AlertsCreator; import org.telegram.ui.Components.AlertsCreator;
import org.telegram.ui.Components.AnimatedEmojiDrawable; import org.telegram.ui.Components.AnimatedEmojiDrawable;
@ -464,11 +465,7 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
canvas.drawPaint(sharedResources.gradientBackgroundPaint); canvas.drawPaint(sharedResources.gradientBackgroundPaint);
} }
if (progressToFullBlackout < 1f) { if (progressToFullBlackout < 1f) {
if (progressToDismiss != 0) { canvas.save();
canvas.saveLayerAlpha(0, gradientTop, getMeasuredWidth(), getMeasuredHeight(), 255, Canvas.ALL_SAVE_FLAG);
} else {
canvas.save();
}
sharedResources.gradientBackgroundPaint.setColor(ColorUtils.setAlphaComponent(Color.BLACK, (int) (255 * 0.506f * (1f - progressToFullBlackout) * hideCaptionAlpha))); sharedResources.gradientBackgroundPaint.setColor(ColorUtils.setAlphaComponent(Color.BLACK, (int) (255 * 0.506f * (1f - progressToFullBlackout) * hideCaptionAlpha)));
sharedResources.bottomOverlayGradient.setAlpha((int) (255 * (1f - progressToFullBlackout) * hideCaptionAlpha)); sharedResources.bottomOverlayGradient.setAlpha((int) (255 * (1f - progressToFullBlackout) * hideCaptionAlpha));
sharedResources.bottomOverlayGradient.setBounds(0, gradientTop, getMeasuredWidth(), gradientBottom); sharedResources.bottomOverlayGradient.setBounds(0, gradientTop, getMeasuredWidth(), gradientBottom);
@ -777,15 +774,16 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
bulletin.show(true); bulletin.show(true);
} }
}; };
storyCaptionView.captionTextview.setOnClickListener(new OnClickListener() { storyCaptionView.captionTextview.setOnClickListener(v -> {
@Override if (storyCaptionView.expanded) {
public void onClick(View v) { if (!storyCaptionView.textSelectionHelper.isInSelectionMode()) {
if (storyCaptionView.expanded) {
storyCaptionView.collapse(); storyCaptionView.collapse();
} else { } else {
checkBlackoutMode = true; storyCaptionView.checkCancelTextSelection();
storyCaptionView.expand();
} }
} else {
checkBlackoutMode = true;
storyCaptionView.expand();
} }
}); });
@ -1226,6 +1224,19 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
muteIconContainer.setBackground(Theme.createSimpleSelectorRoundRectDrawable(dp(20), Color.TRANSPARENT, ColorUtils.setAlphaComponent(Color.WHITE, 100))); muteIconContainer.setBackground(Theme.createSimpleSelectorRoundRectDrawable(dp(20), Color.TRANSPARENT, ColorUtils.setAlphaComponent(Color.WHITE, 100)));
optionsIconView.setBackground(Theme.createSimpleSelectorRoundRectDrawable(dp(20), Color.TRANSPARENT, ColorUtils.setAlphaComponent(Color.WHITE, 100))); optionsIconView.setBackground(Theme.createSimpleSelectorRoundRectDrawable(dp(20), Color.TRANSPARENT, ColorUtils.setAlphaComponent(Color.WHITE, 100)));
shareButton.setBackground(Theme.createSimpleSelectorRoundRectDrawable(dp(20), Color.TRANSPARENT, ColorUtils.setAlphaComponent(Color.WHITE, 100))); shareButton.setBackground(Theme.createSimpleSelectorRoundRectDrawable(dp(20), Color.TRANSPARENT, ColorUtils.setAlphaComponent(Color.WHITE, 100)));
View overlay = storyCaptionView.textSelectionHelper.getOverlayView(context);
if (overlay != null) {
AndroidUtilities.removeFromParent(overlay);
addView(overlay);
}
storyCaptionView.textSelectionHelper.setCallback(new TextSelectionHelper.Callback() {
@Override
public void onStateChanged(boolean isSelected) {
delegate.setIsInSelectionMode(storyCaptionView.textSelectionHelper.isInSelectionMode());
}
});
storyCaptionView.textSelectionHelper.setParentView(this);
} }
private ArrayList<TLRPC.InputStickerSet> getAnimatedEmojiSets(StoryItemHolder storyHolder) { private ArrayList<TLRPC.InputStickerSet> getAnimatedEmojiSets(StoryItemHolder storyHolder) {
@ -3044,6 +3055,10 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
} }
public boolean closeKeyboardOrEmoji() { public boolean closeKeyboardOrEmoji() {
if (storyCaptionView.textSelectionHelper.isInSelectionMode()) {
storyCaptionView.textSelectionHelper.clear(false);
return true;
}
if (privacyHint != null) { if (privacyHint != null) {
privacyHint.hide(); privacyHint.hide();
} }
@ -3149,6 +3164,7 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
//storyViewer.allowScreenshots(allowScreenshots); //storyViewer.allowScreenshots(allowScreenshots);
} else { } else {
cancelTextSelection();
muteIconView.clearAnimationDrawable(); muteIconView.clearAnimationDrawable();
viewsThumbImageReceiver = null; viewsThumbImageReceiver = null;
isLongPressed = false; isLongPressed = false;
@ -3196,6 +3212,7 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
progressToHideInterface.set(0, false); progressToHideInterface.set(0, false);
viewsThumbImageReceiver = null; viewsThumbImageReceiver = null;
messageSent = false; messageSent = false;
cancelTextSelection();
} }
public void onActivityResult(int requestCode, int resultCode, Intent data) { public void onActivityResult(int requestCode, int resultCode, Intent data) {
@ -3377,6 +3394,26 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
muteIconContainer.callOnClick(); muteIconContainer.callOnClick();
} }
public boolean checkTextSelectionEvent(MotionEvent ev) {
if (storyCaptionView.textSelectionHelper.isInSelectionMode()) {
float xOffset = getX();
float yOffset = getY() + ((View) getParent()).getY();
ev.offsetLocation(-xOffset, -yOffset);
if (storyCaptionView.textSelectionHelper.getOverlayView(getContext()).onTouchEvent(ev)) {
return true;
} else {
ev.offsetLocation(xOffset, yOffset);
}
}
return false;
}
public void cancelTextSelection() {
if (storyCaptionView.textSelectionHelper.isInSelectionMode()) {
storyCaptionView.textSelectionHelper.clear();
}
}
public static class PeerHeaderView extends FrameLayout { public static class PeerHeaderView extends FrameLayout {
public BackupImageView backupImageView; public BackupImageView backupImageView;
@ -3601,6 +3638,8 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
void setIsHintVisible(boolean visible); void setIsHintVisible(boolean visible);
void setIsSwiping(boolean swiping); void setIsSwiping(boolean swiping);
void setIsInSelectionMode(boolean selectionMode);
} }
public class StoryItemHolder { public class StoryItemHolder {
@ -4006,6 +4045,12 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
if (progressToHideInterface.get() != prevToHideProgress) { if (progressToHideInterface.get() != prevToHideProgress) {
storyContainer.invalidate(); storyContainer.invalidate();
} }
if (progressToDismissLocal != 0) {
//fix jittering caption shadow
storyContainer.setLayerType(LAYER_TYPE_HARDWARE, null);
} else {
storyContainer.setLayerType(LAYER_TYPE_NONE, null);
}
prevToHideProgress = progressToHideInterface.get(); prevToHideProgress = progressToHideInterface.get();
progressToDismiss = progressToDismissLocal; progressToDismiss = progressToDismissLocal;
progressToKeyboard = progressToKeyboardLocal; progressToKeyboard = progressToKeyboardLocal;
@ -4014,6 +4059,7 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
return; return;
} }
if (reactionsContainerLayout != null) { if (reactionsContainerLayout != null) {
reactionsContainerLayout.setVisibility(progressToKeyboard > 0 ? View.VISIBLE : View.GONE); reactionsContainerLayout.setVisibility(progressToKeyboard > 0 ? View.VISIBLE : View.GONE);
} }
@ -4031,7 +4077,7 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
for (int i = 0; i < getChildCount(); i++) { for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i); View child = getChildAt(i);
if (child.getVisibility() != View.VISIBLE || child == selfView || child.getTag(R.id.parent_tag) != null) { if (child.getVisibility() != View.VISIBLE || child == selfView || child.getTag(R.id.parent_tag) != null || child == storyCaptionView.textSelectionHelper.getOverlayView(getContext())) {
if (child == selfView) { if (child == selfView) {
if (BIG_SCREEN) { if (BIG_SCREEN) {
child.setAlpha((1f - progressToDismiss) * hideInterfaceAlpha * (1f - outT)); child.setAlpha((1f - progressToDismiss) * hideInterfaceAlpha * (1f - outT));

View file

@ -70,7 +70,6 @@ public class SelfStoryViewsPage extends FrameLayout implements NotificationCente
titleView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20); titleView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20);
titleView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); titleView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
titleView.setPadding(AndroidUtilities.dp(21), AndroidUtilities.dp(6), AndroidUtilities.dp(21), AndroidUtilities.dp(8)); titleView.setPadding(AndroidUtilities.dp(21), AndroidUtilities.dp(6), AndroidUtilities.dp(21), AndroidUtilities.dp(8));
addView(titleView);
recyclerListView = new RecyclerListView(context) { recyclerListView = new RecyclerListView(context) {
@Override @Override
@ -109,15 +108,18 @@ public class SelfStoryViewsPage extends FrameLayout implements NotificationCente
View shadowView2 = new View(getContext()); View shadowView2 = new View(getContext());
shadowView2.setBackgroundColor(Theme.getColor(Theme.key_dialogBackground, resourcesProvider)); shadowView2.setBackgroundColor(Theme.getColor(Theme.key_dialogBackground, resourcesProvider));
addView(shadowView2, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 8, 0, 0, TOP_PADDING - 16, 0, 0)); addView(shadowView2, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 10, 0, 0, TOP_PADDING - 17, 0, 0));
addView(titleView);
} }
@Override @Override
protected boolean drawChild(Canvas canvas, View child, long drawingTime) { protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
if (child == recyclerListView) { if (child == recyclerListView) {
canvas.save();
canvas.clipRect(0, AndroidUtilities.dp(TOP_PADDING), getMeasuredWidth(), getMeasuredHeight()); canvas.clipRect(0, AndroidUtilities.dp(TOP_PADDING), getMeasuredWidth(), getMeasuredHeight());
super.drawChild(canvas, child, drawingTime); super.drawChild(canvas, child, drawingTime);
canvas.restore();
return true; return true;
} }
return super.drawChild(canvas, child, drawingTime); return super.drawChild(canvas, child, drawingTime);

View file

@ -216,9 +216,11 @@ public class SelfStoryViewsView extends FrameLayout {
float alpha = Utilities.clamp(progressToOpen / 0.5f, 1f, 0); float alpha = Utilities.clamp(progressToOpen / 0.5f, 1f, 0);
// selfStoriesPreviewView.setAlpha(alpha); // selfStoriesPreviewView.setAlpha(alpha);
PeerStoriesView currentView = storyViewer.getCurrentPeerView(); final PeerStoriesView currentView = storyViewer.getCurrentPeerView();
if (oldProgressToOpen == 1f && progressToOpen != 1f) { if (oldProgressToOpen == 1f && progressToOpen != 1f) {
currentView.selectPosition(selfStoriesPreviewView.getClosestPosition()); if (currentView != null) {
currentView.selectPosition(selfStoriesPreviewView.getClosestPosition());
}
selfStoriesPreviewView.abortScroll(); selfStoriesPreviewView.abortScroll();
} }
if (currentView != null) { if (currentView != null) {

View file

@ -13,6 +13,7 @@ import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Cells.ChatActionCell; import org.telegram.ui.Cells.ChatActionCell;
import org.telegram.ui.Cells.ChatMessageCell; import org.telegram.ui.Cells.ChatMessageCell;
import org.telegram.ui.Cells.DialogCell; import org.telegram.ui.Cells.DialogCell;
import org.telegram.ui.Cells.ProfileSearchCell;
import org.telegram.ui.Cells.ReactedUserHolderView; import org.telegram.ui.Cells.ReactedUserHolderView;
import org.telegram.ui.Cells.SharedPhotoVideoCell2; import org.telegram.ui.Cells.SharedPhotoVideoCell2;
import org.telegram.ui.Cells.UserCell; import org.telegram.ui.Cells.UserCell;
@ -178,6 +179,16 @@ public class StoriesListPlaceProvider implements StoryViewer.PlaceProvider {
updateClip(holder); updateClip(holder);
return true; return true;
} }
} else if (child instanceof ProfileSearchCell) {
ProfileSearchCell cell = (ProfileSearchCell) child;
if (cell.getDialogId() == dialogId) {
holder.view = cell;
holder.params = cell.avatarStoryParams;
holder.avatarImage = cell.avatarImage;
holder.clipParent = (View) cell.getParent();
updateClip(holder);
return true;
}
} }
} }
return false; return false;

View file

@ -33,6 +33,7 @@ import org.telegram.messenger.UserConfig;
import org.telegram.messenger.Utilities; import org.telegram.messenger.Utilities;
import org.telegram.tgnet.ConnectionsManager; import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.TLRPC; import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.ActionBar.SimpleTextView; import org.telegram.ui.ActionBar.SimpleTextView;
import org.telegram.ui.ActionBar.Theme; import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.AnimatedTextView; import org.telegram.ui.Components.AnimatedTextView;
@ -40,6 +41,7 @@ import org.telegram.ui.Components.ButtonBounce;
import org.telegram.ui.Components.ColoredImageSpan; import org.telegram.ui.Components.ColoredImageSpan;
import org.telegram.ui.Components.CubicBezierInterpolator; import org.telegram.ui.Components.CubicBezierInterpolator;
import org.telegram.ui.Components.GradientTools; import org.telegram.ui.Components.GradientTools;
import org.telegram.ui.Components.RecyclerListView;
import org.telegram.ui.LaunchActivity; import org.telegram.ui.LaunchActivity;
import java.util.Collections; import java.util.Collections;
@ -247,7 +249,13 @@ public class StoriesUtilities {
if (params.drawSegments) { if (params.drawSegments) {
checkGrayPaint(); checkGrayPaint();
checkStoryCellGrayPaint(params.isArchive); checkStoryCellGrayPaint(params.isArchive);
int globalState = storiesController.getUnreadState(dialogId); int globalState;
if (params.crossfadeToDialog != 0) {
globalState = storiesController.getUnreadState(params.crossfadeToDialog);
} else {
globalState = storiesController.getUnreadState(dialogId);
}
params.globalState = globalState == StoriesController.STATE_READ ? STATE_READ : STATE_HAS_UNREAD; params.globalState = globalState == StoriesController.STATE_READ ? STATE_READ : STATE_HAS_UNREAD;
TLRPC.TL_userStories userStories = storiesController.getStories(params.dialogId); TLRPC.TL_userStories userStories = storiesController.getStories(params.dialogId);
int storiesCount; int storiesCount;
@ -256,6 +264,16 @@ public class StoriesUtilities {
} else { } else {
storiesCount = userStories == null || userStories.stories.size() == 1 ? 1 : userStories.stories.size(); storiesCount = userStories == null || userStories.stories.size() == 1 ? 1 : userStories.stories.size();
} }
Paint globalPaint;
if (globalState == StoriesController.STATE_UNREAD_CLOSE_FRIEND) {
getCloseFriendsPaint(avatarImage);
globalPaint = closeFriendsGradientTools.paint;
} else if (globalState == StoriesController.STATE_UNREAD) {
getActiveCirclePaint(avatarImage, params.isStoryCell);
globalPaint = storiesGradientTools[params.isStoryCell ? 1 : 0].paint;
} else {
globalPaint = params.isStoryCell ? storyCellGreyPaint[params.isArchive ? 1 : 0] : grayPaint;
}
if (storiesCount == 1) { if (storiesCount == 1) {
Paint localPaint = paint; Paint localPaint = paint;
if (storiesController.hasUnreadStories(dialogId)) { if (storiesController.hasUnreadStories(dialogId)) {
@ -267,6 +285,17 @@ public class StoriesUtilities {
startAngle = 90; startAngle = 90;
endAngle = 270; endAngle = 270;
drawSegment(canvas, rectTmp, localPaint, startAngle, endAngle, params); drawSegment(canvas, rectTmp, localPaint, startAngle, endAngle, params);
if (params.progressToSegments != 1 && localPaint != globalPaint) {
globalPaint.setAlpha((int) (255 * (1f - params.progressToSegments)));
startAngle = -90;
endAngle = 90;
drawSegment(canvas, rectTmp, globalPaint, startAngle, endAngle, params);
startAngle = 90;
endAngle = 270;
drawSegment(canvas, rectTmp, globalPaint, startAngle, endAngle, params);
globalPaint.setAlpha(255);
}
// canvas.drawCircle(rectTmp.centerX(), rectTmp.centerY(), rectTmp.width() / 2f, localPaint); // canvas.drawCircle(rectTmp.centerX(), rectTmp.centerY(), rectTmp.width() / 2f, localPaint);
} else { } else {
float step = 360 / (float) storiesCount; float step = 360 / (float) storiesCount;
@ -275,16 +304,7 @@ public class StoriesUtilities {
if (gapLen > step) { if (gapLen > step) {
gapLen = 0;//step * 0.4f; gapLen = 0;//step * 0.4f;
} }
Paint globalPaint;
if (globalState == StoriesController.STATE_UNREAD_CLOSE_FRIEND) {
getCloseFriendsPaint(avatarImage);
globalPaint = closeFriendsGradientTools.paint;
} else if (globalState == StoriesController.STATE_UNREAD) {
getActiveCirclePaint(avatarImage, params.isStoryCell);
globalPaint = storiesGradientTools[params.isStoryCell ? 1 : 0].paint;
} else {
globalPaint = params.isStoryCell ? storyCellGreyPaint[params.isArchive ? 1 : 0] : grayPaint;
}
int maxUnread = params.drawHiddenStoriesAsSegments ? 0 : Math.max(userStories.max_read_id, storiesController.dialogIdToMaxReadId.get(dialogId, 0)); int maxUnread = params.drawHiddenStoriesAsSegments ? 0 : Math.max(userStories.max_read_id, storiesController.dialogIdToMaxReadId.get(dialogId, 0));
for (int i = 0; i < storiesCount; i++) { for (int i = 0; i < storiesCount; i++) {
@ -751,6 +771,8 @@ public class StoriesUtilities {
public int unreadState; public int unreadState;
public int animateFromUnreadState; public int animateFromUnreadState;
public boolean drawHiddenStoriesAsSegments; public boolean drawHiddenStoriesAsSegments;
public long crossfadeToDialog;
public float crossfadeToDialogProgress;
private long dialogId; private long dialogId;
public int currentState; public int currentState;
@ -792,8 +814,10 @@ public class StoriesUtilities {
float startX, startY; float startX, startY;
Runnable longPressRunnable; Runnable longPressRunnable;
public View child;
public boolean checkOnTouchEvent(MotionEvent event, View view) { public boolean checkOnTouchEvent(MotionEvent event, View view) {
child = view;
StoriesController storiesController = MessagesController.getInstance(UserConfig.selectedAccount).getStoriesController(); StoriesController storiesController = MessagesController.getInstance(UserConfig.selectedAccount).getStoriesController();
if (event.getAction() == MotionEvent.ACTION_DOWN && originalAvatarRect.contains(event.getX(), event.getY())) { if (event.getAction() == MotionEvent.ACTION_DOWN && originalAvatarRect.contains(event.getX(), event.getY())) {
TLRPC.User user = MessagesController.getInstance(UserConfig.selectedAccount).getUser(dialogId); TLRPC.User user = MessagesController.getInstance(UserConfig.selectedAccount).getUser(dialogId);
@ -891,6 +915,11 @@ public class StoriesUtilities {
} }
public void openStory(long dialogId, Runnable onDone) { public void openStory(long dialogId, Runnable onDone) {
BaseFragment fragment = LaunchActivity.getLastFragment();
if (fragment != null && child != null) {
fragment.getOrCreateStoryViewer().doOnAnimationReady(onDone);
fragment.getOrCreateStoryViewer().open(fragment.getContext(), dialogId, StoriesListPlaceProvider.of((RecyclerListView) child.getParent()));
}
} }
public float getScale() { public float getScale() {

View file

@ -9,6 +9,7 @@ import android.view.ViewGroup;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.viewpager.widget.PagerAdapter; import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager; import androidx.viewpager.widget.ViewPager;
@ -168,7 +169,7 @@ public class StoriesViewPager extends ViewPager {
@Override @Override
public void onPageSelected(int position) { public void onPageSelected(int position) {
PeerStoriesView peerStoriesView = getCurrentPeerView(); final PeerStoriesView peerStoriesView = getCurrentPeerView();
if (peerStoriesView == null) { if (peerStoriesView == null) {
return; return;
} }
@ -222,6 +223,7 @@ public class StoriesViewPager extends ViewPager {
return true; return true;
} }
@Nullable
public PeerStoriesView getCurrentPeerView() { public PeerStoriesView getCurrentPeerView() {
for (int i = 0; i < getChildCount(); i++) { for (int i = 0; i < getChildCount(); i++) {
if ((Integer) getChildAt(i).getTag() == getCurrentItem()) { if ((Integer) getChildAt(i).getTag() == getCurrentItem()) {
@ -264,7 +266,7 @@ public class StoriesViewPager extends ViewPager {
super.onLayout(changed, l, t, r, b); super.onLayout(changed, l, t, r, b);
if (updateDelegate) { if (updateDelegate) {
updateDelegate = false; updateDelegate = false;
PeerStoriesView peerStoriesView = getCurrentPeerView(); final PeerStoriesView peerStoriesView = getCurrentPeerView();
if (peerStoriesView != null) { if (peerStoriesView != null) {
delegate.onPeerSelected(peerStoriesView.getCurrentPeer(), peerStoriesView.getSelectedPosition()); delegate.onPeerSelected(peerStoriesView.getCurrentPeer(), peerStoriesView.getSelectedPosition());
} }
@ -343,7 +345,7 @@ public class StoriesViewPager extends ViewPager {
public void setKeyboardHeight(int realKeyboardHeight) { public void setKeyboardHeight(int realKeyboardHeight) {
if (keyboardHeight != realKeyboardHeight) { if (keyboardHeight != realKeyboardHeight) {
keyboardHeight = realKeyboardHeight; keyboardHeight = realKeyboardHeight;
View view = getCurrentPeerView(); final View view = getCurrentPeerView();
if (view != null) { if (view != null) {
view.requestLayout(); view.requestLayout();
} }

View file

@ -49,6 +49,7 @@ import org.telegram.messenger.R;
import org.telegram.messenger.Utilities; import org.telegram.messenger.Utilities;
import org.telegram.ui.ActionBar.ActionBarPopupWindow; import org.telegram.ui.ActionBar.ActionBarPopupWindow;
import org.telegram.ui.ActionBar.Theme; import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Cells.TextSelectionHelper;
import org.telegram.ui.Components.AnimatedEmojiDrawable; import org.telegram.ui.Components.AnimatedEmojiDrawable;
import org.telegram.ui.Components.AnimatedEmojiSpan; import org.telegram.ui.Components.AnimatedEmojiSpan;
import org.telegram.ui.Components.CubicBezierInterpolator; import org.telegram.ui.Components.CubicBezierInterpolator;
@ -72,6 +73,8 @@ public class StoryCaptionView extends NestedScrollView {
private final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); private final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
TextSelectionHelper.SimpleTextSelectionHelper textSelectionHelper;
private final SpringAnimation springAnimation; private final SpringAnimation springAnimation;
public StoryCaptionTextView captionTextview; public StoryCaptionTextView captionTextview;
@ -80,6 +83,9 @@ public class StoryCaptionView extends NestedScrollView {
private float velocitySign; private float velocitySign;
private float velocityY; private float velocityY;
private float lastMotionX;
private float lastMotionY;
private Method abortAnimatedScrollMethod; private Method abortAnimatedScrollMethod;
private OverScroller scroller; private OverScroller scroller;
@ -109,11 +115,8 @@ public class StoryCaptionView extends NestedScrollView {
NotificationCenter.listenEmojiLoading(this); NotificationCenter.listenEmojiLoading(this);
captionTextview = new StoryCaptionTextView(getContext(), resourcesProvider); captionTextview = new StoryCaptionTextView(getContext(), resourcesProvider);
//captionTextview.setTextIsSelectable(true); textSelectionHelper = new TextSelectionHelper.SimpleTextSelectionHelper(captionTextview, resourcesProvider);
textSelectionHelper.useMovingOffset = false;
//captionTextview.setPadding(AndroidUtilities.dp(16), AndroidUtilities.dp(8), AndroidUtilities.dp(16), AndroidUtilities.dp(8));
captionContainer.addView(captionTextview, LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT); captionContainer.addView(captionTextview, LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT);
addView(captionContainer, new ViewGroup.LayoutParams(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT)); addView(captionContainer, new ViewGroup.LayoutParams(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
@ -322,6 +325,7 @@ public class StoryCaptionView extends NestedScrollView {
} }
captionTextview.setTranslationY(overScrollY); captionTextview.setTranslationY(overScrollY);
textSelectionHelper.invalidate();
return true; return true;
} }
@ -359,6 +363,7 @@ public class StoryCaptionView extends NestedScrollView {
} }
} }
} }
textSelectionHelper.invalidate();
} }
private void startSpringAnimationIfNotRunning(float velocityY) { private void startSpringAnimationIfNotRunning(float velocityY) {
@ -466,6 +471,7 @@ public class StoryCaptionView extends NestedScrollView {
if (getParent() != null) { if (getParent() != null) {
((View) getParent()).invalidate(); ((View) getParent()).invalidate();
} }
textSelectionHelper.invalidate();
} }
public float getProgressToBlackout() { public float getProgressToBlackout() {
@ -539,7 +545,13 @@ public class StoryCaptionView extends NestedScrollView {
return captionContainer.getBottom() - getMeasuredHeight() > 0; return captionContainer.getBottom() - getMeasuredHeight() > 0;
} }
public class StoryCaptionTextView extends View { public void checkCancelTextSelection() {
if (textSelectionHelper.isInSelectionMode()) {
textSelectionHelper.getOverlayView(getContext()).checkCancel(lastMotionX, lastMotionY, false);
}
}
public class StoryCaptionTextView extends View implements TextSelectionHelper.SelectableView, TextSelectionHelper.SimpleSelectabeleView {
private final PorterDuffColorFilter emojiColorFilter; private final PorterDuffColorFilter emojiColorFilter;
private LinkSpanDrawable<CharacterStyle> pressedLink; private LinkSpanDrawable<CharacterStyle> pressedLink;
@ -561,7 +573,6 @@ public class StoryCaptionView extends NestedScrollView {
int textHeight; int textHeight;
float textX; float textX;
float textY; float textY;
boolean expanded = false;
float progressToExpand; float progressToExpand;
float showMoreY; float showMoreY;
float showMoreX; float showMoreX;
@ -621,7 +632,11 @@ public class StoryCaptionView extends NestedScrollView {
// invalidateSpoilers(); // invalidateSpoilers();
this.text = text; this.text = text;
sizeCached = 0; sizeCached = 0;
if (getMeasuredWidth() > 0) {
createLayout(getMeasuredWidth());
}
requestLayout(); requestLayout();
invalidate();
} }
@SuppressLint("DrawAllocation") @SuppressLint("DrawAllocation")
@ -632,65 +647,69 @@ public class StoryCaptionView extends NestedScrollView {
verticalPadding = AndroidUtilities.dp(8); verticalPadding = AndroidUtilities.dp(8);
if (sizeCached != size) { if (sizeCached != size) {
sizeCached = size; sizeCached = size;
int width = MeasureSpec.getSize(widthMeasureSpec) - horizontalPadding * 2; createLayout(MeasureSpec.getSize(widthMeasureSpec));
fullLayout = makeTextLayout(textPaint, text, width);
textHeight = fullLayout.getHeight();
textX = horizontalPadding;
textY = verticalPadding;
float space = textPaint.measureText(" ");
if (fullLayout.getLineCount() > 3) {
String showMoreText = LocaleController.getString("ShowMore", R.string.ShowMore);
showMore = makeTextLayout(showMorePaint, showMoreText, width);
float collapsedY = fullLayout.getLineTop(2) + fullLayout.getTopPadding();
showMoreY = textY + collapsedY - AndroidUtilities.dpf2(0.3f);
showMoreX = MeasureSpec.getSize(widthMeasureSpec) - horizontalPadding - showMorePaint.measureText(showMoreText);
firstLayout = makeTextLayout(textPaint, text.subSequence(0, fullLayout.getLineEnd(2)), width);
spoilersPool.addAll(spoilers);
spoilers.clear();
SpoilerEffect.addSpoilers(this, fullLayout, spoilersPool, spoilers);
float x = fullLayout.getLineRight(2) + space;
if (nextLinesLayouts != null) {
for (int i = 0; i < nextLinesLayouts.length; i++) {
if (nextLinesLayouts[i] == null) {
continue;
}
AnimatedEmojiSpan.release(this, nextLinesLayouts[i].layoutEmoji);
}
}
nextLinesLayouts = new LineInfo[fullLayout.getLineCount() - 3];
if (spoilers.isEmpty()) {
for (int line = 3; line < fullLayout.getLineCount(); ++line) {
int s = fullLayout.getLineStart(line), e = fullLayout.getLineEnd(line);
final StaticLayout layout = makeTextLayout(textPaint, text.subSequence(Math.min(s, e), Math.max(s, e)), width);
LineInfo lineInfo = new LineInfo();
nextLinesLayouts[line - 3] = lineInfo;
lineInfo.staticLayout = layout;
lineInfo.finalX = fullLayout.getLineLeft(line);
lineInfo.finalY = fullLayout.getLineTop(line) + fullLayout.getTopPadding();
if (x < showMoreX - AndroidUtilities.dp(16)) {
lineInfo.collapsedY = collapsedY;
lineInfo.collapsedX = x;
x += layout.getLineRight(0) + space;
} else {
lineInfo.collapsedY = lineInfo.finalY;
lineInfo.collapsedX = lineInfo.finalX;
}
}
}
} else {
showMore = null;
firstLayout = null;
spoilersPool.addAll(spoilers);
spoilers.clear();
SpoilerEffect.addSpoilers(this, fullLayout, spoilersPool, spoilers);
}
} }
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(verticalPadding * 2 + textHeight, MeasureSpec.EXACTLY)); super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(verticalPadding * 2 + textHeight, MeasureSpec.EXACTLY));
} }
private void createLayout(int measuredWidth) {
int width = measuredWidth - horizontalPadding * 2;
fullLayout = makeTextLayout(textPaint, text, width);
textHeight = fullLayout.getHeight();
textX = horizontalPadding;
textY = verticalPadding;
float space = textPaint.measureText(" ");
if (fullLayout.getLineCount() > 3) {
String showMoreText = LocaleController.getString("ShowMore", R.string.ShowMore);
showMore = makeTextLayout(showMorePaint, showMoreText, width);
float collapsedY = fullLayout.getLineTop(2) + fullLayout.getTopPadding();
showMoreY = textY + collapsedY - AndroidUtilities.dpf2(0.3f);
showMoreX = width - horizontalPadding - showMorePaint.measureText(showMoreText);
firstLayout = makeTextLayout(textPaint, text.subSequence(0, fullLayout.getLineEnd(2)), width);
spoilersPool.addAll(spoilers);
spoilers.clear();
SpoilerEffect.addSpoilers(this, fullLayout, spoilersPool, spoilers);
float x = fullLayout.getLineRight(2) + space;
if (nextLinesLayouts != null) {
for (int i = 0; i < nextLinesLayouts.length; i++) {
if (nextLinesLayouts[i] == null) {
continue;
}
AnimatedEmojiSpan.release(this, nextLinesLayouts[i].layoutEmoji);
}
}
nextLinesLayouts = new LineInfo[fullLayout.getLineCount() - 3];
if (spoilers.isEmpty()) {
for (int line = 3; line < fullLayout.getLineCount(); ++line) {
int s = fullLayout.getLineStart(line), e = fullLayout.getLineEnd(line);
final StaticLayout layout = makeTextLayout(textPaint, text.subSequence(Math.min(s, e), Math.max(s, e)), width);
LineInfo lineInfo = new LineInfo();
nextLinesLayouts[line - 3] = lineInfo;
lineInfo.staticLayout = layout;
lineInfo.finalX = fullLayout.getLineLeft(line);
lineInfo.finalY = fullLayout.getLineTop(line) + fullLayout.getTopPadding();
if (x < showMoreX - AndroidUtilities.dp(16)) {
lineInfo.collapsedY = collapsedY;
lineInfo.collapsedX = x;
x += layout.getLineRight(0) + space;
} else {
lineInfo.collapsedY = lineInfo.finalY;
lineInfo.collapsedX = lineInfo.finalX;
}
}
}
} else {
showMore = null;
firstLayout = null;
spoilersPool.addAll(spoilers);
spoilers.clear();
SpoilerEffect.addSpoilers(this, fullLayout, spoilersPool, spoilers);
}
}
@Override @Override
protected void onDraw(Canvas canvas) { protected void onDraw(Canvas canvas) {
if (showMore != null) { if (showMore != null) {
@ -710,12 +729,21 @@ public class StoryCaptionView extends NestedScrollView {
if (fullLayout != null) { if (fullLayout != null) {
canvas.save(); canvas.save();
canvas.translate(textX, textY); canvas.translate(textX, textY);
if (textSelectionHelper.isInSelectionMode()) {
textSelectionHelper.draw(canvas);
}
drawLayout(fullLayout, canvas); drawLayout(fullLayout, canvas);
fullLayoutEmoji = AnimatedEmojiSpan.update(AnimatedEmojiDrawable.CACHE_TYPE_MESSAGES, this, fullLayoutEmoji, fullLayout); fullLayoutEmoji = AnimatedEmojiSpan.update(AnimatedEmojiDrawable.CACHE_TYPE_MESSAGES, this, fullLayoutEmoji, fullLayout);
AnimatedEmojiSpan.drawAnimatedEmojis(canvas, fullLayout, fullLayoutEmoji, 0, spoilers, 0, 0, 0, 1f, emojiColorFilter); AnimatedEmojiSpan.drawAnimatedEmojis(canvas, fullLayout, fullLayoutEmoji, 0, spoilers, 0, 0, 0, 1f, emojiColorFilter);
canvas.restore(); canvas.restore();
} }
} else { } else {
if (textSelectionHelper.isInSelectionMode()) {
canvas.save();
canvas.translate(textX, textY);
textSelectionHelper.draw(canvas);
canvas.restore();
}
if (firstLayout != null) { if (firstLayout != null) {
canvas.save(); canvas.save();
canvas.translate(textX, textY); canvas.translate(textX, textY);
@ -793,6 +821,16 @@ public class StoryCaptionView extends NestedScrollView {
return textPaint; return textPaint;
} }
@Override
public CharSequence getText() {
return text;
}
@Override
public StaticLayout getStaticTextLayout() {
return fullLayout;
}
public class LineInfo { public class LineInfo {
private AnimatedEmojiSpan.EmojiGroupedSpans layoutEmoji; private AnimatedEmojiSpan.EmojiGroupedSpans layoutEmoji;
StaticLayout staticLayout; StaticLayout staticLayout;
@ -926,6 +964,8 @@ public class StoryCaptionView extends NestedScrollView {
@Override @Override
public boolean dispatchTouchEvent(MotionEvent event) { public boolean dispatchTouchEvent(MotionEvent event) {
boolean allowIntercept = true; boolean allowIntercept = true;
lastMotionX = event.getX();
lastMotionY = event.getY();
if (showMore != null) { if (showMore != null) {
AndroidUtilities.rectTmp.set(showMoreX , showMoreY, showMoreX + showMore.getWidth(), showMoreY + showMore.getHeight()); AndroidUtilities.rectTmp.set(showMoreX , showMoreY, showMoreX + showMore.getWidth(), showMoreY + showMore.getHeight());
if (AndroidUtilities.rectTmp.contains(event.getX(), event.getY())) { if (AndroidUtilities.rectTmp.contains(event.getX(), event.getY())) {
@ -933,6 +973,10 @@ public class StoryCaptionView extends NestedScrollView {
} }
} }
if (allowIntercept && allowClickSpoilers && clickDetector.onTouchEvent(event)) return true; if (allowIntercept && allowClickSpoilers && clickDetector.onTouchEvent(event)) return true;
// if (allowIntercept && (expanded || firstLayout == null)) {
// textSelectionHelper.update(textX, textY);
// textSelectionHelper.onTouchEvent(event);
// }
return super.dispatchTouchEvent(event); return super.dispatchTouchEvent(event);
} }
} }

View file

@ -22,7 +22,6 @@ import android.graphics.SurfaceTexture;
import android.media.AudioManager; import android.media.AudioManager;
import android.net.Uri; import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.util.Log;
import android.util.SparseArray; import android.util.SparseArray;
import android.view.GestureDetector; import android.view.GestureDetector;
import android.view.Gravity; import android.view.Gravity;
@ -38,6 +37,7 @@ import android.view.WindowManager;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.graphics.ColorUtils; import androidx.core.graphics.ColorUtils;
import androidx.core.math.MathUtils; import androidx.core.math.MathUtils;
import androidx.viewpager.widget.ViewPager; import androidx.viewpager.widget.ViewPager;
@ -74,7 +74,6 @@ import org.telegram.ui.LaunchActivity;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Objects; import java.util.Objects;
import java.util.TreeSet;
public class StoryViewer { public class StoryViewer {
@ -203,6 +202,7 @@ public class StoryViewer {
private boolean flingCalled; private boolean flingCalled;
private boolean invalidateOutRect; private boolean invalidateOutRect;
private boolean isHintVisible; private boolean isHintVisible;
private boolean isInTextSelectionMode;
private boolean isOverlayVisible; private boolean isOverlayVisible;
Bitmap playerStubBitmap; Bitmap playerStubBitmap;
public Paint playerStubPaint; public Paint playerStubPaint;
@ -374,7 +374,7 @@ public class StoryViewer {
return false; return false;
} }
if (allowIntercept && peerView != null) { if (allowIntercept && peerView != null) {
if (keyboardVisible || isCaption || isCaptionPartVisible || isHintVisible) { if (keyboardVisible || isCaption || isCaptionPartVisible || isHintVisible || isInTextSelectionMode) {
closeKeyboardOrEmoji(); closeKeyboardOrEmoji();
} else { } else {
boolean forward = e.getX() > containerView.getMeasuredWidth() * 0.33f; boolean forward = e.getX() > containerView.getMeasuredWidth() * 0.33f;
@ -758,6 +758,10 @@ public class StoryViewer {
@Override @Override
public boolean dispatchTouchEvent(MotionEvent ev) { public boolean dispatchTouchEvent(MotionEvent ev) {
boolean swipeToReplyCancelled = false; boolean swipeToReplyCancelled = false;
PeerStoriesView peerStoriesView = storiesViewPager.getCurrentPeerView();
if (peerStoriesView != null && peerStoriesView.checkTextSelectionEvent(ev)) {
return true;
}
if (ev.getAction() == MotionEvent.ACTION_UP || ev.getAction() == MotionEvent.ACTION_CANCEL) { if (ev.getAction() == MotionEvent.ACTION_UP || ev.getAction() == MotionEvent.ACTION_CANCEL) {
inSwipeToDissmissMode = false; inSwipeToDissmissMode = false;
AndroidUtilities.cancelRunOnUIThread(longPressRunnable); AndroidUtilities.cancelRunOnUIThread(longPressRunnable);
@ -787,7 +791,6 @@ public class StoryViewer {
} }
if (ev.getAction() == MotionEvent.ACTION_DOWN) { if (ev.getAction() == MotionEvent.ACTION_DOWN) {
swipeToReplyWaitingKeyboard = false; swipeToReplyWaitingKeyboard = false;
PeerStoriesView peerStoriesView = storiesViewPager.getCurrentPeerView();
if (peerStoriesView != null) { if (peerStoriesView != null) {
peerStoriesView.onActionDown(ev); peerStoriesView.onActionDown(ev);
} }
@ -812,14 +815,11 @@ public class StoryViewer {
override = true; override = true;
} }
} }
if (selfStoriesViewsOffset == 0 && !inSwipeToDissmissMode && !isCaption && storiesViewPager.currentState != ViewPager.SCROLL_STATE_DRAGGING) { if (peerStoriesView != null && selfStoriesViewsOffset == 0 && !inSwipeToDissmissMode && !isCaption && storiesViewPager.currentState != ViewPager.SCROLL_STATE_DRAGGING) {
PeerStoriesView peerStoriesView = storiesViewPager.getCurrentPeerView(); AndroidUtilities.getViewPositionInParent(peerStoriesView.storyContainer, this, pointPosition);
if (peerStoriesView != null) { ev.offsetLocation(-pointPosition[0], -pointPosition[1]);
AndroidUtilities.getViewPositionInParent(peerStoriesView.storyContainer, this, pointPosition); storiesViewPager.getCurrentPeerView().checkPinchToZoom(ev);
ev.offsetLocation(-pointPosition[0], -pointPosition[1]); ev.offsetLocation(pointPosition[0], pointPosition[1]);
storiesViewPager.getCurrentPeerView().checkPinchToZoom(ev);
ev.offsetLocation(pointPosition[0], pointPosition[1]);
}
} }
if (ev.getAction() == MotionEvent.ACTION_UP || ev.getAction() == MotionEvent.ACTION_CANCEL) { if (ev.getAction() == MotionEvent.ACTION_UP || ev.getAction() == MotionEvent.ACTION_CANCEL) {
lastX.clear(); lastX.clear();
@ -859,7 +859,7 @@ public class StoryViewer {
delayedTapRunnable = () -> setInTouchMode(true); delayedTapRunnable = () -> setInTouchMode(true);
AndroidUtilities.runOnUIThread(delayedTapRunnable, 150); AndroidUtilities.runOnUIThread(delayedTapRunnable, 150);
} }
if (allowIntercept && !keyboardVisible) { if (allowIntercept && !keyboardVisible && !isInTextSelectionMode) {
AndroidUtilities.runOnUIThread(longPressRunnable, 400); AndroidUtilities.runOnUIThread(longPressRunnable, 400);
} }
} else if (ev.getAction() == MotionEvent.ACTION_MOVE) { } else if (ev.getAction() == MotionEvent.ACTION_MOVE) {
@ -869,6 +869,9 @@ public class StoryViewer {
if (dy > dx && dy > AndroidUtilities.touchSlop * 2) { if (dy > dx && dy > AndroidUtilities.touchSlop * 2) {
inSwipeToDissmissMode = true; inSwipeToDissmissMode = true;
PeerStoriesView peerView = storiesViewPager.getCurrentPeerView(); PeerStoriesView peerView = storiesViewPager.getCurrentPeerView();
if (peerView != null) {
peerView.cancelTextSelection();
}
allowSwipeToReply = !peerView.isSelf; allowSwipeToReply = !peerView.isSelf;
allowSelfStoriesView = peerView.isSelf && !peerView.unsupported && peerView.currentStory.storyItem != null; allowSelfStoriesView = peerView.isSelf && !peerView.unsupported && peerView.currentStory.storyItem != null;
if (allowSelfStoriesView) { if (allowSelfStoriesView) {
@ -1313,6 +1316,12 @@ public class StoryViewer {
updatePlayingMode(); updatePlayingMode();
} }
@Override
public void setIsInSelectionMode(boolean selectionMode) {
StoryViewer.this.isInTextSelectionMode = selectionMode;
updatePlayingMode();
}
@Override @Override
public int getKeyboardHeight() { public int getKeyboardHeight() {
return realKeyboardHeight; return realKeyboardHeight;
@ -1452,10 +1461,11 @@ public class StoryViewer {
} }
private void showKeyboard() { private void showKeyboard() {
storiesViewPager.getCurrentPeerView().showKeyboard(); PeerStoriesView currentPeerView = storiesViewPager.getCurrentPeerView();
AndroidUtilities.runOnUIThread(() -> { if (currentPeerView != null) {
cancelSwipeToReply(); currentPeerView.showKeyboard();
}, 200); }
AndroidUtilities.runOnUIThread(this::cancelSwipeToReply, 200);
} }
ValueAnimator swipeToViewsAnimator; ValueAnimator swipeToViewsAnimator;
@ -1469,7 +1479,10 @@ public class StoryViewer {
swipeToViewsAnimator = ValueAnimator.ofFloat(selfStoriesViewsOffset, open ? selfStoryViewsView.maxSelfStoriesViewsOffset : 0); swipeToViewsAnimator = ValueAnimator.ofFloat(selfStoriesViewsOffset, open ? selfStoryViewsView.maxSelfStoriesViewsOffset : 0);
swipeToViewsAnimator.addUpdateListener(animation -> { swipeToViewsAnimator.addUpdateListener(animation -> {
selfStoriesViewsOffset = (float) animation.getAnimatedValue(); selfStoriesViewsOffset = (float) animation.getAnimatedValue();
storiesViewPager.getCurrentPeerView().invalidate(); final PeerStoriesView peerStoriesView = storiesViewPager.getCurrentPeerView();
if (peerStoriesView != null) {
peerStoriesView.invalidate();
}
containerView.invalidate(); containerView.invalidate();
}); });
swipeToViewsAnimator.addListener(new AnimatorListenerAdapter() { swipeToViewsAnimator.addListener(new AnimatorListenerAdapter() {
@ -1477,7 +1490,10 @@ public class StoryViewer {
public void onAnimationEnd(Animator animation) { public void onAnimationEnd(Animator animation) {
locker.unlock(); locker.unlock();
selfStoriesViewsOffset = open ? selfStoryViewsView.maxSelfStoriesViewsOffset : 0; selfStoriesViewsOffset = open ? selfStoryViewsView.maxSelfStoriesViewsOffset : 0;
storiesViewPager.getCurrentPeerView().invalidate(); final PeerStoriesView peerStoriesView = storiesViewPager.getCurrentPeerView();
if (peerStoriesView != null) {
peerStoriesView.invalidate();
}
containerView.invalidate(); containerView.invalidate();
swipeToViewsAnimator = null; swipeToViewsAnimator = null;
} }
@ -1499,7 +1515,9 @@ public class StoryViewer {
containerView.addView(selfStoryViewsView, 0); containerView.addView(selfStoryViewsView, 0);
} }
PeerStoriesView peerStoriesView = storiesViewPager.getCurrentPeerView(); PeerStoriesView peerStoriesView = storiesViewPager.getCurrentPeerView();
selfStoryViewsView.setItems(peerStoriesView.getStoryItems(), peerStoriesView.getSelectedPosition()); if (peerStoriesView != null) {
selfStoryViewsView.setItems(peerStoriesView.getStoryItems(), peerStoriesView.getSelectedPosition());
}
} }
public void showDialog(Dialog dialog) { public void showDialog(Dialog dialog) {
@ -1528,7 +1546,10 @@ public class StoryViewer {
swipeToReplyOffset = (float) animation.getAnimatedValue(); swipeToReplyOffset = (float) animation.getAnimatedValue();
int maxOffset = AndroidUtilities.dp(200); int maxOffset = AndroidUtilities.dp(200);
swipeToReplyProgress = Utilities.clamp(swipeToReplyOffset / maxOffset, 1f, 0); swipeToReplyProgress = Utilities.clamp(swipeToReplyOffset / maxOffset, 1f, 0);
storiesViewPager.getCurrentPeerView().invalidate(); PeerStoriesView peerView = storiesViewPager == null ? null : storiesViewPager.getCurrentPeerView();
if (peerView != null) {
peerView.invalidate();
}
}); });
swipeToReplyBackAnimator.addListener(new AnimatorListenerAdapter() { swipeToReplyBackAnimator.addListener(new AnimatorListenerAdapter() {
@Override @Override
@ -1536,7 +1557,10 @@ public class StoryViewer {
swipeToReplyBackAnimator = null; swipeToReplyBackAnimator = null;
swipeToReplyOffset = 0; swipeToReplyOffset = 0;
swipeToReplyProgress = 0; swipeToReplyProgress = 0;
storiesViewPager.getCurrentPeerView().invalidate(); PeerStoriesView peerView = storiesViewPager == null ? null : storiesViewPager.getCurrentPeerView();
if (peerView != null) {
peerView.invalidate();
}
} }
}); });
swipeToReplyBackAnimator.setDuration(AdjustPanLayoutHelper.keyboardDuration); swipeToReplyBackAnimator.setDuration(AdjustPanLayoutHelper.keyboardDuration);
@ -1564,6 +1588,7 @@ public class StoryViewer {
return true; return true;
} }
@Nullable
public PeerStoriesView getCurrentPeerView() { public PeerStoriesView getCurrentPeerView() {
if (storiesViewPager == null) { if (storiesViewPager == null) {
return null; return null;
@ -1604,8 +1629,10 @@ public class StoryViewer {
for (int i = 0; i < preparedPlayers.size(); i++) { for (int i = 0; i < preparedPlayers.size(); i++) {
preparedPlayers.get(i).setAudioEnabled(!isInSilentMode, true); preparedPlayers.get(i).setAudioEnabled(!isInSilentMode, true);
} }
PeerStoriesView peerStoriesView = storiesViewPager.getCurrentPeerView(); final PeerStoriesView peerStoriesView = storiesViewPager.getCurrentPeerView();
peerStoriesView.sharedResources.setIconMuted(!soundEnabled(), true); if (peerStoriesView != null) {
peerStoriesView.sharedResources.setIconMuted(!soundEnabled(), true);
}
} }
private void checkInSilentMode() { private void checkInSilentMode() {
@ -1626,7 +1653,7 @@ public class StoryViewer {
transitionViewHolder.storyImage.setVisible(true, true); transitionViewHolder.storyImage.setVisible(true, true);
} }
if (storiesList != null) { if (storiesList != null) {
PeerStoriesView peerView = storiesViewPager.getCurrentPeerView(); final PeerStoriesView peerView = storiesViewPager.getCurrentPeerView();
if (peerView != null) { if (peerView != null) {
int position = peerView.getSelectedPosition(); int position = peerView.getSelectedPosition();
if (position >= 0 && position < storiesList.messageObjects.size()) { if (position >= 0 && position < storiesList.messageObjects.size()) {
@ -1656,7 +1683,7 @@ public class StoryViewer {
transitionViewHolder.storyImage.setAlpha(1f); transitionViewHolder.storyImage.setAlpha(1f);
transitionViewHolder.storyImage.setVisible(true, true); transitionViewHolder.storyImage.setVisible(true, true);
} }
PeerStoriesView peerView = storiesViewPager.getCurrentPeerView(); final PeerStoriesView peerView = storiesViewPager.getCurrentPeerView();
int position = peerView == null ? 0 : peerView.getSelectedPosition(); int position = peerView == null ? 0 : peerView.getSelectedPosition();
int storyId = peerView == null || position < 0 || position >= peerView.storyItems.size() ? 0 : peerView.storyItems.get(position).id; int storyId = peerView == null || position < 0 || position >= peerView.storyItems.size() ? 0 : peerView.storyItems.get(position).id;
TLRPC.StoryItem storyItem = peerView == null || position < 0 || position >= peerView.storyItems.size() ? null : peerView.storyItems.get(position); TLRPC.StoryItem storyItem = peerView == null || position < 0 || position >= peerView.storyItems.size() ? null : peerView.storyItems.get(position);
@ -1759,7 +1786,7 @@ public class StoryViewer {
} }
public boolean isPaused() { public boolean isPaused() {
return isPopupVisible || isBulletinVisible || isCaption || isWaiting || isInTouchMode || keyboardVisible || currentDialog != null || allowTouchesByViewpager || isClosed || isRecording || progressToOpen != 1f || selfStoriesViewsOffset != 0 || isHintVisible || (isSwiping && USE_SURFACE_VIEW) || isOverlayVisible; return isPopupVisible || isBulletinVisible || isCaption || isWaiting || isInTouchMode || keyboardVisible || currentDialog != null || allowTouchesByViewpager || isClosed || isRecording || progressToOpen != 1f || selfStoriesViewsOffset != 0 || isHintVisible || (isSwiping && USE_SURFACE_VIEW) || isOverlayVisible || isInTextSelectionMode;
} }
public void updatePlayingMode() { public void updatePlayingMode() {
@ -1792,7 +1819,7 @@ public class StoryViewer {
if (selfStoryViewsView != null && selfStoriesViewsOffset != 0) { if (selfStoryViewsView != null && selfStoriesViewsOffset != 0) {
return true; return true;
} }
PeerStoriesView currentPeerView = storiesViewPager.getCurrentPeerView(); final PeerStoriesView currentPeerView = storiesViewPager.getCurrentPeerView();
if (currentPeerView != null) { if (currentPeerView != null) {
//fix view pager strange coordinates //fix view pager strange coordinates
//just skip page.getX() //just skip page.getX()
@ -1818,7 +1845,7 @@ public class StoryViewer {
} }
public boolean closeKeyboardOrEmoji() { public boolean closeKeyboardOrEmoji() {
PeerStoriesView peerStoriesView = storiesViewPager.getCurrentPeerView(); final PeerStoriesView peerStoriesView = storiesViewPager.getCurrentPeerView();
if (peerStoriesView != null) { if (peerStoriesView != null) {
return peerStoriesView.closeKeyboardOrEmoji(); return peerStoriesView.closeKeyboardOrEmoji();
} }
@ -1835,7 +1862,7 @@ public class StoryViewer {
if (progressToDismiss != newProgress) { if (progressToDismiss != newProgress) {
progressToDismiss = newProgress; progressToDismiss = newProgress;
checkNavBarColor(); checkNavBarColor();
PeerStoriesView peerStoriesView = storiesViewPager.getCurrentPeerView(); final PeerStoriesView peerStoriesView = storiesViewPager.getCurrentPeerView();
if (peerStoriesView != null) { if (peerStoriesView != null) {
peerStoriesView.progressToDismissUpdated(); peerStoriesView.progressToDismissUpdated();
} }
@ -1854,7 +1881,7 @@ public class StoryViewer {
animationInProgress = true; animationInProgress = true;
fromDismissOffset = swipeToDismissOffset; fromDismissOffset = swipeToDismissOffset;
if (transitionViewHolder.radialProgressUpload != null) { if (transitionViewHolder.radialProgressUpload != null) {
PeerStoriesView peerStoriesView = getCurrentPeerView(); final PeerStoriesView peerStoriesView = getCurrentPeerView();
if (peerStoriesView != null && peerStoriesView.headerView.radialProgress != null) { if (peerStoriesView != null && peerStoriesView.headerView.radialProgress != null) {
peerStoriesView.headerView.radialProgress.copyParams(transitionViewHolder.radialProgressUpload); peerStoriesView.headerView.radialProgress.copyParams(transitionViewHolder.radialProgressUpload);
} }
@ -1888,7 +1915,7 @@ public class StoryViewer {
transitionViewHolder.storyImage.setAlpha(1f); transitionViewHolder.storyImage.setAlpha(1f);
transitionViewHolder.storyImage.setVisible(true, true); transitionViewHolder.storyImage.setVisible(true, true);
} }
PeerStoriesView peerStoriesView = getCurrentPeerView(); final PeerStoriesView peerStoriesView = getCurrentPeerView();
if (peerStoriesView != null) { if (peerStoriesView != null) {
peerStoriesView.updatePosition(); peerStoriesView.updatePosition();
} }
@ -1989,7 +2016,7 @@ public class StoryViewer {
transitionViewHolder.storyImage.setVisible(true, true); transitionViewHolder.storyImage.setVisible(true, true);
} }
if (transitionViewHolder.radialProgressUpload != null) { if (transitionViewHolder.radialProgressUpload != null) {
PeerStoriesView peerStoriesView = getCurrentPeerView(); final PeerStoriesView peerStoriesView = getCurrentPeerView();
if (peerStoriesView != null && peerStoriesView.headerView.radialProgress != null) { if (peerStoriesView != null && peerStoriesView.headerView.radialProgress != null) {
transitionViewHolder.radialProgressUpload.copyParams(peerStoriesView.headerView.radialProgress); transitionViewHolder.radialProgressUpload.copyParams(peerStoriesView.headerView.radialProgress);
} }
@ -2146,8 +2173,13 @@ public class StoryViewer {
return containerView; return containerView;
} }
@Nullable
public FrameLayout getContainerForBulletin() { public FrameLayout getContainerForBulletin() {
return storiesViewPager.getCurrentPeerView().storyContainer; final PeerStoriesView peerStoriesView = storiesViewPager.getCurrentPeerView();
if (peerStoriesView != null) {
return peerStoriesView.storyContainer;
}
return null;
} }
public void startActivityForResult(Intent photoPickerIntent, int code) { public void startActivityForResult(Intent photoPickerIntent, int code) {
@ -2159,7 +2191,9 @@ public class StoryViewer {
public void onActivityResult(int requestCode, int resultCode, Intent data) { public void onActivityResult(int requestCode, int resultCode, Intent data) {
PeerStoriesView currentPeerView = storiesViewPager.getCurrentPeerView(); PeerStoriesView currentPeerView = storiesViewPager.getCurrentPeerView();
currentPeerView.onActivityResult(requestCode, resultCode, data); if (currentPeerView != null) {
currentPeerView.onActivityResult(requestCode, resultCode, data);
}
} }
public void dispatchKeyEvent(KeyEvent event) { public void dispatchKeyEvent(KeyEvent event) {
@ -2193,7 +2227,10 @@ public class StoryViewer {
public void setSelfStoriesViewsOffset(float currentTranslation) { public void setSelfStoriesViewsOffset(float currentTranslation) {
selfStoriesViewsOffset = currentTranslation; selfStoriesViewsOffset = currentTranslation;
storiesViewPager.getCurrentPeerView().invalidate(); final PeerStoriesView peerStoriesView = storiesViewPager.getCurrentPeerView();
if (peerStoriesView != null) {
peerStoriesView.invalidate();
}
containerView.invalidate(); containerView.invalidate();
} }
@ -2415,7 +2452,7 @@ public class StoryViewer {
if (firstFrameRendered && playbackState == ExoPlayer.STATE_BUFFERING) { if (firstFrameRendered && playbackState == ExoPlayer.STATE_BUFFERING) {
logBuffering = true; logBuffering = true;
AndroidUtilities.runOnUIThread(() -> { AndroidUtilities.runOnUIThread(() -> {
PeerStoriesView storiesView = getCurrentPeerView(); final PeerStoriesView storiesView = getCurrentPeerView();
if (storiesView != null && storiesView.currentStory.storyItem != null) { if (storiesView != null && storiesView.currentStory.storyItem != null) {
FileLog.d("StoryViewer displayed story buffering dialogId=" + storiesView.getCurrentPeer() + " storyId=" + storiesView.currentStory.storyItem.id); FileLog.d("StoryViewer displayed story buffering dialogId=" + storiesView.getCurrentPeer() + " storyId=" + storiesView.currentStory.storyItem.id);
} }
@ -2424,7 +2461,7 @@ public class StoryViewer {
if (logBuffering && playbackState == ExoPlayer.STATE_READY) { if (logBuffering && playbackState == ExoPlayer.STATE_READY) {
logBuffering = false; logBuffering = false;
AndroidUtilities.runOnUIThread(() -> { AndroidUtilities.runOnUIThread(() -> {
PeerStoriesView storiesView = getCurrentPeerView(); final PeerStoriesView storiesView = getCurrentPeerView();
if (storiesView != null && storiesView.currentStory.storyItem != null) { if (storiesView != null && storiesView.currentStory.storyItem != null) {
FileLog.d("StoryViewer displayed story playing dialogId=" + storiesView.getCurrentPeer() + " storyId=" + storiesView.currentStory.storyItem.id); FileLog.d("StoryViewer displayed story playing dialogId=" + storiesView.getCurrentPeer() + " storyId=" + storiesView.currentStory.storyItem.id);
} }
@ -2516,6 +2553,10 @@ public class StoryViewer {
} }
videoPlayer = null; videoPlayer = null;
}); });
if (playerStubBitmap != null) {
AndroidUtilities.recycleBitmap(playerStubBitmap);
playerStubBitmap = null;
}
return true; return true;
} }

View file

@ -137,16 +137,16 @@ public class DownloadButton extends ImageView {
toast.hide(); toast.hide();
toast = null; toast = null;
} }
if (buildingVideo != null) {
buildingVideo.stop(true);
buildingVideo = null;
}
if (prepare != null) { if (prepare != null) {
preparing = true; preparing = true;
prepare.run(this::onClickInternal); prepare.run(this::onClickInternal);
} }
if (currentEntry.wouldBeVideo()) { if (currentEntry.wouldBeVideo()) {
downloadingVideo = true; downloadingVideo = true;
if (buildingVideo != null) {
buildingVideo.stop(true);
buildingVideo = null;
}
toast = new PreparingVideoToast(getContext()); toast = new PreparingVideoToast(getContext());
toast.setOnCancelListener(() -> { toast.setOnCancelListener(() -> {
preparing = false; preparing = false;

View file

@ -315,6 +315,17 @@ public class StoryEntry extends IStoryPart {
return file; return file;
} }
private String ext(File file) {
if (file == null) {
return null;
}
String s = file.getPath();
int i;
if ((i = s.lastIndexOf('.')) > 0)
return s.substring(i + 1);
return null;
}
public void updateFilter(PhotoFilterView filterView, Runnable whenDone) { public void updateFilter(PhotoFilterView filterView, Runnable whenDone) {
clearFilter(); clearFilter();
@ -329,6 +340,9 @@ public class StoryEntry extends IStoryPart {
Bitmap bitmap = filterView.getBitmap(); Bitmap bitmap = filterView.getBitmap();
if (bitmap == null) { if (bitmap == null) {
if (whenDone != null) {
whenDone.run();
}
return; return;
} }
@ -345,11 +359,13 @@ public class StoryEntry extends IStoryPart {
if (filterFile != null && filterFile.exists()) { if (filterFile != null && filterFile.exists()) {
filterFile.delete(); filterFile.delete();
} }
filterFile = makeCacheFile(currentAccount, "webp"); String ext = ext(file);
final boolean supportTransparent = "png".equals(ext) || "webp".equals(ext);
filterFile = makeCacheFile(currentAccount, supportTransparent ? "webp" : "jpg");
if (whenDone == null) { if (whenDone == null) {
try { try {
FileOutputStream stream = new FileOutputStream(filterFile); FileOutputStream stream = new FileOutputStream(filterFile);
rotatedBitmap.compress(Bitmap.CompressFormat.WEBP, 90, stream); rotatedBitmap.compress(supportTransparent ? Bitmap.CompressFormat.WEBP : Bitmap.CompressFormat.JPEG, 90, stream);
} catch (Exception e) { } catch (Exception e) {
FileLog.e(e); FileLog.e(e);
} }
@ -358,14 +374,16 @@ public class StoryEntry extends IStoryPart {
Utilities.themeQueue.postRunnable(() -> { Utilities.themeQueue.postRunnable(() -> {
try { try {
FileOutputStream stream = new FileOutputStream(filterFile); FileOutputStream stream = new FileOutputStream(filterFile);
rotatedBitmap.compress(Bitmap.CompressFormat.WEBP, 90, stream); rotatedBitmap.compress(supportTransparent ? Bitmap.CompressFormat.WEBP : Bitmap.CompressFormat.JPEG, 90, stream);
} catch (Exception e) { } catch (Exception e) {
FileLog.e(e, false); FileLog.e(e, false);
try { if (supportTransparent) {
FileOutputStream stream = new FileOutputStream(filterFile); try {
rotatedBitmap.compress(Bitmap.CompressFormat.PNG, 90, stream); FileOutputStream stream = new FileOutputStream(filterFile);
} catch (Exception e2) { rotatedBitmap.compress(Bitmap.CompressFormat.PNG, 90, stream);
FileLog.e(e2, false); } catch (Exception e2) {
FileLog.e(e2, false);
}
} }
} }
rotatedBitmap.recycle(); rotatedBitmap.recycle();

View file

@ -244,7 +244,7 @@ public class StoryRecorder implements NotificationCenter.NotificationCenterDeleg
SourceView src = new SourceView() { SourceView src = new SourceView() {
@Override @Override
protected void show() { protected void show() {
PeerStoriesView peerView = storyViewer.getCurrentPeerView(); final PeerStoriesView peerView = storyViewer.getCurrentPeerView();
if (peerView != null) { if (peerView != null) {
peerView.animateOut(false); peerView.animateOut(false);
} }
@ -256,7 +256,7 @@ public class StoryRecorder implements NotificationCenter.NotificationCenterDeleg
@Override @Override
protected void hide() { protected void hide() {
PeerStoriesView peerView = storyViewer.getCurrentPeerView(); final PeerStoriesView peerView = storyViewer.getCurrentPeerView();
if (peerView != null) { if (peerView != null) {
peerView.animateOut(true); peerView.animateOut(true);
} }
@ -267,7 +267,7 @@ public class StoryRecorder implements NotificationCenter.NotificationCenterDeleg
} }
src.type = 1; src.type = 1;
src.rounding = dp(8); src.rounding = dp(8);
PeerStoriesView peerView = storyViewer.getCurrentPeerView(); final PeerStoriesView peerView = storyViewer.getCurrentPeerView();
if (peerView != null) { if (peerView != null) {
src.view = peerView.storyContainer; src.view = peerView.storyContainer;
} }
@ -3434,7 +3434,7 @@ public class StoryRecorder implements NotificationCenter.NotificationCenterDeleg
captionEdit.keyboardNotifier.ignore(toMode != EDIT_MODE_NONE); captionEdit.keyboardNotifier.ignore(toMode != EDIT_MODE_NONE);
// privacySelectorHint.hide(); // privacySelectorHint.hide();
Bulletin.hideVisible(); Bulletin.hideVisible();
if (photoFilterView != null && toMode == EDIT_MODE_FILTER) { if (photoFilterView != null && fromMode == EDIT_MODE_FILTER) {
applyFilter(null); applyFilter(null);
} }
if (photoFilterEnhanceView != null) { if (photoFilterEnhanceView != null) {
@ -3518,8 +3518,19 @@ public class StoryRecorder implements NotificationCenter.NotificationCenterDeleg
return; return;
} }
Bitmap photoBitmap = previewView.getPhotoBitmap(); Bitmap photoBitmap = null;
if (photoBitmap == null) { if (!outputEntry.isVideo) {
if (outputEntry.filterFile == null) {
photoBitmap = previewView.getPhotoBitmap();
} else {
if (photoFilterBitmap != null) {
photoFilterBitmap.recycle();
photoFilterBitmap = null;
}
photoBitmap = photoFilterBitmap = StoryEntry.getScaledBitmap(opts -> BitmapFactory.decodeFile(outputEntry.file.getAbsolutePath(), opts), AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y, true);
}
}
if (photoBitmap == null && !outputEntry.isVideo) {
return; return;
} }

View file

@ -4860,7 +4860,7 @@ public class ThemePreviewActivity extends BaseFragment implements DownloadContro
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) { public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View view; View view;
if (viewType == 0) { if (viewType == 0) {
view = new ChatMessageCell(mContext, false, new Theme.ResourcesProvider() { view = new ChatMessageCell(mContext, false, null, new Theme.ResourcesProvider() {
@Override @Override
public int getColor(int key) { public int getColor(int key) {
return getThemedColor(key); return getThemedColor(key);

View file

@ -13,8 +13,8 @@
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true # org.gradle.parallel=true
#Sat Mar 12 05:53:50 MSK 2016 #Sat Mar 12 05:53:50 MSK 2016
APP_VERSION_CODE=3712 APP_VERSION_CODE=3721
APP_VERSION_NAME=9.7.4 APP_VERSION_NAME=9.7.6
APP_PACKAGE=org.telegram.messenger APP_PACKAGE=org.telegram.messenger
RELEASE_KEY_PASSWORD=android RELEASE_KEY_PASSWORD=android
RELEASE_KEY_ALIAS=androidkey RELEASE_KEY_ALIAS=androidkey