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

View file

@ -97,19 +97,19 @@ public final class DefaultMediaCodecAdapterFactory implements MediaCodecAdapter.
@Override
public MediaCodecAdapter createAdapter(MediaCodecAdapter.Configuration configuration)
throws IOException {
// if (Util.SDK_INT >= 23
// && (asynchronousMode == MODE_ENABLED
// || (asynchronousMode == MODE_DEFAULT && Util.SDK_INT >= 31))) {
// int trackType = MimeTypes.getTrackType(configuration.format.sampleMimeType);
// Log.i(
// TAG,
// "Creating an asynchronous MediaCodec adapter for track type "
// + Util.getTrackTypeString(trackType));
// AsynchronousMediaCodecAdapter.Factory factory =
// new AsynchronousMediaCodecAdapter.Factory(
// trackType, enableSynchronizeCodecInteractionsWithQueueing);
// return factory.createAdapter(configuration);
// }
if (Util.SDK_INT >= 23
&& (asynchronousMode == MODE_ENABLED
|| (asynchronousMode == MODE_DEFAULT && Util.SDK_INT >= 31))) {
int trackType = MimeTypes.getTrackType(configuration.format.sampleMimeType);
Log.i(
TAG,
"Creating an asynchronous MediaCodec adapter for track type "
+ Util.getTrackTypeString(trackType));
AsynchronousMediaCodecAdapter.Factory factory =
new AsynchronousMediaCodecAdapter.Factory(
trackType, enableSynchronizeCodecInteractionsWithQueueing);
return 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.OutputStream;
import java.io.RandomAccessFile;
import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.IDN;
@ -247,9 +248,6 @@ public class AndroidUtilities {
private static int adjustOwnerClassGuid = 0;
private static int altFocusableClassGuid = 0;
private static Paint roundPaint;
private static RectF bitmapRect;
public static final RectF rectTmp = new RectF();
public static final Rect rectTmp2 = new Rect();
@ -513,9 +511,17 @@ public class AndroidUtilities {
return;
}
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(() -> {
for (int i = 0; i < bitmapToRecycle.size(); i++) {
Bitmap bitmap = bitmapToRecycle.get(i);
for (int i = 0; i < bitmapsToRecycleRef.size(); i++) {
Bitmap bitmap = bitmapsToRecycleRef.get(i).get();
bitmapsToRecycleRef.get(i).clear();
if (bitmap != null && !bitmap.isRecycled()) {
try {
bitmap.recycle();
@ -3202,10 +3208,10 @@ public class AndroidUtilities {
}
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) {
return String.format("%d KB", 0);
} else if (size < 1024) {
@ -3228,6 +3234,8 @@ public class AndroidUtilities {
float value = (int) (size / 1024L / 1024L) / 1000.0f;
if (removeZero && (value - (int) value) * 10 == 0) {
return String.format("%d GB", (int) value);
} else if (makeShort) {
return String.format("%.1f GB", value);
} else {
return String.format("%.2f GB", value);
}
@ -5370,10 +5378,12 @@ public class AndroidUtilities {
System.gc();
clone = ByteBuffer.allocate(original.capacity());
}
int position = original.position();
original.rewind();
clone.put(original);
original.rewind();
clone.flip();
clone.position(position);
return clone;
}
}

View file

@ -24,8 +24,8 @@ public class BuildVars {
public static boolean USE_CLOUD_STRINGS = true;
public static boolean CHECK_UPDATES = true;
public static boolean NO_SCOPED_STORAGE = Build.VERSION.SDK_INT <= 29;
public static int BUILD_VERSION = 3712;
public static String BUILD_VERSION_STRING = "9.7.4";
public static int BUILD_VERSION = 3721;
public static String BUILD_VERSION_STRING = "9.7.6";
public static int APP_ID = 4;
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 static int indexPointer = 0;
public final int index = indexPointer++;
private int priority = THREAD_PRIORITY_DEFAULT;
private int threadPriority = THREAD_PRIORITY_DEFAULT;
public DispatchQueue(final String threadName) {
this(threadName, true);
@ -39,7 +39,7 @@ public class DispatchQueue extends Thread {
}
public DispatchQueue(final String threadName, boolean start, int priority) {
this.priority = priority;
this.threadPriority = priority;
setName(threadName);
if (start) {
start();
@ -126,8 +126,8 @@ public class DispatchQueue extends Thread {
return true;
});
syncLatch.countDown();
if (priority != THREAD_PRIORITY_DEFAULT) {
Process.setThreadPriority(priority);
if (threadPriority != THREAD_PRIORITY_DEFAULT) {
Process.setThreadPriority(threadPriority);
}
Looper.loop();
}

View file

@ -708,7 +708,12 @@ public class FileLoadOperation {
final CountDownLatch countDownLatch = new CountDownLatch(1);
final long[] result = new long[2];
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) {
result[1] = 1;
}

View file

@ -165,6 +165,7 @@ public class FileLog {
privateFields.add("networkType");
privateFields.add("disableFree");
privateFields.add("mContext");
privateFields.add("priority");
//exclude file loading
excludeRequests = new HashSet<>();
@ -183,7 +184,7 @@ public class FileLog {
@Override
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();

View file

@ -71,6 +71,7 @@ public class FileStreamLoadOperation extends BaseDataSource implements FileLoadO
@Override
public long open(DataSpec dataSpec) throws IOException {
uri = dataSpec.uri;
transferInitializing(dataSpec);
currentAccount = Utilities.parseInt(uri.getQueryParameter("account"));
parentObject = FileLoader.getInstance(currentAccount).getParentObject(Utilities.parseInt(uri.getQueryParameter("rid")));
document = new TLRPC.TL_document();
@ -124,6 +125,7 @@ public class FileStreamLoadOperation extends BaseDataSource implements FileLoadO
return C.RESULT_END_OF_INPUT;
} else {
int availableLength = 0;
int bytesRead;
try {
if (bytesRemaining < readLength) {
readLength = (int) bytesRemaining;
@ -165,14 +167,16 @@ public class FileStreamLoadOperation extends BaseDataSource implements FileLoadO
if (!opened) {
return 0;
}
file.readFully(buffer, offset, availableLength);
currentOffset += availableLength;
bytesRemaining -= availableLength;
bytesTransferred(availableLength);
bytesRead = file.read(buffer, offset, availableLength);
if (bytesRead > 0) {
currentOffset += bytesRead;
bytesRemaining -= bytesRead;
bytesTransferred(bytesRead);
}
} catch (Exception 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.Point;
import org.telegram.ui.Components.RLottieDrawable;
import org.telegram.ui.Components.Reactions.HwEmojis;
import org.telegram.ui.Components.SlotsDrawable;
import org.telegram.ui.Components.ThemePreviewDrawable;
@ -103,6 +102,8 @@ import java.util.zip.GZIPInputStream;
*/
public class ImageLoader {
private static final boolean DEBUG_MODE = false;
private HashMap<String, Integer> bitmapUseCounts = new HashMap<>();
private LruCache<BitmapDrawable> smallImagesMemCache;
private LruCache<BitmapDrawable> memCache;
@ -1822,7 +1823,9 @@ public class ImageLoader {
data[164] = photoBytes[1];
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")) {
Utilities.blurBitmap(bitmap, 3, 1, bitmap.getWidth(), bitmap.getHeight(), bitmap.getRowBytes());
}
@ -2060,15 +2063,15 @@ public class ImageLoader {
} else {
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 smallImagesCacheSize = (int) (cacheSize * 0.2f);
int commonCacheSize = DEBUG_MODE ? 1 : (int) (cacheSize * 0.8f);
int smallImagesCacheSize = DEBUG_MODE ? 1 : (int) (cacheSize * 0.2f);
memCache = new LruCache<BitmapDrawable>(commonCacheSize) {
@Override
protected int sizeOf(String key, BitmapDrawable value) {
return value.getBitmap().getByteCount();
return sizeOfBitmapDrawable(value);
}
@Override
@ -2090,7 +2093,7 @@ public class ImageLoader {
smallImagesMemCache = new LruCache<BitmapDrawable>(smallImagesCacheSize) {
@Override
protected int sizeOf(String key, BitmapDrawable value) {
return value.getBitmap().getByteCount();
return sizeOfBitmapDrawable(value);
}
@Override
@ -2109,18 +2112,18 @@ public class ImageLoader {
}
}
};
wallpaperMemCache = new LruCache<BitmapDrawable>(cacheSize / 4) {
wallpaperMemCache = new LruCache<BitmapDrawable>(DEBUG_MODE ? 1 : cacheSize / 4) {
@Override
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
protected int sizeOf(String key, BitmapDrawable value) {
return value.getIntrinsicWidth() * value.getIntrinsicHeight() * 4 * 2;
return sizeOfBitmapDrawable(value);
}
@Override
@ -2327,6 +2330,18 @@ public class ImageLoader {
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() {
checkMediaPaths(null);
}

View file

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

View file

@ -2090,9 +2090,9 @@ public class MediaDataController extends BaseController {
}
public static long calcHash(long hash, long id) {
hash ^= id >> 21;
hash ^= id << 35;
hash ^= id >> 4;
hash ^= hash >> 21;
hash ^= hash << 35;
hash ^= hash >> 4;
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() {
if (photoThumbs == null || !canCreateStripedThubms() && !hasExtendedMediaPreview()) {
if (photoThumbs == null || !canCreateStripedThubms() && !hasExtendedMediaPreview() || strippedThumb != null) {
return;
}
try {
@ -4835,7 +4835,15 @@ public class MessageObject {
}
String text = messageOwner.message;
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;
}
if (captionTranslated = translated) {
@ -4844,7 +4852,7 @@ public class MessageObject {
}
if (!isMediaEmpty() && !(getMedia(messageOwner) instanceof TLRPC.TL_messageMediaGame) && !TextUtils.isEmpty(text)) {
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;
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) {
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) {
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))) {
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 {
if (threadMessageId != 0) {
if (loadDialog && isTopic && load_type == 2 && last_message_id == 0) {
TLRPC.TL_forumTopic topic = topicsController.findTopic(-dialogId, threadMessageId);
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;
}
}
@ -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 {
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);
@ -8091,7 +8094,7 @@ public class MessagesController extends BaseController implements NotificationCe
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 {
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 {
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,
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) {
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);
} else {
reload = resCount == 0 && (!isInitialLoading || (SystemClock.elapsedRealtime() - lastServerQueryTime.get(dialogId, 0L)) > 60 * 1000 || (isCache && isTopic));
if (isCache && dialogId < 0) {
TLRPC.Chat chat = getChat(-dialogId);
if (chat == null) {
chat = chatsDict.get(-dialogId);
}
if (chat != null && mode == 0 && ChatObject.isNotInChat(chat) && (SystemClock.elapsedRealtime() - lastServerQueryTime.get(dialogId, 0L)) > 24 * 60 * 60 * 1000) {
messagesRes.messages.clear();
reload = true;
}
}
// if (isCache && dialogId < 0) {
// TLRPC.Chat chat = getChat(-dialogId);
// if (chat == null) {
// chat = chatsDict.get(-dialogId);
// }
// if (chat != null && mode == 0 && ChatObject.isNotInChat(chat) && (SystemClock.elapsedRealtime() - lastServerQueryTime.get(dialogId, 0L)) > 24 * 60 * 60 * 1000) {
// messagesRes.messages.clear();
// reload = true;
// }
// }
}
if (!DialogObject.isEncryptedDialog(dialogId) && isCache && reload) {
int hash;
@ -8274,7 +8277,10 @@ public class MessagesController extends BaseController implements NotificationCe
lastServerQueryTime.put(dialogId, SystemClock.elapsedRealtime());
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()) {
return;
}
@ -8367,10 +8373,16 @@ public class MessagesController extends BaseController implements NotificationCe
if (BuildVars.LOGS_ENABLED) {
FileLog.d("process time=" + (SystemClock.elapsedRealtime() - startProcessTime) + " count=" + objects.size() + " for dialog " + dialogId);
}
if (loaderLogger != null) {
loaderLogger.logStageQueueProcessing();
}
AndroidUtilities.runOnUIThread(() -> {
putUsers(messagesRes.users, isCache);
putChats(messagesRes.chats, isCache);
if (loaderLogger != null) {
loaderLogger.finish();
}
if (messagesRes.animatedEmoji != null && needProcess) {
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) {
startShortPoll(chat, guid, stop, null);
}
public void startShortPoll(TLRPC.Chat chat, int guid, boolean stop, Consumer<Boolean> needPollConsumer) {
if (chat == null) {
return;
}
@ -12212,9 +12227,17 @@ public class MessagesController extends BaseController implements NotificationCe
if (!guids.contains(guid)) {
guids.add(guid);
}
boolean needGetDifference = false;
if (shortPollChannels.indexOfKey(chat.id) < 0) {
needGetDifference = true;
getChannelDifference(chat.id, 3, 0, null);
}
boolean finalNeedGetDifference = needGetDifference;
if (needPollConsumer != null) {
AndroidUtilities.runOnUIThread(() -> {
needPollConsumer.accept(finalNeedGetDifference);
});
}
if (chat.megagroup) {
if (onlineGuids == null) {
onlineGuids = new ArrayList<>();
@ -12259,6 +12282,9 @@ public class MessagesController extends BaseController implements NotificationCe
if (newDialogType == 1) {
channelPts = channelsPts.get(channelId);
if (channelPts != 0) {
AndroidUtilities.runOnUIThread(() -> {
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.onReceivedChannelDifference, channelId);
});
return;
}
channelPts = 1;
@ -12271,10 +12297,16 @@ public class MessagesController extends BaseController implements NotificationCe
channelsPts.put(channelId, channelPts);
}
if (channelPts == 0 && (newDialogType == 2 || newDialogType == 3)) {
AndroidUtilities.runOnUIThread(() -> {
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.onReceivedChannelDifference, channelId);
});
return;
}
}
if (channelPts == 0) {
AndroidUtilities.runOnUIThread(() -> {
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.onReceivedChannelDifference, channelId);
});
return;
}
}
@ -12293,6 +12325,9 @@ public class MessagesController extends BaseController implements NotificationCe
if (taskId != 0) {
getMessagesStorage().removePendingTask(taskId);
}
AndroidUtilities.runOnUIThread(() -> {
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.onReceivedChannelDifference, channelId);
});
return;
}
long newTaskId;
@ -12382,6 +12417,7 @@ public class MessagesController extends BaseController implements NotificationCe
}
Utilities.stageQueue.postRunnable(() -> {
boolean notifyAbountDifference = true;
if (res instanceof TLRPC.TL_updates_channelDifference || res instanceof TLRPC.TL_updates_channelDifferenceEmpty) {
if (!res.new_messages.isEmpty()) {
LongSparseArray<ArrayList<MessageObject>> messages = new LongSparseArray<>();
@ -12464,7 +12500,10 @@ public class MessagesController extends BaseController implements NotificationCe
message.dialog_id = -channelId;
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);
channelsPts.put(channelId, res.pts);
@ -12483,10 +12522,18 @@ public class MessagesController extends BaseController implements NotificationCe
if (newTaskId != 0) {
getMessagesStorage().removePendingTask(newTaskId);
}
if (notifyAbountDifference) {
AndroidUtilities.runOnUIThread(() -> {
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.onReceivedChannelDifference, channelId);
});
}
});
});
} 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);
if (newTaskId != 0) {
getMessagesStorage().removePendingTask(newTaskId);
@ -17672,9 +17719,9 @@ public class MessagesController extends BaseController implements NotificationCe
int lastMessageId = (int) args[4];
if ((size < count / 2 && !isEnd) && isCache) {
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 {
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 {
getNotificationCenter().removeObserver(this, NotificationCenter.messagesDidLoadWithoutProcess);
@ -17698,9 +17745,9 @@ public class MessagesController extends BaseController implements NotificationCe
getNotificationCenter().addObserver(delegate, NotificationCenter.loadingMessagesFailed);
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 {
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();
long currentUserId = getUserConfig().clientUserId;
int count_unread = 0;
@ -8623,7 +8623,7 @@ public class MessagesStorage extends BaseController {
};
} else {*/
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(() -> {
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(() -> {
if (loaderLogger != null) {
loaderLogger.logStageQueuePost();
}
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(() -> {
SQLiteCursor cursor = null;
try {
@ -9978,6 +9987,9 @@ public class MessagesStorage extends BaseController {
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 uploadStoryEnd = totalEvents++;
public static final int customTypefacesLoaded = totalEvents++;
public static final int stealthModeChanged = totalEvents++;
public static final int onReceivedChannelDifference = totalEvents++;
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));
}
Notification mainNotification = notificationBuilder.build();
if (Build.VERSION.SDK_INT < 18) {
if (Build.VERSION.SDK_INT <= 19) {
notificationManager.notify(notificationId, mainNotification);
if (BuildVars.LOGS_ENABLED) {
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));
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 {
@ -244,7 +244,7 @@ public class SaveToGallerySettingsHelper {
}
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 {
builder.append(LocaleController.formatString("SaveToGalleryVideos", R.string.SaveToGalleryVideos));
}

View file

@ -43,6 +43,8 @@ import android.util.SparseArray;
import androidx.core.graphics.ColorUtils;
import com.google.android.exoplayer2.util.Log;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.DrawingInBackgroundThreadDrawable;
import org.xml.sax.Attributes;
@ -109,19 +111,19 @@ public class SvgHelper {
private Paint backgroundPaint;
protected int width;
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 Canvas[] backgroundCanvas = new Canvas[1 + DrawingInBackgroundThreadDrawable.THREAD_COUNT];
private LinearGradient[] placeholderGradient = new LinearGradient[1 + DrawingInBackgroundThreadDrawable.THREAD_COUNT];
private Matrix[] placeholderMatrix = new Matrix[1 + DrawingInBackgroundThreadDrawable.THREAD_COUNT];
private final Bitmap[] backgroundBitmap = new Bitmap[1 + DrawingInBackgroundThreadDrawable.THREAD_COUNT];
private final Canvas[] backgroundCanvas = new Canvas[1 + DrawingInBackgroundThreadDrawable.THREAD_COUNT];
private final LinearGradient[] placeholderGradient = new LinearGradient[1 + DrawingInBackgroundThreadDrawable.THREAD_COUNT];
private final Matrix[] placeholderMatrix = new Matrix[1 + DrawingInBackgroundThreadDrawable.THREAD_COUNT];
private static float totalTranslation;
private static float gradientWidth;
private static long lastUpdateTime;
private static Runnable shiftRunnable;
private static WeakReference<Drawable> shiftDrawable;
private ImageReceiver parentImageReceiver;
private int[] currentColor = new int[2];
private final int[] currentColor = new int[2];
private int currentColorKey;
private Integer overrideColor;
private Theme.ResourcesProvider currentResourcesProvider;
@ -441,6 +443,7 @@ public class SvgHelper {
SAXParser sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader();
SVGHandler handler = new SVGHandler(width, height, color, false, scale);
///handler.alphaOnly = true;
xr.setContentHandler(handler);
xr.parse(new InputSource(stream));
return handler.getBitmap();
@ -456,6 +459,9 @@ public class SvgHelper {
SAXParser sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader();
SVGHandler handler = new SVGHandler(width, height, white ? 0xffffffff : null, false, 1f);
if (!white) {
handler.alphaOnly = true;
}
xr.setContentHandler(handler);
xr.parse(new InputSource(stream));
return handler.getBitmap();
@ -1116,6 +1122,7 @@ public class SvgHelper {
boolean pushed = false;
private HashMap<String, StyleSet> globalStyles = new HashMap<>();
private boolean alphaOnly;
private SVGHandler(int dw, int dh, Integer color, boolean asDrawable, float scale) {
globalScale = scale;
@ -1275,7 +1282,7 @@ public class SvgHelper {
height *= scale;
}
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);
canvas = new Canvas(bitmap);
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_inlineResultAudio;
public static Drawable chat_inlineResultLocation;
public static Drawable chat_redLocationIcon;
public static Drawable chat_msgOutLocationDrawable;
public static Drawable chat_contextResult_shadowUnderSwitchDrawable;
public static Drawable chat_shareIconDrawable;
@ -3226,7 +3225,6 @@ public class Theme {
public static Drawable chat_msgCallDownRedDrawable;
public static Drawable chat_msgCallDownGreenDrawable;
public static Drawable chat_msgAvatarLiveLocationDrawable;
public static Drawable chat_attachEmptyDrawable;
public static RLottieDrawable[] chat_attachButtonDrawables = new RLottieDrawable[6];
public static Drawable[] chat_locationDrawable = new Drawable[2];
@ -7670,11 +7668,17 @@ public class Theme {
options.inSampleSize *= 2;
} while (options.inSampleSize < scale);
}
options.inPreferredConfig = Bitmap.Config.ALPHA_8;
options.inJustDecodeBounds = false;
Bitmap wallpaper = BitmapFactory.decodeFile(wallpaperPath, options);
if (wallpaper != null) {
if (color2 != 0 && accent != null) {
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.setBounds(0, 0, bitmap.getWidth(), bitmap.getHeight());
wallpaperDrawable.draw(canvas);
@ -8466,12 +8470,10 @@ public class Theme {
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_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_inlineResultAudio = resources.getDrawable(R.drawable.bot_music);
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_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_composeShadowRoundDrawable = context.getResources().getDrawable(R.drawable.sheet_shadow_round).mutate();
try {
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) {
}
chat_roundVideoShadow = new RoundVideoShadow();
defaultChatDrawables.clear();
defaultChatDrawableColorKeys.clear();
@ -9590,7 +9570,15 @@ public class Theme {
try {
if (backgroundColor != 0 && gradientToColor1 != 0 && gradientToColor2 != 0) {
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());
settings.wallpaper = motionBackgroundDrawable;
} else {
@ -9932,6 +9920,7 @@ public class Theme {
photoH /= 2;
}
}
opts.inPreferredConfig = Bitmap.Config.ALPHA_8;
opts.inJustDecodeBounds = false;
opts.inSampleSize = scaleFactor;
Bitmap bitmap = BitmapFactory.decodeStream(stream, null, opts);
@ -9943,6 +9932,11 @@ public class Theme {
} else {
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.setPatternColorFilter(motionBackgroundDrawable.getPatternColor());
return motionBackgroundDrawable;

View file

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

View file

@ -149,7 +149,7 @@ public class CacheControlActivity extends BaseFragment implements NotificationCe
private LinearLayoutManager layoutManager;
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 cacheSize = -1, cacheEmojiSize = -1, cacheTempSize = -1;
private long documentsSize = -1;
@ -374,7 +374,7 @@ public class CacheControlActivity extends BaseFragment implements NotificationCe
if (canceled) {
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();
File path;
@ -441,13 +441,13 @@ public class CacheControlActivity extends BaseFragment implements NotificationCe
private void updateChart() {
if (cacheChart != null) {
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) {
ItemInner item = itemInners.get(i);
if (item.viewType == VIEW_TYPE_SECTION) {
if (item.index < 0) {
if (collapsed) {
segments[8] = CacheChart.SegmentSize.of(item.size, selected[8]);
segments[9] = CacheChart.SegmentSize.of(item.size, selected[9]);
}
} else {
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));
}
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) {
sections.add(ItemInner.asCheckBox(LocaleController.getString(R.string.LocalAudioCache), 4, audioSize, Theme.key_statisticChartLine_lightgreen));
}
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) {
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;
if (tempSizes == null) {
tempSizes = new float[9];
tempSizes = new float[10];
}
for (int i = 0; i < tempSizes.length; ++i) {
tempSizes[i] = (float) size(i);
}
if (percents == null) {
percents = new int[9];
percents = new int[10];
}
AndroidUtilities.roundPercents(tempSizes, percents);
@ -759,7 +759,7 @@ public class CacheControlActivity extends BaseFragment implements NotificationCe
sum += sections.get(i).size;
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));
if (!collapsed) {
itemInners.addAll(sections.subList(MAX_NOT_COLLAPSED, sections.size()));
@ -963,7 +963,7 @@ public class CacheControlActivity extends BaseFragment implements NotificationCe
long clearedSize = 0;
boolean allItemsClear = true;
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();
Utilities.Callback<Float> updateProgress = t -> {
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;
} else if (a == 6) {
type = 100;
clearedSize += stickersCacheSize + cacheEmojiSize;
clearedSize += stickersCacheSize;
} else if (a == 7) {
clearedSize += cacheSize;
documentsMusicType = 5;
@ -1088,7 +1088,7 @@ public class CacheControlActivity extends BaseFragment implements NotificationCe
}
}
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();
Arrays.fill(selected, true);
@ -1176,16 +1176,17 @@ public class CacheControlActivity extends BaseFragment implements NotificationCe
case 2: return documentsSize;
case 3: return musicSize;
case 4: return audioSize;
case 5: return stickersCacheSize;
case 6: return cacheSize;
case 7: return cacheTempSize;
case 5: return storiesSize;
case 6: return stickersCacheSize;
case 7: return cacheSize;
case 8: return cacheTempSize;
default: return 0;
}
}
private int sectionsSelected() {
int count = 0;
for (int i = 0; i < 8; ++i) {
for (int i = 0; i < 9; ++i) {
if (selected[i] && size(i) > 0) {
count++;
}

View file

@ -84,6 +84,7 @@ import org.telegram.PhoneFormat.PhoneFormat;
import org.telegram.messenger.AccountInstance;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.ChatMessageSharedResources;
import org.telegram.messenger.ChatObject;
import org.telegram.messenger.ContactsController;
import org.telegram.messenger.DialogObject;
@ -1287,6 +1288,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
private Theme.ResourcesProvider resourcesProvider;
private final boolean canDrawBackgroundInParent;
private ChatMessageSharedResources sharedResources;
// Public for enter transition
public List<SpoilerEffect> replySpoilers = new ArrayList<>();
@ -1298,13 +1300,17 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
public boolean isBlurred;
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);
this.resourcesProvider = resourcesProvider;
this.canDrawBackgroundInParent = canDrawBackgroundInParent;
this.sharedResources = sharedResources;
if (this.sharedResources == null) {
this.sharedResources = new ChatMessageSharedResources(context);
}
backgroundDrawable = new MessageBackgroundDrawable(this);
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()) {
int w = (int) (Theme.chat_redLocationIcon.getIntrinsicWidth() * 0.8f);
int h = (int) (Theme.chat_redLocationIcon.getIntrinsicHeight() * 0.8f);
Drawable redLocationIcon = sharedResources.getRedLocationIcon();
int w = (int) (redLocationIcon.getIntrinsicWidth() * 0.8f);
int h = (int) (redLocationIcon.getIntrinsicHeight() * 0.8f);
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())));
Theme.chat_redLocationIcon.setAlpha((int) (255 * Math.min(1, photoImage.getCurrentAlpha() * 5)));
Theme.chat_redLocationIcon.setBounds(x, y, x + w, y + h);
Theme.chat_redLocationIcon.draw(canvas);
redLocationIcon.setAlpha((int) (255 * Math.min(1, photoImage.getCurrentAlpha() * 5)));
redLocationIcon.setBounds(x, y, x + w, y + h);
redLocationIcon.draw(canvas);
if (photoImage.getCurrentAlpha() < 1) {
invalidate();
}
@ -17192,9 +17199,10 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
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)));
setDrawableBounds(Theme.chat_msgAvatarLiveLocationDrawable, cx, cy);
Theme.chat_msgAvatarLiveLocationDrawable.setAlpha((int) (255 * Math.min(1, progress * 5)));
Theme.chat_msgAvatarLiveLocationDrawable.draw(canvas);
Drawable msgAvatarLiveLocation = sharedResources.getAvatarLiveLocation();
setDrawableBounds(msgAvatarLiveLocation, cx, cy);
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.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.DialogsActivity;
import org.telegram.ui.RightSlidingDialogContainer;
import org.telegram.ui.Stories.StoriesController;
import org.telegram.ui.Stories.StoriesListPlaceProvider;
import org.telegram.ui.Stories.StoriesUtilities;
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();
public void setMoving(boolean moving) {
@ -708,6 +709,7 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
AnimatedEmojiSpan.release(this, animatedEmojiStack3);
AnimatedEmojiSpan.release(this, animatedEmojiStackName);
storyParams.onDetachFromWindow();
canvasButton = null;
}
@Override
@ -3765,7 +3767,11 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
);
thumbImage[i].draw(canvas);
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);
canvas.save();
@ -4383,7 +4389,10 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
} else {
archivedChatsDrawable.outCy = storyParams.originalAvatarRect.centerY();
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.startOutAnimation();

View file

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

View file

@ -38,6 +38,7 @@ import android.widget.Magnifier;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.core.widget.NestedScrollView;
import androidx.recyclerview.widget.LinearLayoutManager;
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() {
longpressDelay = ViewConfiguration.getLongPressTimeout();
@ -288,6 +292,11 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
selectionPaint.setPathEffect(new CornerPathEffect(cornerRadius = AndroidUtilities.dp(6)));
}
public void setInvalidateParent() {
invalidateParent = true;
}
public interface OnTranslateListener {
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;
fillLayoutForOffset(offset, layoutBlock);
StaticLayout layout = layoutBlock.layout;
Layout layout = layoutBlock.layout;
if (layout == null) {
return;
}
@ -389,17 +398,18 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
int line = layout.getLineForOffset(offset);
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;
int startLine;
int endLine;
if (selectedView instanceof ArticleViewer.BlockTableCell) {
startLine = (int) selectedView.getX();
endLine = (int) selectedView.getX() + selectedView.getMeasuredWidth();
startLine = (int) coordsInParent[0];
endLine = (int) coordsInParent[0] + selectedView.getMeasuredWidth();
} else {
startLine = (int) (selectedView.getX() + textX + layout.getLineLeft(line));
endLine = (int) (selectedView.getX() + textX + layout.getLineRight(line));
startLine = (int) (coordsInParent[0] + textX + layout.getLineLeft(line));
endLine = (int) (coordsInParent[0] + textX + layout.getLineRight(line));
}
if (x < startLine) {
x = startLine;
@ -467,7 +477,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
handleViewAnimator.start();
}
public boolean isSelectionMode() {
public boolean isInSelectionMode() {
return selectionStart >= 0 && selectionEnd >= 0;
}
@ -481,7 +491,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
return;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!movingHandle && isSelectionMode() && canShowActions()) {
if (!movingHandle && isInSelectionMode() && canShowActions()) {
if (!actionsIsShowing) {
if (actionMode == null) {
FloatingToolbar floatingToolbar = new FloatingToolbar(textSelectionOverlay.getContext(), textSelectionOverlay, STYLE_THEME, getResourcesProvider());
@ -496,11 +506,11 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
}
} else {
if (!showActionsAsPopupAlways) {
if (actionMode == null && isSelectionMode()) {
if (actionMode == null && isInSelectionMode()) {
actionMode = textSelectionOverlay.startActionMode(textSelectActionCallback);
}
} else {
if (!movingHandle && isSelectionMode() && canShowActions()) {
if (!movingHandle && isInSelectionMode() && canShowActions()) {
if (popupLayout == null) {
popupRect = new android.graphics.Rect();
popupLayout = new ActionBarPopupWindow.ActionBarPopupWindowLayout(textSelectionOverlay.getContext());
@ -544,7 +554,8 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
if (selectedView != null) {
int lineHeight = -getLineHeight();
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;
}
@ -580,7 +591,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
}
actionsIsShowing = false;
}
if (!isSelectionMode() && actionMode != null) {
if (!isInSelectionMode() && actionMode != null) {
actionMode.finish();
actionMode = null;
}
@ -658,7 +669,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
}
public void onParentScrolled() {
if (isSelectionMode() && textSelectionOverlay != null) {
if (isInSelectionMode() && textSelectionOverlay != null) {
parentIsScrolling = true;
textSelectionOverlay.invalidate();
hideActions();
@ -695,7 +706,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
public boolean checkOnTap(MotionEvent event) {
if (!isSelectionMode() || movingHandle) return false;
if (!isInSelectionMode() || movingHandle) return false;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
pressedX = event.getX();
@ -717,7 +728,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
@Override
public boolean onTouchEvent(MotionEvent event) {
if (!isSelectionMode()) return false;
if (!isInSelectionMode()) return false;
if (event.getPointerCount() > 1) {
return movingHandle;
}
@ -747,8 +758,13 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
float textSizeHalf = getLineHeight() / 2;
movingOffsetX = cords[0] + textX + selectedView.getX() - x;
movingOffsetY = cords[1] + textY + selectedView.getTop() - y - textSizeHalf;
int[] coordsInParent = getCoordsInParent();
if (useMovingOffset) {
movingOffsetX = cords[0] + textX + coordsInParent[0] - x;
} else {
movingOffsetX = 0;
}
movingOffsetY = cords[1] + textY + coordsInParent[1] - y - textSizeHalf;
hideActions();
return true;
}
@ -763,8 +779,9 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
int[] cords = offsetToCord(selectionEnd);
float textSizeHalf = getLineHeight() / 2;
movingOffsetX = cords[0] + textX + selectedView.getX() - x;
movingOffsetY = cords[1] + textY + selectedView.getTop() - y - textSizeHalf;
int[] coordsInParent = getCoordsInParent();
movingOffsetX = cords[0] + textX + coordsInParent[0] - x;
movingOffsetY = cords[1] + textY + coordsInParent[1] - y - textSizeHalf;
showMagnifier(lastX);
hideActions();
return true;
@ -799,15 +816,16 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
fillLayoutForOffset(selectionEnd, layoutBlock);
}
StaticLayout oldTextLayout = layoutBlock.layout;
Layout oldTextLayout = layoutBlock.layout;
if (oldTextLayout == null) {
return true;
}
float oldYoffset = layoutBlock.yOffset;
Cell oldSelectedView = selectedView;
y -= selectedView.getTop();
x -= selectedView.getX();
int[] coordsInParent = getCoordsInParent();
y -= coordsInParent[1];
x -= coordsInParent[0];
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());
@ -852,10 +870,10 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
CharSequence text = getText(selectedView, false);
fillLayoutForOffset(newSelection, layoutBlock);
StaticLayout layoutOld = layoutBlock.layout;
Layout layoutOld = layoutBlock.layout;
fillLayoutForOffset(selectionStart, layoutBlock);
StaticLayout layoutNew = layoutBlock.layout;
Layout layoutNew = layoutBlock.layout;
if (layoutOld == null || layoutNew == null) {
return true;
@ -954,10 +972,10 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
fillLayoutForOffset(newSelection, layoutBlock);
StaticLayout layoutOld = layoutBlock.layout;
Layout layoutOld = layoutBlock.layout;
fillLayoutForOffset(selectionEnd, layoutBlock);
StaticLayout layoutNew = layoutBlock.layout;
Layout layoutNew = layoutBlock.layout;
if (layoutOld == null || layoutNew == null) {
return true;
@ -1037,7 +1055,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
movingHandle = false;
movingDirectionSettling = false;
isOneTouch = false;
if (isSelectionMode()) {
if (isInSelectionMode()) {
showActions();
showHandleViews();
}
@ -1053,7 +1071,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
@Override
protected void onDraw(Canvas canvas) {
if (!isSelectionMode()) return;
if (!isInSelectionMode()) return;
int handleViewSize = AndroidUtilities.dp(22);
int count = 0;
@ -1061,8 +1079,10 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
pickEndView();
if (selectedView != null) {
canvas.save();
float yOffset = selectedView.getY() + textY;
float xOffset = selectedView.getX() + textX;
int[] coordsInParent = getCoordsInParent();
float yOffset = coordsInParent[1] + textY;
float xOffset = coordsInParent[0] + textX;
canvas.translate(xOffset, yOffset);
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) {
fillLayoutForOffset(selectionEnd, layoutBlock);
StaticLayout layout = layoutBlock.layout;
Layout layout = layoutBlock.layout;
if (layout != null) {
int end = selectionEnd - layoutBlock.charOffset;
int textLen = layout.getText().length();
@ -1133,15 +1153,16 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
pickStartView();
if (selectedView != null) {
canvas.save();
float yOffset = selectedView.getY() + textY;
float xOffset = selectedView.getX() + textX;
int[] coordsInParent = getCoordsInParent();
float yOffset = coordsInParent[1] + textY;
float xOffset = coordsInParent[0] + textX;
canvas.translate(xOffset, yOffset);
int len = getText(selectedView, false).length();
if (selectionStart >= 0 && selectionStart <= len) {
fillLayoutForOffset(selectionStart, layoutBlock);
StaticLayout layout = layoutBlock.layout;
Layout layout = layoutBlock.layout;
if (layout != null) {
int start = selectionStart - layoutBlock.charOffset;
int line = layout.getLineForOffset(start);
@ -1222,6 +1243,67 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
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) {
@ -1333,7 +1415,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
if (!isSelectionMode()) {
if (!isInSelectionMode()) {
return true;
}
switch (item.getItemId()) {
@ -1396,17 +1478,18 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
@Override
public void onGetContentRect(ActionMode mode, View view, Rect outRect) {
if (!isSelectionMode()) {
if (!isInSelectionMode()) {
return;
}
pickStartView();
int x1 = 0;
int y1 = 1;
int[] coordsInParent = getCoordsInParent();
if (selectedView != null) {
int lineHeight = -getLineHeight();
int[] coords = offsetToCord(selectionStart);
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;
}
@ -1428,7 +1511,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
}
private void copyText() {
if (!isSelectionMode()) {
if (!isInSelectionMode()) {
return;
}
CharSequence str = getSelectedText();
@ -1444,7 +1527,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
}
private void translateText() {
if (!isSelectionMode()) {
if (!isInSelectionMode()) {
return;
}
CharSequence str = getSelectedText();
@ -1464,7 +1547,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
protected int[] offsetToCord(int offset) {
fillLayoutForOffset(offset, layoutBlock);
StaticLayout layout = layoutBlock.layout;
Layout layout = layoutBlock.layout;
int blockOffset = offset - layoutBlock.charOffset;
if (layout == null || blockOffset < 0 || blockOffset > layout.getText().length()) {
return tmpCoord;
@ -1477,7 +1560,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
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();
selectionHandlePath.reset();
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 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();
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;
StaticLayout layout;
float yOffset;
float xOffset;
public Layout layout;
public float yOffset;
public float xOffset;
}
@ -1634,6 +1717,109 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
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> {
SparseArray<Animator> animatorSparseArray = new SparseArray<>();
@ -1817,7 +2003,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
return -1;
}
StaticLayout layout = layoutBlock.layout;
Layout layout = layoutBlock.layout;
x -= layoutBlock.xOffset;
@ -2476,7 +2662,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
boolean startPeek;
protected void pickEndView() {
if (!isSelectionMode()) {
if (!isInSelectionMode()) {
return;
}
startPeek = false;
@ -2518,7 +2704,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
}
protected void pickStartView() {
if (!isSelectionMode()) {
if (!isInSelectionMode()) {
return;
}
startPeek = true;
@ -2769,6 +2955,13 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
void fillTextLayoutBlocks(ArrayList<TextLayoutBlock> blocks);
}
public interface SimpleSelectabeleView extends SelectableView {
CharSequence getText();
Layout getStaticTextLayout();
}
public interface SelectableView {
int getBottom();
@ -2886,10 +3079,10 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
}
protected int getThemedColor(int key) {
return Theme.getColor(key);
return Theme.getColor(key, resourcesProvider);
}
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.BotWebViewVibrationEffect;
import org.telegram.messenger.BuildVars;
import org.telegram.messenger.ChatMessageSharedResources;
import org.telegram.messenger.ChatMessagesMetadataController;
import org.telegram.messenger.ChatObject;
import org.telegram.messenger.ChatThemeController;
@ -746,6 +747,13 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
private boolean chatListViewAttached;
public boolean forceDisallowApplyWallpeper;
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);
@ -864,6 +872,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
private TextSelectionHint textSelectionHint;
private boolean textSelectionHintWasShowed;
private float lastTouchY;
ContentPreviewViewer.ContentPreviewViewerDelegate contentPreviewViewerDelegate;
private ChatMessageCell dummyMessageCell;
private FireworksOverlay fireworksOverlay;
@ -1032,6 +1041,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
public float drawingChatLisViewYoffset;
public int blurredViewTopOffset;
public int blurredViewBottomOffset;
public ChatMessageSharedResources sharedResources;
private ValueAnimator searchExpandAnimator;
private float searchExpandProgress;
@ -1321,7 +1331,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
RecyclerListView.OnItemLongClickListenerExtended onItemLongClickListener = new RecyclerListView.OnItemLongClickListenerExtended() {
@Override
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;
}
wasManualScroll = true;
@ -2090,11 +2100,11 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
reportType = arguments.getInt("report", -1);
pulled = arguments.getBoolean("pulled", false);
boolean historyPreloaded = arguments.getBoolean("historyPreloaded", false);
historyPreloaded = arguments.getBoolean("historyPreloaded", false);
if (highlightMessageId != 0 && highlightMessageId != Integer.MAX_VALUE) {
startLoadFromMessageId = highlightMessageId;
}
int migrated_to = arguments.getInt("migrated_to", 0);
migrated_to = arguments.getInt("migrated_to", 0);
scrollToTopOnResume = arguments.getBoolean("scrollToTopOnResume", false);
needRemovePreviousSameChatActivity = arguments.getBoolean("need_remove_previous_same_chat_activity", true);
justCreatedChat = arguments.getBoolean("just_created_chat", false);
@ -2121,7 +2131,17 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
dialog_id = -chatId;
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) {
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.messageTranslated);
getNotificationCenter().addObserver(this, NotificationCenter.messageTranslating);
getNotificationCenter().addObserver(this, NotificationCenter.onReceivedChannelDifference);
super.onFragmentCreate();
@ -2351,7 +2372,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
}
boolean loadInfo = false;
loadInfo = false;
if (currentChat != null) {
chatInfo = getMessagesController().getChatFull(currentChat.id);
groupCall = getMessagesController().getGroupCall(currentChat.id, true);
@ -2382,35 +2403,15 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
checkDispatchHideSkeletons(false);
}
if (chatMode != MODE_PINNED && !forceHistoryEmpty) {
waitingForLoad.add(lastLoadIndex);
int initialMessagesSize;
if (SharedConfig.deviceIsHigh()) {
initialMessagesSize = (isThreadChat() && !isTopic) ? 30 : 25;
} else {
initialMessagesSize = (isThreadChat() && !isTopic) ? 20 : 15;
}
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 (!waitingForGetDifference) {
firstLoadMessages();
}
}
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 (userId != 0 && currentUser.bot) {
@ -2439,7 +2440,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (chatInfo != null && chatInfo.linked_chat_id != 0) {
TLRPC.Chat chat = getMessagesController().getChat(chatInfo.linked_chat_id);
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;
}
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) {
if (currentChat == null || chatInfo == null || ChatObject.isNotInChat(currentChat) || currentChat.creator) {
return;
@ -2568,6 +2598,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (chatAttachAlert != null) {
chatAttachAlert.dismissInternal();
}
ContentPreviewViewer.getInstance().clearDelegate(contentPreviewViewerDelegate);
getNotificationCenter().onAnimationFinish(transitionAnimationIndex);
NotificationCenter.getGlobalInstance().onAnimationFinish(transitionAnimationGlobalIndex);
getNotificationCenter().onAnimationFinish(scrollAnimationIndex);
@ -2656,6 +2687,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
getNotificationCenter().removeObserver(this, NotificationCenter.dialogIsTranslatable);
getNotificationCenter().removeObserver(this, NotificationCenter.messageTranslated);
getNotificationCenter().removeObserver(this, NotificationCenter.messageTranslating);
getNotificationCenter().removeObserver(this, NotificationCenter.onReceivedChannelDifference);
if (currentEncryptedChat != null) {
getNotificationCenter().removeObserver(this, NotificationCenter.didVerifyMessagesStickers);
}
@ -2762,10 +2794,11 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
actionBar.setSubtitleColor(getThemedColor(Theme.key_actionBarActionModeDefaultIcon));
}
actionBarBackgroundPaint.setColor(getThemedColor(Theme.key_actionBarDefault));
sharedResources = new ChatMessageSharedResources(context);
if (chatMessageCellsCache.isEmpty()) {
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--) {
@ -3574,7 +3607,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
forceScrollToTop = false;
if (textSelectionHelper != null && textSelectionHelper.isSelectionMode()) {
if (textSelectionHelper != null && textSelectionHelper.isInSelectionMode()) {
textSelectionHelper.invalidate();
}
isSkeletonVisible();
@ -3837,7 +3870,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
currentEncryptedChat == null && message.getId() < 0 ||
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)) ||
textSelectionHelper.isSelectionMode()) {
textSelectionHelper.isInSelectionMode()) {
slidingView.setSlidingOffset(0);
slidingView = null;
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));
final ContentPreviewViewer.ContentPreviewViewerDelegate contentPreviewViewerDelegate = new ContentPreviewViewer.ContentPreviewViewerDelegate() {
contentPreviewViewerDelegate = new ContentPreviewViewer.ContentPreviewViewerDelegate() {
@Override
public void sendSticker(TLRPC.Document sticker, String query, Object parent, boolean notify, int 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) {
if (chatLayoutManager == null || paused || chatAdapter.isFrozen) {
if (chatLayoutManager == null || paused || chatAdapter.isFrozen || waitingForGetDifference) {
return;
}
int firstVisibleItem = RecyclerListView.NO_POSITION;
@ -10631,9 +10664,11 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
final MessagesController messagesController = getMessagesController();
Utilities.searchQueue.postRunnable(() -> {
boolean requestAnyway = false;
if (linkSearchRequestId != 0) {
getConnectionsManager().cancelRequest(linkSearchRequestId, true);
linkSearchRequestId = 0;
requestAnyway = true;
}
ArrayList<CharSequence> urls = null;
CharSequence textToCheck;
@ -10668,7 +10703,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
clear = false;
}
}
if (clear) {
if (clear && !requestAnyway) {
return;
}
}
@ -12123,7 +12158,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
return 0;
}
if (dummyMessageCell == null) {
dummyMessageCell = new ChatMessageCell(getParentActivity(), true, themeDelegate);
dummyMessageCell = new ChatMessageCell(getParentActivity(), true, sharedResources, themeDelegate);
}
dummyMessageCell.isChat = currentChat != null || UserObject.isUserSelf(currentUser);
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) {
if (waitingForGetDifference) {
return;
}
if (id == 0 || NotificationCenter.getInstance(currentAccount).isAnimationInProgress() || getParentActivity() == null) {
if (NotificationCenter.getInstance(currentAccount).isAnimationInProgress()) {
nextScrollToMessageId = id;
@ -12393,7 +12431,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (pagedownButton == null) {
return;
}
boolean show = canShowPagedownButton && !textSelectionHelper.isSelectionMode() && !chatActivityEnterView.isRecordingAudioVideo();
boolean show = canShowPagedownButton && !textSelectionHelper.isInSelectionMode() && !chatActivityEnterView.isRecordingAudioVideo();
if (show) {
if (animated && (openAnimationStartTime == 0 || SystemClock.elapsedRealtime() < openAnimationStartTime + 150)) {
animated = false;
@ -12752,7 +12790,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
lastTouchY = ev.getY();
TextSelectionHelper.TextSelectionOverlay selectionOverlay = textSelectionHelper.getOverlayView(getContext());
ev.offsetLocation(-selectionOverlay.getX(), -selectionOverlay.getY());
if (textSelectionHelper.isSelectionMode() && textSelectionHelper.getOverlayView(getContext()).onTouchEvent(ev)) {
if (textSelectionHelper.isInSelectionMode() && textSelectionHelper.getOverlayView(getContext()).onTouchEvent(ev)) {
return true;
} else {
ev.offsetLocation(selectionOverlay.getX(), selectionOverlay.getY());
@ -12762,7 +12800,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
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());
if (textSelectionHelper.getOverlayView(getContext()).onTouchEvent(ev)) {
ev.offsetLocation(selectionOverlay.getX(), selectionOverlay.getY());
@ -17897,10 +17935,12 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (newGroups != null) {
for (int b = 0, N = newGroups.size(); b < N; b++) {
MessageObject.GroupedMessages groupedMessages = newGroups.valueAt(b);
MessageObject messageObject = groupedMessages.messages.get(groupedMessages.messages.size() - 1);
int index = messages.indexOf(messageObject);
if (index >= 0) {
chatAdapter.notifyItemRangeChanged(index + chatAdapter.messagesStartRow, groupedMessages.messages.size());
if (!groupedMessages.messages.isEmpty()) {
MessageObject messageObject = groupedMessages.messages.get(groupedMessages.messages.size() - 1);
int index = messages.indexOf(messageObject);
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);
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;
} else if (checkRecordLocked(false)) {
return false;
} else if (textSelectionHelper.isSelectionMode()) {
} else if (textSelectionHelper.isInSelectionMode()) {
textSelectionHelper.clear();
return false;
} else if (actionBar != null && actionBar.isActionModeShowed()) {
@ -26613,6 +26659,12 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (photoEntry == null) {
return;
}
if (videoEditedInfo != null && videoEditedInfo.roundVideo) {
AndroidUtilities.runOnUIThread(closeInstantCameraAnimation = () -> {
closeInstantCameraAnimation = null;
runCloseInstantCameraAnimation();
}, 3000);
}
fillEditingMediaWithCaption(photoEntry.caption, photoEntry.entities);
if (photoEntry.isVideo) {
if (videoEditedInfo != null) {
@ -26630,6 +26682,32 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
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) {
if (emoji == null) {
return;
@ -26781,7 +26859,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
};
NotificationCenter.getInstance(currentAccount).addObserver(observer, NotificationCenter.messagesDidLoad);
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 {
openCommentsChat.run();
@ -27757,7 +27835,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
view = chatMessageCellsCache.get(0);
chatMessageCellsCache.remove(0);
} else {
view = new ChatMessageCell(mContext, true, themeDelegate);
view = new ChatMessageCell(mContext, true, sharedResources, themeDelegate);
}
ChatMessageCell chatMessageCell = (ChatMessageCell) view;
chatMessageCell.setResourcesProvider(themeDelegate);
@ -28160,6 +28238,10 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
boolean applyAnimation = false;
if (message.type == MessageObject.TYPE_ROUND_VIDEO && instantCameraView != null && instantCameraView.getTextureView() != null) {
applyAnimation = true;
if (closeInstantCameraAnimation != null) {
AndroidUtilities.cancelRunOnUIThread(closeInstantCameraAnimation);
closeInstantCameraAnimation = null;
}
messageCell.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {

View file

@ -503,11 +503,11 @@ public class AnimatedEmojiDrawable extends Drawable {
}
};
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()) {
imageReceiver.setColorFilter(colorFilterToSet);
}

View file

@ -23,17 +23,18 @@ import android.graphics.Shader;
import android.graphics.drawable.Animatable;
import android.graphics.drawable.BitmapDrawable;
import android.os.Build;
import android.util.Log;
import android.view.View;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.AnimatedFileDrawableStream;
import org.telegram.messenger.BuildVars;
import org.telegram.messenger.DispatchQueue;
import org.telegram.messenger.DispatchQueuePoolBackground;
import org.telegram.messenger.FileLoader;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.ImageLocation;
import org.telegram.messenger.ImageReceiver;
import org.telegram.messenger.SharedConfig;
import org.telegram.messenger.utils.BitmapsCache;
import org.telegram.tgnet.TLRPC;
@ -48,6 +49,11 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable,
public boolean skipFrameUpdate;
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 void destroyDecoder(long ptr);
@ -259,26 +265,34 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable,
}
loadFrameTask = null;
if (nextRenderingBitmap == null && nextRenderingBitmap2 == null) {
if (!PRERENDER_FRAME) {
nextRenderingBitmap = backgroundBitmap;
nextRenderingBitmapTime = backgroundBitmapTime;
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];
if (nextRenderingBitmap == null && nextRenderingBitmap2 == null) {
nextRenderingBitmap = backgroundBitmap;
nextRenderingBitmapTime = backgroundBitmapTime;
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;
@ -394,7 +408,7 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable,
} catch (Throwable 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);
}
}
@ -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) {
path = file;
PRERENDER_FRAME = SharedConfig.deviceIsAboveAverage() && limitFps;
streamFileSize = streamSize;
this.streamLoadingPriority = streamLoadingPriority;
currentAccount = account;
@ -503,6 +518,7 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable,
public void setIsWebmSticker(boolean b) {
isWebmSticker = b;
PRERENDER_FRAME = false;
if (isWebmSticker) {
useSharedQueue = true;
}
@ -750,7 +766,7 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable,
}
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;
}
long ms = 0;
@ -874,33 +890,36 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable,
}
if (hasRoundRadius()) {
int index = drawInBackground ? threadIndex + 1 : 0;
if (renderingShader[index] == null) {
renderingShader[index] = new BitmapShader(renderingBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
}
paint.setShader(renderingShader[index]);
Matrix matrix = shaderMatrix[index];
if (matrix == null) {
matrix = shaderMatrix[index] = new Matrix();
if (USE_BITMAP_SHADER) {
if (renderingShader[index] == null) {
renderingShader[index] = new BitmapShader(renderingBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
}
paint.setShader(renderingShader[index]);
Matrix matrix = shaderMatrix[index];
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];
if (path == null) {
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 (!drawInBackground) {
invalidatePath = false;
@ -909,29 +928,39 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable,
radii[a * 2] = roundRadius[a];
radii[a * 2 + 1] = roundRadius[a];
}
path.reset();
path.rewind();
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 {
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(scaleX, scaleY);
canvas.drawBitmap(renderingBitmap, 0, 0, paint);
drawBitmap(rect, paint, canvas, scaleX, scaleY);
}
}
}
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() {
return lastTimeStamp;
}
@ -1067,6 +1096,9 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable,
public void setLimitFps(boolean limitFps) {
this.limitFps = limitFps;
if (limitFps) {
PRERENDER_FRAME = false;
}
}
public ArrayList<ImageReceiver> getParents() {
@ -1225,4 +1257,12 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable,
public int getFps() {
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 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[] {
Theme.key_statisticChartLine_lightblue,
Theme.key_statisticChartLine_blue,
Theme.key_statisticChartLine_green,
Theme.key_statisticChartLine_red,
Theme.key_statisticChartLine_purple,
Theme.key_statisticChartLine_lightgreen,
Theme.key_statisticChartLine_indigo,
Theme.key_statisticChartLine_red,
Theme.key_statisticChartLine_orange,
Theme.key_statisticChartLine_cyan,
Theme.key_statisticChartLine_purple,
@ -65,7 +65,7 @@ public class CacheChart extends View {
R.raw.cache_documents,
R.raw.cache_music,
R.raw.cache_videos,
R.raw.cache_other,
R.raw.cache_music,
R.raw.cache_stickers,
R.raw.cache_profile_photos,
R.raw.cache_other,
@ -705,7 +705,7 @@ public class CacheChart extends View {
k++;
}
String[] fileSize = AndroidUtilities.formatFileSize(segmentsSum).split(" ");
String[] fileSize = AndroidUtilities.formatFileSize(segmentsSum, true, true).split(" ");
String top = fileSize.length > 0 ? fileSize[0] : "";
if (top.length() >= 4 && segmentsSum < 1024L * 1024L * 1024L) {
top = top.split("\\.")[0];

View file

@ -5185,7 +5185,11 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
return;
} else {
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)) {
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()) {
colorPickerView.dismiss();
}
ContentPreviewViewer.getInstance().clearDelegate(contentPreviewViewerDelegate);
}
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.BuildVars;
import org.telegram.messenger.ChatMessageSharedResources;
import org.telegram.messenger.ChatObject;
import org.telegram.messenger.ContactsController;
import org.telegram.messenger.FileLog;
@ -91,6 +92,7 @@ public class ForwardingPreviewView extends FrameLayout {
ArrayList<ActionBarMenuSubItem> actionItems = new ArrayList<>();
Rect rect = new Rect();
ChatMessageSharedResources sharedResources;
private boolean firstLayout = true;
ValueAnimator offsetsAnimator;
@ -116,6 +118,7 @@ public class ForwardingPreviewView extends FrameLayout {
@SuppressLint("ClickableViewAccessibility")
public ForwardingPreviewView(@NonNull Context context, ForwardingMessagesParams params, TLRPC.User user, TLRPC.Chat chat, int currentAccount, ResourcesDelegate resourcesProvider) {
super(context);
sharedResources = new ChatMessageSharedResources(context);
this.currentAccount = currentAccount;
currentUser = user;
currentChat = chat;
@ -976,10 +979,11 @@ public class ForwardingPreviewView extends FrameLayout {
}
private class Adapter extends RecyclerView.Adapter {
@NonNull
@Override
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);
}

View file

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

View file

@ -30,6 +30,7 @@ public class PremiumLockIconView extends ImageView {
StarParticlesView.Drawable starParticles;
private boolean locked;
private Theme.ResourcesProvider resourcesProvider;
boolean attachedToWindow;
public PremiumLockIconView(Context context, int type) {
this(context, type, null);
@ -165,6 +166,9 @@ public class PremiumLockIconView extends ImageView {
}
private void updateGradient() {
if (!attachedToWindow) {
return;
}
if (getMeasuredHeight() != 0 && getMeasuredWidth() != 0) {
int c1 = currentColor;
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() {
waitingImage = true;
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);
}
} 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.caption = frameLayout2.getTag() != null && commentTextView.length() > 0 && text[0] != null ? text[0].toString() : null;
params.sendingStory = storyItem;
}
SendMessagesHelper.getInstance(currentAccount).sendMessage(params);

View file

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

View file

@ -39,17 +39,17 @@ public class SpoilerEffectBitmapFactory {
int size;
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);
if (size < AndroidUtilities.dp(100)) {
size = AndroidUtilities.dp(100);
if (size < AndroidUtilities.dp(80)) {
size = AndroidUtilities.dp(80);
}
}
Paint getPaint() {
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);
shaderPaint = new Paint();
shaderSpoilerEffects = new ArrayList<>(10 * 10);
@ -89,10 +89,10 @@ public class SpoilerEffectBitmapFactory {
dispatchQueue.postRunnable(() -> {
Bitmap bitmap = bufferBitmapFinall;
if (bitmap == null) {
bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ALPHA_8);
}
if (backgroundBitmap == null) {
backgroundBitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
backgroundBitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ALPHA_8);
} else {
backgroundBitmap.eraseColor(Color.TRANSPARENT);
}

View file

@ -10,16 +10,18 @@ import android.graphics.Rect;
import android.graphics.Region;
import android.text.Layout;
import android.text.Spanned;
import android.text.StaticLayout;
import android.view.MotionEvent;
import android.widget.TextView;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.ui.Cells.TextSelectionHelper;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
public class SpoilersTextView extends TextView {
public class SpoilersTextView extends TextView implements TextSelectionHelper.SimpleSelectabeleView {
private SpoilersClickDetector clickDetector;
protected List<SpoilerEffect> spoilers = new ArrayList<>();
private Stack<SpoilerEffect> spoilersPool = new Stack<>();
@ -147,4 +149,9 @@ public class SpoilersTextView extends TextView {
}
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) {
delegate = contentPreviewViewerDelegate;
this.resourcesProvider = resourcesProvider;
if (delegate != null && !delegate.can()) {
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) {
delegate = contentPreviewViewerDelegate;
this.resourcesProvider = resourcesProvider;
if (delegate != null && !delegate.can()) {
return false;
}
@ -1299,12 +1297,24 @@ public class ContentPreviewViewer {
currentQuery = null;
delegate = null;
isVisible = false;
resourcesProvider = null;
if (unlockPremiumView != null) {
unlockPremiumView.animate().alpha(0).translationY(AndroidUtilities.dp(56)).setDuration(150).setInterpolator(CubicBezierInterpolator.DEFAULT).start();
}
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() {
isVisible = false;
delegate = null;
@ -1494,20 +1504,10 @@ public class ContentPreviewViewer {
AndroidUtilities.makeGlobalBlurBitmap(bitmap -> {
blurrBitmap = bitmap;
preparingBitmap = false;
if (containerView != null) {
containerView.invalidate();
}
}, 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) {

View file

@ -836,14 +836,14 @@ public class DataSettingsActivity extends BaseFragment {
builder.append(", ");
}
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 (builder.length() > 0) {
builder.append(", ");
}
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 {
builder.append(LocaleController.getString("NoMediaAutoDownload", R.string.NoMediaAutoDownload));

View file

@ -45,6 +45,7 @@ import android.os.Build;
import android.os.Bundle;
import android.text.TextPaint;
import android.text.TextUtils;
import android.util.Log;
import android.util.LongSparseArray;
import android.util.Property;
import android.util.StateSet;
@ -1925,7 +1926,7 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
ignoreLayout = false;
}
} 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) {
ignoreLayout = true;
@ -3718,7 +3719,7 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
if (firstView != null) {
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());
setStoriesOvercroll(viewPage, newOverScroll);
}
@ -3726,7 +3727,7 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
}
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());
setStoriesOvercroll(viewPage, newOverScroll);
}
@ -5359,7 +5360,7 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
// }
public void showSelectStatusDialog() {
if (selectAnimatedEmojiDialog != null || SharedConfig.appLocked || !dialogStoriesCell.isExpanded()) {
if (selectAnimatedEmojiDialog != null || SharedConfig.appLocked || (hasStories && !dialogStoriesCell.isExpanded())) {
return;
}
final SelectAnimatedEmojiDialog.SelectAnimatedEmojiDialogWindow[] popup = new SelectAnimatedEmojiDialog.SelectAnimatedEmojiDialogWindow[1];
@ -6389,7 +6390,9 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
@Override
public void onResume() {
super.onResume();
dialogStoriesCell.onResume();
if (dialogStoriesCell != null) {
dialogStoriesCell.onResume();
}
if (rightSlidingDialogContainer != null) {
rightSlidingDialogContainer.onResume();
}

View file

@ -186,6 +186,7 @@ import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Adapters.MentionsAdapter;
import org.telegram.ui.Cells.CheckBoxCell;
import org.telegram.ui.Cells.PhotoPickerPhotoCell;
import org.telegram.ui.Cells.TextSelectionHelper;
import org.telegram.ui.Components.AlertsCreator;
import org.telegram.ui.Components.AnimatedEmojiDrawable;
import org.telegram.ui.Components.AnimatedEmojiSpan;
@ -297,6 +298,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
private PhotoViewerActionBarContainer actionBarContainer;
private PhotoCountView countView;
public boolean closePhotoAfterSelect = true;
private TextSelectionHelper.SimpleTextSelectionHelper textSelectionHelper;
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
protected void onAttachedToWindow() {
super.onAttachedToWindow();
@ -4477,6 +4492,22 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
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);
@ -6129,7 +6160,6 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
return false;
});
captionLimitView = new TextView(parentActivity);
captionLimitView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
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.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) {
@ -7388,7 +7428,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
}
private TextView createCaptionTextView() {
TextView textView = new SpoilersTextView(activityContext) {
SpoilersTextView textView = new SpoilersTextView(activityContext) {
private LinkSpanDrawable<ClickableSpan> pressedLink;
private LinkSpanDrawable.LinkCollector links = new LinkSpanDrawable.LinkCollector(this);
@ -7398,6 +7438,11 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
if (getLayout() == null) {
return false;
}
if (textSelectionHelper != null && getStaticTextLayout() != null) {
textSelectionHelper.setSelectabeleView(this);
textSelectionHelper.update(getPaddingLeft(), getPaddingTop());
textSelectionHelper.onTouchEvent(event);
}
boolean linkResult = false;
if (event.getAction() == MotionEvent.ACTION_DOWN || pressedLink != null && event.getAction() == MotionEvent.ACTION_UP) {
int x = (int) (event.getX() - getPaddingLeft());
@ -7452,6 +7497,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
return bottomTouchEnabled && b;
}
@Override
public void setPressed(boolean pressed) {
final boolean needsRefresh = pressed != isPressed();
@ -7465,6 +7511,15 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
@Override
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.translate(getPaddingLeft(), 0);
if (links.draw(canvas)) {
@ -7504,6 +7559,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
canvas.restore();
}
};
ViewHelper.setPadding(textView, 16, 8, 16, 8);
textView.setLinkTextColor(0xff79c4fc);
textView.setTextColor(0xffffffff);

View file

@ -399,7 +399,7 @@ public class SaveToGallerySettingsActivity extends BaseFragment {
SelectableAnimatedTextView lowerTextView = new SelectableAnimatedTextView(getContext());
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));
SelectableAnimatedTextView midTextView = new SelectableAnimatedTextView(getContext());
@ -409,7 +409,7 @@ public class SaveToGallerySettingsActivity extends BaseFragment {
SelectableAnimatedTextView topTextView = new SelectableAnimatedTextView(getContext());
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));
@ -450,7 +450,7 @@ public class SaveToGallerySettingsActivity extends BaseFragment {
} else {
midTextView.setText(
LocaleController.formatString("UpToFileSize", R.string.UpToFileSize,
AndroidUtilities.formatFileSize(value, true)
AndroidUtilities.formatFileSize(value, true, false)
), false);
lowerTextView.setSelectedInternal(false, animated);
midTextView.setSelectedInternal(true, animated);

View file

@ -212,7 +212,7 @@ public class StatisticActivity extends BaseFragment implements NotificationCente
if (recentPostsAll.size() > 0) {
int lastPostId = recentPostsAll.get(0).counters.msg_id;
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(() -> {

View file

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

View file

@ -14,9 +14,12 @@ import android.graphics.PorterDuffColorFilter;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.text.Layout;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.style.ClickableSpan;
import android.view.Gravity;
import android.view.HapticFeedbackConstants;
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.RadialProgress;
import org.telegram.ui.Components.RecyclerListView;
import org.telegram.ui.Components.TypefaceSpan;
import org.telegram.ui.PremiumPreviewFragment;
import org.telegram.ui.Stories.recorder.HintView2;
import org.telegram.ui.Stories.recorder.StoryRecorder;
@ -1273,6 +1277,7 @@ public class DialogStoriesCell extends FrameLayout implements NotificationCenter
params.progressToArc = getArcProgress(cx, radius);
params.isLast = isLast;
params.isFirst = isFirst;
params.crossfadeToDialog = 0;
StoriesUtilities.drawAvatarWithStory(dialogId, canvas, avatarImage, storiesController.hasSelfStories(), params);
// avatarImage.draw(canvas);
}
@ -1292,6 +1297,12 @@ public class DialogStoriesCell extends FrameLayout implements NotificationCenter
params.progressToArc = getArcProgress(cx, radius);
params.isLast = isLast;
params.isFirst = isFirst;
if (crossfadeToDialog) {
params.crossfadeToDialog = crossfadeToDialogId;
params.crossfadeToDialogProgress = progressToCollapsed2;
} else {
params.crossfadeToDialog = 0;
}
StoriesUtilities.drawAvatarWithStory(dialogId, canvas, avatarImage, storiesController.hasStories(dialogId), params);
// avatarImage.draw(canvas);
}
@ -1475,6 +1486,7 @@ public class DialogStoriesCell extends FrameLayout implements NotificationCenter
public void setCrossfadeTo(long dialogId) {
if (crossfadeToDialogId != dialogId) {
this.crossfadeToDialogId = dialogId;
crossfadeToDialog = dialogId != -1;
if (crossfadeToDialog) {
TLObject object;
@ -1604,12 +1616,18 @@ public class DialogStoriesCell extends FrameLayout implements NotificationCenter
.setMultilineText(true)
.setTextAlign(Layout.Alignment.ALIGN_CENTER)
.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) {
premiumHint.hide();
}
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.setText(text);
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.SimpleTextView;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Cells.TextSelectionHelper;
import org.telegram.ui.ChatActivity;
import org.telegram.ui.Components.AlertsCreator;
import org.telegram.ui.Components.AnimatedEmojiDrawable;
@ -464,11 +465,7 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
canvas.drawPaint(sharedResources.gradientBackgroundPaint);
}
if (progressToFullBlackout < 1f) {
if (progressToDismiss != 0) {
canvas.saveLayerAlpha(0, gradientTop, getMeasuredWidth(), getMeasuredHeight(), 255, Canvas.ALL_SAVE_FLAG);
} else {
canvas.save();
}
canvas.save();
sharedResources.gradientBackgroundPaint.setColor(ColorUtils.setAlphaComponent(Color.BLACK, (int) (255 * 0.506f * (1f - progressToFullBlackout) * hideCaptionAlpha)));
sharedResources.bottomOverlayGradient.setAlpha((int) (255 * (1f - progressToFullBlackout) * hideCaptionAlpha));
sharedResources.bottomOverlayGradient.setBounds(0, gradientTop, getMeasuredWidth(), gradientBottom);
@ -777,15 +774,16 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
bulletin.show(true);
}
};
storyCaptionView.captionTextview.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (storyCaptionView.expanded) {
storyCaptionView.captionTextview.setOnClickListener(v -> {
if (storyCaptionView.expanded) {
if (!storyCaptionView.textSelectionHelper.isInSelectionMode()) {
storyCaptionView.collapse();
} else {
checkBlackoutMode = true;
storyCaptionView.expand();
storyCaptionView.checkCancelTextSelection();
}
} 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)));
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)));
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) {
@ -3044,6 +3055,10 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
}
public boolean closeKeyboardOrEmoji() {
if (storyCaptionView.textSelectionHelper.isInSelectionMode()) {
storyCaptionView.textSelectionHelper.clear(false);
return true;
}
if (privacyHint != null) {
privacyHint.hide();
}
@ -3149,6 +3164,7 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
//storyViewer.allowScreenshots(allowScreenshots);
} else {
cancelTextSelection();
muteIconView.clearAnimationDrawable();
viewsThumbImageReceiver = null;
isLongPressed = false;
@ -3196,6 +3212,7 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
progressToHideInterface.set(0, false);
viewsThumbImageReceiver = null;
messageSent = false;
cancelTextSelection();
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
@ -3377,6 +3394,26 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
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 BackupImageView backupImageView;
@ -3601,6 +3638,8 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
void setIsHintVisible(boolean visible);
void setIsSwiping(boolean swiping);
void setIsInSelectionMode(boolean selectionMode);
}
public class StoryItemHolder {
@ -4006,6 +4045,12 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
if (progressToHideInterface.get() != prevToHideProgress) {
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();
progressToDismiss = progressToDismissLocal;
progressToKeyboard = progressToKeyboardLocal;
@ -4014,6 +4059,7 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
return;
}
if (reactionsContainerLayout != null) {
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++) {
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 (BIG_SCREEN) {
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.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
titleView.setPadding(AndroidUtilities.dp(21), AndroidUtilities.dp(6), AndroidUtilities.dp(21), AndroidUtilities.dp(8));
addView(titleView);
recyclerListView = new RecyclerListView(context) {
@Override
@ -109,15 +108,18 @@ public class SelfStoryViewsPage extends FrameLayout implements NotificationCente
View shadowView2 = new View(getContext());
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
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
if (child == recyclerListView) {
canvas.save();
canvas.clipRect(0, AndroidUtilities.dp(TOP_PADDING), getMeasuredWidth(), getMeasuredHeight());
super.drawChild(canvas, child, drawingTime);
canvas.restore();
return true;
}
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);
// selfStoriesPreviewView.setAlpha(alpha);
PeerStoriesView currentView = storyViewer.getCurrentPeerView();
final PeerStoriesView currentView = storyViewer.getCurrentPeerView();
if (oldProgressToOpen == 1f && progressToOpen != 1f) {
currentView.selectPosition(selfStoriesPreviewView.getClosestPosition());
if (currentView != null) {
currentView.selectPosition(selfStoriesPreviewView.getClosestPosition());
}
selfStoriesPreviewView.abortScroll();
}
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.ChatMessageCell;
import org.telegram.ui.Cells.DialogCell;
import org.telegram.ui.Cells.ProfileSearchCell;
import org.telegram.ui.Cells.ReactedUserHolderView;
import org.telegram.ui.Cells.SharedPhotoVideoCell2;
import org.telegram.ui.Cells.UserCell;
@ -178,6 +179,16 @@ public class StoriesListPlaceProvider implements StoryViewer.PlaceProvider {
updateClip(holder);
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;

View file

@ -33,6 +33,7 @@ import org.telegram.messenger.UserConfig;
import org.telegram.messenger.Utilities;
import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.ActionBar.SimpleTextView;
import org.telegram.ui.ActionBar.Theme;
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.CubicBezierInterpolator;
import org.telegram.ui.Components.GradientTools;
import org.telegram.ui.Components.RecyclerListView;
import org.telegram.ui.LaunchActivity;
import java.util.Collections;
@ -247,7 +249,13 @@ public class StoriesUtilities {
if (params.drawSegments) {
checkGrayPaint();
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;
TLRPC.TL_userStories userStories = storiesController.getStories(params.dialogId);
int storiesCount;
@ -256,6 +264,16 @@ public class StoriesUtilities {
} else {
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) {
Paint localPaint = paint;
if (storiesController.hasUnreadStories(dialogId)) {
@ -267,6 +285,17 @@ public class StoriesUtilities {
startAngle = 90;
endAngle = 270;
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);
} else {
float step = 360 / (float) storiesCount;
@ -275,16 +304,7 @@ public class StoriesUtilities {
if (gapLen > step) {
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));
for (int i = 0; i < storiesCount; i++) {
@ -751,6 +771,8 @@ public class StoriesUtilities {
public int unreadState;
public int animateFromUnreadState;
public boolean drawHiddenStoriesAsSegments;
public long crossfadeToDialog;
public float crossfadeToDialogProgress;
private long dialogId;
public int currentState;
@ -792,8 +814,10 @@ public class StoriesUtilities {
float startX, startY;
Runnable longPressRunnable;
public View child;
public boolean checkOnTouchEvent(MotionEvent event, View view) {
child = view;
StoriesController storiesController = MessagesController.getInstance(UserConfig.selectedAccount).getStoriesController();
if (event.getAction() == MotionEvent.ACTION_DOWN && originalAvatarRect.contains(event.getX(), event.getY())) {
TLRPC.User user = MessagesController.getInstance(UserConfig.selectedAccount).getUser(dialogId);
@ -891,6 +915,11 @@ public class StoriesUtilities {
}
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() {

View file

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

View file

@ -49,6 +49,7 @@ import org.telegram.messenger.R;
import org.telegram.messenger.Utilities;
import org.telegram.ui.ActionBar.ActionBarPopupWindow;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Cells.TextSelectionHelper;
import org.telegram.ui.Components.AnimatedEmojiDrawable;
import org.telegram.ui.Components.AnimatedEmojiSpan;
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);
TextSelectionHelper.SimpleTextSelectionHelper textSelectionHelper;
private final SpringAnimation springAnimation;
public StoryCaptionTextView captionTextview;
@ -80,6 +83,9 @@ public class StoryCaptionView extends NestedScrollView {
private float velocitySign;
private float velocityY;
private float lastMotionX;
private float lastMotionY;
private Method abortAnimatedScrollMethod;
private OverScroller scroller;
@ -109,11 +115,8 @@ public class StoryCaptionView extends NestedScrollView {
NotificationCenter.listenEmojiLoading(this);
captionTextview = new StoryCaptionTextView(getContext(), resourcesProvider);
//captionTextview.setTextIsSelectable(true);
//captionTextview.setPadding(AndroidUtilities.dp(16), AndroidUtilities.dp(8), AndroidUtilities.dp(16), AndroidUtilities.dp(8));
textSelectionHelper = new TextSelectionHelper.SimpleTextSelectionHelper(captionTextview, resourcesProvider);
textSelectionHelper.useMovingOffset = false;
captionContainer.addView(captionTextview, 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);
textSelectionHelper.invalidate();
return true;
}
@ -359,6 +363,7 @@ public class StoryCaptionView extends NestedScrollView {
}
}
}
textSelectionHelper.invalidate();
}
private void startSpringAnimationIfNotRunning(float velocityY) {
@ -466,6 +471,7 @@ public class StoryCaptionView extends NestedScrollView {
if (getParent() != null) {
((View) getParent()).invalidate();
}
textSelectionHelper.invalidate();
}
public float getProgressToBlackout() {
@ -539,7 +545,13 @@ public class StoryCaptionView extends NestedScrollView {
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 LinkSpanDrawable<CharacterStyle> pressedLink;
@ -561,7 +573,6 @@ public class StoryCaptionView extends NestedScrollView {
int textHeight;
float textX;
float textY;
boolean expanded = false;
float progressToExpand;
float showMoreY;
float showMoreX;
@ -621,7 +632,11 @@ public class StoryCaptionView extends NestedScrollView {
// invalidateSpoilers();
this.text = text;
sizeCached = 0;
if (getMeasuredWidth() > 0) {
createLayout(getMeasuredWidth());
}
requestLayout();
invalidate();
}
@SuppressLint("DrawAllocation")
@ -632,65 +647,69 @@ public class StoryCaptionView extends NestedScrollView {
verticalPadding = AndroidUtilities.dp(8);
if (sizeCached != size) {
sizeCached = size;
int width = MeasureSpec.getSize(widthMeasureSpec) - 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 = 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);
}
createLayout(MeasureSpec.getSize(widthMeasureSpec));
}
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
protected void onDraw(Canvas canvas) {
if (showMore != null) {
@ -710,12 +729,21 @@ public class StoryCaptionView extends NestedScrollView {
if (fullLayout != null) {
canvas.save();
canvas.translate(textX, textY);
if (textSelectionHelper.isInSelectionMode()) {
textSelectionHelper.draw(canvas);
}
drawLayout(fullLayout, canvas);
fullLayoutEmoji = AnimatedEmojiSpan.update(AnimatedEmojiDrawable.CACHE_TYPE_MESSAGES, this, fullLayoutEmoji, fullLayout);
AnimatedEmojiSpan.drawAnimatedEmojis(canvas, fullLayout, fullLayoutEmoji, 0, spoilers, 0, 0, 0, 1f, emojiColorFilter);
canvas.restore();
}
} else {
if (textSelectionHelper.isInSelectionMode()) {
canvas.save();
canvas.translate(textX, textY);
textSelectionHelper.draw(canvas);
canvas.restore();
}
if (firstLayout != null) {
canvas.save();
canvas.translate(textX, textY);
@ -793,6 +821,16 @@ public class StoryCaptionView extends NestedScrollView {
return textPaint;
}
@Override
public CharSequence getText() {
return text;
}
@Override
public StaticLayout getStaticTextLayout() {
return fullLayout;
}
public class LineInfo {
private AnimatedEmojiSpan.EmojiGroupedSpans layoutEmoji;
StaticLayout staticLayout;
@ -926,6 +964,8 @@ public class StoryCaptionView extends NestedScrollView {
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
boolean allowIntercept = true;
lastMotionX = event.getX();
lastMotionY = event.getY();
if (showMore != null) {
AndroidUtilities.rectTmp.set(showMoreX , showMoreY, showMoreX + showMore.getWidth(), showMoreY + showMore.getHeight());
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 && (expanded || firstLayout == null)) {
// textSelectionHelper.update(textX, textY);
// textSelectionHelper.onTouchEvent(event);
// }
return super.dispatchTouchEvent(event);
}
}

View file

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

View file

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

View file

@ -315,6 +315,17 @@ public class StoryEntry extends IStoryPart {
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) {
clearFilter();
@ -329,6 +340,9 @@ public class StoryEntry extends IStoryPart {
Bitmap bitmap = filterView.getBitmap();
if (bitmap == null) {
if (whenDone != null) {
whenDone.run();
}
return;
}
@ -345,11 +359,13 @@ public class StoryEntry extends IStoryPart {
if (filterFile != null && filterFile.exists()) {
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) {
try {
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) {
FileLog.e(e);
}
@ -358,14 +374,16 @@ public class StoryEntry extends IStoryPart {
Utilities.themeQueue.postRunnable(() -> {
try {
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) {
FileLog.e(e, false);
try {
FileOutputStream stream = new FileOutputStream(filterFile);
rotatedBitmap.compress(Bitmap.CompressFormat.PNG, 90, stream);
} catch (Exception e2) {
FileLog.e(e2, false);
if (supportTransparent) {
try {
FileOutputStream stream = new FileOutputStream(filterFile);
rotatedBitmap.compress(Bitmap.CompressFormat.PNG, 90, stream);
} catch (Exception e2) {
FileLog.e(e2, false);
}
}
}
rotatedBitmap.recycle();

View file

@ -244,7 +244,7 @@ public class StoryRecorder implements NotificationCenter.NotificationCenterDeleg
SourceView src = new SourceView() {
@Override
protected void show() {
PeerStoriesView peerView = storyViewer.getCurrentPeerView();
final PeerStoriesView peerView = storyViewer.getCurrentPeerView();
if (peerView != null) {
peerView.animateOut(false);
}
@ -256,7 +256,7 @@ public class StoryRecorder implements NotificationCenter.NotificationCenterDeleg
@Override
protected void hide() {
PeerStoriesView peerView = storyViewer.getCurrentPeerView();
final PeerStoriesView peerView = storyViewer.getCurrentPeerView();
if (peerView != null) {
peerView.animateOut(true);
}
@ -267,7 +267,7 @@ public class StoryRecorder implements NotificationCenter.NotificationCenterDeleg
}
src.type = 1;
src.rounding = dp(8);
PeerStoriesView peerView = storyViewer.getCurrentPeerView();
final PeerStoriesView peerView = storyViewer.getCurrentPeerView();
if (peerView != null) {
src.view = peerView.storyContainer;
}
@ -3434,7 +3434,7 @@ public class StoryRecorder implements NotificationCenter.NotificationCenterDeleg
captionEdit.keyboardNotifier.ignore(toMode != EDIT_MODE_NONE);
// privacySelectorHint.hide();
Bulletin.hideVisible();
if (photoFilterView != null && toMode == EDIT_MODE_FILTER) {
if (photoFilterView != null && fromMode == EDIT_MODE_FILTER) {
applyFilter(null);
}
if (photoFilterEnhanceView != null) {
@ -3518,8 +3518,19 @@ public class StoryRecorder implements NotificationCenter.NotificationCenterDeleg
return;
}
Bitmap photoBitmap = previewView.getPhotoBitmap();
if (photoBitmap == null) {
Bitmap 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;
}

View file

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

View file

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