mirror of
https://github.com/DrKLO/Telegram.git
synced 2024-12-21 22:15:16 +01:00
update to 9.7.2 (3705)
This commit is contained in:
parent
65f01a70e7
commit
f10844350d
106 changed files with 2383 additions and 871 deletions
|
@ -1,6 +1,9 @@
|
|||
package org.telegram;
|
||||
|
||||
import org.telegram.messenger.FileLog;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.PriorityBlockingQueue;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
@ -21,8 +24,21 @@ public class DispatchQueuePriority {
|
|||
}
|
||||
return priority2 - priority1;
|
||||
}
|
||||
}));
|
||||
})) {
|
||||
@Override
|
||||
protected void beforeExecute(Thread t, Runnable r) {
|
||||
CountDownLatch latch = pauseLatch;
|
||||
if (latch != null) {
|
||||
try {
|
||||
latch.await();
|
||||
} catch (InterruptedException e) {
|
||||
FileLog.e(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private volatile CountDownLatch pauseLatch;
|
||||
|
||||
public DispatchQueuePriority(String threadName) {
|
||||
|
||||
|
@ -41,15 +57,11 @@ public class DispatchQueuePriority {
|
|||
}
|
||||
|
||||
public Runnable postRunnable(Runnable runnable, int priority) {
|
||||
if (priority == 1) {
|
||||
postRunnable(runnable);
|
||||
return runnable;
|
||||
} else {
|
||||
PriorityRunnable priorityRunnable = new PriorityRunnable(priority, runnable);
|
||||
|
||||
threadPoolExecutor.execute(priorityRunnable);
|
||||
return priorityRunnable;
|
||||
if (priority != 1) {
|
||||
runnable = new PriorityRunnable(priority, runnable);
|
||||
}
|
||||
postRunnable(runnable);
|
||||
return runnable;
|
||||
}
|
||||
|
||||
public void cancelRunnable(Runnable runnable) {
|
||||
|
@ -57,7 +69,20 @@ public class DispatchQueuePriority {
|
|||
return;
|
||||
}
|
||||
threadPoolExecutor.remove(runnable);
|
||||
}
|
||||
|
||||
public void pause() {
|
||||
if (pauseLatch == null) {
|
||||
pauseLatch = new CountDownLatch(1);
|
||||
}
|
||||
}
|
||||
|
||||
public void resume() {
|
||||
CountDownLatch latch = pauseLatch;
|
||||
if (latch != null) {
|
||||
latch.countDown();
|
||||
pauseLatch = null;
|
||||
}
|
||||
}
|
||||
|
||||
private static class PriorityRunnable implements Runnable {
|
||||
|
|
|
@ -99,7 +99,6 @@ import android.view.inputmethod.InputMethodSubtype;
|
|||
import android.view.inspector.WindowInspector;
|
||||
import android.webkit.MimeTypeMap;
|
||||
import android.widget.EdgeEffect;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.HorizontalScrollView;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
|
@ -123,7 +122,6 @@ import androidx.viewpager.widget.ViewPager;
|
|||
|
||||
import com.android.internal.telephony.ITelephony;
|
||||
import com.google.android.exoplayer2.util.Consumer;
|
||||
import com.google.android.exoplayer2.util.Log;
|
||||
import com.google.android.gms.auth.api.phone.SmsRetriever;
|
||||
import com.google.android.gms.auth.api.phone.SmsRetrieverClient;
|
||||
import com.google.android.gms.tasks.Task;
|
||||
|
@ -155,7 +153,6 @@ import org.telegram.ui.Components.MotionBackgroundDrawable;
|
|||
import org.telegram.ui.Components.PickerBottomLayout;
|
||||
import org.telegram.ui.Components.RecyclerListView;
|
||||
import org.telegram.ui.Components.ShareAlert;
|
||||
import org.telegram.ui.Components.SizeNotifierFrameLayout;
|
||||
import org.telegram.ui.Components.TypefaceSpan;
|
||||
import org.telegram.ui.Components.URLSpanReplacement;
|
||||
import org.telegram.ui.Components.UndoView;
|
||||
|
@ -177,7 +174,6 @@ 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;
|
||||
|
@ -196,7 +192,6 @@ import java.util.Hashtable;
|
|||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
@ -590,7 +585,7 @@ public class AndroidUtilities {
|
|||
}
|
||||
|
||||
public static void removeFromParent(View child) {
|
||||
if (child.getParent() != null) {
|
||||
if (child != null && child.getParent() != null) {
|
||||
((ViewGroup) child.getParent()).removeView(child);
|
||||
}
|
||||
}
|
||||
|
@ -2750,6 +2745,39 @@ public class AndroidUtilities {
|
|||
return new SpannableStringBuilder(str);
|
||||
}
|
||||
|
||||
private static Pattern linksPattern;
|
||||
public static SpannableStringBuilder replaceLinks(String str, Theme.ResourcesProvider resourcesProvider) {
|
||||
if (linksPattern == null) {
|
||||
linksPattern = Pattern.compile("\\[(.+?)\\]\\((.+?)\\)");
|
||||
}
|
||||
SpannableStringBuilder spannable = new SpannableStringBuilder();
|
||||
Matcher matcher = linksPattern.matcher(str);
|
||||
int lastMatchEnd = 0;
|
||||
while (matcher.find()) {
|
||||
spannable.append(str, lastMatchEnd, matcher.start());
|
||||
String linkText = matcher.group(1);
|
||||
String url = matcher.group(2);
|
||||
spannable.append(linkText);
|
||||
int start = spannable.length() - linkText.length();
|
||||
int end = spannable.length();
|
||||
spannable.setSpan(new ClickableSpan() {
|
||||
@Override
|
||||
public void onClick(@NonNull View widget) {
|
||||
Browser.openUrl(ApplicationLoader.applicationContext, url);
|
||||
}
|
||||
@Override
|
||||
public void updateDrawState(@NonNull TextPaint ds) {
|
||||
ds.setColor(Theme.getColor(Theme.key_chat_messageLinkIn, resourcesProvider));
|
||||
ds.setUnderlineText(false);
|
||||
}
|
||||
}, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
|
||||
lastMatchEnd = matcher.end();
|
||||
}
|
||||
spannable.append(str, lastMatchEnd, str.length());
|
||||
return spannable;
|
||||
}
|
||||
|
||||
public static class LinkMovementMethodMy extends LinkMovementMethod {
|
||||
@Override
|
||||
public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) {
|
||||
|
@ -5324,4 +5352,12 @@ public class AndroidUtilities {
|
|||
} catch (Exception ignore) {}
|
||||
return "";
|
||||
}
|
||||
|
||||
public static void quietSleep(long millis) {
|
||||
try {
|
||||
Thread.sleep(millis);
|
||||
} catch (InterruptedException ignored) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 = 3687;
|
||||
public static String BUILD_VERSION_STRING = "9.7.0";
|
||||
public static int BUILD_VERSION = 3705;
|
||||
public static String BUILD_VERSION_STRING = "9.7.2";
|
||||
public static int APP_ID = 4;
|
||||
public static String APP_HASH = "014b35b6184100b085b0d0572f9b5103";
|
||||
|
||||
|
|
|
@ -11,17 +11,21 @@ package org.telegram.messenger;
|
|||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.os.Process;
|
||||
import android.os.SystemClock;
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
public class DispatchQueue extends Thread {
|
||||
|
||||
private static final int THREAD_PRIORITY_DEFAULT = -1000;
|
||||
|
||||
private volatile Handler handler = null;
|
||||
private CountDownLatch syncLatch = new CountDownLatch(1);
|
||||
private long lastTaskTime;
|
||||
private static int indexPointer = 0;
|
||||
public final int index = indexPointer++;
|
||||
private int priority = THREAD_PRIORITY_DEFAULT;
|
||||
|
||||
public DispatchQueue(final String threadName) {
|
||||
this(threadName, true);
|
||||
|
@ -34,6 +38,14 @@ public class DispatchQueue extends Thread {
|
|||
}
|
||||
}
|
||||
|
||||
public DispatchQueue(final String threadName, boolean start, int priority) {
|
||||
this.priority = priority;
|
||||
setName(threadName);
|
||||
if (start) {
|
||||
start();
|
||||
}
|
||||
}
|
||||
|
||||
public void sendMessage(Message msg, int delay) {
|
||||
try {
|
||||
syncLatch.await();
|
||||
|
@ -114,6 +126,9 @@ public class DispatchQueue extends Thread {
|
|||
return true;
|
||||
});
|
||||
syncLatch.countDown();
|
||||
if (priority != THREAD_PRIORITY_DEFAULT) {
|
||||
Process.setThreadPriority(priority);
|
||||
}
|
||||
Looper.loop();
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,8 @@ import android.util.SparseIntArray;
|
|||
|
||||
import androidx.annotation.UiThread;
|
||||
|
||||
import org.telegram.ui.Components.Reactions.HwEmojis;
|
||||
|
||||
import java.util.LinkedList;
|
||||
|
||||
public class DispatchQueuePool {
|
||||
|
@ -68,6 +70,11 @@ public class DispatchQueuePool {
|
|||
busyQueues.add(queue);
|
||||
int count = busyQueuesMap.get(queue.index, 0);
|
||||
busyQueuesMap.put(queue.index, count + 1);
|
||||
if (HwEmojis.isHwEnabled()) {
|
||||
queue.setPriority(Thread.MIN_PRIORITY);
|
||||
} else if (queue.getPriority() != Thread.MAX_PRIORITY) {
|
||||
queue.setPriority(Thread.MAX_PRIORITY);
|
||||
}
|
||||
queue.postRunnable(() -> {
|
||||
runnable.run();
|
||||
AndroidUtilities.runOnUIThread(() -> {
|
||||
|
|
|
@ -5,6 +5,8 @@ import android.util.SparseIntArray;
|
|||
|
||||
import androidx.annotation.UiThread;
|
||||
|
||||
import org.telegram.ui.Components.Reactions.HwEmojis;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class DispatchQueuePoolBackground {
|
||||
|
@ -77,6 +79,11 @@ public class DispatchQueuePoolBackground {
|
|||
busyQueues.add(queue);
|
||||
int count = busyQueuesMap.get(queue.index, 0);
|
||||
busyQueuesMap.put(queue.index, count + 1);
|
||||
if(HwEmojis.isHwEnabled()) {
|
||||
queue.setPriority(Thread.MIN_PRIORITY);
|
||||
} else if (queue.getPriority() != Thread.MAX_PRIORITY) {
|
||||
queue.setPriority(Thread.MAX_PRIORITY);
|
||||
}
|
||||
queue.postRunnable(() -> {
|
||||
runnable.run();
|
||||
Utilities.globalQueue.postRunnable(() -> {
|
||||
|
|
|
@ -638,7 +638,7 @@ public class FileLoadOperation {
|
|||
final CountDownLatch countDownLatch = new CountDownLatch(1);
|
||||
final File[] result = new File[1];
|
||||
Utilities.stageQueue.postRunnable(() -> {
|
||||
if (state == stateFinished) {
|
||||
if (state == stateFinished && !preloadFinished) {
|
||||
result[0] = cacheFileFinal;
|
||||
} else {
|
||||
result[0] = cacheFileTemp;
|
||||
|
@ -654,7 +654,7 @@ public class FileLoadOperation {
|
|||
}
|
||||
|
||||
protected File getCurrentFileFast() {
|
||||
if (state == stateFinished) {
|
||||
if (state == stateFinished && !preloadFinished) {
|
||||
return cacheFileFinal;
|
||||
} else {
|
||||
return cacheFileTemp;
|
||||
|
|
|
@ -938,7 +938,7 @@ public class FileLoader extends BaseController {
|
|||
}
|
||||
|
||||
loaderQueue.add(operation);
|
||||
loaderQueue.checkLoadingOperations();
|
||||
loaderQueue.checkLoadingOperations(operation.isStory && priority >= PRIORITY_HIGH);
|
||||
|
||||
if (BuildVars.LOGS_ENABLED) {
|
||||
FileLog.d("create load operation fileName=" + finalFileName + " documentName=" + getDocumentFileName(document) + "size=" + AndroidUtilities.formatFileSize(operation.totalBytesCount) + " position in queue " + operation.getPositionInQueue() + " account=" + currentAccount);
|
||||
|
|
|
@ -69,6 +69,15 @@ public class FileLoaderPriorityQueue {
|
|||
}
|
||||
|
||||
public void checkLoadingOperations() {
|
||||
checkLoadingOperations(false);
|
||||
}
|
||||
|
||||
public void checkLoadingOperations(boolean immediate) {
|
||||
if (immediate) {
|
||||
workerQueue.cancelRunnable(checkOperationsRunnable);
|
||||
checkOperationsRunnable.run();
|
||||
return;
|
||||
}
|
||||
if (checkOperationsScheduled) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ import org.telegram.messenger.time.FastDateFormat;
|
|||
import org.telegram.messenger.video.MediaCodecVideoConvertor;
|
||||
import org.telegram.tgnet.TLObject;
|
||||
import org.telegram.tgnet.TLRPC;
|
||||
import org.telegram.ui.Components.AnimatedFileDrawable;
|
||||
import org.telegram.ui.LaunchActivity;
|
||||
|
||||
import java.io.File;
|
||||
|
@ -170,7 +171,7 @@ public class FileLog {
|
|||
excludeRequests.add("TL_upload_getFile");
|
||||
excludeRequests.add("TL_upload_a");
|
||||
|
||||
gson = new GsonBuilder().addSerializationExclusionStrategy(new ExclusionStrategy() {
|
||||
ExclusionStrategy strategy = new ExclusionStrategy() {
|
||||
|
||||
@Override
|
||||
public boolean shouldSkipField(FieldAttributes f) {
|
||||
|
@ -182,12 +183,10 @@ public class FileLog {
|
|||
|
||||
@Override
|
||||
public boolean shouldSkipClass(Class<?> clazz) {
|
||||
if (clazz.isInstance(ColorStateList.class) || clazz.isInstance(Context.class)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return clazz.isInstance(AnimatedFileDrawable.class) || clazz.isInstance(ColorStateList.class) || clazz.isInstance(Context.class);
|
||||
}
|
||||
}).registerTypeAdapterFactory(RuntimeClassNameTypeAdapterFactory.of(TLObject.class, "type_")).create();
|
||||
};
|
||||
gson = new GsonBuilder().addSerializationExclusionStrategy(strategy).registerTypeAdapterFactory(RuntimeClassNameTypeAdapterFactory.of(TLObject.class, "type_", strategy)).create();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1059,19 +1059,21 @@ public class FileRefController extends BaseController {
|
|||
Object arg = requester.args[1];
|
||||
if (arg instanceof FileLoadOperation) {
|
||||
FileLoadOperation operation = (FileLoadOperation) requester.args[1];
|
||||
TLRPC.StoryItem storyItem = (TLRPC.StoryItem) operation.parentObject;
|
||||
if (newStoryItem == null) {
|
||||
TLRPC.TL_updateStory story = new TLRPC.TL_updateStory();
|
||||
story.user_id = storyItem.dialogId;
|
||||
story.story = new TLRPC.TL_storyItemDeleted();
|
||||
story.story.id = storyItem.id;
|
||||
ArrayList<TLRPC.Update> updates = new ArrayList<>();
|
||||
updates.add(story);
|
||||
getMessagesController().processUpdateArray(updates, null, null, false, 0);
|
||||
} else {
|
||||
TLRPC.User user = getMessagesController().getUser(storyItem.dialogId);
|
||||
if (user != null && user.contact) {
|
||||
MessagesController.getInstance(currentAccount).getStoriesController().getStoriesStorage().updateStoryItem(storyItem.dialogId, newStoryItem);
|
||||
if (operation.parentObject instanceof TLRPC.StoryItem) {
|
||||
TLRPC.StoryItem storyItem = (TLRPC.StoryItem) operation.parentObject;
|
||||
if (newStoryItem == null) {
|
||||
TLRPC.TL_updateStory story = new TLRPC.TL_updateStory();
|
||||
story.user_id = storyItem.dialogId;
|
||||
story.story = new TLRPC.TL_storyItemDeleted();
|
||||
story.story.id = storyItem.id;
|
||||
ArrayList<TLRPC.Update> updates = new ArrayList<>();
|
||||
updates.add(story);
|
||||
getMessagesController().processUpdateArray(updates, null, null, false, 0);
|
||||
} else {
|
||||
TLRPC.User user = getMessagesController().getUser(storyItem.dialogId);
|
||||
if (user != null && user.contact) {
|
||||
MessagesController.getInstance(currentAccount).getStoriesController().getStoriesStorage().updateStoryItem(storyItem.dialogId, newStoryItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import java.io.EOFException;
|
|||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
|
@ -141,8 +142,16 @@ public class FileStreamLoadOperation extends BaseDataSource implements FileLoadO
|
|||
countDownLatch = null;
|
||||
}
|
||||
}
|
||||
if (file == null) {
|
||||
currentFile = loadOperation.getCurrentFile();
|
||||
File currentFileFast = loadOperation.getCurrentFileFast();
|
||||
if (file == null || !Objects.equals(currentFile, currentFileFast)) {
|
||||
if (file != null) {
|
||||
try {
|
||||
file.close();
|
||||
} catch (Exception ignore) {
|
||||
|
||||
}
|
||||
}
|
||||
currentFile = currentFileFast;
|
||||
if (currentFile != null) {
|
||||
try {
|
||||
file = new RandomAccessFile(currentFile, "r");
|
||||
|
|
|
@ -52,6 +52,7 @@ 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;
|
||||
|
||||
|
@ -171,6 +172,10 @@ public class ImageLoader {
|
|||
return null;
|
||||
}
|
||||
|
||||
public static boolean isSdCardPath(File videoFile) {
|
||||
return !TextUtils.isEmpty(SharedConfig.storageCacheDir) && videoFile.getAbsolutePath().startsWith(SharedConfig.storageCacheDir);
|
||||
}
|
||||
|
||||
public void moveToFront(String key) {
|
||||
if (key == null) {
|
||||
return;
|
||||
|
@ -3291,6 +3296,9 @@ public class ImageLoader {
|
|||
}
|
||||
|
||||
public void loadImageForImageReceiver(ImageReceiver imageReceiver) {
|
||||
loadImageForImageReceiver(imageReceiver, null);
|
||||
}
|
||||
public void loadImageForImageReceiver(ImageReceiver imageReceiver, List<ImageReceiver> preloadReceiver) {
|
||||
if (imageReceiver == null) {
|
||||
return;
|
||||
}
|
||||
|
@ -3300,24 +3308,26 @@ public class ImageLoader {
|
|||
int guid = imageReceiver.getNewGuid();
|
||||
if (mediaKey != null) {
|
||||
ImageLocation mediaLocation = imageReceiver.getMediaLocation();
|
||||
Drawable drawable;
|
||||
if (useLottieMemCache(mediaLocation, mediaKey)) {
|
||||
drawable = getFromLottieCache(mediaKey);
|
||||
} else {
|
||||
drawable = memCache.get(mediaKey);
|
||||
if (drawable != null) {
|
||||
memCache.moveToFront(mediaKey);
|
||||
}
|
||||
if (drawable == null) {
|
||||
drawable = smallImagesMemCache.get(mediaKey);
|
||||
Drawable drawable = findInPreloadImageReceivers(mediaKey, preloadReceiver);
|
||||
if (drawable == null) {
|
||||
if (useLottieMemCache(mediaLocation, mediaKey)) {
|
||||
drawable = getFromLottieCache(mediaKey);
|
||||
} else {
|
||||
drawable = memCache.get(mediaKey);
|
||||
if (drawable != null) {
|
||||
smallImagesMemCache.moveToFront(mediaKey);
|
||||
memCache.moveToFront(mediaKey);
|
||||
}
|
||||
}
|
||||
if (drawable == null) {
|
||||
drawable = wallpaperMemCache.get(mediaKey);
|
||||
if (drawable != null) {
|
||||
wallpaperMemCache.moveToFront(mediaKey);
|
||||
if (drawable == null) {
|
||||
drawable = smallImagesMemCache.get(mediaKey);
|
||||
if (drawable != null) {
|
||||
smallImagesMemCache.moveToFront(mediaKey);
|
||||
}
|
||||
}
|
||||
if (drawable == null) {
|
||||
drawable = wallpaperMemCache.get(mediaKey);
|
||||
if (drawable != null) {
|
||||
wallpaperMemCache.moveToFront(mediaKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3342,8 +3352,8 @@ public class ImageLoader {
|
|||
String imageKey = imageReceiver.getImageKey();
|
||||
if (!imageSet && imageKey != null) {
|
||||
ImageLocation imageLocation = imageReceiver.getImageLocation();
|
||||
Drawable drawable = null;
|
||||
if (useLottieMemCache(imageLocation, imageKey)) {
|
||||
Drawable drawable = findInPreloadImageReceivers(imageKey, preloadReceiver);
|
||||
if (drawable == null && useLottieMemCache(imageLocation, imageKey)) {
|
||||
drawable = getFromLottieCache(imageKey);
|
||||
}
|
||||
if (drawable == null) {
|
||||
|
@ -3599,6 +3609,22 @@ public class ImageLoader {
|
|||
}
|
||||
}
|
||||
|
||||
private Drawable findInPreloadImageReceivers(String imageKey, List<ImageReceiver> receivers) {
|
||||
if (receivers == null) {
|
||||
return null;
|
||||
}
|
||||
for (int i = 0; i < receivers.size(); i++) {
|
||||
ImageReceiver receiver = receivers.get(i);
|
||||
if (imageKey.equals(receiver.getImageKey())) {
|
||||
return receiver.getImageDrawable();
|
||||
}
|
||||
if (imageKey.equals(receiver.getMediaKey())) {
|
||||
return receiver.getMediaDrawable();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private BitmapDrawable getFromLottieCache(String imageKey) {
|
||||
BitmapDrawable drawable = lottieMemCache.get(imageKey);
|
||||
if (drawable instanceof AnimatedFileDrawable) {
|
||||
|
|
|
@ -43,9 +43,12 @@ import org.telegram.ui.Components.RecyclableDrawable;
|
|||
import org.telegram.ui.Components.VectorAvatarThumbDrawable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class ImageReceiver implements NotificationCenter.NotificationCenterDelegate {
|
||||
|
||||
List<ImageReceiver> preloadReceivers;
|
||||
public boolean updateThumbShaderMatrix() {
|
||||
if (currentThumbDrawable != null && thumbShader != null) {
|
||||
drawDrawable(null, currentThumbDrawable, 255, thumbShader, 0, 0, 0, null);
|
||||
|
@ -58,6 +61,18 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
|
|||
return false;
|
||||
}
|
||||
|
||||
public void setPreloadingReceivers(List<ImageReceiver> preloadReceivers) {
|
||||
this.preloadReceivers = preloadReceivers;
|
||||
}
|
||||
|
||||
public Drawable getImageDrawable() {
|
||||
return currentImageDrawable;
|
||||
}
|
||||
|
||||
public Drawable getMediaDrawable() {
|
||||
return currentMediaDrawable;
|
||||
}
|
||||
|
||||
public interface ImageReceiverDelegate {
|
||||
void didSetImage(ImageReceiver imageReceiver, boolean set, boolean thumb, boolean memCache);
|
||||
|
||||
|
@ -706,7 +721,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
|
|||
}
|
||||
|
||||
private void loadImage() {
|
||||
ImageLoader.getInstance().loadImageForImageReceiver(this);
|
||||
ImageLoader.getInstance().loadImageForImageReceiver(this, preloadReceivers);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
|
@ -1047,6 +1062,12 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
|
|||
if (setImageBackup != null && setImageBackup.isSet()) {
|
||||
SetImageBackup temp = setImageBackup;
|
||||
setImageBackup = null;
|
||||
if (temp.thumb instanceof BitmapDrawable) {
|
||||
BitmapDrawable bitmapDrawable = (BitmapDrawable) temp.thumb;
|
||||
if (!(bitmapDrawable instanceof RLottieDrawable) && !(bitmapDrawable instanceof AnimatedFileDrawable) && bitmapDrawable.getBitmap() != null && bitmapDrawable.getBitmap().isRecycled()) {
|
||||
temp.thumb = null;
|
||||
}
|
||||
}
|
||||
setImage(temp.mediaLocation, temp.mediaFilter, temp.imageLocation, temp.imageFilter, temp.thumbLocation, temp.thumbFilter, temp.thumb, temp.size, temp.ext, temp.parentObject, temp.cacheType);
|
||||
temp.clear();
|
||||
setImageBackup = temp;
|
||||
|
|
|
@ -17508,7 +17508,10 @@ public class MessagesController extends BaseController implements NotificationCe
|
|||
reason = getRestrictionReason(user.restriction_reason);
|
||||
if (type != 3 && user.bot) {
|
||||
type = 1;
|
||||
closeLast = true;
|
||||
BaseFragment lastFragment = LaunchActivity.getLastFragment();
|
||||
if (!(lastFragment.storyViewer != null && lastFragment.storyViewer.isShown())) {
|
||||
closeLast = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (reason != null) {
|
||||
|
|
|
@ -22,8 +22,6 @@ import android.util.SparseIntArray;
|
|||
import androidx.annotation.UiThread;
|
||||
import androidx.collection.LongSparseArray;
|
||||
|
||||
import com.google.android.exoplayer2.util.Log;
|
||||
|
||||
import org.telegram.PhoneFormat.PhoneFormat;
|
||||
import org.telegram.SQLite.SQLiteCursor;
|
||||
import org.telegram.SQLite.SQLiteDatabase;
|
||||
|
|
|
@ -3708,7 +3708,11 @@ public class NotificationsController extends BaseController {
|
|||
} else if (names.isEmpty()) {
|
||||
msg.message = "";
|
||||
} else if (names.size() == 1) {
|
||||
msg.message = LocaleController.formatPluralString("StoryNotification1", storiesCount, names.get(0));
|
||||
if (storiesCount == 1) {
|
||||
msg.message = LocaleController.getString("StoryNotificationSingle");
|
||||
} else {
|
||||
msg.message = LocaleController.formatPluralString("StoryNotification1", storiesCount, names.get(0));
|
||||
}
|
||||
} else if (names.size() == 2) {
|
||||
msg.message = LocaleController.formatString(R.string.StoryNotification2, names.get(0), names.get(1));
|
||||
} else if (names.size() == 3 && storyPushMessages.size() == 3) {
|
||||
|
@ -4682,7 +4686,11 @@ public class NotificationsController extends BaseController {
|
|||
} else if (names.isEmpty()) {
|
||||
continue;
|
||||
} else if (names.size() == 1) {
|
||||
text.append(LocaleController.formatPluralString("StoryNotification1", storiesCount, names.get(0)));
|
||||
if (storiesCount == 1) {
|
||||
text.append(LocaleController.getString("StoryNotificationSingle"));
|
||||
} else {
|
||||
text.append(LocaleController.formatPluralString("StoryNotification1", storiesCount, names.get(0)));
|
||||
}
|
||||
} else if (names.size() == 2) {
|
||||
text.append(LocaleController.formatString(R.string.StoryNotification2, names.get(0), names.get(1)));
|
||||
} else if (names.size() == 3 && storyPushMessages.size() == 3) {
|
||||
|
|
|
@ -459,7 +459,7 @@ public class PushListenerController {
|
|||
} else {
|
||||
switch (loc_key) {
|
||||
case "STORY_NOTEXT": {
|
||||
messageText = LocaleController.formatPluralString("StoryNotification1", 1, args[0]);
|
||||
messageText = LocaleController.getString("StoryNotificationSingle");
|
||||
message1 = null;
|
||||
msg_id = story_id;
|
||||
break;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package org.telegram.messenger;
|
||||
|
||||
import com.google.gson.ExclusionStrategy;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
|
@ -114,21 +115,23 @@ public final class RuntimeClassNameTypeAdapterFactory<T> implements TypeAdapterF
|
|||
private final String typeFieldName;
|
||||
private final Map<String, Class<?>> labelToSubtype = new LinkedHashMap<String, Class<?>>();
|
||||
private final Map<Class<?>, String> subtypeToLabel = new LinkedHashMap<Class<?>, String>();
|
||||
private final ExclusionStrategy exclusionStrategy;
|
||||
|
||||
private RuntimeClassNameTypeAdapterFactory(Class<?> baseType, String typeFieldName) {
|
||||
private RuntimeClassNameTypeAdapterFactory(Class<?> baseType, String typeFieldName, ExclusionStrategy exclusionStrategy) {
|
||||
if (typeFieldName == null || baseType == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
this.baseType = baseType;
|
||||
this.typeFieldName = typeFieldName;
|
||||
this.exclusionStrategy = exclusionStrategy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new runtime type adapter using for {@code baseType} using {@code
|
||||
* typeFieldName} as the type field name. Type field names are case sensitive.
|
||||
*/
|
||||
public static <T> RuntimeClassNameTypeAdapterFactory<T> of(Class<T> baseType, String typeFieldName) {
|
||||
return new RuntimeClassNameTypeAdapterFactory<T>(baseType, typeFieldName);
|
||||
public static <T> RuntimeClassNameTypeAdapterFactory<T> of(Class<T> baseType, String typeFieldName, ExclusionStrategy exclusionStrategy) {
|
||||
return new RuntimeClassNameTypeAdapterFactory<T>(baseType, typeFieldName, exclusionStrategy);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -136,7 +139,7 @@ public final class RuntimeClassNameTypeAdapterFactory<T> implements TypeAdapterF
|
|||
* the type field name.
|
||||
*/
|
||||
public static <T> RuntimeClassNameTypeAdapterFactory<T> of(Class<T> baseType) {
|
||||
return new RuntimeClassNameTypeAdapterFactory<T>(baseType, "class");
|
||||
return new RuntimeClassNameTypeAdapterFactory<T>(baseType, "class", null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -171,6 +174,9 @@ public final class RuntimeClassNameTypeAdapterFactory<T> implements TypeAdapterF
|
|||
|
||||
public <R> TypeAdapter<R> create(Gson gson, TypeToken<R> type) {
|
||||
|
||||
if (exclusionStrategy.shouldSkipClass(type.getRawType().getClass())) {
|
||||
return null;
|
||||
}
|
||||
final Map<String, TypeAdapter<?>> labelToDelegate
|
||||
= new LinkedHashMap<String, TypeAdapter<?>>();
|
||||
final Map<Class<?>, TypeAdapter<?>> subtypeToDelegate
|
||||
|
|
|
@ -436,6 +436,7 @@ public class CameraController implements MediaRecorder.OnInfoListener {
|
|||
if (!ignoreOrientation && orientation != -1) {
|
||||
matrix.setRotate(orientation);
|
||||
}
|
||||
orientation = 0;
|
||||
matrix.postScale(-1, 1);
|
||||
Bitmap scaled = Bitmaps.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
|
||||
if (scaled != bitmap) {
|
||||
|
|
|
@ -60,9 +60,11 @@ import androidx.interpolator.view.animation.FastOutSlowInInterpolator;
|
|||
import com.google.zxing.common.detector.MathUtils;
|
||||
|
||||
import org.telegram.messenger.AndroidUtilities;
|
||||
import org.telegram.messenger.ApplicationLoader;
|
||||
import org.telegram.messenger.BuildVars;
|
||||
import org.telegram.messenger.DispatchQueue;
|
||||
import org.telegram.messenger.FileLog;
|
||||
import org.telegram.messenger.ImageLoader;
|
||||
import org.telegram.messenger.MessagesController;
|
||||
import org.telegram.messenger.R;
|
||||
import org.telegram.messenger.SharedConfig;
|
||||
|
@ -77,6 +79,7 @@ import org.telegram.ui.Components.LayoutHelper;
|
|||
import org.telegram.ui.Components.RLottieDrawable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
@ -96,6 +99,8 @@ import javax.microedition.khronos.opengles.GL;
|
|||
@SuppressLint("NewApi")
|
||||
public class CameraView extends FrameLayout implements TextureView.SurfaceTextureListener, CameraController.ICameraView {
|
||||
|
||||
public boolean WRITE_TO_FILE_IN_BACKGROUND = true;
|
||||
|
||||
public boolean isStory;
|
||||
private Size[] previewSize = new Size[2];
|
||||
private Size[] pictureSize = new Size[2];
|
||||
|
@ -272,7 +277,7 @@ public class CameraView extends FrameLayout implements TextureView.SurfaceTextur
|
|||
addToDualWait(400L);
|
||||
return;
|
||||
}
|
||||
if (!isFrontface && "samsung".equalsIgnoreCase(Build.MANUFACTURER) && !toggledDualAsSave) {
|
||||
if (!isFrontface && "samsung".equalsIgnoreCase(Build.MANUFACTURER) && !toggledDualAsSave && cameraSession[0] != null) {
|
||||
final Handler handler = cameraThread.getHandler();
|
||||
if (handler != null) {
|
||||
cameraThread.sendMessage(handler.obtainMessage(cameraThread.BLUR_CAMERA1), 0);
|
||||
|
@ -1042,7 +1047,7 @@ public class CameraView extends FrameLayout implements TextureView.SurfaceTextur
|
|||
|
||||
private CameraSession currentSession[] = new CameraSession[2];
|
||||
|
||||
private SurfaceTexture[] cameraSurface = new SurfaceTexture[2];
|
||||
private final SurfaceTexture[] cameraSurface = new SurfaceTexture[2];
|
||||
|
||||
private final int DO_RENDER_MESSAGE = 0;
|
||||
private final int DO_SHUTDOWN_MESSAGE = 1;
|
||||
|
@ -1329,11 +1334,13 @@ public class CameraView extends FrameLayout implements TextureView.SurfaceTextur
|
|||
}
|
||||
|
||||
public void finish() {
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
if (cameraSurface[i] != null) {
|
||||
cameraSurface[i].setOnFrameAvailableListener(null);
|
||||
cameraSurface[i].release();
|
||||
cameraSurface[i] = null;
|
||||
if (cameraSurface != null) {
|
||||
for (int i = 0; i < cameraSurface.length; ++i) {
|
||||
if (cameraSurface[i] != null) {
|
||||
cameraSurface[i].setOnFrameAvailableListener(null);
|
||||
cameraSurface[i].release();
|
||||
cameraSurface[i] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (eglSurface != null) {
|
||||
|
@ -1464,7 +1471,10 @@ public class CameraView extends FrameLayout implements TextureView.SurfaceTextur
|
|||
continue;
|
||||
}
|
||||
final int i = a < 0 ? 1 : a;
|
||||
if (cameraSurface[i] == null || i != 0 && (currentSession[i] == null || !currentSession[i].isInitied()) || i == 0 && cameraId1 < 0 && !dual || i == 1 && cameraId2 < 0) {
|
||||
if (cameraSurface[i] == null) {
|
||||
continue;
|
||||
}
|
||||
if (i != 0 && (currentSession[i] == null || !currentSession[i].isInitied()) || i == 0 && cameraId1 < 0 && !dual || i == 1 && cameraId2 < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1489,7 +1499,7 @@ public class CameraView extends FrameLayout implements TextureView.SurfaceTextur
|
|||
GLES20.glUniformMatrix4fv(vertexMatrixHandle, 1, false, mMVPMatrix[i], 0);
|
||||
if (i == 0) {
|
||||
GLES20.glUniform2f(pixelHandle, pixelW, pixelH);
|
||||
GLES20.glUniform1f(dualHandle, 0f);
|
||||
GLES20.glUniform1f(dualHandle, dual ? 1 : 0);
|
||||
} else {
|
||||
GLES20.glUniform2f(pixelHandle, pixelDualW, pixelDualH);
|
||||
GLES20.glUniform1f(dualHandle, 1f);
|
||||
|
@ -1947,6 +1957,8 @@ public class CameraView extends FrameLayout implements TextureView.SurfaceTextur
|
|||
private static final int IFRAME_INTERVAL = 1;
|
||||
|
||||
private File videoFile;
|
||||
private File fileToWrite;
|
||||
private boolean writingToDifferentFile;
|
||||
private int videoBitrate;
|
||||
private boolean videoConvertFirstWrite = true;
|
||||
private boolean blendEnabled;
|
||||
|
@ -2348,7 +2360,8 @@ public class CameraView extends FrameLayout implements TextureView.SurfaceTextur
|
|||
GLES20.glEnable(GLES20.GL_BLEND);
|
||||
blendEnabled = true;
|
||||
}
|
||||
if (dual) {
|
||||
final boolean isDual = dual;
|
||||
if (isDual) {
|
||||
GLES20.glClearColor(0.f, 0.f, 0.f, 1.f);
|
||||
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
|
@ -2379,7 +2392,7 @@ public class CameraView extends FrameLayout implements TextureView.SurfaceTextur
|
|||
GLES20.glUniform1f(blurHandle, 0);
|
||||
if (i == 0) {
|
||||
GLES20.glUniform2f(pixelHandle, pixelW, pixelH);
|
||||
GLES20.glUniform1f(dualHandle, 0f);
|
||||
GLES20.glUniform1f(dualHandle, isDual ? 1f : 0f);
|
||||
} else {
|
||||
GLES20.glUniform2f(pixelHandle, pixelDualW, pixelDualH);
|
||||
GLES20.glUniform1f(dualHandle, 1f);
|
||||
|
@ -2484,6 +2497,19 @@ public class CameraView extends FrameLayout implements TextureView.SurfaceTextur
|
|||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (writingToDifferentFile) {
|
||||
if (!fileToWrite.renameTo(videoFile)) {
|
||||
FileLog.e("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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EGL14.eglDestroySurface(eglDisplay, eglSurface);
|
||||
eglSurface = EGL14.EGL_NO_SURFACE;
|
||||
if (surface != null) {
|
||||
|
@ -2586,8 +2612,24 @@ public class CameraView extends FrameLayout implements TextureView.SurfaceTextur
|
|||
surface = videoEncoder.createInputSurface();
|
||||
videoEncoder.start();
|
||||
|
||||
boolean isSdCard = ImageLoader.isSdCardPath(videoFile);
|
||||
fileToWrite = videoFile;
|
||||
if (isSdCard) {
|
||||
try {
|
||||
fileToWrite = new File(ApplicationLoader.getFilesDirFixed(), "camera_tmp.mp4");
|
||||
if (fileToWrite.exists()) {
|
||||
fileToWrite.delete();
|
||||
}
|
||||
writingToDifferentFile = true;
|
||||
} catch (Throwable e) {
|
||||
FileLog.e(e);
|
||||
fileToWrite = videoFile;
|
||||
writingToDifferentFile = false;
|
||||
}
|
||||
}
|
||||
|
||||
Mp4Movie movie = new Mp4Movie();
|
||||
movie.setCacheFile(videoFile);
|
||||
movie.setCacheFile(fileToWrite);
|
||||
movie.setRotation(0);
|
||||
movie.setSize(videoWidth, videoHeight);
|
||||
mediaMuxer = new MP4Builder().createMovie(movie, false, false);
|
||||
|
@ -2749,7 +2791,6 @@ public class CameraView extends FrameLayout implements TextureView.SurfaceTextur
|
|||
if (encodedData == null) {
|
||||
throw new RuntimeException("encoderOutputBuffer " + encoderStatus + " was null");
|
||||
}
|
||||
boolean allowReleaseBuffer = true;
|
||||
if (videoBufferInfo.size > 1) {
|
||||
if ((videoBufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) == 0) {
|
||||
if (prependHeaderSize != 0 && (videoBufferInfo.flags & MediaCodec.BUFFER_FLAG_KEY_FRAME) != 0) {
|
||||
|
@ -2765,18 +2806,10 @@ public class CameraView extends FrameLayout implements TextureView.SurfaceTextur
|
|||
bufferInfo.offset = videoBufferInfo.offset;
|
||||
bufferInfo.flags = videoBufferInfo.flags;
|
||||
bufferInfo.presentationTimeUs = videoBufferInfo.presentationTimeUs;
|
||||
allowReleaseBuffer = false;
|
||||
ByteBuffer byteBuffer = encodedData.duplicate();
|
||||
fileWriteQueue.postRunnable(() -> {
|
||||
try {
|
||||
mediaMuxer.writeSampleData(videoTrackIndex, encodedData, bufferInfo, true);
|
||||
MediaCodec videoEncoder = VideoRecorder.this.videoEncoder;
|
||||
if (videoEncoder != null) {
|
||||
try {
|
||||
videoEncoder.releaseOutputBuffer(encoderStatus, false);
|
||||
} catch (Throwable e) {
|
||||
//ignore IllegalStateException if codec released
|
||||
}
|
||||
}
|
||||
mediaMuxer.writeSampleData(videoTrackIndex, byteBuffer, bufferInfo, true);
|
||||
} catch (Exception e) {
|
||||
FileLog.e(e);
|
||||
}
|
||||
|
@ -2813,9 +2846,7 @@ public class CameraView extends FrameLayout implements TextureView.SurfaceTextur
|
|||
videoTrackIndex = mediaMuxer.addTrack(newFormat, false);
|
||||
}
|
||||
}
|
||||
if (allowReleaseBuffer) {
|
||||
videoEncoder.releaseOutputBuffer(encoderStatus, false);
|
||||
}
|
||||
videoEncoder.releaseOutputBuffer(encoderStatus, false);
|
||||
if ((videoBufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
|
||||
break;
|
||||
}
|
||||
|
@ -2860,24 +2891,16 @@ public class CameraView extends FrameLayout implements TextureView.SurfaceTextur
|
|||
bufferInfo.offset = audioBufferInfo.offset;
|
||||
bufferInfo.flags = audioBufferInfo.flags;
|
||||
bufferInfo.presentationTimeUs = audioBufferInfo.presentationTimeUs;
|
||||
ByteBuffer byteBuffer = encodedData.duplicate();
|
||||
fileWriteQueue.postRunnable(() -> {
|
||||
try {
|
||||
mediaMuxer.writeSampleData(audioTrackIndex, encodedData, bufferInfo, false);
|
||||
MediaCodec audioEncoder = VideoRecorder.this.audioEncoder;
|
||||
if (audioEncoder != null) {
|
||||
try {
|
||||
audioEncoder.releaseOutputBuffer(encoderStatus, false);
|
||||
} catch (Throwable e) {
|
||||
//ignore IllegalStateException if codec released
|
||||
}
|
||||
}
|
||||
mediaMuxer.writeSampleData(audioTrackIndex, byteBuffer, bufferInfo, false);
|
||||
} catch (Exception e) {
|
||||
FileLog.e(e);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
audioEncoder.releaseOutputBuffer(encoderStatus, false);
|
||||
}
|
||||
audioEncoder.releaseOutputBuffer(encoderStatus, false);
|
||||
if ((audioBufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -760,6 +760,7 @@ public class ActionBarLayout extends FrameLayout implements INavigationLayout, F
|
|||
parent.removeViewInLayout(lastFragment.actionBar);
|
||||
}
|
||||
}
|
||||
lastFragment.detachStoryViewer();
|
||||
}
|
||||
layoutToIgnore = null;
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ import android.animation.ValueAnimator;
|
|||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Path;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.PorterDuffColorFilter;
|
||||
import android.graphics.Rect;
|
||||
|
@ -166,6 +167,12 @@ public class ActionBarPopupWindow extends PopupWindow {
|
|||
|
||||
try {
|
||||
scrollView = new ScrollView(context);
|
||||
scrollView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
|
||||
@Override
|
||||
public void onScrollChanged() {
|
||||
invalidate();
|
||||
}
|
||||
});
|
||||
scrollView.setVerticalScrollBarEnabled(false);
|
||||
if (swipeBackLayout != null) {
|
||||
swipeBackLayout.addView(scrollView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, shownFromBottom ? Gravity.BOTTOM : Gravity.TOP));
|
||||
|
@ -416,6 +423,8 @@ public class ActionBarPopupWindow extends PopupWindow {
|
|||
return super.dispatchKeyEvent(event);
|
||||
}
|
||||
|
||||
Path path;
|
||||
|
||||
@Override
|
||||
protected void dispatchDraw(Canvas canvas) {
|
||||
if (swipeBackGravityRight) {
|
||||
|
@ -487,9 +496,15 @@ public class ActionBarPopupWindow extends PopupWindow {
|
|||
backgroundDrawable.draw(canvas);
|
||||
if (hasGap) {
|
||||
canvas.save();
|
||||
AndroidUtilities.rectTmp2.set(backgroundDrawable.getBounds());
|
||||
AndroidUtilities.rectTmp2.inset(AndroidUtilities.dp(8), AndroidUtilities.dp(8));
|
||||
canvas.clipRect(AndroidUtilities.rectTmp2);
|
||||
AndroidUtilities.rectTmp.set(backgroundDrawable.getBounds());
|
||||
AndroidUtilities.rectTmp.inset(AndroidUtilities.dp(8), AndroidUtilities.dp(8));
|
||||
if (path == null) {
|
||||
path = new Path();
|
||||
} else {
|
||||
path.rewind();
|
||||
}
|
||||
path.addRoundRect(AndroidUtilities.rectTmp, AndroidUtilities.dp(8), AndroidUtilities.dp(8), Path.Direction.CW);
|
||||
canvas.clipPath(path);
|
||||
for (int i = 0; i < linearLayout.getChildCount(); i++) {
|
||||
if (linearLayout.getChildAt(i) instanceof GapView && linearLayout.getChildAt(i).getVisibility() == View.VISIBLE) {
|
||||
canvas.save();
|
||||
|
@ -504,7 +519,7 @@ public class ActionBarPopupWindow extends PopupWindow {
|
|||
break;
|
||||
}
|
||||
}
|
||||
canvas.translate(x, y * scrollView.getScaleY());
|
||||
canvas.translate(x, y * scrollView.getScaleY() - scrollView.getScrollY());
|
||||
child.draw(canvas);
|
||||
canvas.restore();
|
||||
}
|
||||
|
|
|
@ -84,26 +84,13 @@ public class ContactsAdapter extends RecyclerListView.SectionsAdapter {
|
|||
}
|
||||
|
||||
public void setStories(ArrayList<TLRPC.TL_userStories> stories, boolean animated) {
|
||||
boolean hasStories = !stories.isEmpty();
|
||||
userStories.clear();
|
||||
userStories.addAll(stories);
|
||||
if (this.hasStories != hasStories) {
|
||||
this.hasStories = hasStories;
|
||||
// if (!animated) {
|
||||
// notifyDataSetChanged();
|
||||
// } else {
|
||||
// cleanupCache();
|
||||
// notifyDataSetChanged();
|
||||
// if (hasStories) {
|
||||
// notifyItemInserted(0);
|
||||
// } else {
|
||||
// notifyItemRemoved(0);
|
||||
// notifyItemRangeChanged(1, getItemCount());
|
||||
// }
|
||||
// }
|
||||
}
|
||||
update(true);
|
||||
// notifyDataSetChanged();
|
||||
// boolean hasStories = !stories.isEmpty();
|
||||
// userStories.clear();
|
||||
// userStories.addAll(stories);
|
||||
// if (this.hasStories != hasStories) {
|
||||
// this.hasStories = hasStories;
|
||||
// }
|
||||
// update(true);
|
||||
}
|
||||
|
||||
public void setDisableSections(boolean value) {
|
||||
|
|
|
@ -74,6 +74,7 @@ import org.telegram.ui.Components.PullForegroundDrawable;
|
|||
import org.telegram.ui.Components.RecyclerListView;
|
||||
import org.telegram.ui.DialogsActivity;
|
||||
import org.telegram.ui.Stories.DialogStoriesCell;
|
||||
import org.telegram.ui.Stories.StoriesController;
|
||||
import org.telegram.ui.Stories.StoriesListPlaceProvider;
|
||||
import org.telegram.ui.Stories.StoriesUtilities;
|
||||
|
||||
|
@ -92,8 +93,8 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
|
|||
VIEW_TYPE_USER = 6,
|
||||
VIEW_TYPE_HEADER = 7,
|
||||
VIEW_TYPE_SHADOW = 8,
|
||||
// VIEW_TYPE_ARCHIVE = 9,
|
||||
VIEW_TYPE_LAST_EMPTY = 10,
|
||||
// VIEW_TYPE_ARCHIVE = 9,
|
||||
VIEW_TYPE_LAST_EMPTY = 10,
|
||||
VIEW_TYPE_NEW_CHAT_HINT = 11,
|
||||
VIEW_TYPE_TEXT = 12,
|
||||
VIEW_TYPE_CONTACTS_FLICKER = 13,
|
||||
|
@ -487,7 +488,7 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
|
|||
if (view != null) {
|
||||
float offset = view.getTop() - recyclerListView.getPaddingTop();
|
||||
if (!hasStories) {
|
||||
// offset += tabsTranslation;
|
||||
// offset += tabsTranslation;
|
||||
} else {
|
||||
tabsTranslation = 0;
|
||||
}
|
||||
|
@ -660,8 +661,8 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
|
|||
case VIEW_TYPE_ARCHIVE_FULLSCREEN:
|
||||
LastEmptyView lastEmptyView = new LastEmptyView(mContext);
|
||||
lastEmptyView.addView(
|
||||
new ArchiveHelp(mContext, currentAccount, null, DialogsAdapter.this::onArchiveSettingsClick,null),
|
||||
LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.CENTER, 0, -(int) (DialogStoriesCell.HEIGHT_IN_DP * .5f), 0, 0)
|
||||
new ArchiveHelp(mContext, currentAccount, null, DialogsAdapter.this::onArchiveSettingsClick, null),
|
||||
LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.CENTER, 0, -(int) (DialogStoriesCell.HEIGHT_IN_DP * .5f), 0, 0)
|
||||
);
|
||||
view = lastEmptyView;
|
||||
break;
|
||||
|
@ -733,6 +734,7 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
|
|||
if (dialogsType == DialogsActivity.DIALOGS_TYPE_BOT_REQUEST_PEER) {
|
||||
view.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case VIEW_TYPE_STORIES: {
|
||||
view = new View(mContext) {
|
||||
|
@ -1091,6 +1093,23 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
|
|||
parentFragment.showChatPreview(cell);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void openHiddenStories() {
|
||||
StoriesController storiesController = MessagesController.getInstance(currentAccount).getStoriesController();
|
||||
if (storiesController.getHiddenList().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
boolean unreadOnly = storiesController.getUnreadState(storiesController.getHiddenList().get(0).user_id) != StoriesController.STATE_READ;
|
||||
ArrayList<Long> peerIds = new ArrayList<>();
|
||||
for (int i = 0; i < storiesController.getHiddenList().size(); i++) {
|
||||
if (!unreadOnly || storiesController.getUnreadState(storiesController.getHiddenList().get(i).user_id) != StoriesController.STATE_READ) {
|
||||
peerIds.add(storiesController.getHiddenList().get(i).user_id);
|
||||
}
|
||||
}
|
||||
|
||||
parentFragment.getOrCreateStoryViewer().open(mContext, null, peerIds, 0, null, null, StoriesListPlaceProvider.of(recyclerListView, true), false);
|
||||
}
|
||||
|
||||
public void setIsTransitionSupport() {
|
||||
this.isTransitionSupport = true;
|
||||
}
|
||||
|
|
|
@ -316,12 +316,12 @@ public class DrawerLayoutAdapter extends RecyclerListView.SelectionAdapter {
|
|||
items.add(new Item(15, LocaleController.getString("SetEmojiStatus", R.string.SetEmojiStatus), R.drawable.msg_status_set));
|
||||
}
|
||||
}
|
||||
// if (MessagesController.getInstance(UserConfig.selectedAccount).storiesEnabled()) {
|
||||
if (MessagesController.getInstance(UserConfig.selectedAccount).storiesEnabled()) {
|
||||
items.add(new Item(16, LocaleController.getString("ProfileMyStories", R.string.ProfileMyStories), R.drawable.msg_menu_stories));
|
||||
items.add(null); // divider
|
||||
// } else if (me != null && me.isPremium()) {
|
||||
// items.add(null); // divider
|
||||
// }
|
||||
} else if (me != null && me.isPremium()) {
|
||||
items.add(null); // divider
|
||||
}
|
||||
items.add(new Item(2, LocaleController.getString("NewGroup", R.string.NewGroup), newGroupIcon));
|
||||
//items.add(new Item(3, LocaleController.getString("NewSecretChat", R.string.NewSecretChat), newSecretIcon));
|
||||
//items.add(new Item(4, LocaleController.getString("NewChannel", R.string.NewChannel), newChannelIcon));
|
||||
|
|
|
@ -112,7 +112,7 @@ public class AudioPlayerCell extends View implements DownloadController.FileDown
|
|||
try {
|
||||
CharSequence author = currentMessageObject.getMusicAuthor().replace('\n', ' ');
|
||||
if (viewType == VIEW_TYPE_GLOBAL_SEARCH) {
|
||||
author = new SpannableStringBuilder(author).append(' ').append(dotSpan).append(' ').append(FilteredSearchView.createFromInfoString(currentMessageObject));
|
||||
author = new SpannableStringBuilder(author).append(' ').append(dotSpan).append(' ').append(FilteredSearchView.createFromInfoString(currentMessageObject, 2));
|
||||
}
|
||||
CharSequence authorFinal = TextUtils.ellipsize(author, Theme.chat_contextResult_descriptionTextPaint, maxWidth, TextUtils.TruncateAt.END);
|
||||
descriptionLayout = new StaticLayout(authorFinal, Theme.chat_contextResult_descriptionTextPaint, maxWidth + AndroidUtilities.dp(4), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
|
||||
|
|
|
@ -1063,7 +1063,7 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
|
|||
private int getImageSize(MessageObject messageObject) {
|
||||
int imageSize = stickerSize;
|
||||
if (messageObject.type == MessageObject.TYPE_SUGGEST_PHOTO || isNewStyleButtonLayout()) {
|
||||
imageSize = (int) (stickerSize * 0.7f);
|
||||
imageSize = AndroidUtilities.dp(78);//Math.max(, (int) (stickerSize * 0.7f));
|
||||
}
|
||||
return imageSize;
|
||||
}
|
||||
|
@ -1178,7 +1178,7 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
|
|||
} else {
|
||||
giftPremiumTitleLayout = null;
|
||||
}
|
||||
if (currentMessageObject != null && (currentMessageObject.type == MessageObject.TYPE_SUGGEST_PHOTO || currentMessageObject.isStoryMention())) {
|
||||
if (currentMessageObject != null && isNewStyleButtonLayout()) {
|
||||
giftSubtitlePaint.setTextSize(AndroidUtilities.dp(13));
|
||||
} else {
|
||||
giftSubtitlePaint.setTextSize(AndroidUtilities.dp(15));
|
||||
|
|
|
@ -4894,6 +4894,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
|
|||
type = webpage == null ? null : webpage.type;
|
||||
duration = storyItem != null && storyItem.media != null && storyItem.media.document != null ? (int) MessageObject.getDocumentDuration(storyItem.media.document) : 0;
|
||||
smallImage = false;
|
||||
isSmallImage = false;
|
||||
} else if (hasLinkPreview) {
|
||||
TLRPC.TL_webPage webPage = (TLRPC.TL_webPage) webpage;
|
||||
site_name = webPage.site_name;
|
||||
|
|
|
@ -161,16 +161,26 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
|
|||
private TimerDrawable timerDrawable;
|
||||
private Paint timerPaint;
|
||||
private Paint timerPaint2;
|
||||
public final StoriesUtilities.AvatarStoryParams params = new StoriesUtilities.AvatarStoryParams(false) {
|
||||
public final StoriesUtilities.AvatarStoryParams storyParams = new StoriesUtilities.AvatarStoryParams(false) {
|
||||
@Override
|
||||
public void openStory(long dialogId, Runnable onDone) {
|
||||
if (delegate != null) {
|
||||
delegate.openStory(DialogCell.this, onDone);
|
||||
if (delegate == null) {
|
||||
return;
|
||||
}
|
||||
if (currentDialogFolderId != 0) {
|
||||
delegate.openHiddenStories();
|
||||
} else {
|
||||
if (delegate != null) {
|
||||
delegate.openStory(DialogCell.this, onDone);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLongPress() {
|
||||
if (delegate == null) {
|
||||
return;
|
||||
}
|
||||
delegate.showChatPreview(DialogCell.this);
|
||||
}
|
||||
};
|
||||
|
@ -522,7 +532,7 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
|
|||
|
||||
public DialogCell(DialogsActivity fragment, Context context, boolean needCheck, boolean forceThreeLines, int account, Theme.ResourcesProvider resourcesProvider) {
|
||||
super(context);
|
||||
params.allowLongress = true;
|
||||
storyParams.allowLongress = true;
|
||||
this.resourcesProvider = resourcesProvider;
|
||||
parentFragment = fragment;
|
||||
Theme.createDialogsResources(context);
|
||||
|
@ -697,7 +707,7 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
|
|||
AnimatedEmojiSpan.release(this, animatedEmojiStack2);
|
||||
AnimatedEmojiSpan.release(this, animatedEmojiStack3);
|
||||
AnimatedEmojiSpan.release(this, animatedEmojiStackName);
|
||||
params.onDetachFromWindow();
|
||||
storyParams.onDetachFromWindow();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1888,7 +1898,7 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
|
|||
avatarLeft = AndroidUtilities.dp(10);
|
||||
thumbLeft = avatarLeft + AndroidUtilities.dp(56 + 13);
|
||||
}
|
||||
params.originalAvatarRect.set(avatarLeft, avatarTop, avatarLeft + AndroidUtilities.dp(56), avatarTop + AndroidUtilities.dp(56));
|
||||
storyParams.originalAvatarRect.set(avatarLeft, avatarTop, avatarLeft + AndroidUtilities.dp(56), avatarTop + AndroidUtilities.dp(56));
|
||||
for (int i = 0; i < thumbImage.length; ++i) {
|
||||
thumbImage[i].setImageCoords(thumbLeft + (thumbSize + 2) * i, avatarTop + AndroidUtilities.dp(31) + (twoLinesForName ? AndroidUtilities.dp(20) : 0), AndroidUtilities.dp(18), AndroidUtilities.dp(18));
|
||||
}
|
||||
|
@ -1911,7 +1921,7 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
|
|||
avatarLeft = AndroidUtilities.dp(10);
|
||||
thumbLeft = avatarLeft + AndroidUtilities.dp(56 + 11);
|
||||
}
|
||||
params.originalAvatarRect.set(avatarLeft, avatarTop, avatarLeft + AndroidUtilities.dp(54), avatarTop + AndroidUtilities.dp(54));
|
||||
storyParams.originalAvatarRect.set(avatarLeft, avatarTop, avatarLeft + AndroidUtilities.dp(54), avatarTop + AndroidUtilities.dp(54));
|
||||
for (int i = 0; i < thumbImage.length; ++i) {
|
||||
thumbImage[i].setImageCoords(thumbLeft + (thumbSize + 2) * i, avatarTop + AndroidUtilities.dp(30) + (twoLinesForName ? AndroidUtilities.dp(20) : 0), AndroidUtilities.dp(thumbSize), AndroidUtilities.dp(thumbSize));
|
||||
}
|
||||
|
@ -3793,8 +3803,9 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
|
|||
canvas.scale(scale, scale, avatarImage.getCenterX(), avatarImage.getCenterY());
|
||||
}
|
||||
|
||||
if (drawAvatar && (!(currentDialogFolderId != 0 || isTopic && forumTopic != null && forumTopic.id == 1) || archivedChatsDrawable == null || !archivedChatsDrawable.isDraw())) {
|
||||
StoriesUtilities.drawAvatarWithStory(currentDialogId, canvas, avatarImage, params);
|
||||
if (drawAvatar && (!(isTopic && forumTopic != null && forumTopic.id == 1) || archivedChatsDrawable == null || !archivedChatsDrawable.isDraw())) {
|
||||
storyParams.drawHiddenStoriesAsSegments = currentDialogFolderId != 0;
|
||||
StoriesUtilities.drawAvatarWithStory(currentDialogId, canvas, avatarImage, storyParams);
|
||||
}
|
||||
|
||||
if (animatingArchiveAvatar) {
|
||||
|
@ -3812,8 +3823,8 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
|
|||
} else {
|
||||
drawCounterMuted = chat != null && chat.forum && forumTopic == null ? !hasUnmutedTopics : dialogMuted;
|
||||
}
|
||||
int countLeftLocal = (int) (params.originalAvatarRect.left + avatarImage.getImageWidth() - countWidth - AndroidUtilities.dp(5f));
|
||||
int countLeftOld = (int) (params.originalAvatarRect.left + avatarImage.getImageWidth() - countWidthOld - AndroidUtilities.dp(5f));
|
||||
int countLeftLocal = (int) (storyParams.originalAvatarRect.left + avatarImage.getImageWidth() - countWidth - AndroidUtilities.dp(5f));
|
||||
int countLeftOld = (int) (storyParams.originalAvatarRect.left + avatarImage.getImageWidth() - countWidthOld - AndroidUtilities.dp(5f));
|
||||
int countTop = (int) (avatarImage.getImageY() + avatarImage.getImageHeight() - AndroidUtilities.dp(22));
|
||||
drawCounter(canvas, drawCounterMuted, countTop, countLeftLocal, countLeftOld, rightFragmentOpenedProgress, true);
|
||||
}
|
||||
|
@ -3970,9 +3981,9 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
|
|||
int top = (int) (avatarImage.getImageY2() - AndroidUtilities.dp(9));
|
||||
int left;
|
||||
if (LocaleController.isRTL) {
|
||||
left = (int) (params.originalAvatarRect.left + AndroidUtilities.dp(9));
|
||||
left = (int) (storyParams.originalAvatarRect.left + AndroidUtilities.dp(9));
|
||||
} else {
|
||||
left = (int) (params.originalAvatarRect.right - AndroidUtilities.dp(9));
|
||||
left = (int) (storyParams.originalAvatarRect.right - AndroidUtilities.dp(9));
|
||||
}
|
||||
timerDrawable.setBounds(
|
||||
0, 0, AndroidUtilities.dp(22), AndroidUtilities.dp(22)
|
||||
|
@ -4011,12 +4022,12 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
|
|||
if (user != null && !MessagesController.isSupportUser(user) && !user.bot) {
|
||||
boolean isOnline = isOnline();
|
||||
if (isOnline || onlineProgress != 0) {
|
||||
int top = (int) (params.originalAvatarRect.bottom - AndroidUtilities.dp(useForceThreeLines || SharedConfig.useThreeLinesLayout ? 6 : 8));
|
||||
int top = (int) (storyParams.originalAvatarRect.bottom - AndroidUtilities.dp(useForceThreeLines || SharedConfig.useThreeLinesLayout ? 6 : 8));
|
||||
int left;
|
||||
if (LocaleController.isRTL) {
|
||||
left = (int) (params.originalAvatarRect.left + AndroidUtilities.dp(useForceThreeLines || SharedConfig.useThreeLinesLayout ? 10 : 6));
|
||||
left = (int) (storyParams.originalAvatarRect.left + AndroidUtilities.dp(useForceThreeLines || SharedConfig.useThreeLinesLayout ? 10 : 6));
|
||||
} else {
|
||||
left = (int) (params.originalAvatarRect.right - AndroidUtilities.dp(useForceThreeLines || SharedConfig.useThreeLinesLayout ? 10 : 6));
|
||||
left = (int) (storyParams.originalAvatarRect.right - AndroidUtilities.dp(useForceThreeLines || SharedConfig.useThreeLinesLayout ? 10 : 6));
|
||||
}
|
||||
|
||||
Theme.dialogs_onlineCirclePaint.setColor(Theme.getColor(Theme.key_windowBackgroundWhite, resourcesProvider));
|
||||
|
@ -4045,12 +4056,12 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
|
|||
hasCall = chat.call_active && chat.call_not_empty;
|
||||
if ((hasCall || chatCallProgress != 0) && rightFragmentOpenedProgress < 1f) {
|
||||
float checkProgress = checkBox != null && checkBox.isChecked() ? 1.0f - checkBox.getProgress() : 1.0f;
|
||||
int top = (int) (params.originalAvatarRect.bottom - AndroidUtilities.dp(useForceThreeLines || SharedConfig.useThreeLinesLayout ? 6 : 8));
|
||||
int top = (int) (storyParams.originalAvatarRect.bottom - AndroidUtilities.dp(useForceThreeLines || SharedConfig.useThreeLinesLayout ? 6 : 8));
|
||||
int left;
|
||||
if (LocaleController.isRTL) {
|
||||
left = (int) (params.originalAvatarRect.left + AndroidUtilities.dp(useForceThreeLines || SharedConfig.useThreeLinesLayout ? 10 : 6));
|
||||
left = (int) (storyParams.originalAvatarRect.left + AndroidUtilities.dp(useForceThreeLines || SharedConfig.useThreeLinesLayout ? 10 : 6));
|
||||
} else {
|
||||
left = (int) (params.originalAvatarRect.right - AndroidUtilities.dp(useForceThreeLines || SharedConfig.useThreeLinesLayout ? 10 : 6));
|
||||
left = (int) (storyParams.originalAvatarRect.right - AndroidUtilities.dp(useForceThreeLines || SharedConfig.useThreeLinesLayout ? 10 : 6));
|
||||
}
|
||||
|
||||
if (rightFragmentOpenedProgress != 0) {
|
||||
|
@ -4370,9 +4381,9 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
|
|||
archivedChatsDrawable.outRadius = 0;
|
||||
archivedChatsDrawable.outImageSize = 0;
|
||||
} else {
|
||||
archivedChatsDrawable.outCy = params.originalAvatarRect.centerY();
|
||||
archivedChatsDrawable.outCx = params.originalAvatarRect.centerX();
|
||||
archivedChatsDrawable.outRadius = params.originalAvatarRect.width() / 2.0f;
|
||||
archivedChatsDrawable.outCy = storyParams.originalAvatarRect.centerY();
|
||||
archivedChatsDrawable.outCx = storyParams.originalAvatarRect.centerX();
|
||||
archivedChatsDrawable.outRadius = avatarImage.getImageWidth() / 2.0f;
|
||||
archivedChatsDrawable.outImageSize = avatarImage.getBitmapWidth();
|
||||
}
|
||||
archivedChatsDrawable.startOutAnimation();
|
||||
|
@ -4864,7 +4875,7 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
|
|||
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(MotionEvent ev) {
|
||||
if (rightFragmentOpenedProgress == 0 && params.checkOnTouchEvent(ev, this)) {
|
||||
if (rightFragmentOpenedProgress == 0 && storyParams.checkOnTouchEvent(ev, this)) {
|
||||
return true;
|
||||
}
|
||||
return super.onInterceptTouchEvent(ev);
|
||||
|
@ -4873,14 +4884,14 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
|
|||
@Override
|
||||
public boolean dispatchTouchEvent(MotionEvent ev) {
|
||||
if (ev.getAction() == MotionEvent.ACTION_UP || ev.getAction() == MotionEvent.ACTION_CANCEL) {
|
||||
params.checkOnTouchEvent(ev, this);
|
||||
storyParams.checkOnTouchEvent(ev, this);
|
||||
}
|
||||
return super.dispatchTouchEvent(ev);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
if (rightFragmentOpenedProgress == 0 && params.checkOnTouchEvent(event, this)) {
|
||||
if (rightFragmentOpenedProgress == 0 && storyParams.checkOnTouchEvent(event, this)) {
|
||||
return true;
|
||||
}
|
||||
if (delegate == null || delegate.canClickButtonInside()) {
|
||||
|
@ -4935,6 +4946,7 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
|
|||
boolean canClickButtonInside();
|
||||
void openStory(DialogCell dialogCell, Runnable onDone);
|
||||
void showChatPreview(DialogCell dialogCell);
|
||||
void openHiddenStories();
|
||||
}
|
||||
|
||||
private class DialogUpdateHelper {
|
||||
|
|
|
@ -31,7 +31,6 @@ import android.view.accessibility.AccessibilityNodeInfo;
|
|||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
|
@ -65,6 +64,7 @@ import org.telegram.ui.Components.Premium.StarParticlesView;
|
|||
import org.telegram.ui.Components.RLottieDrawable;
|
||||
import org.telegram.ui.Components.RLottieImageView;
|
||||
import org.telegram.ui.Components.Reactions.AnimatedEmojiEffect;
|
||||
import org.telegram.ui.Components.Reactions.HwEmojis;
|
||||
import org.telegram.ui.Components.Reactions.ReactionsLayoutInBubble;
|
||||
import org.telegram.ui.Components.SnowflakesEffect;
|
||||
import org.telegram.ui.ThemeActivity;
|
||||
|
@ -125,6 +125,38 @@ public class DrawerProfileCell extends FrameLayout implements NotificationCenter
|
|||
animatedStatus.translate(AndroidUtilities.rectTmp2.centerX(), AndroidUtilities.rectTmp2.centerY());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidate() {
|
||||
if (HwEmojis.grab(this)) {
|
||||
return;
|
||||
}
|
||||
super.invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidate(int l, int t, int r, int b) {
|
||||
if (HwEmojis.grab(this)) {
|
||||
return;
|
||||
}
|
||||
super.invalidate(l, t, r, b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidateDrawable(Drawable who) {
|
||||
if (HwEmojis.grab(this)) {
|
||||
return;
|
||||
}
|
||||
super.invalidateDrawable(who);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidate(Rect dirty) {
|
||||
if (HwEmojis.grab(this)) {
|
||||
return;
|
||||
}
|
||||
super.invalidate(dirty);
|
||||
}
|
||||
};
|
||||
nameTextView.setRightDrawableOnClick(e -> {
|
||||
if (lastUser != null && lastUser.premium) {
|
||||
|
@ -441,6 +473,7 @@ public class DrawerProfileCell extends FrameLayout implements NotificationCenter
|
|||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
status.attach();
|
||||
updateColors();
|
||||
NotificationCenter.getGlobalInstance().addObserver(this, NotificationCenter.emojiLoaded);
|
||||
for (int i = 0; i < UserConfig.MAX_ACCOUNT_COUNT; i++){
|
||||
|
@ -451,6 +484,7 @@ public class DrawerProfileCell extends FrameLayout implements NotificationCenter
|
|||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
status.detach();
|
||||
NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.emojiLoaded);
|
||||
for (int i = 0; i < UserConfig.MAX_ACCOUNT_COUNT; i++){
|
||||
NotificationCenter.getInstance(i).removeObserver(this, NotificationCenter.currentUserPremiumStatusChanged);
|
||||
|
|
|
@ -88,6 +88,7 @@ public class DrawerUserCell extends FrameLayout implements NotificationCenter.No
|
|||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
textView.setTextColor(Theme.getColor(Theme.key_chats_menuItemText));
|
||||
status.attach();
|
||||
for (int i = 0; i < UserConfig.MAX_ACCOUNT_COUNT; i++){
|
||||
NotificationCenter.getInstance(i).addObserver(this, NotificationCenter.currentUserPremiumStatusChanged);
|
||||
NotificationCenter.getInstance(i).addObserver(this, NotificationCenter.updateInterfaces);
|
||||
|
@ -98,6 +99,7 @@ public class DrawerUserCell extends FrameLayout implements NotificationCenter.No
|
|||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
status.detach();
|
||||
for (int i = 0; i < UserConfig.MAX_ACCOUNT_COUNT; i++){
|
||||
NotificationCenter.getInstance(i).removeObserver(this, NotificationCenter.currentUserPremiumStatusChanged);
|
||||
NotificationCenter.getInstance(i).removeObserver(this, NotificationCenter.updateInterfaces);
|
||||
|
|
|
@ -168,7 +168,7 @@ public class SharedAudioCell extends FrameLayout implements DownloadController.F
|
|||
try {
|
||||
CharSequence title;
|
||||
if (viewType == VIEW_TYPE_GLOBAL_SEARCH && (currentMessageObject.isVoice() || currentMessageObject.isRoundVideo())) {
|
||||
title = FilteredSearchView.createFromInfoString(currentMessageObject);
|
||||
title = FilteredSearchView.createFromInfoString(currentMessageObject, 1);
|
||||
} else {
|
||||
title = currentMessageObject.getMusicTitle().replace('\n', ' ');
|
||||
}
|
||||
|
@ -210,7 +210,7 @@ public class SharedAudioCell extends FrameLayout implements DownloadController.F
|
|||
author = authorH;
|
||||
}
|
||||
if (viewType == VIEW_TYPE_GLOBAL_SEARCH) {
|
||||
author = new SpannableStringBuilder(author).append(' ').append(dotSpan).append(' ').append(FilteredSearchView.createFromInfoString(currentMessageObject));
|
||||
author = new SpannableStringBuilder(author).append(' ').append(dotSpan).append(' ').append(FilteredSearchView.createFromInfoString(currentMessageObject, 1));
|
||||
}
|
||||
TextPaint paint = viewType == VIEW_TYPE_GLOBAL_SEARCH ? description2TextPaint : Theme.chat_contextResult_descriptionTextPaint;
|
||||
author = TextUtils.ellipsize(author, paint, maxWidth, TextUtils.TruncateAt.END);
|
||||
|
|
|
@ -37,6 +37,7 @@ import org.telegram.messenger.ImageLocation;
|
|||
import org.telegram.messenger.LocaleController;
|
||||
import org.telegram.messenger.MediaController;
|
||||
import org.telegram.messenger.MessageObject;
|
||||
import org.telegram.messenger.NotificationCenter;
|
||||
import org.telegram.messenger.R;
|
||||
import org.telegram.messenger.UserConfig;
|
||||
import org.telegram.messenger.Utilities;
|
||||
|
@ -220,6 +221,7 @@ public class SharedDocumentCell extends FrameLayout implements DownloadControlle
|
|||
dateTextView.setSingleLine(true);
|
||||
dateTextView.setEllipsize(TextUtils.TruncateAt.END);
|
||||
dateTextView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.CENTER_VERTICAL);
|
||||
NotificationCenter.listenEmojiLoading(dateTextView);
|
||||
if (viewType == VIEW_TYPE_PICKER) {
|
||||
dateTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 13);
|
||||
addView(dateTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 8 : 72, 34, LocaleController.isRTL ? 72 : 8, 0));
|
||||
|
@ -509,7 +511,7 @@ public class SharedDocumentCell extends FrameLayout implements DownloadControlle
|
|||
fileSize = String.format(Locale.ENGLISH, "%s / %s", AndroidUtilities.formatFileSize(downloadedSize), AndroidUtilities.formatFileSize(message.getDocument().size));
|
||||
}
|
||||
if (viewType == VIEW_TYPE_GLOBAL_SEARCH) {
|
||||
CharSequence fromName = FilteredSearchView.createFromInfoString(message);
|
||||
CharSequence fromName = FilteredSearchView.createFromInfoString(message, true, 2, dateTextView.getPaint());
|
||||
|
||||
dateTextView.setText(new SpannableStringBuilder().append(fileSize)
|
||||
.append(' ').append(dotSpan).append(' ')
|
||||
|
|
|
@ -477,7 +477,7 @@ public class SharedLinkCell extends FrameLayout {
|
|||
}
|
||||
|
||||
if (viewType == VIEW_TYPE_GLOBAL_SEARCH) {
|
||||
fromInfoLayout = ChatMessageCell.generateStaticLayout(FilteredSearchView.createFromInfoString(message), description2TextPaint, maxWidth, maxWidth, 0, desctiptionLines);
|
||||
fromInfoLayout = ChatMessageCell.generateStaticLayout(FilteredSearchView.createFromInfoString(message, true, 2, description2TextPaint), description2TextPaint, maxWidth, maxWidth, 0, desctiptionLines);
|
||||
fromInfoLayoutEmojis = AnimatedEmojiSpan.update(AnimatedEmojiDrawable.CACHE_TYPE_MESSAGES, this, fromInfoLayoutEmojis, fromInfoLayout);
|
||||
}
|
||||
|
||||
|
|
|
@ -65,6 +65,7 @@ public class UserCell extends FrameLayout implements NotificationCenter.Notifica
|
|||
private Theme.ResourcesProvider resourcesProvider;
|
||||
|
||||
private AvatarDrawable avatarDrawable;
|
||||
private boolean storiable;
|
||||
private Object currentObject;
|
||||
private TLRPC.EncryptedChat encryptedChat;
|
||||
|
||||
|
@ -142,8 +143,12 @@ public class UserCell extends FrameLayout implements NotificationCenter.Notifica
|
|||
avatarImageView = new BackupImageView(context) {
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
storyParams.originalAvatarRect.set(0, 0, getMeasuredWidth(), getMeasuredHeight());
|
||||
StoriesUtilities.drawAvatarWithStory(dialogId, canvas, imageReceiver, storyParams);
|
||||
if (storiable) {
|
||||
storyParams.originalAvatarRect.set(0, 0, getMeasuredWidth(), getMeasuredHeight());
|
||||
StoriesUtilities.drawAvatarWithStory(dialogId, canvas, imageReceiver, storyParams);
|
||||
} else {
|
||||
super.onDraw(canvas);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -257,6 +262,7 @@ public class UserCell extends FrameLayout implements NotificationCenter.Notifica
|
|||
if (object == null && name == null && status == null) {
|
||||
currentStatus = null;
|
||||
currentName = null;
|
||||
storiable = false;
|
||||
currentObject = null;
|
||||
nameTextView.setText("");
|
||||
statusTextView.setText("");
|
||||
|
@ -271,6 +277,7 @@ public class UserCell extends FrameLayout implements NotificationCenter.Notifica
|
|||
}
|
||||
} catch (Exception ignore) {}
|
||||
currentName = name;
|
||||
storiable = !(object instanceof String);
|
||||
currentObject = object;
|
||||
currentDrawable = resId;
|
||||
needDivider = divider;
|
||||
|
|
|
@ -23126,7 +23126,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
primaryMessage = null;
|
||||
message = null;
|
||||
}
|
||||
if (message == null || message.type == MessageObject.TYPE_STORY_MENTION) {
|
||||
if (message == null) {
|
||||
return false;
|
||||
}
|
||||
if (!single && message.messageOwner.action instanceof TLRPC.TL_messageActionGiftPremium) {
|
||||
|
@ -23231,7 +23231,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
} else {
|
||||
allowPin = false;
|
||||
}
|
||||
allowPin = allowPin && message.getId() > 0 && (message.messageOwner.action == null || message.messageOwner.action instanceof TLRPC.TL_messageActionEmpty) && !message.isExpiredStory();
|
||||
allowPin = allowPin && message.getId() > 0 && (message.messageOwner.action == null || message.messageOwner.action instanceof TLRPC.TL_messageActionEmpty) && !message.isExpiredStory() && message.type != MessageObject.TYPE_STORY_MENTION;
|
||||
boolean noforwards = getMessagesController().isChatNoForwards(currentChat) || message.messageOwner.noforwards;
|
||||
boolean allowUnpin = message.getDialogId() != mergeDialogId && allowPin && (pinnedMessageObjects.containsKey(message.getId()) || groupedMessages != null && !groupedMessages.messages.isEmpty() && pinnedMessageObjects.containsKey(groupedMessages.messages.get(0).getId())) && !message.isExpiredStory();
|
||||
boolean allowEdit = message.canEditMessage(currentChat) && !chatActivityEnterView.hasAudioToSend() && message.getDialogId() != mergeDialogId && message.type != MessageObject.TYPE_STORY;
|
||||
|
@ -23645,7 +23645,8 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
}
|
||||
if (!selectedObject.isSponsored() && chatMode != MODE_SCHEDULED && (!selectedObject.needDrawBluredPreview() || selectedObject.hasExtendedMediaPreview()) &&
|
||||
!selectedObject.isLiveLocation() && selectedObject.type != MessageObject.TYPE_PHONE_CALL && !noforwards &&
|
||||
selectedObject.type != MessageObject.TYPE_GIFT_PREMIUM && selectedObject.type != MessageObject.TYPE_SUGGEST_PHOTO && !selectedObject.isWallpaperAction() && !message.isExpiredStory()) {
|
||||
selectedObject.type != MessageObject.TYPE_GIFT_PREMIUM && selectedObject.type != MessageObject.TYPE_SUGGEST_PHOTO && !selectedObject.isWallpaperAction()
|
||||
&& !message.isExpiredStory() && message.type != MessageObject.TYPE_STORY_MENTION) {
|
||||
items.add(LocaleController.getString("Forward", R.string.Forward));
|
||||
options.add(OPTION_FORWARD);
|
||||
icons.add(R.drawable.msg_forward);
|
||||
|
|
|
@ -34,6 +34,7 @@ import org.telegram.messenger.ImageReceiver;
|
|||
import org.telegram.messenger.LiteMode;
|
||||
import org.telegram.messenger.MessageObject;
|
||||
import org.telegram.messenger.MessagesStorage;
|
||||
import org.telegram.messenger.NotificationCenter;
|
||||
import org.telegram.messenger.SharedConfig;
|
||||
import org.telegram.messenger.SvgHelper;
|
||||
import org.telegram.messenger.UserConfig;
|
||||
|
@ -41,7 +42,7 @@ import org.telegram.tgnet.ConnectionsManager;
|
|||
import org.telegram.tgnet.NativeByteBuffer;
|
||||
import org.telegram.tgnet.TLRPC;
|
||||
import org.telegram.ui.ActionBar.Theme;
|
||||
import org.telegram.ui.Components.Premium.PremiumLockIconView;
|
||||
import org.telegram.ui.Components.Reactions.HwEmojis;
|
||||
import org.telegram.ui.SelectAnimatedEmojiDialog;
|
||||
|
||||
import java.io.File;
|
||||
|
@ -146,6 +147,7 @@ public class AnimatedEmojiDrawable extends Drawable {
|
|||
}
|
||||
|
||||
private static HashMap<Integer, EmojiDocumentFetcher> fetchers;
|
||||
|
||||
public static EmojiDocumentFetcher getDocumentFetcher(int account) {
|
||||
if (fetchers == null) {
|
||||
fetchers = new HashMap<>();
|
||||
|
@ -156,17 +158,23 @@ public class AnimatedEmojiDrawable extends Drawable {
|
|||
}
|
||||
return fetcher;
|
||||
}
|
||||
|
||||
public static class EmojiDocumentFetcher {
|
||||
private HashMap<Long, TLRPC.Document> emojiDocumentsCache;
|
||||
private HashMap<Long, ArrayList<ReceivedDocument>> loadingDocuments;
|
||||
private HashSet<Long> toFetchDocuments;
|
||||
private Runnable fetchRunnable;
|
||||
private Runnable uiDbCallback;
|
||||
private final int currentAccount;
|
||||
|
||||
public EmojiDocumentFetcher(int account) {
|
||||
currentAccount = account;
|
||||
}
|
||||
|
||||
public void setUiDbCallback(Runnable uiDbCallback) {
|
||||
this.uiDbCallback = uiDbCallback;
|
||||
}
|
||||
|
||||
public void fetchDocument(long id, ReceivedDocument onDone) {
|
||||
synchronized (this) {
|
||||
if (emojiDocumentsCache != null) {
|
||||
|
@ -204,7 +212,7 @@ public class AnimatedEmojiDrawable extends Drawable {
|
|||
AndroidUtilities.runOnUIThread(fetchRunnable = () -> {
|
||||
ArrayList<Long> emojiToLoad = new ArrayList<>(toFetchDocuments);
|
||||
toFetchDocuments.clear();
|
||||
loadFromDatabase(emojiToLoad);
|
||||
loadFromDatabase(emojiToLoad, uiDbCallback == null);
|
||||
fetchRunnable = null;
|
||||
});
|
||||
}
|
||||
|
@ -219,51 +227,73 @@ public class AnimatedEmojiDrawable extends Drawable {
|
|||
return true;
|
||||
}
|
||||
|
||||
private void loadFromDatabase(ArrayList<Long> emojiToLoad, boolean async) {
|
||||
if (async) {
|
||||
MessagesStorage messagesStorage = MessagesStorage.getInstance(currentAccount);
|
||||
messagesStorage.getStorageQueue().postRunnable(() -> loadFromDatabase(emojiToLoad));
|
||||
} else {
|
||||
loadFromDatabase(emojiToLoad);
|
||||
}
|
||||
}
|
||||
|
||||
private void loadFromDatabase(ArrayList<Long> emojiToLoad) {
|
||||
MessagesStorage messagesStorage = MessagesStorage.getInstance(currentAccount);
|
||||
messagesStorage.getStorageQueue().postRunnable(() -> {
|
||||
SQLiteDatabase database = messagesStorage.getDatabase();
|
||||
if (database == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
String idsStr = TextUtils.join(",", emojiToLoad);
|
||||
SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT data FROM animated_emoji WHERE document_id IN (%s)", idsStr));
|
||||
ArrayList<Object> documents = new ArrayList<>();
|
||||
HashSet<Long> loadFromServerIds = new HashSet<>(emojiToLoad);
|
||||
while (cursor.next()) {
|
||||
NativeByteBuffer byteBuffer = cursor.byteBufferValue(0);
|
||||
try {
|
||||
TLRPC.Document document = TLRPC.Document.TLdeserialize(byteBuffer, byteBuffer.readInt32(true), true);
|
||||
if (document != null && document.id != 0) {
|
||||
documents.add(document);
|
||||
loadFromServerIds.remove(document.id);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
FileLog.e(e);
|
||||
}
|
||||
if (byteBuffer != null) {
|
||||
byteBuffer.reuse();
|
||||
SQLiteDatabase database = messagesStorage.getDatabase();
|
||||
if (database == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
String idsStr = TextUtils.join(",", emojiToLoad);
|
||||
SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT data FROM animated_emoji WHERE document_id IN (%s)", idsStr));
|
||||
ArrayList<Object> documents = new ArrayList<>();
|
||||
HashSet<Long> loadFromServerIds = new HashSet<>(emojiToLoad);
|
||||
while (cursor.next()) {
|
||||
NativeByteBuffer byteBuffer = cursor.byteBufferValue(0);
|
||||
try {
|
||||
TLRPC.Document document = TLRPC.Document.TLdeserialize(byteBuffer, byteBuffer.readInt32(true), true);
|
||||
if (document != null && document.id != 0) {
|
||||
documents.add(document);
|
||||
loadFromServerIds.remove(document.id);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
FileLog.e(e);
|
||||
}
|
||||
if (byteBuffer != null) {
|
||||
byteBuffer.reuse();
|
||||
}
|
||||
|
||||
AndroidUtilities.runOnUIThread(() -> {
|
||||
processDocuments(documents);
|
||||
if (!loadFromServerIds.isEmpty()) {
|
||||
loadFromServer(new ArrayList<>(loadFromServerIds));
|
||||
}
|
||||
});
|
||||
cursor.dispose();
|
||||
} catch (SQLiteException e) {
|
||||
messagesStorage.checkSQLException(e);
|
||||
}
|
||||
});
|
||||
|
||||
processDatabaseResult(documents, loadFromServerIds);
|
||||
cursor.dispose();
|
||||
|
||||
if (uiDbCallback != null) {
|
||||
uiDbCallback.run();
|
||||
uiDbCallback = null;
|
||||
}
|
||||
} catch (SQLiteException e) {
|
||||
messagesStorage.checkSQLException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void processDocumentsAndLoadMore(ArrayList<Object> documents, HashSet<Long> loadFromServerIds) {
|
||||
processDocuments(documents);
|
||||
if (!loadFromServerIds.isEmpty()) {
|
||||
loadFromServer(new ArrayList<>(loadFromServerIds));
|
||||
}
|
||||
}
|
||||
|
||||
private void processDatabaseResult(ArrayList<Object> documents, HashSet<Long> loadFromServerIds) {
|
||||
if (Thread.currentThread() == Looper.getMainLooper().getThread()) {
|
||||
processDocumentsAndLoadMore(documents, loadFromServerIds);
|
||||
} else {
|
||||
NotificationCenter.getInstance(currentAccount).doOnIdle(() -> AndroidUtilities.runOnUIThread(() -> processDocumentsAndLoadMore(documents, loadFromServerIds)));
|
||||
}
|
||||
}
|
||||
|
||||
private void loadFromServer(ArrayList<Long> loadFromServerIds) {
|
||||
final TLRPC.TL_messages_getCustomEmojiDocuments req = new TLRPC.TL_messages_getCustomEmojiDocuments();
|
||||
req.document_id = loadFromServerIds;
|
||||
ConnectionsManager.getInstance(currentAccount).sendRequest(req, (res, err) -> AndroidUtilities.runOnUIThread(() -> {
|
||||
ConnectionsManager.getInstance(currentAccount).sendRequest(req, (res, err) -> NotificationCenter.getInstance(currentAccount).doOnIdle(() -> AndroidUtilities.runOnUIThread(() -> {
|
||||
HashSet<Long> loadedFromServer = new HashSet<>(loadFromServerIds);
|
||||
if (res instanceof TLRPC.Vector) {
|
||||
ArrayList<Object> objects = ((TLRPC.Vector) res).objects;
|
||||
|
@ -280,7 +310,7 @@ public class AnimatedEmojiDrawable extends Drawable {
|
|||
loadFromServer(new ArrayList<>(loadedFromServer));
|
||||
}
|
||||
}
|
||||
}));
|
||||
})));
|
||||
}
|
||||
|
||||
private void putToStorage(ArrayList<Object> objects) {
|
||||
|
@ -438,11 +468,13 @@ public class AnimatedEmojiDrawable extends Drawable {
|
|||
sizedp = 34;
|
||||
}
|
||||
}
|
||||
|
||||
public long getDocumentId() {
|
||||
return this.document != null ? this.document.id : this.documentId;
|
||||
}
|
||||
|
||||
private static boolean liteModeKeyboard, liteModeReactions;
|
||||
|
||||
private static void updateLiteModeValues() {
|
||||
liteModeKeyboard = LiteMode.isEnabled(LiteMode.FLAG_ANIMATED_EMOJI_KEYBOARD);
|
||||
liteModeReactions = LiteMode.isEnabled(LiteMode.FLAG_ANIMATED_EMOJI_REACTIONS);
|
||||
|
@ -472,6 +504,7 @@ public class AnimatedEmojiDrawable extends Drawable {
|
|||
};
|
||||
imageReceiver.setAllowLoadingOnAttachedOnly(true);
|
||||
};
|
||||
|
||||
if (cacheType == CACHE_TYPE_RENDERING_VIDEO) {
|
||||
imageReceiver.ignoreNotifications = true;
|
||||
}
|
||||
|
@ -541,7 +574,7 @@ public class AnimatedEmojiDrawable extends Drawable {
|
|||
if (onlyStaticPreview || (!liteModeKeyboard && cacheType != CACHE_TYPE_AVATAR_CONSTRUCTOR_PREVIEW)) {
|
||||
if ("video/webm".equals(document.mime_type)) {
|
||||
imageReceiver.setImage(null, null, ImageLocation.getForDocument(thumb, document), sizedp + "_" + sizedp, null, null, thumbDrawable, document.size, null, document, 1);
|
||||
} else if (MessageObject.isAnimatedStickerDocument(document, true)){
|
||||
} else if (MessageObject.isAnimatedStickerDocument(document, true)) {
|
||||
imageReceiver.setImage(mediaLocation, mediaFilter + "_firstframe", null, null, thumbDrawable, document.size, null, document, 1);
|
||||
} else {
|
||||
imageReceiver.setImage(ImageLocation.getForDocument(thumb, document), sizedp + "_" + sizedp, null, null, thumbDrawable, document.size, null, document, 1);
|
||||
|
@ -612,6 +645,7 @@ public class AnimatedEmojiDrawable extends Drawable {
|
|||
}
|
||||
|
||||
private static Paint placeholderPaint;
|
||||
|
||||
public static void updatePlaceholderPaintColor() {
|
||||
if (placeholderPaint != null) {
|
||||
placeholderPaint.setColor(Theme.isCurrentThemeDark() ? 0x0fffffff : 0x0f000000);
|
||||
|
@ -706,6 +740,7 @@ public class AnimatedEmojiDrawable extends Drawable {
|
|||
|
||||
public static int attachedCount = 0;
|
||||
public static ArrayList<AnimatedEmojiDrawable> attachedDrawable;
|
||||
|
||||
private void updateAttachState() {
|
||||
if (imageReceiver == null) {
|
||||
return;
|
||||
|
@ -742,6 +777,7 @@ public class AnimatedEmojiDrawable extends Drawable {
|
|||
}
|
||||
|
||||
private Boolean canOverrideColorCached = null;
|
||||
|
||||
public boolean canOverrideColor() {
|
||||
if (canOverrideColorCached != null) {
|
||||
return canOverrideColorCached;
|
||||
|
@ -753,6 +789,7 @@ public class AnimatedEmojiDrawable extends Drawable {
|
|||
}
|
||||
|
||||
private Boolean isDefaultStatusEmojiCached = null;
|
||||
|
||||
public boolean isDefaultStatusEmoji() {
|
||||
if (isDefaultStatusEmojiCached != null) {
|
||||
return isDefaultStatusEmojiCached;
|
||||
|
@ -760,8 +797,8 @@ public class AnimatedEmojiDrawable extends Drawable {
|
|||
if (document != null) {
|
||||
TLRPC.InputStickerSet set = MessageObject.getInputStickerSet(document);
|
||||
return isDefaultStatusEmojiCached = (
|
||||
set instanceof TLRPC.TL_inputStickerSetEmojiDefaultStatuses ||
|
||||
set instanceof TLRPC.TL_inputStickerSetID && (set.id == 773947703670341676L || set.id == 2964141614563343L)
|
||||
set instanceof TLRPC.TL_inputStickerSetEmojiDefaultStatuses ||
|
||||
set instanceof TLRPC.TL_inputStickerSetID && (set.id == 773947703670341676L || set.id == 2964141614563343L)
|
||||
);
|
||||
}
|
||||
return false;
|
||||
|
@ -812,6 +849,7 @@ public class AnimatedEmojiDrawable extends Drawable {
|
|||
}
|
||||
|
||||
private static HashMap<Long, Integer> dominantColors;
|
||||
|
||||
public static int getDominantColor(AnimatedEmojiDrawable yourDrawable) {
|
||||
if (yourDrawable == null) {
|
||||
return 0;
|
||||
|
@ -868,6 +906,7 @@ public class AnimatedEmojiDrawable extends Drawable {
|
|||
}
|
||||
|
||||
private int alpha = 255;
|
||||
|
||||
@Override
|
||||
public void setAlpha(int alpha) {
|
||||
this.alpha = alpha;
|
||||
|
@ -945,6 +984,7 @@ public class AnimatedEmojiDrawable extends Drawable {
|
|||
|
||||
private Integer lastColor;
|
||||
private ColorFilter colorFilter;
|
||||
|
||||
public void setColor(Integer color) {
|
||||
if (lastColor == null && color == null || lastColor != null && lastColor.equals(color)) {
|
||||
return;
|
||||
|
@ -967,17 +1007,17 @@ public class AnimatedEmojiDrawable extends Drawable {
|
|||
drawables[1].setBounds(bounds);
|
||||
} else if (center) {
|
||||
drawables[1].setBounds(
|
||||
bounds.centerX() - drawables[1].getIntrinsicWidth() / 2,
|
||||
bounds.centerY() - drawables[1].getIntrinsicHeight() / 2,
|
||||
bounds.centerX() + drawables[1].getIntrinsicWidth() / 2,
|
||||
bounds.centerY() + drawables[1].getIntrinsicHeight() / 2
|
||||
bounds.centerX() - drawables[1].getIntrinsicWidth() / 2,
|
||||
bounds.centerY() - drawables[1].getIntrinsicHeight() / 2,
|
||||
bounds.centerX() + drawables[1].getIntrinsicWidth() / 2,
|
||||
bounds.centerY() + drawables[1].getIntrinsicHeight() / 2
|
||||
);
|
||||
} else { // left
|
||||
drawables[1].setBounds(
|
||||
bounds.left,
|
||||
bounds.centerY() - drawables[1].getIntrinsicHeight() / 2,
|
||||
bounds.left + drawables[1].getIntrinsicWidth(),
|
||||
bounds.centerY() + drawables[1].getIntrinsicHeight() / 2
|
||||
bounds.left,
|
||||
bounds.centerY() - drawables[1].getIntrinsicHeight() / 2,
|
||||
bounds.left + drawables[1].getIntrinsicWidth(),
|
||||
bounds.centerY() + drawables[1].getIntrinsicHeight() / 2
|
||||
);
|
||||
}
|
||||
drawables[1].setColorFilter(colorFilter);
|
||||
|
@ -1001,10 +1041,10 @@ public class AnimatedEmojiDrawable extends Drawable {
|
|||
canvas.scale(scale, scale, bounds.centerX(), bounds.centerY());
|
||||
}
|
||||
drawables[0].setBounds(
|
||||
bounds.centerX() - drawables[0].getIntrinsicWidth() / 2,
|
||||
bounds.centerY() - drawables[0].getIntrinsicHeight() / 2,
|
||||
bounds.centerX() + drawables[0].getIntrinsicWidth() / 2,
|
||||
bounds.centerY() + drawables[0].getIntrinsicHeight() / 2
|
||||
bounds.centerX() - drawables[0].getIntrinsicWidth() / 2,
|
||||
bounds.centerY() - drawables[0].getIntrinsicHeight() / 2,
|
||||
bounds.centerX() + drawables[0].getIntrinsicWidth() / 2,
|
||||
bounds.centerY() + drawables[0].getIntrinsicHeight() / 2
|
||||
);
|
||||
} else { // left
|
||||
if (progress < 1) {
|
||||
|
@ -1012,10 +1052,10 @@ public class AnimatedEmojiDrawable extends Drawable {
|
|||
canvas.scale(scale, scale, bounds.left + drawables[0].getIntrinsicWidth() / 2f, bounds.centerY());
|
||||
}
|
||||
drawables[0].setBounds(
|
||||
bounds.left,
|
||||
bounds.centerY() - drawables[0].getIntrinsicHeight() / 2,
|
||||
bounds.left + drawables[0].getIntrinsicWidth(),
|
||||
bounds.centerY() + drawables[0].getIntrinsicHeight() / 2
|
||||
bounds.left,
|
||||
bounds.centerY() - drawables[0].getIntrinsicHeight() / 2,
|
||||
bounds.left + drawables[0].getIntrinsicWidth(),
|
||||
bounds.centerY() + drawables[0].getIntrinsicHeight() / 2
|
||||
);
|
||||
}
|
||||
drawables[0].setAlpha(alpha);
|
||||
|
@ -1185,8 +1225,10 @@ public class AnimatedEmojiDrawable extends Drawable {
|
|||
public void setAlpha(int i) {
|
||||
alpha = i;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColorFilter(@Nullable ColorFilter colorFilter) {}
|
||||
|
||||
@Override
|
||||
public int getOpacity() {
|
||||
return PixelFormat.TRANSPARENT;
|
||||
|
|
|
@ -23,6 +23,7 @@ import android.text.Layout;
|
|||
import android.text.StaticLayout;
|
||||
import android.text.TextPaint;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Pair;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
|
@ -35,6 +36,8 @@ import org.telegram.ui.ActionBar.Theme;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
public class AnimatedTextView extends View {
|
||||
|
@ -352,6 +355,7 @@ public class AnimatedTextView extends View {
|
|||
CharSequence to = splitByWords ? new WordSequence(currentText) : currentText;
|
||||
|
||||
diff(from, to, onEqualRegion, onNewPart, onOldPart);
|
||||
// betterDiff(from, to, onEqualRegion, onNewPart, onOldPart);
|
||||
|
||||
if (this.currentParts == null || this.currentParts.length != currentParts.size()) {
|
||||
this.currentParts = new Part[currentParts.size()];
|
||||
|
@ -597,6 +601,81 @@ public class AnimatedTextView extends View {
|
|||
return (a == null && b == null || a != null && b != null && a.charAt(aIndex) == b.charAt(bIndex));
|
||||
}
|
||||
|
||||
private void betterDiff(final CharSequence oldText, final CharSequence newText,
|
||||
RegionCallback onEqualPart, RegionCallback onNewPart, RegionCallback onOldPart) {
|
||||
int m = oldText.length();
|
||||
int n = newText.length();
|
||||
|
||||
int[][] dp = new int[m+1][n+1];
|
||||
for (int i = 0; i <= m; i++) {
|
||||
for (int j = 0; j <= n; j++) {
|
||||
if (i == 0 || j == 0)
|
||||
dp[i][j] = 0;
|
||||
else if (partEquals(oldText, newText, i - 1, j - 1))
|
||||
dp[i][j] = dp[i - 1][j - 1] + 1;
|
||||
else
|
||||
dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
|
||||
}
|
||||
}
|
||||
|
||||
List<Runnable> parts = new ArrayList<>();
|
||||
int i = m, j = n;
|
||||
while (i > 0 && j > 0) {
|
||||
if (partEquals(oldText, newText, i - 1, j - 1)) {
|
||||
int start = i-1;
|
||||
while (i > 1 && j > 1 && partEquals(oldText, newText, i - 2, j - 2)) {
|
||||
i--;
|
||||
j--;
|
||||
}
|
||||
final int end = i - 1;
|
||||
parts.add(() -> onEqualPart.run(oldText.subSequence(end, start + 1), end, start + 1));
|
||||
i--;
|
||||
j--;
|
||||
} else if (dp[i - 1][j] > dp[i][j - 1]) {
|
||||
int start = i-1;
|
||||
while (i > 1 && dp[i - 2][j] > dp[i - 1][j - 1]) {
|
||||
i--;
|
||||
}
|
||||
final int end = i - 1;
|
||||
parts.add(() -> onOldPart.run(oldText.subSequence(end, start + 1), end, start + 1));
|
||||
i--;
|
||||
} else {
|
||||
int start = j - 1;
|
||||
while (j > 1 && dp[i][j - 2] > dp[i - 1][j - 1]) {
|
||||
j--;
|
||||
}
|
||||
final int end = j - 1;
|
||||
parts.add(() -> onNewPart.run(newText.subSequence(end, start + 1), end, start + 1));
|
||||
j--;
|
||||
}
|
||||
}
|
||||
|
||||
while (i > 0) {
|
||||
final int start = i - 1;
|
||||
while (i > 1 && dp[i - 2][j] >= dp[i - 1][j]) {
|
||||
i--;
|
||||
}
|
||||
final int end = i - 1;
|
||||
parts.add(() -> onOldPart.run(oldText.subSequence(end, start + 1), end, start + 1));
|
||||
i--;
|
||||
}
|
||||
while (j > 0) {
|
||||
final int start = j - 1;
|
||||
while (j > 1 && dp[i][j - 2] >= dp[i][j - 1]) {
|
||||
j--;
|
||||
}
|
||||
final int end = j - 1;
|
||||
parts.add(() -> onNewPart.run(newText.subSequence(end, start + 1), end, start + 1));
|
||||
j--;
|
||||
}
|
||||
|
||||
Collections.reverse(parts);
|
||||
for (Runnable part : parts) {
|
||||
part.run();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void diff(final CharSequence oldText, final CharSequence newText, RegionCallback onEqualPart, RegionCallback onNewPart, RegionCallback onOldPart) {
|
||||
if (updateAll) {
|
||||
onOldPart.run(oldText, 0, oldText.length());
|
||||
|
|
|
@ -41,7 +41,7 @@ public class BackupImageView extends View {
|
|||
|
||||
public BackupImageView(Context context) {
|
||||
super(context);
|
||||
imageReceiver = new ImageReceiver(this);
|
||||
imageReceiver = createImageReciever();
|
||||
imageReceiver.setAllowLoadingOnAttachedOnly(true);
|
||||
imageReceiver.setDelegate((imageReceiver1, set, thumb, memCache) -> {
|
||||
if (set && !thumb) {
|
||||
|
@ -50,6 +50,10 @@ public class BackupImageView extends View {
|
|||
});
|
||||
}
|
||||
|
||||
protected ImageReceiver createImageReciever() {
|
||||
return new ImageReceiver(this);
|
||||
}
|
||||
|
||||
public void setBlurAllowed(boolean blurAllowed) {
|
||||
if (attached) {
|
||||
throw new IllegalStateException("You should call setBlurAllowed(...) only when detached!");
|
||||
|
|
|
@ -947,6 +947,7 @@ public class ChatAttachAlertDocumentLayout extends ChatAttachAlert.AttachAlertLa
|
|||
|
||||
private void checkDirectory(File rootDir) {
|
||||
File[] files = rootDir.listFiles();
|
||||
File storiesDir = FileLoader.checkDirectory(FileLoader.MEDIA_DIR_STORIES);
|
||||
if (files != null) {
|
||||
for (int a = 0; a < files.length; a++) {
|
||||
File file = files[a];
|
||||
|
@ -954,6 +955,9 @@ public class ChatAttachAlertDocumentLayout extends ChatAttachAlert.AttachAlertLa
|
|||
checkDirectory(file);
|
||||
continue;
|
||||
}
|
||||
if (file.equals(storiesDir)) {
|
||||
continue;
|
||||
}
|
||||
ListItem item = new ListItem();
|
||||
item.title = file.getName();
|
||||
item.file = file;
|
||||
|
@ -1165,11 +1169,17 @@ public class ChatAttachAlertDocumentLayout extends ChatAttachAlert.AttachAlertLa
|
|||
}
|
||||
currentDir = dir;
|
||||
listAdapter.items.clear();
|
||||
|
||||
File storiesDir = FileLoader.checkDirectory(FileLoader.MEDIA_DIR_STORIES);
|
||||
for (int a = 0; a < files.length; a++) {
|
||||
File file = files[a];
|
||||
if (file.getName().indexOf('.') == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (file.equals(storiesDir)) {
|
||||
continue;
|
||||
}
|
||||
ListItem item = new ListItem();
|
||||
item.title = file.getName();
|
||||
item.file = file;
|
||||
|
|
|
@ -164,10 +164,10 @@ public class ChatScrimPopupContainerLayout extends LinearLayout {
|
|||
updateBottomViewPosition();
|
||||
}
|
||||
|
||||
public void setPopupAlpha(float aplha) {
|
||||
popupWindowLayout.setAlpha(aplha);
|
||||
public void setPopupAlpha(float alpha) {
|
||||
popupWindowLayout.setAlpha(alpha);
|
||||
if (bottomView != null) {
|
||||
bottomView.setAlpha(aplha);
|
||||
bottomView.setAlpha(alpha);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -94,7 +94,7 @@ public class ColoredImageSpan extends ReplacementSpan {
|
|||
canvas.save();
|
||||
int transY = bottom - (drawable != null ? drawable.getBounds().bottom : bottom);
|
||||
if (verticalAlignment == ALIGN_BASELINE) {
|
||||
transY -= paint.getFontMetricsInt().descent;
|
||||
// transY -= paint.getFontMetricsInt().descent;
|
||||
} else if (verticalAlignment == ALIGN_CENTER) {
|
||||
transY = top + (bottom - top) / 2 - (drawable != null ? drawable.getBounds().height() / 2 : 0);
|
||||
} else if (verticalAlignment == ALIGN_DEFAULT) {
|
||||
|
|
|
@ -451,6 +451,9 @@ public class CropView extends FrameLayout implements CropAreaView.AreaViewListen
|
|||
}
|
||||
|
||||
public void updateMatrix(boolean force) {
|
||||
if (state == null) {
|
||||
return;
|
||||
}
|
||||
overlayMatrix.reset();
|
||||
if (state.getBaseRotation() == 90 || state.getBaseRotation() == 270) {
|
||||
overlayMatrix.postTranslate(-state.getHeight() / 2, -state.getWidth() / 2);
|
||||
|
|
|
@ -9,6 +9,8 @@ import android.text.TextPaint;
|
|||
import android.text.style.CharacterStyle;
|
||||
import android.view.View;
|
||||
|
||||
import org.telegram.ui.Components.Reactions.HwEmojis;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class EllipsizeSpanAnimator {
|
||||
|
@ -81,7 +83,9 @@ public class EllipsizeSpanAnimator {
|
|||
a.addUpdateListener(valueAnimator -> {
|
||||
target.setAlpha((int) valueAnimator.getAnimatedValue());
|
||||
for (int i = 0; i < ellipsizedViews.size(); i++) {
|
||||
ellipsizedViews.get(i).invalidate();
|
||||
if (!HwEmojis.isHwEnabled()) {
|
||||
ellipsizedViews.get(i).invalidate();
|
||||
}
|
||||
}
|
||||
});
|
||||
a.setDuration(duration);
|
||||
|
|
|
@ -37,6 +37,7 @@ import org.telegram.messenger.UserConfig;
|
|||
import org.telegram.tgnet.TLRPC;
|
||||
import org.telegram.ui.ActionBar.Theme;
|
||||
import org.telegram.ui.Components.Premium.PremiumLockIconView;
|
||||
import org.telegram.ui.Components.Reactions.HwEmojis;
|
||||
import org.telegram.ui.SelectAnimatedEmojiDialog;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -127,7 +128,7 @@ public class EmojiTabsStrip extends ScrollableHorizontalScrollView {
|
|||
child.setScaleX(0);
|
||||
child.setScaleY(0);
|
||||
child.setAlpha(0);
|
||||
child.animate().scaleX(1f).scaleY(1f).alpha(1f).setDuration(200).setInterpolator(CubicBezierInterpolator.EASE_OUT_QUINT).start();
|
||||
child.animate().scaleX(1f).scaleY(1f).alpha(1f).setDuration(HwEmojis.isHwEnabledOrPreparing() ? 0 : 200).setInterpolator(CubicBezierInterpolator.EASE_OUT_QUINT).start();
|
||||
}
|
||||
if (id != null) {
|
||||
if (lastX.get(id) != null && lastX.get(id) != x) {
|
||||
|
@ -313,6 +314,17 @@ public class EmojiTabsStrip extends ScrollableHorizontalScrollView {
|
|||
}
|
||||
}
|
||||
|
||||
public void showRecentTabStub(boolean show) {
|
||||
if (recentTab == null) {
|
||||
return;
|
||||
}
|
||||
if (show) {
|
||||
recentTab.setBackground(new StabDrawable(selectorColor()));
|
||||
} else {
|
||||
recentTab.setBackground(null);
|
||||
}
|
||||
}
|
||||
|
||||
public void showSelected(boolean show) {
|
||||
this.showSelected = show;
|
||||
this.contentView.invalidate();
|
||||
|
@ -372,6 +384,37 @@ public class EmojiTabsStrip extends ScrollableHorizontalScrollView {
|
|||
return null;
|
||||
}
|
||||
|
||||
private static class StabDrawable extends Drawable {
|
||||
private final Paint paint = new Paint();
|
||||
private final RectF rectF = new RectF();
|
||||
|
||||
public StabDrawable(int color){
|
||||
paint.setAlpha(45);
|
||||
paint.setColor(color);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(@NonNull Canvas canvas) {
|
||||
rectF.set(0, 0, AndroidUtilities.dp(30), AndroidUtilities.dp(30));
|
||||
canvas.drawRoundRect(rectF, AndroidUtilities.dpf2(8), AndroidUtilities.dpf2(8), paint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAlpha(int alpha) {
|
||||
paint.setAlpha(alpha);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColorFilter(@Nullable ColorFilter colorFilter) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOpacity() {
|
||||
return PixelFormat.TRANSLUCENT;
|
||||
}
|
||||
}
|
||||
|
||||
private static class DelayedAnimatedEmojiDrawable extends Drawable {
|
||||
|
||||
int account;
|
||||
|
@ -678,7 +721,7 @@ public class EmojiTabsStrip extends ScrollableHorizontalScrollView {
|
|||
if (settingsTab != null) {
|
||||
settingsTab.bringToFront();
|
||||
if (settingsTab.getAlpha() < 1) {
|
||||
settingsTab.animate().alpha(1f).setDuration(200).setInterpolator(CubicBezierInterpolator.DEFAULT).start();
|
||||
settingsTab.animate().alpha(1f).setDuration(HwEmojis.isHwEnabledOrPreparing() ? 0 : 200).setInterpolator(CubicBezierInterpolator.DEFAULT).start();
|
||||
}
|
||||
}
|
||||
// if (doAppearAnimation) {
|
||||
|
@ -935,10 +978,21 @@ public class EmojiTabsStrip extends ScrollableHorizontalScrollView {
|
|||
imageView = new ImageView(context) {
|
||||
@Override
|
||||
public void invalidate() {
|
||||
if (HwEmojis.grab(this)) {
|
||||
return;
|
||||
}
|
||||
super.invalidate();
|
||||
updateLockImageReceiver();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidate(int l, int t, int r, int b) {
|
||||
if (HwEmojis.grab(this)) {
|
||||
return;
|
||||
}
|
||||
super.invalidate(l, t, r, b);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
|
||||
|
@ -966,7 +1020,23 @@ public class EmojiTabsStrip extends ScrollableHorizontalScrollView {
|
|||
}
|
||||
addView(imageView);
|
||||
|
||||
lockView = new PremiumLockIconView(context, PremiumLockIconView.TYPE_STICKERS_PREMIUM_LOCKED, resourcesProvider);
|
||||
lockView = new PremiumLockIconView(context, PremiumLockIconView.TYPE_STICKERS_PREMIUM_LOCKED, resourcesProvider) {
|
||||
@Override
|
||||
public void invalidate() {
|
||||
if (HwEmojis.grab(this)) {
|
||||
return;
|
||||
}
|
||||
super.invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidate(int l, int t, int r, int b) {
|
||||
if (HwEmojis.grab(this)) {
|
||||
return;
|
||||
}
|
||||
super.invalidate(l, t, r, b);
|
||||
}
|
||||
};
|
||||
lockView.setAlpha(0f);
|
||||
lockView.setScaleX(0);
|
||||
lockView.setScaleY(0);
|
||||
|
@ -976,6 +1046,22 @@ public class EmojiTabsStrip extends ScrollableHorizontalScrollView {
|
|||
setColor(Theme.getColor(Theme.key_chat_emojiPanelIcon, resourcesProvider));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidate() {
|
||||
if (HwEmojis.grab(this)) {
|
||||
return;
|
||||
}
|
||||
super.invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidate(int l, int t, int r, int b) {
|
||||
if (HwEmojis.grab(this)) {
|
||||
return;
|
||||
}
|
||||
super.invalidate(l, t, r, b);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dispatchDraw(Canvas canvas) {
|
||||
super.dispatchDraw(canvas);
|
||||
|
@ -1116,7 +1202,7 @@ public class EmojiTabsStrip extends ScrollableHorizontalScrollView {
|
|||
}
|
||||
});
|
||||
lockAnimator.setInterpolator(CubicBezierInterpolator.DEFAULT);
|
||||
lockAnimator.setDuration(200);
|
||||
lockAnimator.setDuration(HwEmojis.isHwEnabledOrPreparing() ? 0 : 200);
|
||||
lockAnimator.start();
|
||||
}
|
||||
|
||||
|
@ -1175,7 +1261,7 @@ public class EmojiTabsStrip extends ScrollableHorizontalScrollView {
|
|||
if (animatedEmoji != null && attached && wasVisible) {
|
||||
animatedEmoji.updateView(imageView);
|
||||
}
|
||||
if (wasVisible) {
|
||||
if (wasVisible && animatedEmoji != null) {
|
||||
animatedEmoji.load();
|
||||
}
|
||||
initLock();
|
||||
|
@ -1250,7 +1336,7 @@ public class EmojiTabsStrip extends ScrollableHorizontalScrollView {
|
|||
}
|
||||
}
|
||||
});
|
||||
selectAnimator.setDuration(350);
|
||||
selectAnimator.setDuration(HwEmojis.isHwEnabledOrPreparing() ? 0 : 350);
|
||||
selectAnimator.setInterpolator(CubicBezierInterpolator.EASE_OUT_QUINT);
|
||||
selectAnimator.start();
|
||||
} else {
|
||||
|
|
|
@ -155,6 +155,8 @@ public class EmojiView extends FrameLayout implements NotificationCenter.Notific
|
|||
private final static int TAB_GIFS = 1;
|
||||
private final static int TAB_STICKERS = 2;
|
||||
|
||||
public int emojiCacheType = AnimatedEmojiDrawable.CACHE_TYPE_KEYBOARD;
|
||||
|
||||
private ArrayList<Tab> allTabs = new ArrayList<>();
|
||||
private ArrayList<Tab> currentTabs = new ArrayList<>();
|
||||
private boolean ignorePagerScroll;
|
||||
|
@ -2838,7 +2840,7 @@ public class EmojiView extends FrameLayout implements NotificationCenter.Notific
|
|||
}
|
||||
|
||||
public void updateEmojiDrawables() {
|
||||
animatedEmojiDrawables = AnimatedEmojiSpan.update(AnimatedEmojiDrawable.CACHE_TYPE_KEYBOARD, this, getAnimatedEmojiSpans(), animatedEmojiDrawables);
|
||||
animatedEmojiDrawables = AnimatedEmojiSpan.update(emojiCacheType, this, getAnimatedEmojiSpans(), animatedEmojiDrawables);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -79,6 +79,7 @@ import org.telegram.messenger.BuildVars;
|
|||
import org.telegram.messenger.DispatchQueue;
|
||||
import org.telegram.messenger.FileLoader;
|
||||
import org.telegram.messenger.FileLog;
|
||||
import org.telegram.messenger.ImageLoader;
|
||||
import org.telegram.messenger.ImageReceiver;
|
||||
import org.telegram.messenger.LocaleController;
|
||||
import org.telegram.messenger.MediaController;
|
||||
|
@ -103,6 +104,7 @@ import org.telegram.ui.Components.voip.CellFlickerDrawable;
|
|||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
@ -123,6 +125,8 @@ import javax.microedition.khronos.egl.EGLSurface;
|
|||
@TargetApi(18)
|
||||
public class InstantCameraView extends FrameLayout implements NotificationCenter.NotificationCenterDelegate {
|
||||
|
||||
public boolean WRITE_TO_FILE_IN_BACKGROUND = true;
|
||||
|
||||
private int currentAccount = UserConfig.selectedAccount;
|
||||
private InstantViewCameraContainer cameraContainer;
|
||||
private Delegate delegate;
|
||||
|
@ -1730,6 +1734,8 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
|
|||
private static final int IFRAME_INTERVAL = 1;
|
||||
|
||||
private File videoFile;
|
||||
private File fileToWrite;
|
||||
private boolean writingToDifferentFile;
|
||||
private int videoWidth;
|
||||
private int videoHeight;
|
||||
private int videoBitrate;
|
||||
|
@ -2302,6 +2308,18 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
|
|||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (writingToDifferentFile) {
|
||||
if (!fileToWrite.renameTo(videoFile)) {
|
||||
FileLog.e("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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (generateKeyframeThumbsQueue != null) {
|
||||
generateKeyframeThumbsQueue.cleanupQueue();
|
||||
|
@ -2394,7 +2412,16 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
|
|||
});
|
||||
} else {
|
||||
FileLoader.getInstance(currentAccount).cancelFileUpload(videoFile.getAbsolutePath(), false);
|
||||
videoFile.delete();
|
||||
try {
|
||||
fileToWrite.delete();
|
||||
} catch (Throwable ignore) {
|
||||
|
||||
}
|
||||
try {
|
||||
videoFile.delete();
|
||||
} catch (Throwable ignore) {
|
||||
|
||||
}
|
||||
}
|
||||
EGL14.eglDestroySurface(eglDisplay, eglSurface);
|
||||
eglSurface = EGL14.EGL_NO_SURFACE;
|
||||
|
@ -2491,8 +2518,23 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
|
|||
surface = videoEncoder.createInputSurface();
|
||||
videoEncoder.start();
|
||||
|
||||
boolean isSdCard = ImageLoader.isSdCardPath(videoFile);
|
||||
fileToWrite = videoFile;
|
||||
if (isSdCard) {
|
||||
try {
|
||||
fileToWrite = new File(ApplicationLoader.getFilesDirFixed(), "camera_tmp.mp4");
|
||||
if (fileToWrite.exists()) {
|
||||
fileToWrite.delete();
|
||||
}
|
||||
writingToDifferentFile = true;
|
||||
} catch (Throwable e) {
|
||||
FileLog.e(e);
|
||||
fileToWrite = videoFile;
|
||||
writingToDifferentFile = false;
|
||||
}
|
||||
}
|
||||
Mp4Movie movie = new Mp4Movie();
|
||||
movie.setCacheFile(videoFile);
|
||||
movie.setCacheFile(fileToWrite);
|
||||
movie.setRotation(0);
|
||||
movie.setSize(videoWidth, videoHeight);
|
||||
mediaMuxer = new MP4Builder().createMovie(movie, isSecretChat, false);
|
||||
|
@ -2684,31 +2726,30 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
|
|||
}
|
||||
firstEncode = false;
|
||||
}
|
||||
MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
|
||||
bufferInfo.size = videoBufferInfo.size;
|
||||
bufferInfo.offset = videoBufferInfo.offset;
|
||||
bufferInfo.flags = videoBufferInfo.flags;
|
||||
bufferInfo.presentationTimeUs = videoBufferInfo.presentationTimeUs;
|
||||
needReleaseBuffers = false;
|
||||
fileWriteQueue.postRunnable(() -> {
|
||||
long availableSize = 0;
|
||||
try {
|
||||
availableSize = mediaMuxer.writeSampleData(videoTrackIndex, encodedData, bufferInfo, true);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
MediaCodec videoEncoder = VideoRecorder.this.videoEncoder;
|
||||
if (videoEncoder != null) {
|
||||
if (WRITE_TO_FILE_IN_BACKGROUND) {
|
||||
MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
|
||||
bufferInfo.size = videoBufferInfo.size;
|
||||
bufferInfo.offset = videoBufferInfo.offset;
|
||||
bufferInfo.flags = videoBufferInfo.flags;
|
||||
bufferInfo.presentationTimeUs = videoBufferInfo.presentationTimeUs;
|
||||
ByteBuffer byteBuffer = encodedData.duplicate();
|
||||
fileWriteQueue.postRunnable(() -> {
|
||||
long availableSize = 0;
|
||||
try {
|
||||
videoEncoder.releaseOutputBuffer(encoderStatus, false);
|
||||
} catch (Throwable e) {
|
||||
//ignore IllegalStateException if codec released
|
||||
availableSize = mediaMuxer.writeSampleData(videoTrackIndex, byteBuffer, bufferInfo, true);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (availableSize != 0) {
|
||||
if (availableSize != 0 && !writingToDifferentFile) {
|
||||
didWriteData(videoFile, availableSize, false);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
long availableSize = mediaMuxer.writeSampleData(videoTrackIndex, encodedData, videoBufferInfo, true);
|
||||
if (availableSize != 0 && !writingToDifferentFile) {
|
||||
didWriteData(videoFile, availableSize, false);
|
||||
}
|
||||
});
|
||||
}
|
||||
} else if (videoTrackIndex == -5) {
|
||||
byte[] csd = new byte[videoBufferInfo.size];
|
||||
encodedData.limit(videoBufferInfo.offset + videoBufferInfo.size);
|
||||
|
@ -2780,31 +2821,33 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
|
|||
audioBufferInfo.size = 0;
|
||||
}
|
||||
if (audioBufferInfo.size != 0) {
|
||||
MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
|
||||
bufferInfo.size = audioBufferInfo.size;
|
||||
bufferInfo.offset = audioBufferInfo.offset;
|
||||
bufferInfo.flags = audioBufferInfo.flags;
|
||||
bufferInfo.presentationTimeUs = audioBufferInfo.presentationTimeUs;
|
||||
fileWriteQueue.postRunnable(() -> {
|
||||
long availableSize = 0;
|
||||
try {
|
||||
availableSize = mediaMuxer.writeSampleData(audioTrackIndex, encodedData, bufferInfo, false);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (availableSize != 0) {
|
||||
if (WRITE_TO_FILE_IN_BACKGROUND) {
|
||||
MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
|
||||
bufferInfo.size = audioBufferInfo.size;
|
||||
bufferInfo.offset = audioBufferInfo.offset;
|
||||
bufferInfo.flags = audioBufferInfo.flags;
|
||||
bufferInfo.presentationTimeUs = audioBufferInfo.presentationTimeUs;
|
||||
ByteBuffer byteBuffer = encodedData.duplicate();
|
||||
fileWriteQueue.postRunnable(() -> {
|
||||
long availableSize = 0;
|
||||
try {
|
||||
availableSize = mediaMuxer.writeSampleData(audioTrackIndex, byteBuffer, bufferInfo, false);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (availableSize != 0 && !writingToDifferentFile) {
|
||||
didWriteData(videoFile, availableSize, false);
|
||||
}
|
||||
});
|
||||
audioEncoder.releaseOutputBuffer(encoderStatus, false);
|
||||
} else {
|
||||
long availableSize = mediaMuxer.writeSampleData(audioTrackIndex, encodedData, audioBufferInfo, false);
|
||||
if (availableSize != 0 && !writingToDifferentFile) {
|
||||
didWriteData(videoFile, availableSize, false);
|
||||
}
|
||||
MediaCodec audioEncoder = VideoRecorder.this.audioEncoder;
|
||||
if (audioEncoder != null) {
|
||||
try {
|
||||
audioEncoder.releaseOutputBuffer(encoderStatus, false);
|
||||
} catch (Throwable e) {
|
||||
//ignore IllegalStateException if codec released
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
audioEncoder.releaseOutputBuffer(encoderStatus, false);
|
||||
}
|
||||
} else if (audioEncoder != null) {
|
||||
audioEncoder.releaseOutputBuffer(encoderStatus, false);
|
||||
}
|
||||
if ((audioBufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
|
||||
|
|
|
@ -28,6 +28,7 @@ import androidx.core.graphics.ColorUtils;
|
|||
import com.google.android.exoplayer2.util.Consumer;
|
||||
|
||||
import org.telegram.messenger.AndroidUtilities;
|
||||
import org.telegram.messenger.LocaleController;
|
||||
import org.telegram.messenger.R;
|
||||
import org.telegram.ui.ActionBar.ActionBarMenuSubItem;
|
||||
import org.telegram.ui.ActionBar.ActionBarPopupWindow;
|
||||
|
@ -153,7 +154,7 @@ public class ItemOptions {
|
|||
}
|
||||
|
||||
ActionBarMenuSubItem subItem = new ActionBarMenuSubItem(context, false, false, resourcesProvider);
|
||||
subItem.setPadding(AndroidUtilities.dp(18), 0, AndroidUtilities.dp(18 + 8), 0);
|
||||
subItem.setPadding(AndroidUtilities.dp(18), 0, AndroidUtilities.dp(18 + (LocaleController.isRTL ? 0 : 8)), 0);
|
||||
subItem.setTextAndIcon(text, iconResId);
|
||||
|
||||
subItem.setColors(Theme.getColor(textColorKey, resourcesProvider), Theme.getColor(iconColorKey, resourcesProvider));
|
||||
|
|
|
@ -129,7 +129,7 @@ public class MediaActivity extends BaseFragment implements SharedMediaLayout.Sha
|
|||
public boolean onFragmentCreate() {
|
||||
type = getArguments().getInt("type", TYPE_MEDIA);
|
||||
dialogId = getArguments().getLong("dialog_id");
|
||||
initialTab = getArguments().getInt("start_from", SharedMediaLayout.TAB_STORIES);
|
||||
initialTab = getArguments().getInt("start_from", type == TYPE_MEDIA ? SharedMediaLayout.TAB_PHOTOVIDEO : SharedMediaLayout.TAB_STORIES);
|
||||
getNotificationCenter().addObserver(this, NotificationCenter.userInfoDidLoad);
|
||||
getNotificationCenter().addObserver(this, NotificationCenter.currentUserPremiumStatusChanged);
|
||||
getNotificationCenter().addObserver(this, NotificationCenter.storiesEnabledUpdate);
|
||||
|
@ -612,6 +612,11 @@ public class MediaActivity extends BaseFragment implements SharedMediaLayout.Sha
|
|||
return type == TYPE_STORIES;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean includeStories() {
|
||||
return type == TYPE_STORIES;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getInitialTab() {
|
||||
return initialTab;
|
||||
|
|
|
@ -141,7 +141,12 @@ public class PersistColorPalette {
|
|||
|
||||
public int getColor(int index) {
|
||||
checkIndex(index);
|
||||
|
||||
if (index < 0 || index >= colors.size()) {
|
||||
if (index >= 0 && index < DEFAULT_COLORS.size()) {
|
||||
return DEFAULT_COLORS.get(index);
|
||||
}
|
||||
return DEFAULT_COLORS.get(0);
|
||||
}
|
||||
return colors.get(index);
|
||||
}
|
||||
|
||||
|
@ -155,12 +160,18 @@ public class PersistColorPalette {
|
|||
pendingChange.clear();
|
||||
pendingChange.add(color);
|
||||
pendingChange.addAll(from);
|
||||
pendingChange.remove(pendingChange.size() - 1);
|
||||
if (pendingChange.size() < DEFAULT_COLORS.size()) {
|
||||
for (int j = pendingChange.size(); j < DEFAULT_COLORS.size(); ++j) {
|
||||
pendingChange.add(DEFAULT_COLORS.get(j));
|
||||
}
|
||||
} else if (pendingChange.size() > DEFAULT_COLORS.size()) {
|
||||
pendingChange = pendingChange.subList(0, DEFAULT_COLORS.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void selectColorIndex(int index) {
|
||||
int color = colors.get(index);
|
||||
int color = index < 0 || index >= colors.size() ? DEFAULT_COLORS.get(index) : colors.get(index);
|
||||
List<Integer> from = new ArrayList<>(pendingChange.isEmpty() ? colors : pendingChange);
|
||||
pendingChange.clear();
|
||||
pendingChange.add(color);
|
||||
|
@ -171,6 +182,13 @@ public class PersistColorPalette {
|
|||
pendingChange.add(from.get(i));
|
||||
}
|
||||
}
|
||||
if (pendingChange.size() < DEFAULT_COLORS.size()) {
|
||||
for (int j = pendingChange.size(); j < DEFAULT_COLORS.size(); ++j) {
|
||||
pendingChange.add(DEFAULT_COLORS.get(j));
|
||||
}
|
||||
} else if (pendingChange.size() > DEFAULT_COLORS.size()) {
|
||||
pendingChange = pendingChange.subList(0, DEFAULT_COLORS.size());
|
||||
}
|
||||
}
|
||||
|
||||
private void loadColors() {
|
||||
|
|
|
@ -228,8 +228,11 @@ public class EditTextOutline extends EditTextBoldCursor {
|
|||
}
|
||||
if (traceback) {
|
||||
for (int j = i; j >= 1; --j) {
|
||||
above = lines[i - 1];
|
||||
above = lines[j - 1];
|
||||
line = lines[j];
|
||||
if (above.width() < dp(1) || line.width() < dp(1)) {
|
||||
continue;
|
||||
}
|
||||
if (Math.abs(above.left - line.left) < mr) {
|
||||
line.left = above.left = Math.min(line.left, above.left);
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ import org.telegram.messenger.ImageReceiver;
|
|||
import org.telegram.messenger.LocaleController;
|
||||
import org.telegram.messenger.VideoEditedInfo;
|
||||
import org.telegram.tgnet.TLRPC;
|
||||
import org.telegram.ui.ActionBar.Theme;
|
||||
import org.telegram.ui.Components.Paint.Views.EditTextOutline;
|
||||
import org.telegram.ui.Components.Paint.Views.PaintTextOptionsView;
|
||||
|
||||
|
@ -252,22 +253,22 @@ public class PaintingOverlay extends FrameLayout {
|
|||
if (Build.VERSION.SDK_INT >= 23) {
|
||||
editText.setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE);
|
||||
}
|
||||
if ((entity.subType & 1) != 0) {
|
||||
editText.setTextColor(0xffffffff);
|
||||
editText.setStrokeColor(entity.color);
|
||||
editText.setFrameColor(0);
|
||||
editText.setShadowLayer(0, 0, 0, 0);
|
||||
} else if ((entity.subType & 4) != 0) {
|
||||
editText.setTextColor(0xff000000);
|
||||
editText.setStrokeColor(0);
|
||||
editText.setShadowLayer(0, 0, 0, 0);
|
||||
int textColor = entity.color;
|
||||
if (entity.subType == 0) {
|
||||
editText.setFrameColor(entity.color);
|
||||
editText.setShadowLayer(0, 0, 0, 0);
|
||||
textColor = AndroidUtilities.computePerceivedBrightness(entity.color) >= .721f ? Color.BLACK : Color.WHITE;
|
||||
} else if (entity.subType == 1) {
|
||||
editText.setFrameColor(AndroidUtilities.computePerceivedBrightness(entity.color) >= .25f ? 0x99000000 : 0x99ffffff);
|
||||
} else if (entity.subType == 2) {
|
||||
editText.setFrameColor(AndroidUtilities.computePerceivedBrightness(entity.color) >= .25f ? Color.BLACK : Color.WHITE);
|
||||
} else {
|
||||
editText.setTextColor(entity.color);
|
||||
editText.setStrokeColor(0);
|
||||
editText.setFrameColor(0);
|
||||
editText.setShadowLayer(5, 0, 1, 0x66000000);
|
||||
}
|
||||
editText.setTextColor(textColor);
|
||||
editText.setCursorColor(textColor);
|
||||
editText.setHandlesColor(textColor);
|
||||
editText.setHighlightColor(Theme.multAlpha(textColor, .4f));
|
||||
entity.view = child = editText;
|
||||
}
|
||||
if (child != null) {
|
||||
|
|
|
@ -623,6 +623,8 @@ public class PhotoViewerCaptionEnterView extends FrameLayout implements Notifica
|
|||
return -10177041;
|
||||
} else if (key == Theme.key_dialogFloatingIcon) {
|
||||
return 0xffffffff;
|
||||
} else if (key == Theme.key_chat_emojiPanelStickerSetName) {
|
||||
return 0x73ffffff;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -637,6 +639,7 @@ public class PhotoViewerCaptionEnterView extends FrameLayout implements Notifica
|
|||
return;
|
||||
}
|
||||
emojiView = new EmojiView(null, true, false, false, getContext(), false, null, null, true, resourcesProvider);
|
||||
emojiView.emojiCacheType = AnimatedEmojiDrawable.CACHE_TYPE_ALERT_PREVIEW;
|
||||
emojiView.setDelegate(new EmojiView.EmojiViewDelegate() {
|
||||
@Override
|
||||
public boolean onBackspace() {
|
||||
|
@ -712,6 +715,7 @@ public class PhotoViewerCaptionEnterView extends FrameLayout implements Notifica
|
|||
}
|
||||
if (!isRecent) {
|
||||
span.fromEmojiKeyboard = true;
|
||||
span.cacheType = AnimatedEmojiDrawable.CACHE_TYPE_ALERT_PREVIEW;
|
||||
}
|
||||
spannable.setSpan(span, 0, spannable.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
messageEditText.setText(messageEditText.getText().insert(i, spannable));
|
||||
|
|
|
@ -70,6 +70,7 @@ public class PremiumButtonView extends FrameLayout {
|
|||
LinearLayout linearLayout = new LinearLayout(context);
|
||||
linearLayout.setOrientation(LinearLayout.HORIZONTAL);
|
||||
buttonTextView = new AnimatedTextView(context);
|
||||
buttonTextView.setAnimationProperties(.35f, 0, 350, CubicBezierInterpolator.EASE_OUT_QUINT);
|
||||
buttonTextView.setGravity(Gravity.CENTER);
|
||||
buttonTextView.setTextColor(Color.WHITE);
|
||||
buttonTextView.setTextSize(AndroidUtilities.dp(14));
|
||||
|
|
|
@ -7,6 +7,7 @@ import android.animation.AnimatorListenerAdapter;
|
|||
import android.animation.ValueAnimator;
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Outline;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Path;
|
||||
import android.graphics.PixelFormat;
|
||||
|
@ -15,10 +16,12 @@ import android.graphics.PorterDuffColorFilter;
|
|||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.view.Gravity;
|
||||
import android.view.HapticFeedbackConstants;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewOutlineProvider;
|
||||
import android.view.WindowManager;
|
||||
import android.view.animation.OvershootInterpolator;
|
||||
import android.widget.FrameLayout;
|
||||
|
@ -43,9 +46,11 @@ import org.telegram.ui.ChatActivity;
|
|||
import org.telegram.ui.Components.Bulletin;
|
||||
import org.telegram.ui.Components.BulletinFactory;
|
||||
import org.telegram.ui.Components.CubicBezierInterpolator;
|
||||
import org.telegram.ui.Components.EmojiTabsStrip;
|
||||
import org.telegram.ui.Components.LayoutHelper;
|
||||
import org.telegram.ui.Components.Premium.PremiumFeatureBottomSheet;
|
||||
import org.telegram.ui.Components.ReactionsContainerLayout;
|
||||
import org.telegram.ui.Components.StableAnimator;
|
||||
import org.telegram.ui.LaunchActivity;
|
||||
import org.telegram.ui.PremiumPreviewFragment;
|
||||
import org.telegram.ui.SelectAnimatedEmojiDialog;
|
||||
|
@ -70,7 +75,7 @@ public class CustomEmojiReactionsWindow {
|
|||
|
||||
SelectAnimatedEmojiDialog selectAnimatedEmojiDialog;
|
||||
ReactionsContainerLayout reactionsContainerLayout;
|
||||
Path pathToClip = new Path();
|
||||
private final Path pathToClipApi20 = new Path();
|
||||
private boolean invalidatePath;
|
||||
|
||||
List<ReactionsLayoutInBubble.VisibleReaction> reactions;
|
||||
|
@ -199,6 +204,24 @@ public class CustomEmojiReactionsWindow {
|
|||
containerView.invalidate();
|
||||
}
|
||||
};
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
selectAnimatedEmojiDialog.setOutlineProvider(new ViewOutlineProvider() {
|
||||
final Rect rect = new Rect();
|
||||
final RectF rectTmp = new RectF();
|
||||
final RectF rectF = new RectF();
|
||||
|
||||
@Override
|
||||
public void getOutline(View view, Outline outline) {
|
||||
float radius = AndroidUtilities.lerp(fromRadius, AndroidUtilities.dp(8), enterTransitionProgress);
|
||||
rectTmp.set(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
|
||||
AndroidUtilities.lerp(fromRect, rectTmp, enterTransitionProgress, rectF);
|
||||
rectF.round(rect);
|
||||
outline.setRoundRect(rect, radius);
|
||||
}
|
||||
});
|
||||
selectAnimatedEmojiDialog.setClipToOutline(true);
|
||||
}
|
||||
|
||||
selectAnimatedEmojiDialog.setOnLongPressedListener(new SelectAnimatedEmojiDialog.onLongPressedListener() {
|
||||
@Override
|
||||
public void onLongPressed(SelectAnimatedEmojiDialog.ImageViewEmoji view) {
|
||||
|
@ -234,6 +257,7 @@ public class CustomEmojiReactionsWindow {
|
|||
windowManager.addView(windowView, lp);
|
||||
|
||||
this.reactionsContainerLayout = reactionsContainerLayout;
|
||||
reactionsContainerLayout.setOnSwitchedToLoopView(() -> containerView.invalidate()); //fixed emoji freeze
|
||||
reactionsContainerLayout.prepareAnimation(true);
|
||||
AndroidUtilities.runOnUIThread(() -> {
|
||||
isShowing = true;
|
||||
|
@ -333,50 +357,57 @@ public class CustomEmojiReactionsWindow {
|
|||
cascadeAnimation = false;
|
||||
}
|
||||
if (cascadeAnimation) {
|
||||
updateCascadeEnter(0);
|
||||
updateCascadeEnter(0, true);
|
||||
}
|
||||
updateContainersAlpha();
|
||||
selectAnimatedEmojiDialog.setEnterAnimationInProgress(true);
|
||||
selectAnimatedEmojiDialog.emojiTabs.showRecentTabStub(enter && cascadeAnimation);
|
||||
account = UserConfig.selectedAccount;
|
||||
notificationsLocker.lock();
|
||||
valueAnimator = ValueAnimator.ofFloat(enterTransitionProgress, enter ? 1f : 0);
|
||||
valueAnimator = StableAnimator.ofFloat(enterTransitionProgress, enter ? 1f : 0);
|
||||
valueAnimator.addUpdateListener(animation -> {
|
||||
valueAnimator = null;
|
||||
enterTransitionProgress = (float) animation.getAnimatedValue();
|
||||
reactionsContainerLayout.setCustomEmojiEnterProgress(Utilities.clamp(enterTransitionProgress,1f, 0));
|
||||
updateContainersAlpha();
|
||||
updateContentPosition();
|
||||
reactionsContainerLayout.setCustomEmojiEnterProgress(Utilities.clamp(enterTransitionProgress, 1f, 0));
|
||||
invalidatePath = true;
|
||||
containerView.invalidate();
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
selectAnimatedEmojiDialog.invalidateOutline();
|
||||
}
|
||||
if (cascadeAnimation) {
|
||||
updateCascadeEnter(enterTransitionProgress);
|
||||
updateCascadeEnter(enterTransitionProgress, enter);
|
||||
}
|
||||
});
|
||||
if (!enter) {
|
||||
syncReactionFrames(enter);
|
||||
syncReactionFrames();
|
||||
}
|
||||
valueAnimator.addListener(new AnimatorListenerAdapter() {
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
checkAnimationEnd();
|
||||
updateContainersAlpha();
|
||||
updateContentPosition();
|
||||
checkAnimationEnd(enter);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
selectAnimatedEmojiDialog.invalidateOutline();
|
||||
}
|
||||
enterTransitionProgress = enter ? 1f : 0f;
|
||||
if (enter) {
|
||||
enterTransitionFinished = true;
|
||||
selectAnimatedEmojiDialog.resetBackgroundBitmaps();
|
||||
reactionsContainerLayout.onCustomEmojiWindowOpened();
|
||||
containerView.invalidate();
|
||||
}
|
||||
reactionsContainerLayout.setCustomEmojiEnterProgress(Utilities.clamp(enterTransitionProgress, 1f, 0f));
|
||||
if (enter) {
|
||||
syncReactionFrames(enter);
|
||||
}
|
||||
if (!enter) {
|
||||
reactionsContainerLayout.setSkipDraw(false);
|
||||
}
|
||||
if (!enter) {
|
||||
removeView();
|
||||
Runtime.getRuntime().gc(); //to prevent garbage collection when reopening
|
||||
reactionsContainerLayout.setCustomEmojiReactionsBackground(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
valueAnimator.setStartDelay(30);
|
||||
|
||||
if (cascadeAnimation) {
|
||||
valueAnimator.setDuration(450);
|
||||
valueAnimator.setInterpolator(new OvershootInterpolator(0.5f));
|
||||
|
@ -384,15 +415,68 @@ public class CustomEmojiReactionsWindow {
|
|||
valueAnimator.setDuration(350);
|
||||
valueAnimator.setInterpolator(CubicBezierInterpolator.DEFAULT);
|
||||
}
|
||||
valueAnimator.start();
|
||||
containerView.invalidate();
|
||||
switchLayerType(true);
|
||||
if (!enter) {
|
||||
reactionsContainerLayout.isHiddenNextReaction = true;
|
||||
reactionsContainerLayout.invalidate();
|
||||
valueAnimator.setStartDelay(30);
|
||||
valueAnimator.start();
|
||||
} else {
|
||||
reactionsContainerLayout.setCustomEmojiReactionsBackground(false);
|
||||
final ValueAnimator finalAnimator = valueAnimator;
|
||||
HwEmojis.prepare(finalAnimator::start, cascadeAnimation);
|
||||
}
|
||||
HwEmojis.enableHw();
|
||||
}
|
||||
|
||||
private void updateContainersAlpha() {
|
||||
if (!cascadeAnimation) {
|
||||
selectAnimatedEmojiDialog.searchBox.setAlpha(enterTransitionProgress);
|
||||
selectAnimatedEmojiDialog.emojiGridView.setAlpha(enterTransitionProgress);
|
||||
selectAnimatedEmojiDialog.emojiSearchGridView.setAlpha(enterTransitionProgress);
|
||||
selectAnimatedEmojiDialog.emojiTabs.setAlpha(enterTransitionProgress);
|
||||
selectAnimatedEmojiDialog.emojiTabsShadow.setAlpha(enterTransitionProgress);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateContentPosition() {
|
||||
selectAnimatedEmojiDialog.contentView.setTranslationX(cascadeAnimation ? 0 : containerView.enterTransitionOffsetX);
|
||||
selectAnimatedEmojiDialog.contentView.setTranslationY(containerView.enterTransitionOffsetY);
|
||||
selectAnimatedEmojiDialog.contentView.setPivotX(containerView.enterTransitionScalePx);
|
||||
selectAnimatedEmojiDialog.contentView.setPivotY(containerView.enterTransitionScalePy);
|
||||
selectAnimatedEmojiDialog.contentView.setScaleX(containerView.enterTransitionScale);
|
||||
selectAnimatedEmojiDialog.contentView.setScaleY(containerView.enterTransitionScale);
|
||||
}
|
||||
|
||||
private void switchLayerType(boolean hardware) {
|
||||
int layerType = hardware ? View.LAYER_TYPE_HARDWARE : View.LAYER_TYPE_NONE;
|
||||
selectAnimatedEmojiDialog.emojiGridView.setLayerType(layerType, null);
|
||||
selectAnimatedEmojiDialog.searchBox.setLayerType(layerType, null);
|
||||
if (cascadeAnimation) {
|
||||
for (int i = 0; i < Math.min(selectAnimatedEmojiDialog.emojiTabs.contentView.getChildCount(), 16); i++) {
|
||||
View child = selectAnimatedEmojiDialog.emojiTabs.contentView.getChildAt(i);
|
||||
child.setLayerType(layerType, null);
|
||||
}
|
||||
} else {
|
||||
selectAnimatedEmojiDialog.emojiTabsShadow.setLayerType(layerType, null);
|
||||
selectAnimatedEmojiDialog.emojiTabs.setLayerType(layerType, null);
|
||||
}
|
||||
}
|
||||
|
||||
HashSet<View> animatingEnterChild = new HashSet<>();
|
||||
ArrayList<ValueAnimator> animators = new ArrayList<>();
|
||||
|
||||
private void updateCascadeEnter(float progress) {
|
||||
int fullHeight = selectAnimatedEmojiDialog.contentView.getHeight();
|
||||
private void setScaleForChild(View child, float value) {
|
||||
if (child instanceof SelectAnimatedEmojiDialog.ImageViewEmoji) {
|
||||
((SelectAnimatedEmojiDialog.ImageViewEmoji) child).setAnimatedScale(value);
|
||||
} else if (child instanceof EmojiTabsStrip.EmojiTabButton) {
|
||||
child.setScaleX(value);
|
||||
child.setScaleY(value);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateCascadeEnter(float progress, boolean enter) {
|
||||
int parentTop = (int) (selectAnimatedEmojiDialog.getY() + selectAnimatedEmojiDialog.contentView.getY() + selectAnimatedEmojiDialog.emojiGridView.getY());
|
||||
ArrayList<View> animatedViews = null;
|
||||
boolean updated = false;
|
||||
|
@ -409,8 +493,7 @@ public class CustomEmojiReactionsWindow {
|
|||
animatedViews.add(child);
|
||||
animatingEnterChild.add(child);
|
||||
} else {
|
||||
child.setScaleX(0f);
|
||||
child.setScaleY(0f);
|
||||
setScaleForChild(child, 0f);
|
||||
updated = true;
|
||||
}
|
||||
}
|
||||
|
@ -428,15 +511,12 @@ public class CustomEmojiReactionsWindow {
|
|||
animatedViews.add(child);
|
||||
animatingEnterChild.add(child);
|
||||
} else {
|
||||
child.setScaleX(0f);
|
||||
child.setScaleY(0f);
|
||||
setScaleForChild(child, 0f);
|
||||
updated = true;
|
||||
}
|
||||
}
|
||||
if (updated) {
|
||||
selectAnimatedEmojiDialog.emojiGridView.invalidate();
|
||||
selectAnimatedEmojiDialog.contentView.invalidate();
|
||||
selectAnimatedEmojiDialog.emojiTabs.contentView.invalidate();
|
||||
selectAnimatedEmojiDialog.emojiGridViewContainer.invalidate();
|
||||
}
|
||||
if (animatedViews != null) {
|
||||
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1f);
|
||||
|
@ -444,12 +524,10 @@ public class CustomEmojiReactionsWindow {
|
|||
valueAnimator.addUpdateListener(animation -> {
|
||||
float s = (float) animation.getAnimatedValue();
|
||||
for (int i = 0; i < finalAnimatedViews.size(); i++) {
|
||||
finalAnimatedViews.get(i).setScaleX(s);
|
||||
finalAnimatedViews.get(i).setScaleY(s);
|
||||
View v = finalAnimatedViews.get(i);
|
||||
setScaleForChild(v, s);
|
||||
}
|
||||
selectAnimatedEmojiDialog.emojiGridView.invalidate();
|
||||
selectAnimatedEmojiDialog.contentView.invalidate();
|
||||
selectAnimatedEmojiDialog.emojiTabs.contentView.invalidate();
|
||||
selectAnimatedEmojiDialog.emojiGridViewContainer.invalidate();
|
||||
});
|
||||
animators.add(valueAnimator);
|
||||
valueAnimator.addListener(new AnimatorListenerAdapter() {
|
||||
|
@ -457,7 +535,7 @@ public class CustomEmojiReactionsWindow {
|
|||
public void onAnimationEnd(Animator animation) {
|
||||
super.onAnimationEnd(animation);
|
||||
animators.remove(valueAnimator);
|
||||
checkAnimationEnd();
|
||||
checkAnimationEnd(enter);
|
||||
}
|
||||
});
|
||||
valueAnimator.setDuration(350);
|
||||
|
@ -466,16 +544,32 @@ public class CustomEmojiReactionsWindow {
|
|||
}
|
||||
}
|
||||
|
||||
private void checkAnimationEnd() {
|
||||
private void checkAnimationEnd(boolean enter) {
|
||||
if (animators.isEmpty()) {
|
||||
switchLayerType(false);
|
||||
HwEmojis.disableHw();
|
||||
notificationsLocker.unlock();
|
||||
selectAnimatedEmojiDialog.setEnterAnimationInProgress(false);
|
||||
if (enter) {
|
||||
selectAnimatedEmojiDialog.emojiTabs.showRecentTabStub(false);
|
||||
selectAnimatedEmojiDialog.emojiGridView.invalidate();
|
||||
selectAnimatedEmojiDialog.emojiGridView.invalidateViews();
|
||||
selectAnimatedEmojiDialog.searchBox.checkInitialization();
|
||||
if (reactionsContainerLayout.getPullingLeftProgress() > 0) {
|
||||
reactionsContainerLayout.isHiddenNextReaction = false;
|
||||
reactionsContainerLayout.onCustomEmojiWindowOpened();
|
||||
} else {
|
||||
reactionsContainerLayout.isHiddenNextReaction = true;
|
||||
reactionsContainerLayout.onCustomEmojiWindowOpened();
|
||||
}
|
||||
selectAnimatedEmojiDialog.resetBackgroundBitmaps();
|
||||
syncReactionFrames();
|
||||
containerView.invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void syncReactionFrames(boolean enter) {
|
||||
HashMap<ReactionsLayoutInBubble.VisibleReaction, SelectAnimatedEmojiDialog.ImageViewEmoji> transitionReactions = new HashMap<>();
|
||||
|
||||
private void syncReactionFrames() {
|
||||
for (int i = 0; i < selectAnimatedEmojiDialog.emojiGridView.getChildCount(); i++) {
|
||||
if (selectAnimatedEmojiDialog.emojiGridView.getChildAt(i) instanceof SelectAnimatedEmojiDialog.ImageViewEmoji) {
|
||||
SelectAnimatedEmojiDialog.ImageViewEmoji imageViewEmoji = (SelectAnimatedEmojiDialog.ImageViewEmoji) selectAnimatedEmojiDialog.emojiGridView.getChildAt(i);
|
||||
|
@ -562,7 +656,7 @@ public class CustomEmojiReactionsWindow {
|
|||
windowView.animate().alpha(0).setDuration(150).setListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
checkAnimationEnd();
|
||||
checkAnimationEnd(false);
|
||||
enterTransitionProgress = 0f;
|
||||
reactionsContainerLayout.setCustomEmojiEnterProgress(Utilities.clamp(enterTransitionProgress, 1f, 0f));
|
||||
reactionsContainerLayout.setSkipDraw(false);
|
||||
|
@ -620,6 +714,12 @@ public class CustomEmojiReactionsWindow {
|
|||
|
||||
HashMap<ReactionsLayoutInBubble.VisibleReaction, SelectAnimatedEmojiDialog.ImageViewEmoji> transitionReactions = new HashMap<>();
|
||||
|
||||
float enterTransitionOffsetX = 0;
|
||||
float enterTransitionOffsetY = 0;
|
||||
float enterTransitionScale = 1f;
|
||||
float enterTransitionScalePx = 0;
|
||||
float enterTransitionScalePy = 0;
|
||||
|
||||
@Override
|
||||
protected void dispatchDraw(Canvas canvas) {
|
||||
if (!isShowing) {
|
||||
|
@ -649,11 +749,11 @@ public class CustomEmojiReactionsWindow {
|
|||
reactionsContainerLayout.drawBubbles(canvas);
|
||||
canvas.restore();
|
||||
}
|
||||
float enterTransitionOffsetX = 0;
|
||||
float enterTransitionOffsetY = 0;
|
||||
float enterTransitionScale = 1f;
|
||||
float enterTransitionScalePx = 0;
|
||||
float enterTransitionScalePy = 0;
|
||||
enterTransitionOffsetX = 0;
|
||||
enterTransitionOffsetY = 0;
|
||||
enterTransitionScale = 1f;
|
||||
enterTransitionScalePx = 0;
|
||||
enterTransitionScalePy = 0;
|
||||
|
||||
if (reactionsContainerLayout != null) {
|
||||
for (int i = 0; i < selectAnimatedEmojiDialog.emojiGridView.getChildCount(); i++) {
|
||||
|
@ -669,7 +769,8 @@ public class CustomEmojiReactionsWindow {
|
|||
|
||||
canvas.translate(drawingRect.left, drawingRect.top + reactionsContainerLayout.expandSize() * (1f - enterTransitionProgress));
|
||||
|
||||
float alpha = Math.max(selectAnimatedEmojiDialog.emojiGridView.getAlpha(), 1f - enterTransitionProgress);
|
||||
float a = selectAnimatedEmojiDialog.emojiSearchGridView.getVisibility() == View.VISIBLE ? selectAnimatedEmojiDialog.emojiSearchGridView.getAlpha() : 0;
|
||||
float alpha = Math.max(1f - a, 1f - enterTransitionProgress);
|
||||
if (alpha != 1f) {
|
||||
canvas.saveLayerAlpha(0, 0, drawingRect.width(), drawingRect.height(), (int) (255 * alpha), Canvas.ALL_SAVE_FLAG);
|
||||
}
|
||||
|
@ -678,9 +779,6 @@ public class CustomEmojiReactionsWindow {
|
|||
canvas.clipRect(left, top + AndroidUtilities.dp(36) * enterTransitionProgress, left + selectAnimatedEmojiDialog.emojiGridView.getMeasuredHeight(), top + selectAnimatedEmojiDialog.emojiGridView.getMeasuredWidth());
|
||||
for (int i = -1; i < reactionsContainerLayout.recyclerListView.getChildCount(); i++) {
|
||||
View child;
|
||||
if (enterTransitionProgress == 1 && i == -1) {
|
||||
continue;
|
||||
}
|
||||
if (i == -1) {
|
||||
child = reactionsContainerLayout.nextRecentReaction;
|
||||
} else {
|
||||
|
@ -802,6 +900,9 @@ public class CustomEmojiReactionsWindow {
|
|||
imageReceiver.setAlpha(oldAlpha);
|
||||
}
|
||||
}
|
||||
if (holderView.loopImageView.getVisibility() != View.VISIBLE) {
|
||||
invalidate();
|
||||
}
|
||||
} else {
|
||||
canvas.translate(child.getX() + drawingRect.width() - reactionsContainerLayout.rect.width(), child.getY() + fromRect.top - drawingRect.top);
|
||||
canvas.saveLayerAlpha(0, 0, child.getMeasuredWidth(), child.getMeasuredHeight(), (int) (255 * (1f - progressClpamped)), Canvas.ALL_SAVE_FLAG);
|
||||
|
@ -814,20 +915,20 @@ public class CustomEmojiReactionsWindow {
|
|||
canvas.restoreToCount(restoreCount);
|
||||
}
|
||||
|
||||
if (invalidatePath) {
|
||||
invalidatePath = false;
|
||||
pathToClip.rewind();
|
||||
pathToClip.addRoundRect(drawingRect, radius, radius, Path.Direction.CW);
|
||||
boolean beforeLollipop = Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP;
|
||||
if (beforeLollipop) {
|
||||
if (invalidatePath) {
|
||||
invalidatePath = false;
|
||||
pathToClipApi20.rewind();
|
||||
pathToClipApi20.addRoundRect(drawingRect, radius, radius, Path.Direction.CW);
|
||||
}
|
||||
canvas.save();
|
||||
canvas.clipPath(pathToClipApi20);
|
||||
super.dispatchDraw(canvas);
|
||||
canvas.restore();
|
||||
} else {
|
||||
super.dispatchDraw(canvas);
|
||||
}
|
||||
canvas.save();
|
||||
canvas.clipPath(pathToClip);
|
||||
canvas.translate(cascadeAnimation ? 0 : enterTransitionOffsetX, enterTransitionOffsetY);
|
||||
canvas.scale(enterTransitionScale, enterTransitionScale, enterTransitionScalePx, enterTransitionScalePy);
|
||||
if (!cascadeAnimation) {
|
||||
selectAnimatedEmojiDialog.setAlpha(enterTransitionProgress);
|
||||
}
|
||||
super.dispatchDraw(canvas);
|
||||
canvas.restore();
|
||||
|
||||
if (frameDrawCount < 5) {
|
||||
if (frameDrawCount == 3) {
|
||||
|
@ -840,6 +941,7 @@ public class CustomEmojiReactionsWindow {
|
|||
if (valueAnimator != null) {
|
||||
invalidate();
|
||||
}
|
||||
HwEmojis.exec();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
package org.telegram.ui.Components.Reactions;
|
||||
|
||||
import static org.telegram.messenger.SharedConfig.PERFORMANCE_CLASS_HIGH;
|
||||
import static org.telegram.messenger.SharedConfig.getDevicePerformanceClass;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import org.telegram.messenger.ImageLoader;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class HwEmojis {
|
||||
private static final Set<View> hwViews = new HashSet<>();
|
||||
private static volatile boolean hwEnabled = false;
|
||||
private static Runnable task;
|
||||
private static boolean firstOpen = true;
|
||||
private static boolean isPreparing = false;
|
||||
private static boolean isCascade = false;
|
||||
private static boolean isBeforePreparing = false;
|
||||
private static Boolean isWeakDevice;
|
||||
|
||||
public static void prepare(Runnable runnable, boolean cascade) {
|
||||
isCascade = cascade;
|
||||
isPreparing = true;
|
||||
isBeforePreparing = false;
|
||||
if (firstOpen) {
|
||||
firstOpen = false;
|
||||
}
|
||||
task = runnable;
|
||||
}
|
||||
|
||||
public static void beforePreparing() {
|
||||
ImageLoader.getInstance().getCacheOutQueue().pause();
|
||||
isBeforePreparing = true;
|
||||
}
|
||||
|
||||
public static boolean isCascade() {
|
||||
return isCascade;
|
||||
}
|
||||
|
||||
public static boolean isPreparing() {
|
||||
return isPreparing;
|
||||
}
|
||||
|
||||
public static boolean isFirstOpen() {
|
||||
return firstOpen;
|
||||
}
|
||||
|
||||
public static boolean isHwEnabled() {
|
||||
return hwEnabled;
|
||||
}
|
||||
|
||||
public static boolean isHwEnabledOrPreparing() {
|
||||
return hwEnabled || isPreparing || isBeforePreparing;
|
||||
}
|
||||
|
||||
public static void exec() {
|
||||
if (task != null) {
|
||||
task.run();
|
||||
task = null;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean grab(View view) {
|
||||
if (hwEnabled) {
|
||||
hwViews.add(view);
|
||||
}
|
||||
return hwEnabled;
|
||||
}
|
||||
|
||||
public static boolean grabIfWeakDevice(View... views) {
|
||||
if (isWeakDevice == null) {
|
||||
isWeakDevice = getDevicePerformanceClass() != PERFORMANCE_CLASS_HIGH;
|
||||
}
|
||||
|
||||
if (!isWeakDevice) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (hwEnabled) {
|
||||
hwViews.addAll(Arrays.asList(views));
|
||||
}
|
||||
return hwEnabled;
|
||||
}
|
||||
|
||||
public static void enableHw() {
|
||||
ImageLoader.getInstance().getCacheOutQueue().pause();
|
||||
hwEnabled = true;
|
||||
isPreparing = false;
|
||||
isBeforePreparing = false;
|
||||
}
|
||||
|
||||
public static void disableHw() {
|
||||
ImageLoader.getInstance().getCacheOutQueue().resume();
|
||||
hwEnabled = false;
|
||||
isPreparing = false;
|
||||
isBeforePreparing = false;
|
||||
task = null;
|
||||
for (View view : hwViews) {
|
||||
view.invalidate();
|
||||
}
|
||||
hwViews.clear();
|
||||
}
|
||||
}
|
|
@ -61,10 +61,12 @@ import org.telegram.tgnet.TLRPC;
|
|||
import org.telegram.ui.ActionBar.AlertDialog;
|
||||
import org.telegram.ui.ActionBar.BaseFragment;
|
||||
import org.telegram.ui.ActionBar.Theme;
|
||||
import org.telegram.ui.Cells.ReactedUserHolderView;
|
||||
import org.telegram.ui.Components.ListView.AdapterWithDiffUtils;
|
||||
import org.telegram.ui.Components.Premium.PremiumFeatureBottomSheet;
|
||||
import org.telegram.ui.Components.Premium.PremiumLockIconView;
|
||||
import org.telegram.ui.Components.Reactions.CustomEmojiReactionsWindow;
|
||||
import org.telegram.ui.Components.Reactions.HwEmojis;
|
||||
import org.telegram.ui.Components.Reactions.ReactionsEffectOverlay;
|
||||
import org.telegram.ui.Components.Reactions.ReactionsLayoutInBubble;
|
||||
import org.telegram.ui.Components.Reactions.ReactionsUtils;
|
||||
|
@ -170,6 +172,8 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
|
|||
final AnimationNotificationsLocker notificationsLocker = new AnimationNotificationsLocker();
|
||||
private final int type;
|
||||
public boolean skipEnterAnimation;
|
||||
public boolean isHiddenNextReaction = true;
|
||||
private Runnable onSwitchedToLoopView;
|
||||
|
||||
public ReactionsContainerLayout(int type, BaseFragment fragment, @NonNull Context context, int currentAccount, Theme.ResourcesProvider resourcesProvider) {
|
||||
super(context);
|
||||
|
@ -195,6 +199,7 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
|
|||
shadow.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_chat_messagePanelShadow), PorterDuff.Mode.MULTIPLY));
|
||||
|
||||
recyclerListView = new RecyclerListView(context) {
|
||||
|
||||
@Override
|
||||
public boolean drawChild(Canvas canvas, View child, long drawingTime) {
|
||||
if (pressedReaction != null && (child instanceof ReactionHolderView) && ((ReactionHolderView) child).currentReaction.equals(pressedReaction)) {
|
||||
|
@ -506,6 +511,10 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
|
|||
}
|
||||
}
|
||||
|
||||
public void setOnSwitchedToLoopView(Runnable onSwitchedToLoopView) {
|
||||
this.onSwitchedToLoopView = onSwitchedToLoopView;
|
||||
}
|
||||
|
||||
public void dismissWindow() {
|
||||
reactionsWindow.dismiss();
|
||||
}
|
||||
|
@ -519,8 +528,10 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
|
|||
return;
|
||||
}
|
||||
reactionsWindow = new CustomEmojiReactionsWindow(type, fragment, allReactionsList, selectedReactions, this, resourcesProvider);
|
||||
invalidateLoopViews();
|
||||
reactionsWindow.onDismissListener(() -> {
|
||||
reactionsWindow = null;
|
||||
invalidateLoopViews();
|
||||
if (delegate != null) {
|
||||
delegate.onEmojiWindowDismissed();
|
||||
}
|
||||
|
@ -528,6 +539,15 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
|
|||
//animatePullingBack();
|
||||
}
|
||||
|
||||
private void invalidateLoopViews() {
|
||||
for (int i = 0; i < recyclerListView.getChildCount(); i++) {
|
||||
View child = recyclerListView.getChildAt(i);
|
||||
if (child instanceof ReactionHolderView) {
|
||||
((ReactionHolderView) child).loopImageView.invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean showCustomEmojiReaction() {
|
||||
return !MessagesController.getInstance(currentAccount).premiumLocked && allReactionsAvailable;
|
||||
}
|
||||
|
@ -761,9 +781,10 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
|
|||
}
|
||||
if (pullingLeftOffsetProgress > 0) {
|
||||
float progress = getPullingLeftProgress();
|
||||
int left = lastReactionX + AndroidUtilities.dp(32);
|
||||
float leftProgress = Utilities.clamp(left / (float) (getMeasuredWidth() - AndroidUtilities.dp(34)), 1f, 0f);
|
||||
float pullingOffsetX = leftProgress * progress * AndroidUtilities.dp(32);
|
||||
int reactionSize = nextRecentReaction.getMeasuredWidth() - AndroidUtilities.dp(2);
|
||||
int left = lastReactionX + reactionSize;
|
||||
float leftProgress = Utilities.clamp(left / (float) (getMeasuredWidth() - nextRecentReaction.getMeasuredWidth()), 1f, 0f);
|
||||
float pullingOffsetX = leftProgress * progress * reactionSize;
|
||||
|
||||
if (nextRecentReaction.getTag() == null) {
|
||||
nextRecentReaction.setTag(1f);
|
||||
|
@ -773,10 +794,20 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
|
|||
float scale = Utilities.clamp(progress, 1f, 0f);
|
||||
nextRecentReaction.setScaleX(scale);
|
||||
nextRecentReaction.setScaleY(scale);
|
||||
nextRecentReaction.setTranslationX(recyclerListView.getX() + left - pullingOffsetX - AndroidUtilities.dp(20));
|
||||
nextRecentReaction.setVisibility(View.VISIBLE);
|
||||
float additionalOffset = 0;
|
||||
if (type != TYPE_STORY) {
|
||||
additionalOffset = - AndroidUtilities.dp(20);
|
||||
} else {
|
||||
additionalOffset = - AndroidUtilities.dp(8);
|
||||
}
|
||||
nextRecentReaction.setTranslationX(recyclerListView.getX() + left - pullingOffsetX + additionalOffset);
|
||||
if (nextRecentReaction.getVisibility() != View.VISIBLE) {
|
||||
nextRecentReaction.setVisibility(View.VISIBLE);
|
||||
}
|
||||
} else {
|
||||
nextRecentReaction.setVisibility(View.GONE);
|
||||
if (nextRecentReaction.getVisibility() != View.GONE && isHiddenNextReaction) {
|
||||
nextRecentReaction.setVisibility(View.GONE);
|
||||
}
|
||||
if (nextRecentReaction.getTag() != null) {
|
||||
nextRecentReaction.setTag(null);
|
||||
}
|
||||
|
@ -791,20 +822,25 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
|
|||
return;
|
||||
}
|
||||
|
||||
canvas.clipPath(mPath);
|
||||
boolean showCustomEmojiReaction = showCustomEmojiReaction();
|
||||
if (!showCustomEmojiReaction) {
|
||||
canvas.clipPath(mPath);
|
||||
}
|
||||
canvas.translate((LocaleController.isRTL || mirrorX ? -1 : 1) * getWidth() * (1f - transitionProgress), 0);
|
||||
recyclerListView.setTranslationX(-transitionLeftOffset);
|
||||
super.dispatchDraw(canvas);
|
||||
|
||||
if (leftShadowPaint != null) {
|
||||
float p = Utilities.clamp(leftAlpha * transitionProgress, 1f, 0f);
|
||||
leftShadowPaint.setAlpha((int) (p * 0xFF));
|
||||
canvas.drawRect(rect, leftShadowPaint);
|
||||
}
|
||||
if (rightShadowPaint != null) {
|
||||
float p = Utilities.clamp(rightAlpha * transitionProgress, 1f, 0f);
|
||||
rightShadowPaint.setAlpha((int) (p * 0xFF));
|
||||
canvas.drawRect(rect, rightShadowPaint);
|
||||
if (!showCustomEmojiReaction) {
|
||||
if (leftShadowPaint != null) {
|
||||
float p = Utilities.clamp(leftAlpha * transitionProgress, 1f, 0f);
|
||||
leftShadowPaint.setAlpha((int) (p * 0xFF));
|
||||
canvas.drawRect(rect, leftShadowPaint);
|
||||
}
|
||||
if (rightShadowPaint != null) {
|
||||
float p = Utilities.clamp(rightAlpha * transitionProgress, 1f, 0f);
|
||||
rightShadowPaint.setAlpha((int) (p * 0xFF));
|
||||
canvas.drawRect(rect, rightShadowPaint);
|
||||
}
|
||||
}
|
||||
canvas.restoreToCount(s);
|
||||
|
||||
|
@ -824,7 +860,6 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
|
|||
return;
|
||||
}
|
||||
canvas.save();
|
||||
float scale = transitionProgress;
|
||||
canvas.clipRect(0, AndroidUtilities.lerp(rect.bottom, 0, CubicBezierInterpolator.DEFAULT.getInterpolation(flipVerticalProgress)) - (int) Math.ceil(rect.height() / 2f * (1f - transitionProgress)), getMeasuredWidth(), AndroidUtilities.lerp(getMeasuredHeight() + AndroidUtilities.dp(8), getPaddingTop() - expandSize(), CubicBezierInterpolator.DEFAULT.getInterpolation(flipVerticalProgress)));
|
||||
float cx = LocaleController.isRTL || mirrorX ? bigCircleOffset : getWidth() - bigCircleOffset;
|
||||
float cy = getHeight() - getPaddingBottom() + expandSize();
|
||||
|
@ -937,7 +972,7 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
|
|||
}
|
||||
}
|
||||
|
||||
private float getPullingLeftProgress() {
|
||||
public float getPullingLeftProgress() {
|
||||
return Utilities.clamp(pullingLeftOffset / AndroidUtilities.dp(42), 2f, 0f);
|
||||
}
|
||||
|
||||
|
@ -1160,6 +1195,14 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
|
|||
invalidate();
|
||||
}
|
||||
|
||||
public void setCustomEmojiReactionsBackground(boolean isNeed) {
|
||||
if (isNeed) {
|
||||
customEmojiReactionsIconView.setBackground(Theme.createSimpleSelectorCircleDrawable(AndroidUtilities.dp(28), Color.TRANSPARENT, ColorUtils.setAlphaComponent(Theme.getColor(Theme.key_listSelector), 40)));
|
||||
} else {
|
||||
customEmojiReactionsIconView.setBackground(null);
|
||||
}
|
||||
}
|
||||
|
||||
boolean skipDraw;
|
||||
|
||||
public void setSkipDraw(boolean b) {
|
||||
|
@ -1185,7 +1228,11 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
|
|||
}
|
||||
|
||||
public void onCustomEmojiWindowOpened() {
|
||||
animatePullingBack();
|
||||
pullingLeftOffset = 0f;
|
||||
if (customReactionsContainer != null) {
|
||||
customReactionsContainer.invalidate();
|
||||
}
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void clearRecentReactions() {
|
||||
|
@ -1337,6 +1384,20 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
|
|||
this.recyclerReaction = recyclerReaction;
|
||||
enterImageView = new BackupImageView(context) {
|
||||
|
||||
@Override
|
||||
protected ImageReceiver createImageReciever() {
|
||||
return new ImageReceiver(this) {
|
||||
@Override
|
||||
protected boolean setImageBitmapByKey(Drawable drawable, String key, int type, boolean memCache, int guid) {
|
||||
if (drawable instanceof RLottieDrawable) {
|
||||
RLottieDrawable rLottieDrawable = (RLottieDrawable) drawable;
|
||||
rLottieDrawable.setCurrentFrame(0, false, true);
|
||||
}
|
||||
return super.setImageBitmapByKey(drawable, key, type, memCache, guid);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dispatchDraw(Canvas canvas) {
|
||||
super.dispatchDraw(canvas);
|
||||
|
@ -1347,6 +1408,9 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
|
|||
switchedToLoopView = true;
|
||||
loopImageView.imageReceiver.getLottieAnimation().setCurrentFrame(0, false, true);
|
||||
loopImageView.setVisibility(View.VISIBLE);
|
||||
if (onSwitchedToLoopView != null) {
|
||||
onSwitchedToLoopView.run();
|
||||
}
|
||||
AndroidUtilities.runOnUIThread(() -> {
|
||||
enterImageView.setVisibility(View.INVISIBLE);
|
||||
});
|
||||
|
@ -1356,21 +1420,97 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
|
|||
|
||||
@Override
|
||||
public void invalidate() {
|
||||
if (HwEmojis.grabIfWeakDevice(this, ReactionsContainerLayout.this)) {
|
||||
return;
|
||||
}
|
||||
super.invalidate();
|
||||
ReactionsContainerLayout.this.invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidate(Rect dirty) {
|
||||
if (HwEmojis.grabIfWeakDevice(this, ReactionsContainerLayout.this)) {
|
||||
return;
|
||||
}
|
||||
super.invalidate(dirty);
|
||||
ReactionsContainerLayout.this.invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidate(int l, int t, int r, int b) {
|
||||
if (HwEmojis.grabIfWeakDevice(this)) {
|
||||
return;
|
||||
}
|
||||
super.invalidate(l, t, r, b);
|
||||
}
|
||||
};
|
||||
loopImageView = new BackupImageView(context) {
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
ImageReceiver imageReceiver = animatedEmojiDrawable != null ? animatedEmojiDrawable.getImageReceiver() : this.imageReceiver;
|
||||
if (imageReceiver != null && imageReceiver.getLottieAnimation() != null) {
|
||||
if (reactionsWindow != null || pressed) {
|
||||
imageReceiver.getLottieAnimation().start();
|
||||
} else {
|
||||
if (imageReceiver.getLottieAnimation().getCurrentFrame() <= 2) {
|
||||
imageReceiver.getLottieAnimation().stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
super.onDraw(canvas);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ImageReceiver createImageReciever() {
|
||||
return new ImageReceiver(this) {
|
||||
|
||||
@Override
|
||||
protected boolean setImageBitmapByKey(Drawable drawable, String key, int type, boolean memCache, int guid) {
|
||||
boolean rez = super.setImageBitmapByKey(drawable, key, type, memCache, guid);
|
||||
if (rez) {
|
||||
if (drawable instanceof RLottieDrawable) {
|
||||
RLottieDrawable rLottieDrawable = (RLottieDrawable) drawable;
|
||||
rLottieDrawable.setCurrentFrame(0, false, true);
|
||||
rLottieDrawable.stop();
|
||||
}
|
||||
}
|
||||
return rez;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidate() {
|
||||
if (HwEmojis.grabIfWeakDevice(this)) {
|
||||
return;
|
||||
}
|
||||
super.invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidate(int l, int t, int r, int b) {
|
||||
if (HwEmojis.grabIfWeakDevice(this)) {
|
||||
return;
|
||||
}
|
||||
super.invalidate(l, t, r, b);
|
||||
}
|
||||
};
|
||||
loopImageView = new BackupImageView(context);
|
||||
enterImageView.getImageReceiver().setAutoRepeat(0);
|
||||
enterImageView.getImageReceiver().setAllowStartLottieAnimation(false);
|
||||
|
||||
pressedBackupImageView = new BackupImageView(context) {
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
ImageReceiver imageReceiver = animatedEmojiDrawable != null ? animatedEmojiDrawable.getImageReceiver() : this.imageReceiver;
|
||||
if (imageReceiver != null && imageReceiver.getLottieAnimation() != null) {
|
||||
imageReceiver.getLottieAnimation().start();
|
||||
}
|
||||
super.onDraw(canvas);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidate() {
|
||||
super.invalidate();
|
||||
|
@ -1382,6 +1522,9 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
|
|||
addView(loopImageView, LayoutHelper.createFrame(34, 34, Gravity.CENTER));
|
||||
enterImageView.setLayerNum(Integer.MAX_VALUE);
|
||||
loopImageView.setLayerNum(Integer.MAX_VALUE);
|
||||
loopImageView.imageReceiver.setAutoRepeat(0);
|
||||
loopImageView.imageReceiver.setAllowStartAnimation(false);
|
||||
loopImageView.imageReceiver.setAllowStartLottieAnimation(false);
|
||||
pressedBackupImageView.setLayerNum(Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
|
@ -1413,7 +1556,7 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
|
|||
loopImageView.setAnimatedEmojiDrawable(loopDrawable);
|
||||
}
|
||||
setFocusable(true);
|
||||
shouldSwitchToLoopView = hasEnterAnimation && showCustomEmojiReaction();
|
||||
shouldSwitchToLoopView = hasEnterAnimation && !allReactionsIsDefault;
|
||||
if (!hasEnterAnimation) {
|
||||
enterImageView.setVisibility(View.GONE);
|
||||
loopImageView.setVisibility(View.VISIBLE);
|
||||
|
@ -1448,6 +1591,9 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
|
|||
enterImageView.getImageReceiver().setImage(ImageLocation.getForDocument(defaultReaction.appear_animation), ReactionsUtils.APPEAR_ANIMATION_FILTER, null, null, svgThumb, 0, "tgs", react, 0);
|
||||
loopImageView.getImageReceiver().setImage(ImageLocation.getForDocument(defaultReaction.select_animation), ReactionsUtils.SELECT_ANIMATION_FILTER, null, null, hasEnterAnimation ? null : svgThumb, 0, "tgs", currentReaction, 0);
|
||||
}
|
||||
if (enterImageView.getImageReceiver().getLottieAnimation() != null) {
|
||||
enterImageView.getImageReceiver().getLottieAnimation().setCurrentFrame(0, false, true);
|
||||
}
|
||||
pressedBackupImageView.getImageReceiver().setImage(ImageLocation.getForDocument(defaultReaction.select_animation), ReactionsUtils.SELECT_ANIMATION_FILTER, null, null, svgThumb, 0, "tgs", react, 0);
|
||||
|
||||
preloadImageReceiver.setAllowStartLottieAnimation(false);
|
||||
|
|
|
@ -1053,7 +1053,9 @@ public class RecyclerListView extends RecyclerView {
|
|||
final View view = cv;
|
||||
final int position = currentChildPosition;
|
||||
if (instantClick && position != -1) {
|
||||
view.playSoundEffect(SoundEffectConstants.CLICK);
|
||||
try {
|
||||
view.playSoundEffect(SoundEffectConstants.CLICK);
|
||||
} catch (Exception ignore) {}
|
||||
view.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
|
||||
if (onItemClickListener != null) {
|
||||
onItemClickListener.onItemClick(view, position);
|
||||
|
@ -1070,7 +1072,9 @@ public class RecyclerListView extends RecyclerView {
|
|||
if (view != null) {
|
||||
onChildPressed(view, 0, 0, false);
|
||||
if (!instantClick) {
|
||||
view.playSoundEffect(SoundEffectConstants.CLICK);
|
||||
try {
|
||||
view.playSoundEffect(SoundEffectConstants.CLICK);
|
||||
} catch (Exception ignore) {}
|
||||
view.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
|
||||
if (position != -1) {
|
||||
if (onItemClickListener != null) {
|
||||
|
|
|
@ -1880,10 +1880,11 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
|
|||
if (archivedHintLayout == null || archivedHintLayout.getWidth() != width) {
|
||||
archivedHintLayout = new StaticLayout(LocaleController.getString("ProfileStoriesArchiveHint", R.string.ProfileStoriesArchiveHint), archivedHintPaint, width, Layout.Alignment.ALIGN_CENTER, 1f, 0f, false);
|
||||
archivedHintLayoutWidth = 0;
|
||||
archivedHintLayoutLeft = 0;
|
||||
for (int i = 0; i < archivedHintLayout.getLineCount(); ++i) {
|
||||
archivedHintLayoutWidth = Math.max(archivedHintLayoutWidth, archivedHintLayout.getLineWidth(i));
|
||||
archivedHintLayoutLeft = Math.min(archivedHintLayoutLeft, archivedHintLayout.getLineLeft(i));
|
||||
}
|
||||
archivedHintLayoutLeft = archivedHintLayout.getLineCount() > 0 ? archivedHintLayout.getLineLeft(0) : 0;
|
||||
}
|
||||
|
||||
canvas.save();
|
||||
|
@ -2269,10 +2270,15 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
|
|||
if (mediaPage.selectedType == TAB_GROUPUSERS) {
|
||||
if (view instanceof UserCell) {
|
||||
TLRPC.ChatParticipant participant;
|
||||
final int i;
|
||||
if (!chatUsersAdapter.sortedUsers.isEmpty()) {
|
||||
participant = chatUsersAdapter.chatInfo.participants.participants.get(chatUsersAdapter.sortedUsers.get(position));
|
||||
i = chatUsersAdapter.sortedUsers.get(position);
|
||||
} else {
|
||||
participant = chatUsersAdapter.chatInfo.participants.participants.get(position);
|
||||
i = position;
|
||||
}
|
||||
participant = chatUsersAdapter.chatInfo.participants.participants.get(i);
|
||||
if (i < 0 || i >= chatUsersAdapter.chatInfo.participants.participants.size()) {
|
||||
return;
|
||||
}
|
||||
onMemberClick(participant, false, view);
|
||||
} else if (mediaPage.listView.getAdapter() == groupUsersSearchAdapter) {
|
||||
|
@ -2508,6 +2514,10 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
|
|||
return false;
|
||||
}
|
||||
|
||||
protected boolean includeStories() {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected int getInitialTab() {
|
||||
return 0;
|
||||
}
|
||||
|
@ -4822,7 +4832,7 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
|
|||
if (changed > 3) {
|
||||
idToView = null;
|
||||
}
|
||||
if (DialogObject.isUserDialog(dialog_id) && !DialogObject.isEncryptedDialog(dialog_id) && (userInfo != null && userInfo.stories_pinned_available || isStoriesView())) {
|
||||
if (DialogObject.isUserDialog(dialog_id) && !DialogObject.isEncryptedDialog(dialog_id) && (userInfo != null && userInfo.stories_pinned_available || isStoriesView()) && includeStories()) {
|
||||
if (!scrollSlidingTextTabStrip.hasTab(TAB_STORIES)) {
|
||||
scrollSlidingTextTabStrip.addTextTab(TAB_STORIES, LocaleController.getString("ProfileStories", R.string.ProfileStories), idToView);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
package org.telegram.ui.Components;
|
||||
|
||||
import android.animation.TimeAnimator;
|
||||
|
||||
import org.telegram.messenger.AndroidUtilities;
|
||||
|
||||
/**
|
||||
* Good for animations with a jank at the beginning.
|
||||
*/
|
||||
public class StableAnimator extends TimeAnimator {
|
||||
private int times = 0;
|
||||
private int totalTimes = 0;
|
||||
private AnimatorUpdateListener updateListener;
|
||||
private Object animatedValue;
|
||||
private float[] floatValues;
|
||||
|
||||
public static StableAnimator ofFloat(float... values) {
|
||||
StableAnimator anim = new StableAnimator();
|
||||
anim.setFloatValues(values);
|
||||
return anim;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFloatValues(float[] floatValues) {
|
||||
super.setFloatValues(floatValues);
|
||||
this.floatValues = floatValues;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addUpdateListener(AnimatorUpdateListener listener) {
|
||||
updateListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getAnimatedValue() {
|
||||
return animatedValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void end() {
|
||||
updateListener = null;
|
||||
super.end();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
setTimeListener((animation, totalTime, deltaTime) -> {
|
||||
if (times > 0 && totalTimes > 0) {
|
||||
times--;
|
||||
if (updateListener != null) {
|
||||
if (floatValues != null && floatValues.length == 2) {
|
||||
float percent = (float) times / (float) totalTimes;
|
||||
float fraction = getInterpolator().getInterpolation(1f - percent);
|
||||
animatedValue = floatValues[0] + ((floatValues[1] - floatValues[0]) * fraction);
|
||||
updateListener.onAnimationUpdate(this);
|
||||
} else {
|
||||
end();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
end();
|
||||
}
|
||||
});
|
||||
this.times = (int) (getDuration() / AndroidUtilities.screenRefreshTime);
|
||||
this.totalTimes = this.times;
|
||||
super.start();
|
||||
}
|
||||
}
|
|
@ -18,6 +18,8 @@ import android.text.TextPaint;
|
|||
import android.text.TextUtils;
|
||||
import android.text.style.CharacterStyle;
|
||||
|
||||
import com.google.android.exoplayer2.util.Log;
|
||||
|
||||
import org.telegram.messenger.AndroidUtilities;
|
||||
import org.telegram.messenger.FileLog;
|
||||
|
||||
|
@ -133,6 +135,10 @@ public class StaticLayoutEx {
|
|||
}*/
|
||||
try {
|
||||
if (maxLines == 1) {
|
||||
int index = TextUtils.indexOf(source, "\n") - 1;
|
||||
if (index > 0) {
|
||||
source = SpannableStringBuilder.valueOf(source.subSequence(0, index)).append("…");
|
||||
}
|
||||
CharSequence text = TextUtils.ellipsize(source, paint, ellipsisWidth, TextUtils.TruncateAt.END);
|
||||
return new StaticLayout(text, 0, text.length(), paint, outerWidth, align, spacingMult, spacingAdd, includePad);
|
||||
} else {
|
||||
|
|
|
@ -5,6 +5,7 @@ import static org.telegram.messenger.AndroidUtilities.dp;
|
|||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Canvas;
|
||||
|
@ -32,6 +33,7 @@ import org.telegram.messenger.CacheFetcher;
|
|||
import org.telegram.messenger.FileLog;
|
||||
import org.telegram.messenger.LiteMode;
|
||||
import org.telegram.messenger.MessagesStorage;
|
||||
import org.telegram.messenger.NotificationCenter;
|
||||
import org.telegram.messenger.R;
|
||||
import org.telegram.messenger.UserConfig;
|
||||
import org.telegram.messenger.Utilities;
|
||||
|
@ -114,6 +116,7 @@ public class StickerCategoriesListView extends RecyclerListView {
|
|||
this(context, additionalCategories, categoriesType, null);
|
||||
}
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
public StickerCategoriesListView(Context context, EmojiCategory[] additionalCategories, @CategoriesType int categoriesType, Theme.ResourcesProvider resourcesProvider) {
|
||||
super(context, resourcesProvider);
|
||||
|
||||
|
@ -136,19 +139,22 @@ public class StickerCategoriesListView extends RecyclerListView {
|
|||
long start = System.currentTimeMillis();
|
||||
fetcher.fetch(UserConfig.selectedAccount, categoriesType, (emojiGroups) -> {
|
||||
if (emojiGroups != null) {
|
||||
categories = new EmojiCategory[(additionalCategories == null ? 0 : additionalCategories.length) + emojiGroups.groups.size()];
|
||||
int i = 0;
|
||||
if (additionalCategories != null) {
|
||||
for (; i < additionalCategories.length; ++i) {
|
||||
categories[i] = additionalCategories[i];
|
||||
Runnable action = () -> {
|
||||
categories = new EmojiCategory[(additionalCategories == null ? 0 : additionalCategories.length) + emojiGroups.groups.size()];
|
||||
int i = 0;
|
||||
if (additionalCategories != null) {
|
||||
for (; i < additionalCategories.length; ++i) {
|
||||
categories[i] = additionalCategories[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int j = 0; j < emojiGroups.groups.size(); ++j) {
|
||||
categories[i + j] = EmojiCategory.remote(emojiGroups.groups.get(j));
|
||||
}
|
||||
adapter.notifyDataSetChanged();
|
||||
setCategoriesShownT(0);
|
||||
updateCategoriesShown(categoriesShouldShow, System.currentTimeMillis() - start > 16);
|
||||
for (int j = 0; j < emojiGroups.groups.size(); ++j) {
|
||||
categories[i + j] = EmojiCategory.remote(emojiGroups.groups.get(j));
|
||||
}
|
||||
adapter.notifyDataSetChanged();
|
||||
setCategoriesShownT(0);
|
||||
updateCategoriesShown(categoriesShouldShow, System.currentTimeMillis() - start > 16);
|
||||
};
|
||||
NotificationCenter.getInstance(UserConfig.selectedAccount).doOnIdle(action);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -160,7 +160,6 @@ public class VideoPlayer implements Player.Listener, VideoListener, AnalyticsLis
|
|||
NotificationCenter.getGlobalInstance().addObserver(this, NotificationCenter.playerDidStartPlaying);
|
||||
}
|
||||
playerCounter++;
|
||||
//Log.d("kek", "playerCounter " + playerCounter);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -343,7 +342,6 @@ public class VideoPlayer implements Player.Listener, VideoListener, AnalyticsLis
|
|||
NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.playerDidStartPlaying);
|
||||
}
|
||||
playerCounter--;
|
||||
//Log.d("kek", "playerCounter " + playerCounter);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -7,6 +7,7 @@ import android.graphics.Color;
|
|||
import android.graphics.Matrix;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Shader;
|
||||
import android.os.Process;
|
||||
|
||||
import org.telegram.messenger.AndroidUtilities;
|
||||
import org.telegram.messenger.DispatchQueue;
|
||||
|
@ -25,7 +26,7 @@ public class SpoilerEffectBitmapFactory {
|
|||
return factory;
|
||||
}
|
||||
|
||||
final DispatchQueue dispatchQueue = new DispatchQueue("SpoilerEffectBitmapFactory");
|
||||
final DispatchQueue dispatchQueue = new DispatchQueue("SpoilerEffectBitmapFactory", true, 3 * Process.THREAD_PRIORITY_LESS_FAVORABLE);
|
||||
private Bitmap shaderBitmap;
|
||||
Bitmap bufferBitmap;
|
||||
Bitmap backgroundBitmap;
|
||||
|
|
|
@ -2086,10 +2086,11 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
|
|||
int currentPosition = layoutManager.findFirstVisibleItemPosition();
|
||||
if (currentPosition == 0) {
|
||||
int pTop = getPaddingTop();
|
||||
View view = findArchiveDialogCell(parentPage);
|
||||
int height = (int) (AndroidUtilities.dp(SharedConfig.useThreeLinesLayout ? 78 : 72) * PullForegroundDrawable.SNAP_HEIGHT);
|
||||
int diff = (view.getTop() - pTop) + view.getMeasuredHeight();
|
||||
if (view instanceof DialogCell) {
|
||||
DialogCell view = findArchiveDialogCell(parentPage);
|
||||
if (view != null) {
|
||||
int height = (int) (AndroidUtilities.dp(SharedConfig.useThreeLinesLayout ? 78 : 72) * PullForegroundDrawable.SNAP_HEIGHT);
|
||||
int diff = (view.getTop() - pTop) + view.getMeasuredHeight();
|
||||
|
||||
long pullingTime = System.currentTimeMillis() - startArchivePullingTime;
|
||||
if (diff < height || pullingTime < PullForegroundDrawable.minPullingTime) {
|
||||
disableActionBarScrolling = true;
|
||||
|
@ -2941,6 +2942,9 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
|
|||
actionBar.setBackButtonContentDescription(LocaleController.getString("AccDescrGoBack", R.string.AccDescrGoBack));
|
||||
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.needCheckSystemBarColors);
|
||||
((SizeNotifierFrameLayout) fragmentView).invalidateBlur();
|
||||
if (optionsItem != null) {
|
||||
optionsItem.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -2990,12 +2994,15 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
|
|||
}
|
||||
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.needCheckSystemBarColors, true);
|
||||
((SizeNotifierFrameLayout) fragmentView).invalidateBlur();
|
||||
if (optionsItem != null) {
|
||||
optionsItem.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(EditText editText) {
|
||||
String text = editText.getText().toString();
|
||||
if (text.length() != 0 || (searchViewPager.dialogsSearchAdapter != null && searchViewPager.dialogsSearchAdapter.hasRecentSearch()) || searchFiltersWasShowed) {
|
||||
if (text.length() != 0 || (searchViewPager.dialogsSearchAdapter != null && searchViewPager.dialogsSearchAdapter.hasRecentSearch()) || searchFiltersWasShowed || hasStories) {
|
||||
searchWas = true;
|
||||
if (!searchIsShowed) {
|
||||
showSearch(true, false, true);
|
||||
|
@ -3024,7 +3031,6 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
|
|||
searchItem.setVisibility(View.GONE);
|
||||
}
|
||||
if (isArchive()) {
|
||||
searchItem.searchRightMargin = -44;
|
||||
optionsItem = menu.addItem(4, R.drawable.ic_ab_other);
|
||||
optionsItem.addSubItem(5, R.drawable.msg_customize, LocaleController.getString("ArchiveSettings")).setColors(getThemedColor(Theme.key_actionBarDefaultSubmenuItem), getThemedColor(Theme.key_actionBarDefaultSubmenuItem));
|
||||
optionsItem.addSubItem(6, R.drawable.msg_help, LocaleController.getString("HowDoesItWork")).setColors(getThemedColor(Theme.key_actionBarDefaultSubmenuItem), getThemedColor(Theme.key_actionBarDefaultSubmenuItem));
|
||||
|
@ -3271,7 +3277,7 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
|
|||
if (initialDialogsType != DIALOGS_TYPE_DEFAULT) {
|
||||
return false;
|
||||
}
|
||||
if (actionBar.isActionModeShowed()) {
|
||||
if (actionBar.isActionModeShowed() || storiesOverscroll != 0) {
|
||||
return false;
|
||||
}
|
||||
if (filterOptions != null && filterOptions.isShown()) {
|
||||
|
@ -4844,7 +4850,7 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
|
|||
}, subItem -> {
|
||||
subItem.setMultiline(false);
|
||||
})
|
||||
.addIf(!isArchive(), R.drawable.msg_archive, LocaleController.getString("ArchiveStories", R.string.ArchiveStories), () -> {
|
||||
.addIf(!isArchive(), R.drawable.msg_archive, LocaleController.getString("ArchivePeerStories", R.string.ArchivePeerStories), () -> {
|
||||
toggleArciveForStory(dialogId);
|
||||
}, subItem -> {
|
||||
subItem.setMultiline(false);
|
||||
|
@ -6750,10 +6756,10 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
|
|||
if (searchFiltersWasShowed) {
|
||||
onlyDialogsAdapter = false;
|
||||
} else {
|
||||
onlyDialogsAdapter = onlyDialogsAdapter() && !hasStories;
|
||||
onlyDialogsAdapter = onlyDialogsAdapter();
|
||||
}
|
||||
searchViewPager.showOnlyDialogsAdapter(onlyDialogsAdapter);
|
||||
whiteActionBar = !onlyDialogsAdapter;
|
||||
whiteActionBar = !onlyDialogsAdapter || hasStories;
|
||||
if (whiteActionBar) {
|
||||
searchFiltersWasShowed = true;
|
||||
}
|
||||
|
@ -7048,7 +7054,7 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
|
|||
|
||||
public boolean onlyDialogsAdapter() {
|
||||
int dialogsCount = getMessagesController().getTotalDialogsCount();
|
||||
return onlySelect || !searchViewPager.dialogsSearchAdapter.hasRecentSearch() || dialogsCount <= 10;
|
||||
return onlySelect || !searchViewPager.dialogsSearchAdapter.hasRecentSearch() || dialogsCount <= 10 && !hasStories;
|
||||
}
|
||||
|
||||
private void updateFilterTabsVisibility(boolean animated) {
|
||||
|
@ -8053,6 +8059,10 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
|
|||
this.storiesEnabled = storiesEnabled;
|
||||
}
|
||||
|
||||
if (floatingButton == null || floatingButtonContainer == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (initialDialogsType == DIALOGS_TYPE_WIDGET) {
|
||||
floatingButton.setImageResource(R.drawable.floating_check);
|
||||
floatingButtonContainer.setContentDescription(LocaleController.getString("Done", R.string.Done));
|
||||
|
@ -11802,7 +11812,7 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
|
|||
if (StoryRecorder.isVisible() || (storyViewer != null && storyViewer.isFullyVisible())) {
|
||||
animated = false;
|
||||
}
|
||||
boolean onlySelfStories = getStoriesController().hasOnlySelfStories();
|
||||
boolean onlySelfStories = !isArchive() && getStoriesController().hasOnlySelfStories();
|
||||
boolean newVisibility;
|
||||
if (isArchive()) {
|
||||
newVisibility = !getStoriesController().getHiddenList().isEmpty();
|
||||
|
|
|
@ -12,6 +12,7 @@ import android.graphics.Paint;
|
|||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.TextPaint;
|
||||
import android.text.TextUtils;
|
||||
import android.util.SparseArray;
|
||||
import android.view.Gravity;
|
||||
|
@ -116,7 +117,7 @@ public class FilteredSearchView extends FrameLayout implements NotificationCente
|
|||
|
||||
private String currentDataQuery;
|
||||
|
||||
private static SpannableStringBuilder arrowSpan;
|
||||
private static SpannableStringBuilder[] arrowSpan = new SpannableStringBuilder[3];
|
||||
|
||||
private int photoViewerClassGuid;
|
||||
|
||||
|
@ -246,7 +247,7 @@ public class FilteredSearchView extends FrameLayout implements NotificationCente
|
|||
|
||||
@Override
|
||||
public CharSequence getTitleFor(int i) {
|
||||
return createFromInfoString(messages.get(i));
|
||||
return createFromInfoString(messages.get(i), 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -422,20 +423,37 @@ public class FilteredSearchView extends FrameLayout implements NotificationCente
|
|||
emptyView.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
public static CharSequence createFromInfoString(MessageObject messageObject) {
|
||||
return createFromInfoString(messageObject, true);
|
||||
public static CharSequence createFromInfoString(MessageObject messageObject, int arrowType) {
|
||||
return createFromInfoString(messageObject, true, arrowType);
|
||||
}
|
||||
|
||||
public static CharSequence createFromInfoString(MessageObject messageObject, boolean includeChat) {
|
||||
public static CharSequence createFromInfoString(MessageObject messageObject, boolean includeChat, int arrowType) {
|
||||
return createFromInfoString(messageObject, includeChat, arrowType, null);
|
||||
}
|
||||
|
||||
public static CharSequence createFromInfoString(MessageObject messageObject, boolean includeChat, int arrowType, TextPaint textPaint) {
|
||||
if (messageObject == null) {
|
||||
return "";
|
||||
}
|
||||
if (arrowSpan == null) {
|
||||
arrowSpan = new SpannableStringBuilder(">");
|
||||
Drawable arrowDrawable = ContextCompat.getDrawable(ApplicationLoader.applicationContext, R.drawable.attach_arrow_right).mutate();
|
||||
ColoredImageSpan span = new ColoredImageSpan(arrowDrawable, ColoredImageSpan.ALIGN_CENTER);
|
||||
arrowDrawable.setBounds(0, AndroidUtilities.dp(1), AndroidUtilities.dp(13), AndroidUtilities.dp(1 + 13));
|
||||
arrowSpan.setSpan(span, 0, arrowSpan.length(), 0);
|
||||
if (arrowSpan[arrowType] == null) {
|
||||
arrowSpan[arrowType] = new SpannableStringBuilder(">");
|
||||
int resId;
|
||||
if (arrowType == 0) {
|
||||
resId = R.drawable.attach_arrow_right;
|
||||
} else if (arrowType == 1) {
|
||||
resId = R.drawable.msg_mini_arrow_mediathin;
|
||||
} else if (arrowType == 2) {
|
||||
resId = R.drawable.msg_mini_arrow_mediabold;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
Drawable arrowDrawable = ContextCompat.getDrawable(ApplicationLoader.applicationContext, resId).mutate();
|
||||
ColoredImageSpan span = new ColoredImageSpan(arrowDrawable, arrowType == 0 ? ColoredImageSpan.ALIGN_CENTER : ColoredImageSpan.ALIGN_BASELINE);
|
||||
// arrowDrawable.setBounds(0, 0, AndroidUtilities.dp(13), AndroidUtilities.dp(13));
|
||||
if (arrowType == 1 || arrowType == 2) {
|
||||
span.setScale(.85f);
|
||||
}
|
||||
arrowSpan[arrowType].setSpan(span, 0, arrowSpan[arrowType].length(), 0);
|
||||
}
|
||||
CharSequence fromName = null;
|
||||
TLRPC.User user = messageObject.messageOwner.from_id.user_id != 0 ? MessagesController.getInstance(UserConfig.selectedAccount).getUser(messageObject.messageOwner.from_id.user_id) : null;
|
||||
|
@ -459,17 +477,17 @@ public class FilteredSearchView extends FrameLayout implements NotificationCente
|
|||
chatTitle = ForumUtilities.getTopicSpannedName(topic, null);
|
||||
}
|
||||
}
|
||||
chatTitle = Emoji.replaceEmoji(chatTitle, null, AndroidUtilities.dp(12), false);
|
||||
chatTitle = Emoji.replaceEmoji(chatTitle, textPaint == null ? null : textPaint.getFontMetricsInt(), false);
|
||||
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder();
|
||||
spannableStringBuilder
|
||||
.append(Emoji.replaceEmoji(UserObject.getFirstName(user), null, AndroidUtilities.dp(12), false))
|
||||
.append(Emoji.replaceEmoji(UserObject.getFirstName(user), textPaint == null ? null : textPaint.getFontMetricsInt(), false))
|
||||
.append(' ')
|
||||
.append(arrowSpan)
|
||||
.append(arrowSpan[arrowType])
|
||||
.append(' ')
|
||||
.append(chatTitle);
|
||||
fromName = spannableStringBuilder;
|
||||
} else if (user != null) {
|
||||
fromName = Emoji.replaceEmoji(UserObject.getUserName(user), null, AndroidUtilities.dp(12), false);
|
||||
fromName = Emoji.replaceEmoji(UserObject.getUserName(user), textPaint == null ? null : textPaint.getFontMetricsInt(), false);
|
||||
} else if (chatFrom != null) {
|
||||
CharSequence chatTitle = chatFrom.title;
|
||||
if (ChatObject.isForum(chatFrom)) {
|
||||
|
@ -478,7 +496,7 @@ public class FilteredSearchView extends FrameLayout implements NotificationCente
|
|||
chatTitle = ForumUtilities.getTopicSpannedName(topic, null);
|
||||
}
|
||||
}
|
||||
chatTitle = Emoji.replaceEmoji(chatTitle, null, AndroidUtilities.dp(12), false);
|
||||
chatTitle = Emoji.replaceEmoji(chatTitle, textPaint == null ? null : textPaint.getFontMetricsInt(), false);
|
||||
fromName = chatTitle;
|
||||
}
|
||||
return fromName == null ? "" : fromName;
|
||||
|
|
|
@ -3630,7 +3630,7 @@ public class LaunchActivity extends BasePermissionsActivity implements INavigati
|
|||
if (baseFragment != null) {
|
||||
storyItem.dialogId = peerId;
|
||||
StoryViewer storyViewer = baseFragment.getOrCreateStoryViewer();
|
||||
if (storyViewer.isShown()) {
|
||||
if (storyViewer.isShown() && storyViewer.attachedToParent()) {
|
||||
StoryViewer overlayStoryViewer = baseFragment.getOrCreateOverlayStoryViewer();
|
||||
final StoryViewer storyViewer1 = storyViewer;
|
||||
overlayStoryViewer.setOnCloseListener(() -> storyViewer1.setOverlayVisible(false));
|
||||
|
@ -5693,7 +5693,9 @@ public class LaunchActivity extends BasePermissionsActivity implements INavigati
|
|||
super.onDestroy();
|
||||
onFinish();
|
||||
FloatingDebugController.onDestroy();
|
||||
flagSecureReason.detach();
|
||||
if (flagSecureReason != null) {
|
||||
flagSecureReason.detach();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -12067,7 +12067,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
|
|||
newMessageObject.updateTranslation();
|
||||
isVideo = newMessageObject.isVideo();
|
||||
|
||||
title = FilteredSearchView.createFromInfoString(newMessageObject, opennedFromMedia && !openedFromProfile);
|
||||
title = FilteredSearchView.createFromInfoString(newMessageObject, opennedFromMedia && !openedFromProfile, 0);
|
||||
CharSequence subtitle = null;
|
||||
if (newMessageObject.messageOwner != null) {
|
||||
subtitle = LocaleController.formatDateAudio(newMessageObject.messageOwner.date, false);
|
||||
|
|
|
@ -191,6 +191,7 @@ import org.telegram.ui.Components.InstantCameraView;
|
|||
import org.telegram.ui.Components.ItemOptions;
|
||||
import org.telegram.ui.Components.LayoutHelper;
|
||||
import org.telegram.ui.Components.LinkSpanDrawable;
|
||||
import org.telegram.ui.Components.Paint.PersistColorPalette;
|
||||
import org.telegram.ui.Components.Premium.GiftPremiumBottomSheet;
|
||||
import org.telegram.ui.Components.Premium.PremiumFeatureBottomSheet;
|
||||
import org.telegram.ui.Components.Premium.PremiumGradient;
|
||||
|
@ -3453,6 +3454,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
|
|||
ChatThemeController.getInstance(currentAccount).clearCache();
|
||||
getNotificationCenter().postNotificationName(NotificationCenter.newSuggestionsAvailable);
|
||||
RestrictedLanguagesSelectActivity.cleanup();
|
||||
PersistColorPalette.getInstance(currentAccount).cleanup();
|
||||
} else if (which == 7) {
|
||||
VoIPHelper.showCallDebugSettings(getParentActivity());
|
||||
} else if (which == 8) {
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -38,22 +38,20 @@ public class SponsoredMessageInfoView extends FrameLayout {
|
|||
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20);
|
||||
|
||||
LinkSpanDrawable.LinksTextView description1 = new LinkSpanDrawable.LinksTextView(context, resourcesProvider);
|
||||
description1.setText(AndroidUtilities.replaceSingleTag(LocaleController.getString("SponsoredMessageInfoDescriptionLink", R.string.SponsoredMessageInfoDescriptionLink), () -> {
|
||||
Browser.openUrl(getContext(), "https://telegram.org/privacy#5-6-no-ads-based-on-user-data");
|
||||
}));
|
||||
description1.setText(AndroidUtilities.replaceLinks(LocaleController.getString("SponsoredMessageInfo2Description1"), resourcesProvider));
|
||||
description1.setLinkTextColor(Theme.getColor(Theme.key_chat_messageLinkIn, resourcesProvider));
|
||||
description1.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText, resourcesProvider));
|
||||
description1.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
|
||||
description1.setLineSpacing(AndroidUtilities.dp(2), 1f);
|
||||
|
||||
TextView description2 = new TextView(context);
|
||||
description2.setText(LocaleController.getString("SponsoredMessageInfoDescription2", R.string.SponsoredMessageInfoDescription2));
|
||||
LinkSpanDrawable.LinksTextView description2 = new LinkSpanDrawable.LinksTextView(context);
|
||||
description2.setText(AndroidUtilities.replaceLinks(LocaleController.getString("SponsoredMessageInfo2Description2"), resourcesProvider));
|
||||
description2.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText, resourcesProvider));
|
||||
description2.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
|
||||
description2.setLineSpacing(AndroidUtilities.dp(2), 1f);
|
||||
|
||||
TextView description3 = new TextView(context);
|
||||
description3.setText(LocaleController.getString("SponsoredMessageInfoDescription3", R.string.SponsoredMessageInfoDescription3));
|
||||
LinkSpanDrawable.LinksTextView description3 = new LinkSpanDrawable.LinksTextView(context);
|
||||
description3.setText(AndroidUtilities.replaceLinks(LocaleController.getString("SponsoredMessageInfo2Description3"), resourcesProvider));
|
||||
description3.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText, resourcesProvider));
|
||||
description3.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
|
||||
description3.setLineSpacing(AndroidUtilities.dp(2), 1f);
|
||||
|
@ -86,22 +84,32 @@ public class SponsoredMessageInfoView extends FrameLayout {
|
|||
button.setGravity(Gravity.CENTER_VERTICAL);
|
||||
|
||||
|
||||
TextView description4 = new TextView(context);
|
||||
description4.setText(LocaleController.getString("SponsoredMessageInfoDescription4", R.string.SponsoredMessageInfoDescription4));
|
||||
LinkSpanDrawable.LinksTextView description4 = new LinkSpanDrawable.LinksTextView(context);
|
||||
description4.setText(AndroidUtilities.replaceLinks(LocaleController.getString("SponsoredMessageInfo2Description4"), resourcesProvider));
|
||||
description4.setLineSpacing(AndroidUtilities.dp(2), 1f);
|
||||
description4.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText, resourcesProvider));
|
||||
description4.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
|
||||
|
||||
textView.setPadding(AndroidUtilities.dp(22), 0, AndroidUtilities.dp(22), 0);
|
||||
linearLayout.addView(textView);
|
||||
|
||||
description1.setPadding(AndroidUtilities.dp(22), 0, AndroidUtilities.dp(22), 0);
|
||||
linearLayout.addView(description1, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, 0, 0, 18, 0, 0));
|
||||
|
||||
description2.setPadding(AndroidUtilities.dp(22), 0, AndroidUtilities.dp(22), 0);
|
||||
linearLayout.addView(description2, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, 0, 0, 24, 0, 0));
|
||||
|
||||
description3.setPadding(AndroidUtilities.dp(22), 0, AndroidUtilities.dp(22), 0);
|
||||
linearLayout.addView(description3, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, 0, 0, 24, 0, 0));
|
||||
linearLayout.addView(button, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, 34, Gravity.CENTER_HORIZONTAL, 0, 14, 0, 0));
|
||||
|
||||
linearLayout.addView(button, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, 34, Gravity.CENTER_HORIZONTAL, 22, 14, 22, 0));
|
||||
|
||||
description4.setPadding(AndroidUtilities.dp(22), 0, AndroidUtilities.dp(22), 0);
|
||||
linearLayout.addView(description4, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, 0, 0, 14, 0, 0));
|
||||
|
||||
ScrollView scrollView = new ScrollView(getContext());
|
||||
scrollView.addView(linearLayout);
|
||||
addView(scrollView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, 0, 22, 12, 22, 22));
|
||||
addView(scrollView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, 0, 0, 12, 0, 22));
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1594,13 +1594,15 @@ public class DialogStoriesCell extends FrameLayout implements NotificationCenter
|
|||
.setBgColor(Theme.getColor(Theme.key_undo_background))
|
||||
.setMultilineText(true)
|
||||
.setTextAlign(Layout.Alignment.ALIGN_CENTER)
|
||||
.setText(AndroidUtilities.replaceSingleTag(LocaleController.getString("StoriesPremiumHint"), Theme.key_undo_cancelColor, 0, () -> {
|
||||
if (premiumHint != null) {
|
||||
premiumHint.hide();
|
||||
}
|
||||
fragment.presentFragment(new PremiumPreviewFragment("stories"));
|
||||
}))
|
||||
.setJoint(0, 37 - 8);
|
||||
CharSequence text = AndroidUtilities.replaceSingleTag(LocaleController.getString("StoriesPremiumHint").replace('\n', ' '), Theme.key_undo_cancelColor, 0, () -> {
|
||||
if (premiumHint != null) {
|
||||
premiumHint.hide();
|
||||
}
|
||||
fragment.presentFragment(new PremiumPreviewFragment("stories"));
|
||||
});
|
||||
premiumHint.setMaxWidthPx(HintView2.cutInFancyHalf(text, premiumHint.getTextPaint()));
|
||||
premiumHint.setText(text);
|
||||
premiumHint.setPadding(AndroidUtilities.dp(8), AndroidUtilities.dp(24), AndroidUtilities.dp(8), 0);
|
||||
if (getParent() instanceof FrameLayout) {
|
||||
((FrameLayout) getParent()).addView(premiumHint, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 150, Gravity.LEFT | Gravity.TOP));
|
||||
|
@ -1614,7 +1616,6 @@ public class DialogStoriesCell extends FrameLayout implements NotificationCenter
|
|||
if (premiumHint.shown()) {
|
||||
BotWebViewVibrationEffect.APP_ERROR.vibrate();
|
||||
}
|
||||
premiumHint.setMaxWidthPx(Math.min(AndroidUtilities.dp(450), (int) (AndroidUtilities.displaySize.x * .7f)));
|
||||
premiumHint.show();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,6 @@ import android.view.SurfaceView;
|
|||
import android.view.TextureView;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.OvershootInterpolator;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
|
@ -59,7 +58,6 @@ import org.telegram.messenger.AndroidUtilities;
|
|||
import org.telegram.messenger.AnimationNotificationsLocker;
|
||||
import org.telegram.messenger.BotWebViewVibrationEffect;
|
||||
import org.telegram.messenger.BuildVars;
|
||||
import org.telegram.messenger.ChatObject;
|
||||
import org.telegram.messenger.ContactsController;
|
||||
import org.telegram.messenger.Emoji;
|
||||
import org.telegram.messenger.FileLoader;
|
||||
|
@ -96,7 +94,6 @@ 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.ChatMessageCell;
|
||||
import org.telegram.ui.ChatActivity;
|
||||
import org.telegram.ui.Components.AlertsCreator;
|
||||
import org.telegram.ui.Components.AnimatedEmojiDrawable;
|
||||
|
@ -132,12 +129,11 @@ import org.telegram.ui.Components.ScaleStateListAnimator;
|
|||
import org.telegram.ui.Components.ShareAlert;
|
||||
import org.telegram.ui.Components.SizeNotifierFrameLayout;
|
||||
import org.telegram.ui.Components.TextStyleSpan;
|
||||
import org.telegram.ui.Components.URLSpanMono;
|
||||
import org.telegram.ui.Components.URLSpanNoUnderline;
|
||||
import org.telegram.ui.Components.URLSpanReplacement;
|
||||
import org.telegram.ui.Components.URLSpanUserMention;
|
||||
import org.telegram.ui.Components.spoilers.SpoilersTextView;
|
||||
import org.telegram.ui.Components.voip.CellFlickerDrawable;
|
||||
import org.telegram.ui.DialogsActivity;
|
||||
import org.telegram.ui.LaunchActivity;
|
||||
import org.telegram.ui.NotificationsCustomSettingsActivity;
|
||||
import org.telegram.ui.PinchToZoomHelper;
|
||||
|
@ -174,7 +170,7 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
|
|||
// private final CloseFriendsBadge closeFriendsBadge;
|
||||
private final StoryPrivacyButton privacyButton;
|
||||
private HintView2 privacyHint;
|
||||
private HintView soundTooltip;
|
||||
private HintView2 soundTooltip;
|
||||
private int reactionsContainerIndex;
|
||||
private final StoryViewer storyViewer;
|
||||
private final StoryCaptionView storyCaptionView;
|
||||
|
@ -271,8 +267,6 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
|
|||
public boolean allowScreenshots;
|
||||
public boolean forceUpdateOffsets;
|
||||
private HintView mediaBanTooltip;
|
||||
// private HintView closeFriendsTooltip;
|
||||
ArrayList<HintView> createdTooltips = new ArrayList<>();
|
||||
|
||||
public PinchToZoomHelper pinchToZoomHelper = new PinchToZoomHelper();
|
||||
private boolean imageChanged;
|
||||
|
@ -308,6 +302,7 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
|
|||
this.uploadingStories = new ArrayList<>();
|
||||
|
||||
this.imageReceiver = new ImageReceiver() {
|
||||
|
||||
@Override
|
||||
protected boolean setImageBitmapByKey(Drawable drawable, String key, int type, boolean memCache, int guid) {
|
||||
boolean r = super.setImageBitmapByKey(drawable, key, type, memCache, guid);
|
||||
|
@ -332,6 +327,7 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
|
|||
this.rightPreloadImageReceiver.setAllowLoadingOnAttachedOnly(true);
|
||||
this.rightPreloadImageReceiver.ignoreNotifications = true;
|
||||
this.rightPreloadImageReceiver.setFileLoadingPriority(FileLoader.PRIORITY_LOW);
|
||||
imageReceiver.setPreloadingReceivers(Arrays.asList(leftPreloadImageReceiver, rightPreloadImageReceiver));
|
||||
|
||||
this.avatarDrawable = new AvatarDrawable();
|
||||
this.storyViewer = storyViewer;
|
||||
|
@ -656,7 +652,7 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
|
|||
|
||||
storyCaptionView = new StoryCaptionView(getContext(), storyViewer.resourcesProvider) {
|
||||
@Override
|
||||
public void onLinkClick(ClickableSpan span, View spoilersTextView) {
|
||||
public void onLinkClick(CharacterStyle span, View spoilersTextView) {
|
||||
if (span instanceof URLSpanUserMention) {
|
||||
TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(Utilities.parseLong(((URLSpanUserMention) span).getURL()));
|
||||
if (user != null) {
|
||||
|
@ -678,8 +674,11 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
|
|||
} else if (span instanceof URLSpan) {
|
||||
String url = ((URLSpan) span).getURL();
|
||||
processExternalUrl(2, url, span, span instanceof URLSpanReplacement);
|
||||
} else {
|
||||
span.onClick(spoilersTextView);
|
||||
} else if (span instanceof URLSpanMono) {
|
||||
((URLSpanMono) span).copyToClipboard();
|
||||
BulletinFactory.of(storyContainer, resourcesProvider).createCopyBulletin(LocaleController.getString("TextCopied", R.string.TextCopied)).show();
|
||||
} else if (span instanceof ClickableSpan) {
|
||||
((ClickableSpan) span).onClick(spoilersTextView);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -959,7 +958,7 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
|
|||
});
|
||||
}
|
||||
|
||||
if (allowShare) {
|
||||
if (allowShare || MessagesController.getInstance(currentAccount).storiesExportNopublicLink) {
|
||||
ActionBarMenuItem.addItem(popupLayout, R.drawable.msg_shareout, LocaleController.getString("BotShare", R.string.BotShare), false, resourcesProvider).setOnClickListener(v -> {
|
||||
shareStory(false);
|
||||
if (popupMenu != null) {
|
||||
|
@ -1024,7 +1023,7 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
|
|||
}
|
||||
if (user.contact) {
|
||||
if (!user.stories_hidden) {
|
||||
ActionBarMenuItem.addItem(popupLayout, R.drawable.msg_archive, LocaleController.getString("ArchiveStories", R.string.ArchiveStories), false, resourcesProvider).setOnClickListener(v -> {
|
||||
ActionBarMenuItem.addItem(popupLayout, R.drawable.msg_archive, LocaleController.getString("ArchivePeerStories", R.string.ArchivePeerStories), false, resourcesProvider).setOnClickListener(v -> {
|
||||
toggleArciveForStory(dialogId);
|
||||
if (popupMenu != null) {
|
||||
popupMenu.dismiss();
|
||||
|
@ -1042,16 +1041,16 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
|
|||
}
|
||||
|
||||
if (!unsupported) {
|
||||
//if (UserObject.isService(dialogId)) {
|
||||
if (UserObject.isService(dialogId) || allowShare) {
|
||||
ActionBarMenuItem.addItem(popupLayout, R.drawable.msg_gallery, LocaleController.getString("SaveToGallery", R.string.SaveToGallery), false, resourcesProvider).setOnClickListener(v -> {
|
||||
saveToGallery();
|
||||
if (popupMenu != null) {
|
||||
popupMenu.dismiss();
|
||||
}
|
||||
});
|
||||
// }
|
||||
}
|
||||
}
|
||||
if (allowShare) {
|
||||
if (allowShare || MessagesController.getInstance(currentAccount).storiesExportNopublicLink) {
|
||||
ActionBarMenuItem.addItem(popupLayout, R.drawable.msg_link, LocaleController.getString("CopyLink", R.string.CopyLink), false, resourcesProvider).setOnClickListener(v -> {
|
||||
AndroidUtilities.addToClipboard(currentStory.createLink());
|
||||
onLickCopied();
|
||||
|
@ -1163,16 +1162,18 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
|
|||
firstName = firstName.substring(0, index);
|
||||
}
|
||||
CharSequence text;
|
||||
boolean twoLines = true;
|
||||
if (storyItem.close_friends) {
|
||||
text = AndroidUtilities.replaceTags(LocaleController.formatString("StoryCloseFriendsHint", R.string.StoryCloseFriendsHint, firstName));
|
||||
} else if (storyItem.contacts) {
|
||||
text = AndroidUtilities.replaceTags(LocaleController.formatString("StoryContactsHint", R.string.StoryContactsHint, firstName));
|
||||
twoLines = false;
|
||||
} else if (storyItem.selected_contacts) {
|
||||
text = AndroidUtilities.replaceTags(LocaleController.formatString("StorySelectedContactsHint", R.string.StorySelectedContactsHint, firstName));
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
privacyHint.setMaxWidthPx(HintView2.cutInFancyHalf(text, privacyHint.getTextPaint()));
|
||||
privacyHint.setMaxWidthPx(twoLines ? HintView2.cutInFancyHalf(text, privacyHint.getTextPaint()) : storyContainer.getMeasuredWidth());
|
||||
privacyHint.setText(text);
|
||||
privacyHint.setJoint(1, -(storyContainer.getWidth() - privacyButton.getCenterX()) / AndroidUtilities.density);
|
||||
delegate.setIsHintVisible(true);
|
||||
|
@ -1189,16 +1190,12 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
|
|||
storyViewer.toggleSilentMode();
|
||||
} else {
|
||||
if (soundTooltip == null) {
|
||||
soundTooltip = new HintView.Builder(context, resourcesProvider)
|
||||
.setTopArrow(true)
|
||||
.setBackgroundColor(ColorUtils.setAlphaComponent(Color.BLACK, (int) (0.5f * 255)))
|
||||
.build();
|
||||
soundTooltip.setExtraTranslationY(-dp(8));
|
||||
soundTooltip = new HintView2(context, HintView2.DIRECTION_TOP).setJoint(1, -56);
|
||||
soundTooltip.setText(LocaleController.getString(R.string.StoryNoSound));
|
||||
addView(soundTooltip, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.TOP, 10, 0, 10, 0));
|
||||
createdTooltips.add(soundTooltip);
|
||||
soundTooltip.setPadding(AndroidUtilities.dp(8), 0, AndroidUtilities.dp(8), 0);
|
||||
storyContainer.addView(soundTooltip, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.FILL_HORIZONTAL | Gravity.TOP, 0, 52, 0, 0));
|
||||
}
|
||||
soundTooltip.showForView(muteIconContainer, true);
|
||||
soundTooltip.show();
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -1906,6 +1903,9 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
|
|||
this.dialogId = dialogId;
|
||||
deletedPeer = false;
|
||||
forceUpdateOffsets = true;
|
||||
if (peerIdChanged) {
|
||||
currentStory.clear();
|
||||
}
|
||||
if (dialogId >= 0) {
|
||||
isSelf = dialogId == UserConfig.getInstance(currentAccount).getClientUserId();
|
||||
TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(dialogId);
|
||||
|
@ -2274,7 +2274,7 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
|
|||
|
||||
@Override
|
||||
public void didReceivedNotification(int id, int account, Object... args) {
|
||||
if (id == NotificationCenter.storiesUpdated) {
|
||||
if (id == NotificationCenter.storiesUpdated || id == NotificationCenter.storiesListUpdated && storyViewer.storiesList == args[0]) {
|
||||
if (delegate != null && delegate.isClosed()) {
|
||||
return;
|
||||
}
|
||||
|
@ -2327,15 +2327,14 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
|
|||
final boolean wasUploading = isUploading;
|
||||
final boolean wasEditing = isEditing;
|
||||
|
||||
if (isActive) {
|
||||
ImageLoader.getInstance().cancelLoadingForImageReceiver(leftPreloadImageReceiver, true);
|
||||
ImageLoader.getInstance().cancelLoadingForImageReceiver(rightPreloadImageReceiver, true);
|
||||
}
|
||||
currentStory.editingSourceItem = null;
|
||||
if (!uploadingStories.isEmpty() && position >= storyItems.size()) {
|
||||
isUploading = true;
|
||||
isEditing = false;
|
||||
position -= storyItems.size();
|
||||
if (position < 0 || position >= uploadingStories.size()) {
|
||||
return;
|
||||
}
|
||||
StoriesController.UploadingStory uploadingStory = uploadingStories.get(position);
|
||||
Drawable thumbDrawable = null;
|
||||
imageReceiver.setCrossfadeWithOldImage(false);
|
||||
|
@ -2355,6 +2354,9 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
|
|||
} else {
|
||||
isUploading = false;
|
||||
isEditing = false;
|
||||
if (position < 0 || position > storyItems.size() - 1) {
|
||||
storyViewer.close(true);
|
||||
}
|
||||
TLRPC.StoryItem storyItem = storyItems.get(position);
|
||||
StoriesController.UploadingStory editingStory = storiesController.findEditingStory(storyItem);
|
||||
if (editingStory != null) {
|
||||
|
@ -2385,7 +2387,7 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
|
|||
if (storyItem.media != null) {
|
||||
thumbDrawable = ImageLoader.createStripedBitmap(storyItem.media.document.thumbs);
|
||||
}
|
||||
if (ImageLoader.getInstance().isInMemCache(ImageLocation.getForPath(storyItem.firstFramePath).getKey(null, null, false) + "@" + filter, false)) {
|
||||
if (storyItem.firstFramePath != null && ImageLoader.getInstance().isInMemCache(ImageLocation.getForPath(storyItem.firstFramePath).getKey(null, null, false) + "@" + filter, false)) {
|
||||
imageReceiver.setImage(null, null, ImageLocation.getForPath(storyItem.firstFramePath), filter, null, null, thumbDrawable, 0, null, null, 0);
|
||||
} else {
|
||||
imageReceiver.setImage(null, null, ImageLocation.getForPath(storyItem.attachPath), filter + "_pframe", null, null, thumbDrawable, 0, null, null, 0);
|
||||
|
@ -2436,7 +2438,7 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
|
|||
allowShare = !unsupported && currentStory.storyItem != null && !(currentStory.storyItem instanceof TLRPC.TL_storyItemDeleted) && !(currentStory.storyItem instanceof TLRPC.TL_storyItemSkipped);
|
||||
if (allowShare) {
|
||||
TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(dialogId);
|
||||
allowShare = !currentStory.storyItem.noforwards && (currentStory.storyItem.isPublic || MessagesController.getInstance(currentAccount).storiesExportNopublicLink) && user != null && UserObject.getPublicUsername(user) != null;
|
||||
allowShare = !currentStory.storyItem.noforwards && currentStory.storyItem.isPublic && user != null && UserObject.getPublicUsername(user) != null;
|
||||
}
|
||||
NotificationsController.getInstance(currentAccount).processReadStories(dialogId, storyItem.id);
|
||||
}
|
||||
|
@ -2501,12 +2503,12 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
|
|||
headerView.setSubtitle(string, animateSubtitle);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < createdTooltips.size(); i++) {
|
||||
createdTooltips.get(i).hide(false);
|
||||
}
|
||||
if (privacyHint != null) {
|
||||
privacyHint.hide(false);
|
||||
}
|
||||
if (soundTooltip != null) {
|
||||
soundTooltip.hide(false);
|
||||
}
|
||||
}
|
||||
CharSequence caption = null;
|
||||
if (currentStory.uploadingStory != null) {
|
||||
|
@ -2579,9 +2581,9 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
|
|||
|
||||
|
||||
if (isActive) {
|
||||
requestVideoPlayer(0);
|
||||
updatePreloadImages();
|
||||
imageReceiver.bumpPriority();
|
||||
requestVideoPlayer(0);
|
||||
}
|
||||
|
||||
if (storyViewer.storiesList != null && selectedPosition >= 0 && selectedPosition < storyViewer.storiesList.messageObjects.size()) {
|
||||
|
@ -2987,11 +2989,8 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
|
|||
if (privacyHint != null) {
|
||||
privacyHint.hide();
|
||||
}
|
||||
for (int i = 0; i < createdTooltips.size(); i++) {
|
||||
if (createdTooltips.get(i).getVisibility() == View.VISIBLE) {
|
||||
createdTooltips.get(i).hide(true);
|
||||
return true;
|
||||
}
|
||||
if (soundTooltip != null) {
|
||||
soundTooltip.hide();
|
||||
}
|
||||
|
||||
if (mediaBanTooltip != null) {
|
||||
|
@ -3033,10 +3032,8 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
|
|||
if (privacyHint != null && privacyHint.shown()) {
|
||||
return true;
|
||||
}
|
||||
for (int i = 0; i < createdTooltips.size(); i++) {
|
||||
if (createdTooltips.get(i).getVisibility() == View.VISIBLE) {
|
||||
return true;
|
||||
}
|
||||
if (soundTooltip != null && soundTooltip.shown()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (int i = 0; i < container.getChildCount(); i++) {
|
||||
|
@ -3263,22 +3260,25 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
|
|||
}
|
||||
|
||||
public void onActionDown(MotionEvent ev) {
|
||||
for (int i = 0; i < createdTooltips.size(); i++) {
|
||||
createdTooltips.get(i).hide();
|
||||
}
|
||||
if (privacyHint != null && privacyHint.shown() && privacyButton != null &&
|
||||
!privacyHint.containsTouch(ev, getX() + storyContainer.getX() + privacyHint.getX(), getY() + storyContainer.getY() + privacyHint.getY()) &&
|
||||
!hitPrivacyButton(ev)
|
||||
!hitButton(privacyButton, ev)
|
||||
) {
|
||||
privacyHint.hide();
|
||||
}
|
||||
if (soundTooltip != null && soundTooltip.shown() && muteIconContainer != null &&
|
||||
!soundTooltip.containsTouch(ev, getX() + storyContainer.getX() + soundTooltip.getX(), getY() + storyContainer.getY() + soundTooltip.getY()) &&
|
||||
!hitButton(muteIconContainer, ev)
|
||||
) {
|
||||
soundTooltip.hide();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hitPrivacyButton(MotionEvent e) {
|
||||
float ox = getX() + storyContainer.getX() + privacyButton.getX(), oy = getY() + storyContainer.getY() + privacyButton.getY();
|
||||
private boolean hitButton(View v, MotionEvent e) {
|
||||
float ox = getX() + storyContainer.getX() + v.getX(), oy = getY() + storyContainer.getY() + v.getY();
|
||||
return (
|
||||
e.getX() >= ox && e.getX() <= ox + privacyButton.getWidth() &&
|
||||
e.getY() >= oy && e.getY() <= oy + privacyButton.getHeight()
|
||||
e.getX() >= ox && e.getX() <= ox + v.getWidth() &&
|
||||
e.getY() >= oy && e.getY() <= oy + v.getHeight()
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -165,8 +165,8 @@ public class ProfileStoriesView extends View implements NotificationCenter.Notif
|
|||
final TLRPC.TL_userStories userStories;
|
||||
if (userId == 0) {
|
||||
userStories = null;
|
||||
} else if (stateStories != null) {
|
||||
userStories = stateStories;
|
||||
// } else if (stateStories != null) {
|
||||
// userStories = stateStories;
|
||||
} else {
|
||||
userStories = userFullStories;
|
||||
}
|
||||
|
|
|
@ -210,13 +210,15 @@ public class SelfStoryViewsPage extends FrameLayout implements NotificationCente
|
|||
if (id == NotificationCenter.storiesUpdated) {
|
||||
if (storyItem.uploadingStory != null) {
|
||||
TLRPC.TL_userStories stories = MessagesController.getInstance(currentAccount).storiesController.getStories(UserConfig.getInstance(currentAccount).clientUserId);
|
||||
for (int i = 0; i < stories.stories.size(); i++) {
|
||||
TLRPC.StoryItem storyItem = stories.stories.get(i);
|
||||
if (storyItem.attachPath != null && storyItem.attachPath.equals(this.storyItem.uploadingStory.path)) {
|
||||
this.storyItem.uploadingStory = null;
|
||||
this.storyItem.storyItem = storyItem;
|
||||
setStoryItem(this.storyItem);
|
||||
break;
|
||||
if (stories != null) {
|
||||
for (int i = 0; i < stories.stories.size(); i++) {
|
||||
TLRPC.StoryItem storyItem = stories.stories.get(i);
|
||||
if (storyItem.attachPath != null && storyItem.attachPath.equals(this.storyItem.uploadingStory.path)) {
|
||||
this.storyItem.uploadingStory = null;
|
||||
this.storyItem.storyItem = storyItem;
|
||||
setStoryItem(this.storyItem);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@ import androidx.annotation.NonNull;
|
|||
import androidx.collection.LongSparseArray;
|
||||
|
||||
import com.google.android.exoplayer2.util.Consumer;
|
||||
import com.google.android.exoplayer2.util.Log;
|
||||
|
||||
import org.telegram.SQLite.SQLiteCursor;
|
||||
import org.telegram.SQLite.SQLiteDatabase;
|
||||
|
@ -157,13 +156,18 @@ public class StoriesController {
|
|||
}
|
||||
|
||||
private void sortDialogStories(ArrayList<TLRPC.TL_userStories> list) {
|
||||
fixDeletedStories(list);
|
||||
fixDeletedAndNonContactsStories(list);
|
||||
Collections.sort(list, userStoriesComparator);
|
||||
}
|
||||
|
||||
private void fixDeletedStories(ArrayList<TLRPC.TL_userStories> list) {
|
||||
private void fixDeletedAndNonContactsStories(ArrayList<TLRPC.TL_userStories> list) {
|
||||
for (int k = 0; k < list.size(); k++) {
|
||||
TLRPC.TL_userStories userStories = list.get(k);
|
||||
TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(userStories.user_id);
|
||||
if (user != null && !user.contact) {
|
||||
list.remove(k);
|
||||
k--;
|
||||
}
|
||||
for (int i = 0; i < userStories.stories.size(); i++) {
|
||||
if (userStories.stories.get(i) instanceof TLRPC.TL_storyItemDeleted) {
|
||||
userStories.stories.remove(i);
|
||||
|
@ -578,6 +582,7 @@ public class StoriesController {
|
|||
AndroidUtilities.runOnUIThread(() -> {
|
||||
TLRPC.TL_userStories currentUserStory = allStoriesMap.get(updateStory.user_id);
|
||||
FileLog.d("StoriesController update stories for user " + updateStory.user_id);
|
||||
updateStoriesInLists(updateStory.user_id, Collections.singletonList(updateStory.story));
|
||||
|
||||
ArrayList<TLRPC.StoryItem> newStoryItems = new ArrayList<>();
|
||||
int oldStoriesCount = totalStoriesCount;
|
||||
|
@ -645,7 +650,6 @@ public class StoriesController {
|
|||
}
|
||||
notify = true;
|
||||
}
|
||||
updateStoriesInLists(updateStory.user_id, newStoryItems);
|
||||
} else {
|
||||
if (updateStory.story instanceof TLRPC.TL_storyItemDeleted) {
|
||||
FileLog.d("StoriesController can't add user " + updateStory.user_id + " with new story DELETED");
|
||||
|
@ -671,8 +675,8 @@ public class StoriesController {
|
|||
if (oldStoriesCount != totalStoriesCount) {
|
||||
mainSettings.edit().putInt("total_stores", totalStoriesCount).apply();
|
||||
}
|
||||
fixDeletedStories(dialogListStories);
|
||||
fixDeletedStories(hiddenListStories);
|
||||
fixDeletedAndNonContactsStories(dialogListStories);
|
||||
fixDeletedAndNonContactsStories(hiddenListStories);
|
||||
if (notify) {
|
||||
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.storiesUpdated);
|
||||
}
|
||||
|
@ -789,14 +793,13 @@ public class StoriesController {
|
|||
req.id.add(storyItem.id);
|
||||
ConnectionsManager.getInstance(currentAccount).sendRequest(req, (response, error) -> {
|
||||
if (error == null) {
|
||||
AndroidUtilities.runOnUIThread(() -> {
|
||||
updateDeletedStoriesInLists(getSelfUserId(), Arrays.asList(storyItem));
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
storiesStorage.deleteStory(getSelfUserId(), storyItem.id);
|
||||
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.storiesUpdated);
|
||||
MessagesController.getInstance(currentAccount).checkArchiveFolder();
|
||||
updateDeletedStoriesInLists(getSelfUserId(), Arrays.asList(storyItem));
|
||||
}
|
||||
|
||||
public void deleteStories(ArrayList<TLRPC.StoryItem> storyItems) {
|
||||
|
@ -2126,6 +2129,9 @@ public class StoriesController {
|
|||
}
|
||||
boolean contains = loadedObjects.contains(storyItem.id) || cachedObjects.contains(storyItem.id);
|
||||
boolean shouldContain = type == TYPE_ARCHIVE ? true : storyItem.pinned;
|
||||
if (storyItem instanceof TLRPC.TL_storyItemDeleted) {
|
||||
shouldContain = false;
|
||||
}
|
||||
if (contains != shouldContain) {
|
||||
changed = true;
|
||||
if (!shouldContain) {
|
||||
|
@ -2249,4 +2255,9 @@ public class StoriesController {
|
|||
public boolean hasOnlySelfStories() {
|
||||
return hasSelfStories() && (getDialogListStories().isEmpty() || (getDialogListStories().size() == 1 && getDialogListStories().get(0).user_id == UserConfig.getInstance(currentAccount).clientUserId));
|
||||
}
|
||||
|
||||
public void sortHiddenStories() {
|
||||
sortDialogStories(hiddenListStories);
|
||||
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.storiesUpdated);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,9 +3,10 @@ package org.telegram.ui.Stories;
|
|||
import android.graphics.Canvas;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import org.telegram.messenger.MessageObject;
|
||||
import org.telegram.messenger.MessagesController;
|
||||
import org.telegram.messenger.SharedConfig;
|
||||
import org.telegram.messenger.UserConfig;
|
||||
import org.telegram.tgnet.TLRPC;
|
||||
import org.telegram.ui.Cells.ChatActionCell;
|
||||
import org.telegram.ui.Cells.ChatMessageCell;
|
||||
|
@ -20,12 +21,18 @@ public class StoriesListPlaceProvider implements StoryViewer.PlaceProvider {
|
|||
|
||||
private final RecyclerListView recyclerListView;
|
||||
int[] clipPoint = new int[2];
|
||||
private boolean isHiddenArchive;
|
||||
|
||||
public static StoriesListPlaceProvider of(RecyclerListView recyclerListView) {
|
||||
return new StoriesListPlaceProvider(recyclerListView);
|
||||
return of(recyclerListView, false);
|
||||
}
|
||||
public StoriesListPlaceProvider(RecyclerListView recyclerListView) {
|
||||
|
||||
public static StoriesListPlaceProvider of(RecyclerListView recyclerListView, boolean hiddenArchive) {
|
||||
return new StoriesListPlaceProvider(recyclerListView, hiddenArchive);
|
||||
}
|
||||
public StoriesListPlaceProvider(RecyclerListView recyclerListView, boolean hiddenArchive) {
|
||||
this.recyclerListView = recyclerListView;
|
||||
this.isHiddenArchive = hiddenArchive;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -38,6 +45,9 @@ public class StoriesListPlaceProvider implements StoryViewer.PlaceProvider {
|
|||
r.run();
|
||||
}
|
||||
} else {
|
||||
if (isHiddenArchive) {
|
||||
MessagesController.getInstance(UserConfig.selectedAccount).getStoriesController().sortHiddenStories();
|
||||
}
|
||||
r.run();
|
||||
}
|
||||
}
|
||||
|
@ -48,6 +58,10 @@ public class StoriesListPlaceProvider implements StoryViewer.PlaceProvider {
|
|||
holder.storyImage = null;
|
||||
holder.drawAbove = null;
|
||||
|
||||
if (recyclerListView == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DialogStoriesCell dialogStoriesCell = null;
|
||||
if (recyclerListView.getParent() instanceof DialogStoriesCell) {
|
||||
dialogStoriesCell = (DialogStoriesCell) recyclerListView.getParent();
|
||||
|
@ -75,11 +89,14 @@ public class StoriesListPlaceProvider implements StoryViewer.PlaceProvider {
|
|||
}
|
||||
} else if (child instanceof DialogCell) {
|
||||
DialogCell cell = (DialogCell) child;
|
||||
if (cell.getDialogId() == dialogId) {
|
||||
if (cell.getDialogId() == dialogId || (isHiddenArchive && cell.isDialogFolder())) {
|
||||
holder.view = child;
|
||||
holder.params = cell.params;
|
||||
holder.params = cell.storyParams;
|
||||
holder.avatarImage = cell.avatarImage;
|
||||
holder.clipParent = (View) cell.getParent();
|
||||
if (isHiddenArchive) {
|
||||
holder.crossfadeToAvatarImage = cell.avatarImage;
|
||||
}
|
||||
updateClip(holder);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -13,6 +13,8 @@ import android.view.HapticFeedbackConstants;
|
|||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewConfiguration;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewParent;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.core.graphics.ColorUtils;
|
||||
|
@ -102,6 +104,10 @@ public class StoriesUtilities {
|
|||
int unreadState = 0;
|
||||
boolean showProgress = storiesController.isLoading(dialogId);
|
||||
|
||||
if (params.drawHiddenStoriesAsSegments) {
|
||||
hasStories = storiesController.hasHiddenStories();
|
||||
}
|
||||
|
||||
if (params.storyItem != null) {
|
||||
unreadState = storiesController.getUnreadState(dialogId, params.storyId);
|
||||
state = unreadState == StoriesController.STATE_READ ? STATE_READ : STATE_HAS_UNREAD;
|
||||
|
@ -247,7 +253,13 @@ public class StoriesUtilities {
|
|||
int globalState = storiesController.getUnreadState(dialogId);
|
||||
params.globalState = globalState == StoriesController.STATE_READ ? STATE_READ : STATE_HAS_UNREAD;
|
||||
TLRPC.TL_userStories userStories = storiesController.getStories(params.dialogId);
|
||||
if (userStories == null || userStories.stories.size() == 1) {
|
||||
int storiesCount;
|
||||
if (params.drawHiddenStoriesAsSegments) {
|
||||
storiesCount = storiesController.getHiddenList().size();
|
||||
} else {
|
||||
storiesCount = userStories == null || userStories.stories.size() == 1 ? 1 : userStories.stories.size();
|
||||
}
|
||||
if (storiesCount == 1) {
|
||||
Paint localPaint = paint;
|
||||
if (storiesController.hasUnreadStories(dialogId)) {
|
||||
localPaint = unreadPaint;
|
||||
|
@ -259,9 +271,9 @@ public class StoriesUtilities {
|
|||
endAngle = 270;
|
||||
drawSegment(canvas, rectTmp, localPaint, startAngle, endAngle, params);
|
||||
// canvas.drawCircle(rectTmp.centerX(), rectTmp.centerY(), rectTmp.width() / 2f, localPaint);
|
||||
} else if (userStories != null) {
|
||||
float step = 360 / (float) userStories.stories.size();
|
||||
int gap = userStories.stories.size() > 20 ? 3 : 5;
|
||||
} else {
|
||||
float step = 360 / (float) storiesCount;
|
||||
int gap = storiesCount > 20 ? 3 : 5;
|
||||
float gapLen = gap * params.progressToSegments;
|
||||
if (gapLen > step) {
|
||||
gapLen = 0;//step * 0.4f;
|
||||
|
@ -277,15 +289,24 @@ public class StoriesUtilities {
|
|||
globalPaint = params.isStoryCell ? storyCellGreyPaint[params.isArchive ? 1 : 0] : grayPaint;
|
||||
}
|
||||
|
||||
int maxUnread = Math.max(userStories.max_read_id, storiesController.dialogIdToMaxReadId.get(dialogId, 0));
|
||||
for (int i = 0; i < userStories.stories.size(); i++) {
|
||||
int maxUnread = params.drawHiddenStoriesAsSegments ? 0 : Math.max(userStories.max_read_id, storiesController.dialogIdToMaxReadId.get(dialogId, 0));
|
||||
for (int i = 0; i < storiesCount; i++) {
|
||||
Paint segmentPaint = params.isStoryCell ? storyCellGreyPaint[params.isArchive ? 1 : 0] : grayPaint;
|
||||
if (userStories.stories.get(i).justUploaded || userStories.stories.get(i).id > maxUnread) {
|
||||
if (userStories.stories.get(i).close_friends) {
|
||||
if (params.drawHiddenStoriesAsSegments) {
|
||||
int userUnreadState = storiesController.getUnreadState(storiesController.getHiddenList().get(storiesCount - 1 - i).user_id);
|
||||
if (userUnreadState == StoriesController.STATE_UNREAD_CLOSE_FRIEND) {
|
||||
segmentPaint = closeFriendsPaint;
|
||||
} else {
|
||||
} else if (userUnreadState == StoriesController.STATE_UNREAD) {
|
||||
segmentPaint = unreadPaint;
|
||||
}
|
||||
} else {
|
||||
if (userStories.stories.get(i).justUploaded || userStories.stories.get(i).id > maxUnread) {
|
||||
if (userStories.stories.get(i).close_friends) {
|
||||
segmentPaint = closeFriendsPaint;
|
||||
} else {
|
||||
segmentPaint = unreadPaint;
|
||||
}
|
||||
}
|
||||
}
|
||||
float startAngle = step * i - 90;
|
||||
float endAngle = startAngle + step;
|
||||
|
@ -541,6 +562,9 @@ public class StoriesUtilities {
|
|||
}
|
||||
|
||||
public static void setImage(ImageReceiver imageReceiver, TLRPC.StoryItem storyItem, String filter) {
|
||||
if (storyItem == null) {
|
||||
return;
|
||||
}
|
||||
if (storyItem.media != null && storyItem.media.document != null) {
|
||||
TLRPC.PhotoSize size = FileLoader.getClosestPhotoSizeWithSize(storyItem.media.document.thumbs, Integer.MAX_VALUE);
|
||||
imageReceiver.setImage(ImageLocation.getForDocument(size, storyItem.media.document), filter, null, null, ImageLoader.createStripedBitmap(storyItem.media.document.thumbs), 0, null, storyItem, 0);
|
||||
|
@ -683,6 +707,9 @@ public class StoriesUtilities {
|
|||
}
|
||||
|
||||
public static void applyViewedUser(TLRPC.StoryItem storyItem, TLRPC.User currentUser) {
|
||||
if (currentUser == null) {
|
||||
return;
|
||||
}
|
||||
if (storyItem.dialogId == UserConfig.getInstance(UserConfig.selectedAccount).clientUserId && !hasExpiredViews(storyItem)) {
|
||||
if (storyItem.views == null) {
|
||||
storyItem.views = new TLRPC.TL_storyViews();
|
||||
|
@ -743,6 +770,7 @@ public class StoriesUtilities {
|
|||
public int prevUnreadState;
|
||||
public int unreadState;
|
||||
public int animateFromUnreadState;
|
||||
public boolean drawHiddenStoriesAsSegments;
|
||||
|
||||
private long dialogId;
|
||||
public int currentState;
|
||||
|
@ -795,9 +823,16 @@ public class StoriesUtilities {
|
|||
Runnable longPressRunnable;
|
||||
|
||||
public boolean checkOnTouchEvent(MotionEvent event, View 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);
|
||||
if (dialogId != UserConfig.getInstance(UserConfig.selectedAccount).clientUserId && (MessagesController.getInstance(UserConfig.selectedAccount).getStoriesController().hasStories(dialogId) || user != null && !user.stories_unavailable && user.stories_max_id > 0)) {
|
||||
boolean hasStories;
|
||||
if (drawHiddenStoriesAsSegments) {
|
||||
hasStories = storiesController.hasHiddenStories();
|
||||
} else {
|
||||
hasStories = (MessagesController.getInstance(UserConfig.selectedAccount).getStoriesController().hasStories(dialogId) || user != null && !user.stories_unavailable && user.stories_max_id > 0);
|
||||
}
|
||||
if (dialogId != UserConfig.getInstance(UserConfig.selectedAccount).clientUserId && hasStories) {
|
||||
if (buttonBounce == null) {
|
||||
buttonBounce = new ButtonBounce(view, 1.5f);
|
||||
} else {
|
||||
|
@ -817,7 +852,10 @@ public class StoriesUtilities {
|
|||
if (buttonBounce != null) {
|
||||
buttonBounce.setPressed(false);
|
||||
}
|
||||
view.getParent().requestDisallowInterceptTouchEvent(false);
|
||||
ViewParent parent = view.getParent();
|
||||
if (parent instanceof ViewGroup) {
|
||||
((ViewGroup) parent).requestDisallowInterceptTouchEvent(false);
|
||||
}
|
||||
pressed = false;
|
||||
onLongPress();
|
||||
}, ViewConfiguration.getLongPressTimeout());
|
||||
|
@ -843,7 +881,10 @@ public class StoriesUtilities {
|
|||
if (pressed && event.getAction() == MotionEvent.ACTION_UP) {
|
||||
processOpenStory(view);
|
||||
}
|
||||
view.getParent().requestDisallowInterceptTouchEvent(false);
|
||||
ViewParent parent = view.getParent();
|
||||
if (parent instanceof ViewGroup) {
|
||||
((ViewGroup) parent).requestDisallowInterceptTouchEvent(false);
|
||||
}
|
||||
pressed = false;
|
||||
if (longPressRunnable != null) {
|
||||
AndroidUtilities.cancelRunOnUIThread(longPressRunnable);
|
||||
|
@ -860,6 +901,10 @@ public class StoriesUtilities {
|
|||
int currentAccount = UserConfig.selectedAccount;
|
||||
MessagesController messagesController = MessagesController.getInstance(UserConfig.selectedAccount);
|
||||
StoriesController storiesController = messagesController.getStoriesController();
|
||||
if (drawHiddenStoriesAsSegments) {
|
||||
openStory(0, null);
|
||||
return;
|
||||
}
|
||||
if (dialogId != UserConfig.getInstance(UserConfig.selectedAccount).getClientUserId()) {
|
||||
if (storiesController.hasStories(dialogId)) {
|
||||
openStory(dialogId, null);
|
||||
|
|
|
@ -82,6 +82,7 @@ public class StoriesViewPager extends ViewPager {
|
|||
pageLayout.peerStoryView = view;
|
||||
view.setAccount(currentAccount);
|
||||
view.setDelegate(delegate);
|
||||
view.setLongpressed(storyViewer.isLongpressed);
|
||||
pageLayout.setTag(position);
|
||||
pageLayout.dialogId = dialogs.get(position);
|
||||
pageLayout.addView(view);
|
||||
|
|
|
@ -21,6 +21,7 @@ import android.text.Spannable;
|
|||
import android.text.SpannableString;
|
||||
import android.text.StaticLayout;
|
||||
import android.text.TextPaint;
|
||||
import android.text.style.CharacterStyle;
|
||||
import android.text.style.ClickableSpan;
|
||||
import android.text.style.URLSpan;
|
||||
import android.view.MotionEvent;
|
||||
|
@ -55,6 +56,7 @@ import org.telegram.ui.Components.LayoutHelper;
|
|||
import org.telegram.ui.Components.LinkPath;
|
||||
import org.telegram.ui.Components.LinkSpanDrawable;
|
||||
import org.telegram.ui.Components.StaticLayoutEx;
|
||||
import org.telegram.ui.Components.URLSpanMono;
|
||||
import org.telegram.ui.Components.spoilers.SpoilerEffect;
|
||||
import org.telegram.ui.Components.spoilers.SpoilersClickDetector;
|
||||
import org.telegram.ui.Components.spoilers.SpoilersTextView;
|
||||
|
@ -151,7 +153,7 @@ public class StoryCaptionView extends NestedScrollView {
|
|||
|
||||
}
|
||||
|
||||
public void onLinkClick(ClickableSpan span, View spoilersTextView) {
|
||||
public void onLinkClick(CharacterStyle span, View spoilersTextView) {
|
||||
|
||||
}
|
||||
|
||||
|
@ -540,7 +542,7 @@ public class StoryCaptionView extends NestedScrollView {
|
|||
public class StoryCaptionTextView extends View {
|
||||
|
||||
private final PorterDuffColorFilter emojiColorFilter;
|
||||
private LinkSpanDrawable<ClickableSpan> pressedLink;
|
||||
private LinkSpanDrawable<CharacterStyle> pressedLink;
|
||||
private AnimatedEmojiSpan pressedEmoji;
|
||||
private LinkSpanDrawable.LinkCollector links = new LinkSpanDrawable.LinkCollector(this);
|
||||
|
||||
|
@ -783,7 +785,7 @@ public class StoryCaptionView extends NestedScrollView {
|
|||
if (Build.VERSION.SDK_INT >= 24) {
|
||||
return StaticLayout.Builder.obtain(string, 0, string.length(), textPaint, width).setBreakStrategy(StaticLayout.BREAK_STRATEGY_SIMPLE).setHyphenationFrequency(StaticLayout.HYPHENATION_FREQUENCY_NONE).setAlignment(LocaleController.isRTL ? StaticLayoutEx.ALIGN_RIGHT() : StaticLayoutEx.ALIGN_LEFT()).build();
|
||||
} else {
|
||||
return new StaticLayout(string, Theme.profile_aboutTextPaint, width, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
|
||||
return new StaticLayout(string, textPaint, width, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -818,11 +820,14 @@ public class StoryCaptionView extends NestedScrollView {
|
|||
final int off = fullLayout.getOffsetForHorizontal(line, x);
|
||||
final float left = fullLayout.getLineLeft(line);
|
||||
|
||||
ClickableSpan touchLink = null;
|
||||
CharacterStyle touchLink = null;
|
||||
AnimatedEmojiSpan touchEmoji = null;
|
||||
if (left <= x && left + fullLayout.getLineWidth(line) >= x && y >= 0 && y <= fullLayout.getHeight()) {
|
||||
Spannable buffer = new SpannableString(text);
|
||||
ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class);
|
||||
CharacterStyle[] link = buffer.getSpans(off, off, ClickableSpan.class);
|
||||
if (link == null || link.length == 0) {
|
||||
link = buffer.getSpans(off, off, URLSpanMono.class);
|
||||
}
|
||||
if (link != null && link.length != 0) {
|
||||
touchLink = link[0];
|
||||
if (event.getAction() == MotionEvent.ACTION_DOWN) {
|
||||
|
@ -838,7 +843,7 @@ public class StoryCaptionView extends NestedScrollView {
|
|||
path.setCurrentLayout(fullLayout, start, getPaddingTop());
|
||||
fullLayout.getSelectionPath(start, end, path);
|
||||
|
||||
final LinkSpanDrawable<ClickableSpan> savedPressedLink = pressedLink;
|
||||
final LinkSpanDrawable<CharacterStyle> savedPressedLink = pressedLink;
|
||||
postDelayed(() -> {
|
||||
if (savedPressedLink == pressedLink && pressedLink != null && pressedLink.getSpan() instanceof URLSpan) {
|
||||
onLinkLongPress((URLSpan) pressedLink.getSpan(), this, () -> links.clear());
|
||||
|
|
|
@ -125,15 +125,16 @@ public class StoryContainsEmojiButton extends View {
|
|||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
final boolean exactly = MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY;
|
||||
|
||||
final int height = getPaddingTop() + AndroidUtilities.lerp(dp(29), layout == null ? dp(29) : layout.getHeight(), loadT) + getPaddingBottom();
|
||||
setMeasuredDimension(exactly ? MeasureSpec.getSize(widthMeasureSpec) : getMinimumWidth(), height);
|
||||
|
||||
final int contentWidth = MeasureSpec.getSize(widthMeasureSpec) - getPaddingLeft() - getPaddingRight();
|
||||
if (exactly && (toSetText != null || layout != null && lastContentWidth != contentWidth)) {
|
||||
setText(toSetText != null ? toSetText : layout.getText());
|
||||
toSetText = null;
|
||||
lastContentWidth = contentWidth;
|
||||
}
|
||||
|
||||
final int height = getPaddingTop() + AndroidUtilities.lerp(dp(29), layout == null ? dp(29) : layout.getHeight(), loadT) + getPaddingBottom();
|
||||
setMeasuredDimension(exactly ? MeasureSpec.getSize(widthMeasureSpec) : getMinimumWidth(), height);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -207,6 +208,9 @@ public class StoryContainsEmojiButton extends View {
|
|||
req.media = inputStickeredMediaDocument;
|
||||
}
|
||||
final RequestDelegate requestDelegate = (response, error) -> AndroidUtilities.runOnUIThread(() -> {
|
||||
if (response == null) {
|
||||
return;
|
||||
}
|
||||
TLRPC.Vector vector = this.vector = (TLRPC.Vector) response;
|
||||
lastRequestParentObject = parentObject;
|
||||
lastResponse = vector;
|
||||
|
|
|
@ -118,6 +118,7 @@ public class StoryViewer {
|
|||
float fromWidth;
|
||||
float fromHeight;
|
||||
|
||||
RectF avatarRectTmp = new RectF();
|
||||
float progressToOpen;
|
||||
float progressToDismiss;
|
||||
float swipeToDismissOffset;
|
||||
|
@ -185,7 +186,7 @@ public class StoryViewer {
|
|||
private static boolean runOpenAnimationAfterLayout;
|
||||
private boolean isPopupVisible;
|
||||
|
||||
private boolean isLongpressed;
|
||||
public boolean isLongpressed;
|
||||
|
||||
Runnable longPressRunnable = () -> setLongPressed(true);
|
||||
|
||||
|
@ -225,7 +226,12 @@ public class StoryViewer {
|
|||
if (isLongpressed != b) {
|
||||
isLongpressed = b;
|
||||
updatePlayingMode();
|
||||
storiesViewPager.getCurrentPeerView().setLongpressed(isLongpressed);
|
||||
if (storiesViewPager != null) {
|
||||
PeerStoriesView peerStoriesView = storiesViewPager.getCurrentPeerView();
|
||||
if (peerStoriesView != null) {
|
||||
peerStoriesView.setLongpressed(isLongpressed);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -474,6 +480,15 @@ public class StoryViewer {
|
|||
final RectF outFromRectAvatar = new RectF();
|
||||
final RectF outFromRectContainer = new RectF();
|
||||
|
||||
@Override
|
||||
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
|
||||
if (child == aspectRatioFrameLayout) {
|
||||
return false;
|
||||
}
|
||||
return super.drawChild(canvas, child, drawingTime);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void dispatchDraw(Canvas canvas) {
|
||||
float blackoutAlpha = getBlackoutAlpha();
|
||||
|
@ -669,12 +684,36 @@ public class StoryViewer {
|
|||
AndroidUtilities.lerp(rect1, rect2, progressToOpen, AndroidUtilities.rectTmp);
|
||||
|
||||
if (animateAvatar) {
|
||||
headerView.backupImageView.getImageReceiver().setImageCoords(AndroidUtilities.rectTmp);
|
||||
headerView.backupImageView.getImageReceiver().setRoundRadius((int) (AndroidUtilities.rectTmp.width() / 2f));
|
||||
headerView.backupImageView.getImageReceiver().setVisible(true, false);
|
||||
headerView.drawUploadingProgress(canvas, AndroidUtilities.rectTmp, !runOpenAnimationAfterLayout, progressToOpen);
|
||||
headerView.backupImageView.getImageReceiver().draw(canvas);
|
||||
headerView.backupImageView.getImageReceiver().setVisible(false, false);
|
||||
boolean crossfade = transitionViewHolder != null && transitionViewHolder.crossfadeToAvatarImage != null;
|
||||
if (!crossfade || progressToOpen != 0) {
|
||||
headerView.backupImageView.getImageReceiver().setImageCoords(AndroidUtilities.rectTmp);
|
||||
headerView.backupImageView.getImageReceiver().setRoundRadius((int) (AndroidUtilities.rectTmp.width() / 2f));
|
||||
headerView.backupImageView.getImageReceiver().setVisible(true, false);
|
||||
headerView.backupImageView.getImageReceiver().setAlpha(crossfade ? progressToOpen : 1f);
|
||||
headerView.drawUploadingProgress(canvas, AndroidUtilities.rectTmp, !runOpenAnimationAfterLayout, progressToOpen);
|
||||
headerView.backupImageView.getImageReceiver().draw(canvas);
|
||||
headerView.backupImageView.getImageReceiver().setVisible(false, false);
|
||||
}
|
||||
if (progressToOpen != 1f && crossfade) {
|
||||
avatarRectTmp.set(
|
||||
transitionViewHolder.crossfadeToAvatarImage.getImageX(),
|
||||
transitionViewHolder.crossfadeToAvatarImage.getImageY(),
|
||||
transitionViewHolder.crossfadeToAvatarImage.getImageX2(),
|
||||
transitionViewHolder.crossfadeToAvatarImage.getImageY2()
|
||||
);
|
||||
int oldRadius = transitionViewHolder.crossfadeToAvatarImage.getRoundRadius()[0];
|
||||
boolean isVisible = transitionViewHolder.crossfadeToAvatarImage.getVisible();
|
||||
transitionViewHolder.crossfadeToAvatarImage.setImageCoords(AndroidUtilities.rectTmp);
|
||||
transitionViewHolder.crossfadeToAvatarImage.setRoundRadius((int) (AndroidUtilities.rectTmp.width() / 2f));
|
||||
transitionViewHolder.crossfadeToAvatarImage.setVisible(true, false);
|
||||
canvas.saveLayerAlpha(AndroidUtilities.rectTmp, (int) (255 * (1f - progressToOpen)), Canvas.ALL_SAVE_FLAG);
|
||||
transitionViewHolder.crossfadeToAvatarImage.draw(canvas);
|
||||
canvas.restore();
|
||||
transitionViewHolder.crossfadeToAvatarImage.setVisible(isVisible, false);
|
||||
transitionViewHolder.crossfadeToAvatarImage.setImageCoords(avatarRectTmp);
|
||||
transitionViewHolder.crossfadeToAvatarImage.setRoundRadius(oldRadius);
|
||||
// transitionViewHolder.crossfadeToAvatarImage.setVisible(false, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -759,7 +798,7 @@ public class StoryViewer {
|
|||
boolean override = false;
|
||||
boolean enableTouch = !keyboardVisible && !isClosed && !isRecording;
|
||||
if (selfStoriesViewsOffset == 0 && !inSwipeToDissmissMode && storiesViewPager.currentState == ViewPager.SCROLL_STATE_DRAGGING && ev.getAction() == MotionEvent.ACTION_MOVE && enableTouch) {
|
||||
float dx = lastX.get(ev.getPointerId(0)) - ev.getX(0);
|
||||
float dx = lastX.get(ev.getPointerId(0), 0f) - ev.getX(0);
|
||||
if (dx != 0 && !storiesViewPager.canScroll(dx) || swipeToDismissHorizontalOffset != 0) {
|
||||
if (swipeToDismissHorizontalOffset == 0) {
|
||||
swipeToDismissHorizontalDirection = -dx;
|
||||
|
@ -968,14 +1007,6 @@ public class StoryViewer {
|
|||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
|
||||
if (child == aspectRatioFrameLayout) {
|
||||
return true;
|
||||
}
|
||||
return super.drawChild(canvas, child, drawingTime);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dispatchDraw(Canvas canvas) {
|
||||
PeerStoriesView peerStoriesView = storiesViewPager.getCurrentPeerView();
|
||||
|
@ -1175,6 +1206,7 @@ public class StoryViewer {
|
|||
currentPlayerScope.textureView = textureView;
|
||||
currentPlayerScope.surfaceView = surfaceView;
|
||||
FileStreamLoadOperation.setPriorityForDocument(playerHolder.document, FileLoader.PRIORITY_HIGH);
|
||||
FileLoader.getInstance(currentAccount).changePriority(FileLoader.PRIORITY_HIGH, playerHolder.document, null, null, null, null, null);
|
||||
currentPlayerScope.player.start(isPaused(), uri, t, isInSilentMode);
|
||||
currentPlayerScope.invalidate();
|
||||
}
|
||||
|
@ -1266,10 +1298,6 @@ public class StoryViewer {
|
|||
uries.remove(j);
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
preparedPlayers.remove(i).release(null);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < uries.size(); i++) {
|
||||
Uri uri = uries.get(i);
|
||||
|
@ -1284,21 +1312,14 @@ public class StoryViewer {
|
|||
player.release(null);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
containerView.addView(storiesViewPager, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.CENTER_HORIZONTAL));
|
||||
aspectRatioFrameLayout = new AspectRatioFrameLayout(context);
|
||||
if (USE_SURFACE_VIEW) {
|
||||
surfaceView = new SurfaceView(context) {
|
||||
@Override
|
||||
public void invalidate() {
|
||||
super.invalidate();
|
||||
if (currentPlayerScope != null) {
|
||||
currentPlayerScope.invalidate();
|
||||
}
|
||||
}
|
||||
};
|
||||
surfaceView = new SurfaceView(context);
|
||||
surfaceView.setZOrderMediaOverlay(false);
|
||||
surfaceView.setZOrderOnTop(false);
|
||||
//surfaceView.setZOrderMediaOverlay(true);
|
||||
aspectRatioFrameLayout.addView(surfaceView);
|
||||
} else {
|
||||
|
@ -1315,12 +1336,14 @@ public class StoryViewer {
|
|||
}
|
||||
|
||||
|
||||
containerView.addView(aspectRatioFrameLayout);
|
||||
|
||||
volumeControl = new StoriesVolumeContorl(context);
|
||||
containerView.addView(volumeControl, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, 0, 4, 0, 4, 0));
|
||||
}
|
||||
AndroidUtilities.removeFromParent(containerView);
|
||||
windowView.addView(containerView);
|
||||
AndroidUtilities.removeFromParent(aspectRatioFrameLayout);
|
||||
windowView.addView(aspectRatioFrameLayout);
|
||||
windowView.setClipChildren(false);
|
||||
|
||||
if (ATTACH_TO_FRAGMENT) {
|
||||
|
@ -1480,11 +1503,13 @@ public class StoryViewer {
|
|||
if (page == null || page.storyContainer == null) {
|
||||
return false;
|
||||
}
|
||||
float x = windowView == null ? 0 : windowView.getX();
|
||||
float y = windowView == null ? 0 : windowView.getY();
|
||||
rectF.set(
|
||||
windowView.getX() + swipeToDismissHorizontalOffset + containerView.getLeft() + page.getX() + page.storyContainer.getX(),
|
||||
windowView.getY() + swipeToDismissOffset + containerView.getTop() + page.getY() + page.storyContainer.getY(),
|
||||
windowView.getX() + swipeToDismissHorizontalOffset + containerView.getRight() - (containerView.getWidth() - page.getRight()) - (page.getWidth() - page.storyContainer.getRight()),
|
||||
windowView.getY() + swipeToDismissOffset + containerView.getBottom() - (containerView.getHeight() - page.getBottom()) - (page.getHeight() - page.storyContainer.getBottom())
|
||||
x + swipeToDismissHorizontalOffset + containerView.getLeft() + page.getX() + page.storyContainer.getX(),
|
||||
y + swipeToDismissOffset + containerView.getTop() + page.getY() + page.storyContainer.getY(),
|
||||
x + swipeToDismissHorizontalOffset + containerView.getRight() - (containerView.getWidth() - page.getRight()) - (page.getWidth() - page.storyContainer.getRight()),
|
||||
y + swipeToDismissOffset + containerView.getBottom() - (containerView.getHeight() - page.getBottom()) - (page.getHeight() - page.storyContainer.getBottom())
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
@ -1524,10 +1549,10 @@ public class StoryViewer {
|
|||
public void toggleSilentMode() {
|
||||
isInSilentMode = !isInSilentMode;
|
||||
if (playerHolder != null) {
|
||||
playerHolder.setAudioEnabled(!isInSilentMode);
|
||||
playerHolder.setAudioEnabled(!isInSilentMode, false);
|
||||
}
|
||||
for (int i = 0; i < preparedPlayers.size(); i++) {
|
||||
preparedPlayers.get(i).setAudioEnabled(!isInSilentMode);
|
||||
preparedPlayers.get(i).setAudioEnabled(!isInSilentMode, true);
|
||||
}
|
||||
PeerStoriesView peerStoriesView = storiesViewPager.getCurrentPeerView();
|
||||
peerStoriesView.sharedResources.setIconMuted(!soundEnabled(), true);
|
||||
|
@ -1758,7 +1783,10 @@ public class StoryViewer {
|
|||
if (progressToDismiss != newProgress) {
|
||||
progressToDismiss = newProgress;
|
||||
checkNavBarColor();
|
||||
storiesViewPager.getCurrentPeerView().progressToDismissUpdated();
|
||||
PeerStoriesView peerStoriesView = storiesViewPager.getCurrentPeerView();
|
||||
if (peerStoriesView != null) {
|
||||
peerStoriesView.progressToDismissUpdated();
|
||||
}
|
||||
}
|
||||
|
||||
if (windowView != null) {
|
||||
|
@ -2137,10 +2165,12 @@ public class StoryViewer {
|
|||
surfaceView.setSecure(!allowScreenshots);
|
||||
}
|
||||
if (ATTACH_TO_FRAGMENT) {
|
||||
if (allowScreenshots) {
|
||||
fragment.getParentActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_SECURE);
|
||||
} else {
|
||||
fragment.getParentActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
|
||||
if (fragment.getParentActivity() != null) {
|
||||
if (allowScreenshots) {
|
||||
fragment.getParentActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_SECURE);
|
||||
} else {
|
||||
fragment.getParentActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (allowScreenshots) {
|
||||
|
@ -2160,6 +2190,9 @@ public class StoryViewer {
|
|||
|
||||
public void openFor(BaseFragment fragment, RecyclerListView recyclerListView, ChatActionCell cell) {
|
||||
MessageObject messageObject = cell.getMessageObject();
|
||||
if (fragment == null || fragment.getContext() == null) {
|
||||
return;
|
||||
}
|
||||
if (messageObject.type == MessageObject.TYPE_STORY_MENTION) {
|
||||
TLRPC.StoryItem storyItem = messageObject.messageOwner.media.storyItem;
|
||||
storyItem.dialogId = messageObject.messageOwner.media.user_id;
|
||||
|
@ -2196,6 +2229,7 @@ public class StoryViewer {
|
|||
public View clipParent;
|
||||
public float clipTop;
|
||||
public float clipBottom;
|
||||
public ImageReceiver crossfadeToAvatarImage;
|
||||
StoriesUtilities.AvatarStoryParams params;
|
||||
|
||||
public void clear() {
|
||||
|
@ -2207,6 +2241,7 @@ public class StoryViewer {
|
|||
drawClip = null;
|
||||
clipParent = null;
|
||||
radialProgressUpload = null;
|
||||
crossfadeToAvatarImage = null;
|
||||
clipTop = 0;
|
||||
clipBottom = 0;
|
||||
}
|
||||
|
@ -2474,7 +2509,7 @@ public class StoryViewer {
|
|||
});
|
||||
}
|
||||
|
||||
public void setAudioEnabled(boolean enabled) {
|
||||
public void setAudioEnabled(boolean enabled, boolean prepared) {
|
||||
boolean disabled = !enabled;
|
||||
if (audioDisabled == disabled) {
|
||||
return;
|
||||
|
@ -2494,7 +2529,7 @@ public class StoryViewer {
|
|||
ensurePlayerCreated(audioDisabled);
|
||||
videoPlayer.preparePlayer(uri, "other");
|
||||
videoPlayer.setWorkerQueue(dispatchQueue);
|
||||
if (currentPlayerScope != null) {
|
||||
if (!prepared) {
|
||||
if (USE_SURFACE_VIEW) {
|
||||
videoPlayer.setSurfaceView(surfaceView);
|
||||
} else {
|
||||
|
@ -2503,7 +2538,7 @@ public class StoryViewer {
|
|||
}
|
||||
// videoPlayer.setTextureView(textureView);
|
||||
videoPlayer.seekTo(position + 50);
|
||||
if (playing) {
|
||||
if (playing && !prepared) {
|
||||
videoPlayer.setPlayWhenReady(true);
|
||||
videoPlayer.play();
|
||||
} else {
|
||||
|
|
|
@ -19,6 +19,7 @@ import androidx.annotation.NonNull;
|
|||
|
||||
import org.telegram.messenger.AndroidUtilities;
|
||||
import org.telegram.messenger.LocaleController;
|
||||
import org.telegram.messenger.R;
|
||||
import org.telegram.ui.Components.AnimatedFloat;
|
||||
import org.telegram.ui.Components.AnimatedTextView;
|
||||
import org.telegram.ui.Components.CubicBezierInterpolator;
|
||||
|
|
|
@ -482,13 +482,29 @@ public class DualCameraView extends CameraView implements CameraController.Error
|
|||
-862041025, // XIAOMI WILLOW
|
||||
-1258375037, // XIAOMI INGRES
|
||||
-1320049076, // XIAOMI GINKGO
|
||||
-215749424, // XIAOMI LISA
|
||||
1901578030, // XIAOMI LEMON
|
||||
-215451421, // XIAOMI VIVA
|
||||
1908491424, // XIAOMI STONE
|
||||
-1321491332, // XIAOMI RAPHAEL
|
||||
-1155551678, // XIAOMI MARBLE
|
||||
1908524435, // XIAOMI SURYA
|
||||
976847578, // XIAOMI LAUREL_SPROUT
|
||||
-713271737, // OPPO OP4F2F
|
||||
-2010722764, // SAMSUNG A52SXQ (A52s 5G)
|
||||
1407170066, // SAMSUNG D2Q (Note10+)
|
||||
-1394190055, // SAMSUNG B4Q
|
||||
1407170066, // HUAWEI HWNAM
|
||||
1407159934, // HUAWEI HWCOR
|
||||
1407172057, // HUAWEI HWPCT
|
||||
1231389747, // FAIRPHONE FP3
|
||||
-2076538925, // MOTOROLA RSTAR
|
||||
41497626, // MOTOROLA RHODEC
|
||||
846150482, // MOTOROLA CHANNEL
|
||||
-1198092731, // MOTOROLA CYPRUS64
|
||||
-251277614, // MOTOROLA HANOIP
|
||||
-2078385967, // MOTOROLA PSTAR
|
||||
// -1426053134 // REALME REE2ADL1
|
||||
};
|
||||
|
||||
private static final int[] dualWhitelistByModel = new int[] {
|
||||
|
|
|
@ -1917,7 +1917,7 @@ public class EmojiBottomSheet extends BottomSheet implements NotificationCenter.
|
|||
|
||||
if (emojiLayout != null) {
|
||||
canvas.save();
|
||||
canvas.translate(emojiRect.left + dp(12) + emojiLayoutLeft, emojiRect.top + (emojiRect.height() - emojiLayout.getHeight()) / 2f);
|
||||
canvas.translate(emojiRect.left + dp(12) - emojiLayoutLeft, emojiRect.top + (emojiRect.height() - emojiLayout.getHeight()) / 2f);
|
||||
textPaint.setColor(ColorUtils.blendARGB(0xFF838383, 0xFFFFFFFF, Utilities.clamp(1f - Math.abs(type - 0), 1, 0)));
|
||||
emojiLayout.draw(canvas);
|
||||
canvas.restore();
|
||||
|
@ -1925,7 +1925,7 @@ public class EmojiBottomSheet extends BottomSheet implements NotificationCenter.
|
|||
|
||||
if (stickersLayout != null) {
|
||||
canvas.save();
|
||||
canvas.translate(stickersRect.left + dp(12) + stickersLayoutLeft, stickersRect.top + (stickersRect.height() - stickersLayout.getHeight()) / 2f);
|
||||
canvas.translate(stickersRect.left + dp(12) - stickersLayoutLeft, stickersRect.top + (stickersRect.height() - stickersLayout.getHeight()) / 2f);
|
||||
textPaint.setColor(ColorUtils.blendARGB(0xFF838383, 0xFFFFFFFF, Utilities.clamp(1f - Math.abs(type - 1), 1, 0)));
|
||||
stickersLayout.draw(canvas);
|
||||
canvas.restore();
|
||||
|
@ -1933,7 +1933,7 @@ public class EmojiBottomSheet extends BottomSheet implements NotificationCenter.
|
|||
|
||||
if (masksLayout != null) {
|
||||
canvas.save();
|
||||
canvas.translate(masksRect.left + dp(12) + masksLayoutLeft, masksRect.top + (masksRect.height() - masksLayout.getHeight()) / 2f);
|
||||
canvas.translate(masksRect.left + dp(12) - masksLayoutLeft, masksRect.top + (masksRect.height() - masksLayout.getHeight()) / 2f);
|
||||
textPaint.setColor(ColorUtils.blendARGB(0xFF838383, 0xFFFFFFFF, Utilities.clamp(1f - Math.abs(type - 2), 1, 0)));
|
||||
masksLayout.draw(canvas);
|
||||
canvas.restore();
|
||||
|
|
|
@ -923,7 +923,7 @@ public class GalleryListView extends FrameLayout implements NotificationCenter.N
|
|||
setTypeface(AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_ROBOTO_MEDIUM));
|
||||
setPadding(dp(16), dp(16), dp(21), dp(10));
|
||||
|
||||
setText(LocaleController.getString(onlyPhotos ? R.string.ChoosePhoto : R.string.ChoosePhotoOrVideo));
|
||||
setText(LocaleController.getString(onlyPhotos ? R.string.AddImage : R.string.ChoosePhotoOrVideo));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ public class HintTextView extends View {
|
|||
textDrawable.getPaint().setShadowLayer(AndroidUtilities.dp(1.4f), 0, AndroidUtilities.dp(.4f), 0x4C000000);
|
||||
textDrawable.setGravity(Gravity.CENTER_HORIZONTAL);
|
||||
textDrawable.setCallback(this);
|
||||
textDrawable.setOverrideFullWidth(AndroidUtilities.displaySize.x);
|
||||
}
|
||||
|
||||
public void setText(CharSequence text, boolean animated) {
|
||||
|
@ -45,4 +46,10 @@ public class HintTextView extends View {
|
|||
protected boolean verifyDrawable(@NonNull Drawable who) {
|
||||
return who == textDrawable || super.verifyDrawable(who);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
textDrawable.setOverrideFullWidth(getMeasuredWidth());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -86,6 +86,7 @@ public class HintView2 extends View {
|
|||
private float textX, textY;
|
||||
|
||||
private boolean hideByTouch = true;
|
||||
private boolean repeatedBounce = true;
|
||||
|
||||
private boolean shown;
|
||||
private AnimatedFloat show = new AnimatedFloat(this, 350, CubicBezierInterpolator.EASE_OUT_QUINT);
|
||||
|
@ -185,6 +186,18 @@ public class HintView2 extends View {
|
|||
return this;
|
||||
}
|
||||
|
||||
private static boolean contains(CharSequence text, char c) {
|
||||
if (text == null) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < text.length(); ++i) {
|
||||
if (text.charAt(i) == c) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// returns max width
|
||||
public static int cutInFancyHalf(CharSequence text, TextPaint paint) {
|
||||
if (text == null) {
|
||||
|
@ -257,6 +270,11 @@ public class HintView2 extends View {
|
|||
return this;
|
||||
}
|
||||
|
||||
public HintView2 setBounce(boolean enable) {
|
||||
repeatedBounce = enable;
|
||||
return this;
|
||||
}
|
||||
|
||||
// works only for multiline=true
|
||||
public HintView2 setTextAlign(Layout.Alignment alignment) {
|
||||
textLayoutAlignment = alignment;
|
||||
|
@ -318,6 +336,9 @@ public class HintView2 extends View {
|
|||
private ValueAnimator bounceAnimator;
|
||||
private float bounceT = 1;
|
||||
private void bounceShow() {
|
||||
if (!repeatedBounce) {
|
||||
return;
|
||||
}
|
||||
if (bounceAnimator != null) {
|
||||
bounceAnimator.cancel();
|
||||
bounceAnimator = null;
|
||||
|
@ -487,7 +508,7 @@ public class HintView2 extends View {
|
|||
backgroundPaint.setAlpha(wasAlpha);
|
||||
|
||||
if (multiline) {
|
||||
canvas.saveLayerAlpha(0, 0, getWidth(), getHeight(), (int) (0xFF * alpha), Canvas.ALL_SAVE_FLAG);
|
||||
canvas.saveLayerAlpha(0, 0, getWidth(), Math.max(getHeight(), height), (int) (0xFF * alpha), Canvas.ALL_SAVE_FLAG);
|
||||
canvas.translate(textX = bounds.left + innerPadding.left - textLayoutLeft, textY = bounds.top + innerPadding.top);
|
||||
if (links.draw(canvas)) {
|
||||
invalidate();
|
||||
|
|
|
@ -2739,8 +2739,9 @@ public class PaintView extends SizeNotifierFrameLayoutPhoto implements IPhotoPai
|
|||
deleteView.setTextColor(getThemedColor(Theme.key_actionBarDefaultSubmenuItem));
|
||||
deleteView.setBackground(Theme.getSelectorDrawable(false));
|
||||
deleteView.setGravity(Gravity.CENTER_VERTICAL);
|
||||
deleteView.setEllipsize(TextUtils.TruncateAt.END);
|
||||
deleteView.setPadding(AndroidUtilities.dp(16), 0, AndroidUtilities.dp(14), 0);
|
||||
deleteView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
|
||||
deleteView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
|
||||
deleteView.setTag(0);
|
||||
deleteView.setText(LocaleController.getString("PaintDelete", R.string.PaintDelete));
|
||||
deleteView.setOnClickListener(v -> {
|
||||
|
@ -2757,8 +2758,9 @@ public class PaintView extends SizeNotifierFrameLayoutPhoto implements IPhotoPai
|
|||
editView.setTextColor(getThemedColor(Theme.key_actionBarDefaultSubmenuItem));
|
||||
editView.setBackground(Theme.getSelectorDrawable(false));
|
||||
editView.setGravity(Gravity.CENTER_VERTICAL);
|
||||
editView.setEllipsize(TextUtils.TruncateAt.END);
|
||||
editView.setPadding(AndroidUtilities.dp(16), 0, AndroidUtilities.dp(16), 0);
|
||||
editView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
|
||||
editView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
|
||||
if ((keyboardNotifier.keyboardVisible() && !keyboardNotifier.ignoring) || emojiPadding > 0) {
|
||||
editView.setTag(3);
|
||||
editView.setText(LocaleController.getString("Paste", R.string.Paste));
|
||||
|
@ -2791,9 +2793,10 @@ public class PaintView extends SizeNotifierFrameLayoutPhoto implements IPhotoPai
|
|||
TextView flipView = new TextView(getContext());
|
||||
flipView.setTextColor(getThemedColor(Theme.key_actionBarDefaultSubmenuItem));
|
||||
flipView.setBackground(Theme.getSelectorDrawable(false));
|
||||
flipView.setEllipsize(TextUtils.TruncateAt.END);
|
||||
flipView.setGravity(Gravity.CENTER_VERTICAL);
|
||||
flipView.setPadding(AndroidUtilities.dp(16), 0, AndroidUtilities.dp(16), 0);
|
||||
flipView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
|
||||
flipView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
|
||||
flipView.setTag(4);
|
||||
flipView.setText(LocaleController.getString(R.string.Flip));
|
||||
flipView.setOnClickListener(v -> {
|
||||
|
@ -2809,22 +2812,25 @@ public class PaintView extends SizeNotifierFrameLayoutPhoto implements IPhotoPai
|
|||
parent.addView(flipView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, 48));
|
||||
}
|
||||
|
||||
TextView duplicateView = new TextView(getContext());
|
||||
duplicateView.setTextColor(getThemedColor(Theme.key_actionBarDefaultSubmenuItem));
|
||||
duplicateView.setBackgroundDrawable(Theme.getSelectorDrawable(false));
|
||||
duplicateView.setGravity(Gravity.CENTER_VERTICAL);
|
||||
duplicateView.setPadding(AndroidUtilities.dp(14), 0, AndroidUtilities.dp(16), 0);
|
||||
duplicateView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
|
||||
duplicateView.setTag(2);
|
||||
duplicateView.setText(LocaleController.getString("PaintDuplicate", R.string.PaintDuplicate));
|
||||
duplicateView.setOnClickListener(v -> {
|
||||
duplicateEntity(entityView);
|
||||
if (!(entityView instanceof PhotoView)) {
|
||||
TextView duplicateView = new TextView(getContext());
|
||||
duplicateView.setTextColor(getThemedColor(Theme.key_actionBarDefaultSubmenuItem));
|
||||
duplicateView.setBackground(Theme.getSelectorDrawable(false));
|
||||
duplicateView.setEllipsize(TextUtils.TruncateAt.END);
|
||||
duplicateView.setGravity(Gravity.CENTER_VERTICAL);
|
||||
duplicateView.setPadding(AndroidUtilities.dp(14), 0, AndroidUtilities.dp(16), 0);
|
||||
duplicateView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
|
||||
duplicateView.setTag(2);
|
||||
duplicateView.setText(LocaleController.getString("PaintDuplicate", R.string.PaintDuplicate));
|
||||
duplicateView.setOnClickListener(v -> {
|
||||
duplicateEntity(entityView);
|
||||
|
||||
if (popupWindow != null && popupWindow.isShowing()) {
|
||||
popupWindow.dismiss(true);
|
||||
}
|
||||
});
|
||||
parent.addView(duplicateView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, 48));
|
||||
if (popupWindow != null && popupWindow.isShowing()) {
|
||||
popupWindow.dismiss(true);
|
||||
}
|
||||
});
|
||||
parent.addView(duplicateView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, 48));
|
||||
}
|
||||
|
||||
popupLayout.addView(parent);
|
||||
|
||||
|
@ -2855,6 +2861,8 @@ public class PaintView extends SizeNotifierFrameLayoutPhoto implements IPhotoPai
|
|||
newTextPaintView.setMaxWidth(w - AndroidUtilities.dp(7 + 7 + 18));
|
||||
entitiesView.addView(newTextPaintView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT));
|
||||
entityView = newTextPaintView;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
registerRemovalUndo(entityView);
|
||||
|
@ -3192,6 +3200,9 @@ public class PaintView extends SizeNotifierFrameLayoutPhoto implements IPhotoPai
|
|||
}
|
||||
|
||||
private void registerRemovalUndo(final EntityView entityView) {
|
||||
if (entityView == null) {
|
||||
return;
|
||||
}
|
||||
undoStore.registerUndo(entityView.getUUID(), () -> removeEntity(entityView));
|
||||
}
|
||||
|
||||
|
|
|
@ -278,6 +278,10 @@ public class PreviewView extends FrameLayout {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (imageId < 0 && entry.isVideo && entry.thumbPath == null) {
|
||||
invalidate();
|
||||
return;
|
||||
}
|
||||
if (bitmap == null) {
|
||||
String path = entry.getOriginalFile().getPath();
|
||||
BitmapFactory.Options options = new BitmapFactory.Options();
|
||||
|
@ -286,7 +290,13 @@ public class PreviewView extends FrameLayout {
|
|||
if (entry.thumbPath != null) {
|
||||
BitmapFactory.decodeFile(entry.thumbPath, options);
|
||||
} else {
|
||||
MediaStore.Video.Thumbnails.getThumbnail(getContext().getContentResolver(), imageId, MediaStore.Video.Thumbnails.MINI_KIND, options);
|
||||
try {
|
||||
MediaStore.Video.Thumbnails.getThumbnail(getContext().getContentResolver(), imageId, MediaStore.Video.Thumbnails.MINI_KIND, options);
|
||||
} catch (Throwable e) {
|
||||
bitmap = null;
|
||||
invalidate();
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
BitmapFactory.decodeFile(path, options);
|
||||
|
@ -298,7 +308,13 @@ public class PreviewView extends FrameLayout {
|
|||
if (entry.thumbPath != null) {
|
||||
BitmapFactory.decodeFile(entry.thumbPath, options);
|
||||
} else {
|
||||
bitmap = MediaStore.Video.Thumbnails.getThumbnail(getContext().getContentResolver(), imageId, MediaStore.Video.Thumbnails.MINI_KIND, options);
|
||||
try {
|
||||
bitmap = MediaStore.Video.Thumbnails.getThumbnail(getContext().getContentResolver(), imageId, MediaStore.Video.Thumbnails.MINI_KIND, options);
|
||||
} catch (Throwable e) {
|
||||
bitmap = null;
|
||||
invalidate();
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
bitmap = BitmapFactory.decodeFile(path, options);
|
||||
|
@ -459,7 +475,9 @@ public class PreviewView extends FrameLayout {
|
|||
addView(textureView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.TOP | Gravity.LEFT));
|
||||
|
||||
entry.detectHDR((hdrInfo) -> {
|
||||
textureView.setHDRInfo(hdrInfo);
|
||||
if (textureView != null) {
|
||||
textureView.setHDRInfo(hdrInfo);
|
||||
}
|
||||
});
|
||||
|
||||
Uri uri = Uri.fromFile(entry.getOriginalFile());
|
||||
|
|
|
@ -571,8 +571,8 @@ public class StoryEntry extends IStoryPart {
|
|||
long usedMemory = runtime.totalMemory() - runtime.freeMemory();
|
||||
long availableMemory = maxMemory - usedMemory;
|
||||
final boolean enoughMemory = options.outWidth * options.outHeight * 4L * 2L <= availableMemory;
|
||||
if (!enoughMemory) {
|
||||
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
|
||||
if (!enoughMemory || Math.max(options.outWidth, options.outHeight) > 4200 || SharedConfig.getDevicePerformanceClass() <= SharedConfig.PERFORMANCE_CLASS_LOW) {
|
||||
// options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
|
||||
options.inScaled = true;
|
||||
options.inDensity = options.outWidth;
|
||||
options.inTargetDensity = reqWidth;
|
||||
|
|
|
@ -879,7 +879,7 @@ public class StoryPrivacyBottomSheet extends BottomSheet implements Notification
|
|||
selectedUsers.addAll(selectedContacts);
|
||||
selectedUsersByGroup.putAll(selectedContactsByGroup);
|
||||
}
|
||||
layoutManager.setReverseLayout(pageType == PAGE_TYPE_SHARE);
|
||||
layoutManager.setReverseLayout(adapter.reversedLayout = pageType == PAGE_TYPE_SHARE);
|
||||
updateSpans(false);
|
||||
searchField.setText("");
|
||||
searchField.setVisibility(pageType == PAGE_TYPE_SHARE ? View.GONE : View.VISIBLE);
|
||||
|
@ -912,7 +912,9 @@ public class StoryPrivacyBottomSheet extends BottomSheet implements Notification
|
|||
sectionCell.setVisibility(View.GONE);
|
||||
// items.add(ItemInner.asPad(dp(84) + 4 * dp(56) + (sendAsMessageEnabled ? dp(120) : dp(64))));
|
||||
items.add(ItemInner.asHeader2(
|
||||
LocaleController.getString("StoryPrivacyAlertTitle", R.string.StoryPrivacyAlertTitle),
|
||||
isEdit ?
|
||||
LocaleController.getString("StoryPrivacyAlertEditTitle", R.string.StoryPrivacyAlertEditTitle) :
|
||||
LocaleController.getString("StoryPrivacyAlertTitle", R.string.StoryPrivacyAlertTitle),
|
||||
storyPeriod != Integer.MAX_VALUE ?
|
||||
LocaleController.formatPluralString("StoryPrivacyAlertSubtitle", storyPeriod / 3600) :
|
||||
LocaleController.getString("StoryPrivacyAlertSubtitleProfile", R.string.StoryPrivacyAlertSubtitleProfile)
|
||||
|
@ -1300,7 +1302,7 @@ public class StoryPrivacyBottomSheet extends BottomSheet implements Notification
|
|||
} else if (pageType == PAGE_TYPE_SEND_AS_MESSAGE) {
|
||||
button.setShowZero(true);
|
||||
button.setEnabled(!selectedUsers.isEmpty());
|
||||
button.setText(LocaleController.formatPluralString("StoryPrivacyButtonMessageChats", selectedUsers.size()), animated);
|
||||
// button.setText(LocaleController.formatPluralString("StoryPrivacyButtonMessageChats", selectedUsers.size()), animated);
|
||||
button.setCount(selectedUsers.size(), animated);
|
||||
button2.setVisibility(View.GONE);
|
||||
}
|
||||
|
@ -1536,6 +1538,7 @@ public class StoryPrivacyBottomSheet extends BottomSheet implements Notification
|
|||
}
|
||||
|
||||
private RecyclerListView listView;
|
||||
public boolean reversedLayout;
|
||||
|
||||
@Override
|
||||
public boolean isEnabled(RecyclerView.ViewHolder holder) {
|
||||
|
@ -1587,8 +1590,8 @@ public class StoryPrivacyBottomSheet extends BottomSheet implements Notification
|
|||
}
|
||||
final ItemInner item = items.get(position);
|
||||
final int viewType = holder.getItemViewType();
|
||||
final ItemInner nextItem = position + 1 < items.size() ? items.get(position + 1) : null;
|
||||
final boolean divider = nextItem != null && nextItem.viewType == viewType;
|
||||
final ItemInner neighbour = reversedLayout ? (position > 0 ? items.get(position - 1) : null) : (position + 1 < items.size() ? items.get(position + 1) : null);
|
||||
final boolean divider = neighbour != null && neighbour.viewType == viewType;
|
||||
if (viewType == VIEW_TYPE_USER) {
|
||||
UserCell userCell = (UserCell) holder.itemView;
|
||||
if (item.type > 0) {
|
||||
|
@ -2539,7 +2542,7 @@ public class StoryPrivacyBottomSheet extends BottomSheet implements Notification
|
|||
}
|
||||
}
|
||||
|
||||
private static class HeaderCell2 extends FrameLayout {
|
||||
private static class HeaderCell2 extends LinearLayout {
|
||||
|
||||
private final Theme.ResourcesProvider resourcesProvider;
|
||||
private final TextView titleTextView;
|
||||
|
@ -2547,27 +2550,19 @@ public class StoryPrivacyBottomSheet extends BottomSheet implements Notification
|
|||
|
||||
public HeaderCell2(Context context, Theme.ResourcesProvider resourcesProvider) {
|
||||
super(context);
|
||||
setOrientation(VERTICAL);
|
||||
this.resourcesProvider = resourcesProvider;
|
||||
|
||||
titleTextView = new TextView(context);
|
||||
titleTextView.setTextColor(Theme.getColor(Theme.key_dialogTextBlack, resourcesProvider));
|
||||
titleTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20);
|
||||
titleTextView.setTypeface(AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_ROBOTO_MEDIUM));
|
||||
addView(titleTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.TOP | Gravity.FILL_HORIZONTAL, 27, 16, 27, 0));
|
||||
addView(titleTextView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.TOP | Gravity.FILL_HORIZONTAL, 27, 16, 27, 0));
|
||||
|
||||
subtitleTextView = new TextView(context);
|
||||
subtitleTextView.setTextColor(Theme.getColor(Theme.key_dialogTextGray2, resourcesProvider));
|
||||
subtitleTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
|
||||
NotificationCenter.listenEmojiLoading(subtitleTextView);
|
||||
addView(subtitleTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.TOP | Gravity.FILL_HORIZONTAL, 27, 44, 27, 0));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
super.onMeasure(
|
||||
MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.EXACTLY),
|
||||
MeasureSpec.makeMeasureSpec(dp(72), MeasureSpec.EXACTLY)
|
||||
);
|
||||
addView(subtitleTextView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.TOP | Gravity.FILL_HORIZONTAL, 27, 5, 27, 13));
|
||||
}
|
||||
|
||||
public void setText(CharSequence title, CharSequence subtitle) {
|
||||
|
|
|
@ -106,6 +106,7 @@ import org.telegram.tgnet.TLRPC;
|
|||
import org.telegram.ui.ActionBar.ActionBar;
|
||||
import org.telegram.ui.ActionBar.AlertDialog;
|
||||
import org.telegram.ui.ActionBar.BaseFragment;
|
||||
import org.telegram.ui.ActionBar.SimpleTextView;
|
||||
import org.telegram.ui.ActionBar.Theme;
|
||||
import org.telegram.ui.Components.AlertsCreator;
|
||||
import org.telegram.ui.Components.Bulletin;
|
||||
|
@ -460,6 +461,9 @@ public class StoryRecorder implements NotificationCenter.NotificationCenterDeleg
|
|||
}
|
||||
|
||||
if (outputEntry != null) {
|
||||
if (wasSend && outputEntry.isEdit) {
|
||||
outputEntry.editedMedia = false;
|
||||
}
|
||||
outputEntry.destroy(false);
|
||||
outputEntry = null;
|
||||
}
|
||||
|
@ -561,6 +565,7 @@ public class StoryRecorder implements NotificationCenter.NotificationCenterDeleg
|
|||
|
||||
private void onOpenDone() {
|
||||
isShown = true;
|
||||
wasSend = false;
|
||||
if (openType == 1) {
|
||||
previewContainer.setAlpha(1f);
|
||||
previewContainer.setTranslationX(0);
|
||||
|
@ -1303,7 +1308,7 @@ public class StoryRecorder implements NotificationCenter.NotificationCenterDeleg
|
|||
private FrameLayout navbarContainer;
|
||||
|
||||
private ImageView backButton;
|
||||
private TextView titleTextView;
|
||||
private SimpleTextView titleTextView;
|
||||
private StoryPrivacyBottomSheet privacySheet;
|
||||
|
||||
/* PAGE_CAMERA */
|
||||
|
@ -1609,16 +1614,18 @@ public class StoryRecorder implements NotificationCenter.NotificationCenterDeleg
|
|||
});
|
||||
actionBarContainer.addView(backButton, LayoutHelper.createFrame(56, 56, Gravity.TOP | Gravity.LEFT));
|
||||
|
||||
titleTextView = new TextView(context);
|
||||
titleTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20);
|
||||
titleTextView = new SimpleTextView(context);
|
||||
titleTextView.setTextSize(20);
|
||||
titleTextView.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
|
||||
titleTextView.setTextColor(0xffffffff);
|
||||
titleTextView.setTypeface(AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_ROBOTO_MEDIUM));
|
||||
titleTextView.setText(LocaleController.getString("RecorderNewStory", R.string.RecorderNewStory));
|
||||
titleTextView.setShadowLayer(dpf2(1), 0, 1, 0x40000000);
|
||||
titleTextView.getPaint().setShadowLayer(dpf2(1), 0, 1, 0x40000000);
|
||||
titleTextView.setAlpha(0f);
|
||||
titleTextView.setVisibility(View.GONE);
|
||||
actionBarContainer.addView(titleTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 56, Gravity.TOP | Gravity.FILL_HORIZONTAL, 71, 0, 96, 0));
|
||||
titleTextView.setEllipsizeByGradient(true);
|
||||
titleTextView.setRightPadding(AndroidUtilities.dp(96));
|
||||
actionBarContainer.addView(titleTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 56, Gravity.TOP | Gravity.FILL_HORIZONTAL, 71, 0, 0, 0));
|
||||
|
||||
downloadButton = new DownloadButton(context, () -> {
|
||||
applyFilter();
|
||||
|
@ -1626,7 +1633,11 @@ public class StoryRecorder implements NotificationCenter.NotificationCenterDeleg
|
|||
}, currentAccount, windowView, resourcesProvider);
|
||||
actionBarContainer.addView(downloadButton, LayoutHelper.createFrame(56, 56, Gravity.TOP | Gravity.RIGHT));
|
||||
|
||||
muteHint = new HintView2(activity, HintView2.DIRECTION_TOP).setJoint(1, -68).setDuration(2000);
|
||||
muteHint = new HintView2(activity, HintView2.DIRECTION_TOP)
|
||||
.setJoint(1, -68)
|
||||
.setDuration(2000)
|
||||
.setBounce(false)
|
||||
.setAnimatedTextHacks(true, true, false);
|
||||
muteHint.setPadding(dp(8), 0, dp(8), 0);
|
||||
actionBarContainer.addView(muteHint, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.TOP, 0, 52, 0, 0));
|
||||
|
||||
|
@ -1640,7 +1651,7 @@ public class StoryRecorder implements NotificationCenter.NotificationCenterDeleg
|
|||
return;
|
||||
}
|
||||
outputEntry.muted = !outputEntry.muted;
|
||||
muteHint.setText(outputEntry.muted ? LocaleController.getString("StorySoundMuted") : LocaleController.getString("StorySoundNotMuted"), true);
|
||||
muteHint.setText(outputEntry.muted ? LocaleController.getString("StorySoundMuted") : LocaleController.getString("StorySoundNotMuted"), muteHint.shown());
|
||||
muteHint.show();
|
||||
setIconMuted(outputEntry.muted, true);
|
||||
previewView.mute(outputEntry.muted);
|
||||
|
@ -1703,8 +1714,7 @@ public class StoryRecorder implements NotificationCenter.NotificationCenterDeleg
|
|||
savedDualHint = new HintView2(activity, HintView2.DIRECTION_RIGHT)
|
||||
.setJoint(0, 56 / 2)
|
||||
.setDuration(5000)
|
||||
.setMultilineText(true)
|
||||
.setMaxWidth(140);
|
||||
.setMultilineText(true);
|
||||
actionBarContainer.addView(savedDualHint, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.TOP, 0, 0, 52, 0));
|
||||
|
||||
videoTimerView = new VideoTimerView(context);
|
||||
|
@ -1756,7 +1766,7 @@ public class StoryRecorder implements NotificationCenter.NotificationCenterDeleg
|
|||
navbarContainer.addView(modeSwitcherView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.BOTTOM | Gravity.FILL_HORIZONTAL));
|
||||
|
||||
hintTextView = new HintTextView(context);
|
||||
navbarContainer.addView(hintTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 32, Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 66, 0, 66, 8));
|
||||
navbarContainer.addView(hintTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 32, Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 8, 0, 8, 8));
|
||||
|
||||
previewButtons = new PreviewButtons(context);
|
||||
previewButtons.setVisibility(View.GONE);
|
||||
|
@ -1791,6 +1801,9 @@ public class StoryRecorder implements NotificationCenter.NotificationCenterDeleg
|
|||
.isEdit(false)
|
||||
.setWarnUsers(getUsersFrom(captionEdit.getText()))
|
||||
.whenSelectedRules((privacy, allowScreenshots, keepInProfile, whenDone) -> {
|
||||
if (outputEntry == null) {
|
||||
return;
|
||||
}
|
||||
previewView.updatePauseReason(5, true);
|
||||
if (whenDone != null) {
|
||||
whenDone.run();
|
||||
|
@ -1837,7 +1850,7 @@ public class StoryRecorder implements NotificationCenter.NotificationCenterDeleg
|
|||
trash = new TrashView(context);
|
||||
trash.setAlpha(0f);
|
||||
trash.setVisibility(View.GONE);
|
||||
previewContainer.addView(trash, LayoutHelper.createFrame(120, 120, Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, 0, 0, 16));
|
||||
previewContainer.addView(trash, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 120, Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, 0, 0, 16));
|
||||
|
||||
previewHighlight = new PreviewHighlightView(context, currentAccount, resourcesProvider);
|
||||
previewContainer.addView(previewHighlight, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.FILL));
|
||||
|
@ -2899,6 +2912,9 @@ public class StoryRecorder implements NotificationCenter.NotificationCenterDeleg
|
|||
if (isVideo) {
|
||||
muteButton.setVisibility(View.VISIBLE);
|
||||
setIconMuted(outputEntry != null && outputEntry.muted, false);
|
||||
titleTextView.setRightPadding(AndroidUtilities.dp(96));
|
||||
} else {
|
||||
titleTextView.setRightPadding(AndroidUtilities.dp(48));
|
||||
}
|
||||
downloadButton.setVisibility(View.VISIBLE);
|
||||
// privacySelector.setVisibility(View.VISIBLE);
|
||||
|
@ -3173,13 +3189,13 @@ public class StoryRecorder implements NotificationCenter.NotificationCenterDeleg
|
|||
paintViewBitmap.recycle();
|
||||
paintViewBitmap = null;
|
||||
}
|
||||
if (outputEntry.isDraft && outputEntry.paintFile != null) {
|
||||
if (outputEntry != null && outputEntry.isDraft && outputEntry.paintFile != null) {
|
||||
paintViewBitmap = BitmapFactory.decodeFile(outputEntry.paintFile.getPath());
|
||||
}
|
||||
if (paintViewBitmap == null) {
|
||||
paintViewBitmap = Bitmap.createBitmap(size.first, size.second, Bitmap.Config.ARGB_8888);
|
||||
}
|
||||
paintView = new PaintView(activity, windowView, activity, currentAccount, paintViewBitmap, null, previewView.getOrientation(), outputEntry.mediaEntities, previewContainer.getMeasuredWidth(), previewContainer.getMeasuredHeight(), new MediaController.CropState(), null, resourcesProvider) {
|
||||
paintView = new PaintView(activity, windowView, activity, currentAccount, paintViewBitmap, null, previewView.getOrientation(), outputEntry == null ? null : outputEntry.mediaEntities, previewContainer.getMeasuredWidth(), previewContainer.getMeasuredHeight(), new MediaController.CropState(), null, resourcesProvider) {
|
||||
@Override
|
||||
public void onEntityDraggedTop(boolean value) {
|
||||
previewHighlight.show(true, value, actionBarContainer);
|
||||
|
@ -3673,7 +3689,9 @@ public class StoryRecorder implements NotificationCenter.NotificationCenterDeleg
|
|||
return;
|
||||
}
|
||||
if (savedDualHint != null) {
|
||||
savedDualHint.setText(isFrontface() ? LocaleController.getString(R.string.StoryCameraSavedDualBackHint) : LocaleController.getString(R.string.StoryCameraSavedDualFrontHint));
|
||||
CharSequence text = isFrontface() ? LocaleController.getString(R.string.StoryCameraSavedDualBackHint) : LocaleController.getString(R.string.StoryCameraSavedDualFrontHint);
|
||||
savedDualHint.setMaxWidthPx(HintView2.cutInFancyHalf(text, savedDualHint.getTextPaint()));
|
||||
savedDualHint.setText(text);
|
||||
savedDualHint.show();
|
||||
MessagesController.getGlobalMainSettings().edit().putInt("storysvddualhint", MessagesController.getGlobalMainSettings().getInt("storysvddualhint", 0) + 1).apply();
|
||||
}
|
||||
|
|
|
@ -60,7 +60,7 @@ public class TrashView extends View {
|
|||
|
||||
textDrawable = new AnimatedTextView.AnimatedTextDrawable(true, true, false);
|
||||
textDrawable.setAnimationProperties(.3f, 0, 250, CubicBezierInterpolator.EASE_OUT_QUINT);
|
||||
textDrawable.setOverrideFullWidth(dp(120));
|
||||
textDrawable.setOverrideFullWidth(AndroidUtilities.displaySize.x);
|
||||
textDrawable.setTextSize(dp(14));
|
||||
textDrawable.setTextColor(0xffffffff);
|
||||
textDrawable.setShadowLayer(dpf2(1.33f), 0, dp(1), 0x40000000);
|
||||
|
@ -95,7 +95,7 @@ public class TrashView extends View {
|
|||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
setMeasuredDimension(dp(120), dp(120));
|
||||
setMeasuredDimension(widthMeasureSpec, dp(120));
|
||||
}
|
||||
|
||||
public void onDragInfo(boolean dragged, boolean deleted) {
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 335 B |
Binary file not shown.
After Width: | Height: | Size: 315 B |
Binary file not shown.
After Width: | Height: | Size: 280 B |
Binary file not shown.
After Width: | Height: | Size: 273 B |
Binary file not shown.
After Width: | Height: | Size: 394 B |
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue