update to 9.3.0

This commit is contained in:
xaxtix 2022-12-30 16:32:20 +04:00
parent 2c71f6c92b
commit 3ccf875b1b
327 changed files with 28821 additions and 4208 deletions

View file

@ -186,6 +186,14 @@ JNIEXPORT void Java_org_telegram_messenger_Utilities_aesCbcEncryption(JNIEnv *en
(*env)->ReleaseByteArrayElements(env, iv, ivBuff, JNI_ABORT);
}
#define LISTDIR_DOCTYPE_ALL 0
#define LISTDIR_DOCTYPE_OTHER_THAN_MUSIC 1
#define LISTDIR_DOCTYPE_MUSIC 2
#define LISTDIR_DOCTYPE2_EMOJI 3
#define LISTDIR_DOCTYPE2_TEMP 4
#define LISTDIR_DOCTYPE2_OTHER 5
int64_t listdir(const char *fileName, int32_t mode, int32_t docType, int64_t time, uint8_t subdirs) {
int64_t value = 0;
DIR *dir;
@ -199,15 +207,29 @@ int64_t listdir(const char *fileName, int32_t mode, int32_t docType, int64_t tim
if (name[0] == '.') {
continue;
}
if ((docType == 1 || docType == 2) && len > 4) {
if (name[len - 4] == '.' && (
((name[len - 3] == 'm' || name[len - 3] == 'M') && (name[len - 2] == 'p' || name[len - 2] == 'P') && (name[len - 1] == '3')) ||
((name[len - 3] == 'm' || name[len - 3] == 'M') && (name[len - 2] == '4') && (name[len - 1] == 'a' || name[len - 1] == 'A'))
)) {
if (docType == 1) {
continue;
}
} else if (docType == 2) {
if (docType > 0 && len > 4) {
int isMusic = (
name[len - 4] == '.' && (
((name[len - 3] == 'm' || name[len - 3] == 'M') && (name[len - 2] == 'p' || name[len - 2] == 'P') && (name[len - 1] == '3')) || // mp3
((name[len - 3] == 'm' || name[len - 3] == 'M') && (name[len - 2] == '4') && (name[len - 1] == 'a' || name[len - 1] == 'A')) // m4a
));
int isEmoji = (
name[len - 4] == '.' && (name[len - 3] == 't' || name[len - 3] == 'T') && (name[len - 2] == 'g' || name[len - 2] == 'G') && (name[len - 1] == 's' || name[len - 1] == 'S') || // tgs
len > 5 && name[len - 5] == '.' && (name[len - 4] == 'w' || name[len - 4] == 'W') && (name[len - 3] == 'e' || name[len - 3] == 'E') && (name[len - 2] == 'b' || name[len - 2] == 'B') && (name[len - 1] == 'm' || name[len - 1] == 'M') // webm
);
int isTemp = (
name[len - 4] == '.' && (name[len - 3] == 't' || name[len - 3] == 'T') && (name[len - 2] == 'm' || name[len - 2] == 'M') && (name[len - 1] == 'p' || name[len - 1] == 'P') || // tmp
len > 5 && name[len - 5] == '.' && (name[len - 4] == 't' || name[len - 4] == 'T') && (name[len - 3] == 'e' || name[len - 3] == 'E') && (name[len - 2] == 'm' || name[len - 2] == 'M') && (name[len - 1] == 'p' || name[len - 1] == 'P') || // temp
len > 8 && name[len - 8] == '.' && (name[len - 7] == 'p' || name[len - 7] == 'P') && (name[len - 6] == 'r' || name[len - 6] == 'R') && (name[len - 5] == 'e' || name[len - 5] == 'E') && (name[len - 4] == 'l' || name[len - 4] == 'L') && (name[len - 3] == 'o' || name[len - 3] == 'O') && (name[len - 2] == 'a' || name[len - 2] == 'A') && (name[len - 1] == 'd' || name[len - 1] == 'D') // preload
);
if (
isMusic && docType == LISTDIR_DOCTYPE_OTHER_THAN_MUSIC ||
!isMusic && docType == LISTDIR_DOCTYPE_MUSIC ||
isEmoji && docType == LISTDIR_DOCTYPE2_OTHER ||
!isEmoji && docType == LISTDIR_DOCTYPE2_EMOJI ||
isTemp && docType == LISTDIR_DOCTYPE2_OTHER ||
!isTemp && docType == LISTDIR_DOCTYPE2_TEMP
) {
continue;
}
}
@ -247,6 +269,20 @@ JNIEXPORT jlong Java_org_telegram_messenger_Utilities_getDirSize(JNIEnv *env, jc
return value;
}
JNIEXPORT jlong Java_org_telegram_messenger_Utilities_getLastUsageFileTime(JNIEnv *env, jclass class, jstring path) {
const char *fileName = (*env)->GetStringUTFChars(env, path, NULL);
struct stat attrib;
stat(fileName, &attrib);
jlong value;
if (attrib.st_atim.tv_sec != 0) {
value = attrib.st_atim.tv_sec;
} else {
value = attrib.st_mtim.tv_sec;
}
(*env)->ReleaseStringUTFChars(env, path, fileName);
return value;
}
JNIEXPORT void Java_org_telegram_messenger_Utilities_clearDir(JNIEnv *env, jclass class, jstring path, jint docType, jlong time, jboolean subdirs) {
const char *fileName = (*env)->GetStringUTFChars(env, path, NULL);
listdir(fileName, 1, docType, time, subdirs);

View file

@ -118,7 +118,7 @@ void TL_cdnConfig::readParams(NativeByteBuffer *stream, int32_t instanceNum, boo
int magic = stream->readInt32(&error);
if (magic != 0x1cb5c415) {
error = true;
if (LOGS_ENABLED) DEBUG_FATAL("wrong Vector magic, got %x", magic);
if (LOGS_ENABLED) DEBUG_FATAL("wrong Vector magic in TL_cdnConfig, got %x", magic);
return;
}
int count = stream->readInt32(&error);
@ -173,7 +173,7 @@ void TL_config::readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &
uint32_t magic = stream->readUint32(&error);
if (magic != 0x1cb5c415) {
error = true;
if (LOGS_ENABLED) DEBUG_FATAL("wrong Vector magic, got %x", magic);
if (LOGS_ENABLED) DEBUG_FATAL("wrong Vector magic in TL_config, got %x", magic);
return;
}
int32_t count = stream->readInt32(&error);
@ -456,7 +456,7 @@ void TL_user::readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &er
uint32_t magic = stream->readUint32(&error);
if (magic != 0x1cb5c415) {
error = true;
if (LOGS_ENABLED) DEBUG_FATAL("wrong Vector magic, got %x", magic);
if (LOGS_ENABLED) DEBUG_FATAL("wrong Vector magic in TL_user, got %x", magic);
return;
}
int32_t count = stream->readInt32(&error);
@ -474,11 +474,28 @@ void TL_user::readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &er
if ((flags & 4194304) != 0) {
lang_code = stream->readString(&error);
}
if ((flags & 1073741824) != 0) {
uint32_t magic = stream->readUint32(&error);
if (magic == 0x2de11aae) {
// emojiStatusEmpty
} else if (magic == 0x929b619d) {
// emojiStatus
int64_t document_id = stream->readInt64(&error);
} else if (magic == 0xfa30a8c7) {
// emojiStatusUntil
int64_t document_id = stream->readInt64(&error);
int until = stream->readInt32(&error);
} else {
error = true;
if (LOGS_ENABLED) DEBUG_FATAL("wrong EmojiStatus magic, got %x", magic);
return;
}
}
if ((flags2 & 1) != 0) {
uint32_t magic = stream->readUint32(&error);
if (magic != 0x1cb5c415) {
error = true;
if (LOGS_ENABLED) DEBUG_FATAL("wrong Vector magic, got %x", magic);
if (LOGS_ENABLED) DEBUG_FATAL("wrong Vector magic in TL_user (2), got %x", magic);
return;
}
int32_t count = stream->readInt32(&error);
@ -1001,7 +1018,7 @@ void TL_help_termsOfService::readParams(NativeByteBuffer *stream, int32_t instan
int magic = stream->readInt32(&error);
if (magic != 0x1cb5c415) {
error = true;
if (LOGS_ENABLED) DEBUG_FATAL("wrong Vector magic, got %x", magic);
if (LOGS_ENABLED) DEBUG_FATAL("wrong Vector magic in TL_help_termsOfService, got %x", magic);
return;
}
int count = stream->readInt32(&error);

View file

@ -195,7 +195,7 @@ void TL_resPQ::readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &e
uint32_t magic = stream->readUint32(&error);
if (magic != 0x1cb5c415) {
error = true;
if (LOGS_ENABLED) DEBUG_FATAL("wrong Vector magic, got %x", magic);
if (LOGS_ENABLED) DEBUG_FATAL("wrong Vector magic in TL_resPQ, got %x", magic);
return;
}
uint32_t count = stream->readUint32(&error);
@ -455,7 +455,7 @@ void TL_msgs_state_req::readParams(NativeByteBuffer *stream, int32_t instanceNum
uint32_t magic = stream->readUint32(&error);
if (magic != 0x1cb5c415) {
error = true;
if (LOGS_ENABLED) DEBUG_FATAL("wrong Vector magic, got %x", magic);
if (LOGS_ENABLED) DEBUG_FATAL("wrong Vector magic in TL_msgs_state_req, got %x", magic);
return;
}
uint32_t count = stream->readUint32(&error);
@ -544,7 +544,7 @@ void TL_msgs_all_info::readParams(NativeByteBuffer *stream, int32_t instanceNum,
uint32_t magic = stream->readUint32(&error);
if (magic != 0x1cb5c415) {
error = true;
if (LOGS_ENABLED) DEBUG_FATAL("wrong Vector magic, got %x", magic);
if (LOGS_ENABLED) DEBUG_FATAL("wrong Vector magic in TL_msgs_all_info, got %x", magic);
return;
}
uint32_t count = stream->readUint32(&error);
@ -616,7 +616,7 @@ void TL_msgs_ack::readParams(NativeByteBuffer *stream, int32_t instanceNum, bool
uint32_t magic = stream->readUint32(&error);
if (magic != 0x1cb5c415) {
error = true;
if (LOGS_ENABLED) DEBUG_FATAL("wrong Vector magic, got %x", magic);
if (LOGS_ENABLED) DEBUG_FATAL("wrong Vector magic in TL_msgs_ack, got %x", magic);
return;
}
uint32_t count = stream->readUint32(&error);
@ -721,7 +721,7 @@ void TL_msg_resend_req::readParams(NativeByteBuffer *stream, int32_t instanceNum
uint32_t magic = stream->readUint32(&error);
if (magic != 0x1cb5c415) {
error = true;
if (LOGS_ENABLED) DEBUG_FATAL("wrong Vector magic, got %x", magic);
if (LOGS_ENABLED) DEBUG_FATAL("wrong Vector magic in TL_msg_resend_req, got %x", magic);
return;
}
uint32_t count = stream->readUint32(&error);
@ -1028,7 +1028,7 @@ void TL_jsonArray::readParams(NativeByteBuffer *stream, int32_t instanceNum, boo
int magic = stream->readInt32(&error);
if (magic != 0x1cb5c415) {
error = true;
if (LOGS_ENABLED) DEBUG_FATAL("wrong Vector magic, got %x", magic);
if (LOGS_ENABLED) DEBUG_FATAL("wrong Vector magic in TL_jsonArray, got %x", magic);
return;
}
int count = stream->readInt32(&error);
@ -1055,7 +1055,7 @@ void TL_jsonObject::readParams(NativeByteBuffer *stream, int32_t instanceNum, bo
int magic = stream->readInt32(&error);
if (magic != 0x1cb5c415) {
error = true;
if (LOGS_ENABLED) DEBUG_FATAL("wrong Vector magic, got %x", magic);
if (LOGS_ENABLED) DEBUG_FATAL("wrong Vector magic in TL_jsonObject, got %x", magic);
return;
}
int count = stream->readInt32(&error);

View file

@ -175,7 +175,7 @@ picker_badge=-13261833
chat_outFileInfoSelectedText=-1056964609
chat_outAudioDurationSelectedText=-1056964609
avatar_actionBarSelectorPink=-8684677
statisticChartLine_orange=-1853657
statisticChartLine_orange=-881607
chat_topPanelTitle=-281900315
chat_inAudioCacheSeekbar=1071179248
chat_outContactIcon=-13332255

View file

@ -95,7 +95,7 @@ avatar_backgroundArchived=-4998207
chat_outFileInfoSelectedText=-8674358
chat_outAudioDurationSelectedText=-8674358
avatar_backgroundArchivedHidden=-10832396
statisticChartLine_orange=-1853657
statisticChartLine_orange=-881607
chat_topPanelTitle=-13199648
chat_outContactIcon=-1
chat_inPreviewLine=-348675089

View file

@ -1,5 +0,0 @@
navigator.clipboard.__proto__.readText = function() {
return new Promise(function(resolve, reject) {
resolve(TelegramWebviewProxy.getClipboardText());
});
};

View file

@ -260,7 +260,7 @@ premiumGradientBackground2=-15394271
premiumStarGradient1=-15436801
premiumStarGradient2=-4167942
dialogTextHint=-8549479
statisticChartLine_orange=-1720817
statisticChartLine_orange=-881607
chat_topPanelTitle=-9719066
chat_inAudioCacheSeekbar=-11443856
chat_outContactIcon=-1

View file

@ -189,7 +189,7 @@ chat_outFileInfoSelectedText=-3676417
chat_outAudioDurationSelectedText=-3676417
avatar_backgroundArchivedHidden=-12208385
avatar_actionBarSelectorPink=-8684677
statisticChartLine_orange=-1853657
statisticChartLine_orange=-881607
chat_topPanelTitle=-12478747
chat_inAudioCacheSeekbar=1071179248
chat_outContactIcon=-14707997

View file

@ -278,7 +278,7 @@ premiumGradientBackground2=-16645625
premiumStarGradient1=-2342678
premiumStarGradient2=-9992961
dialogTextHint=-8553091
statisticChartLine_orange=-1457126
statisticChartLine_orange=-881607
chat_topPanelTitle=-10440716
chat_inAudioCacheSeekbar=-10461088
chat_outContactIcon=-1

Binary file not shown.

View file

@ -71,6 +71,7 @@ import androidx.annotation.Px;
import androidx.annotation.RestrictTo;
import androidx.annotation.VisibleForTesting;
import androidx.core.os.TraceCompat;
import androidx.core.util.Consumer;
import androidx.core.util.Preconditions;
import androidx.core.view.AccessibilityDelegateCompat;
import androidx.core.view.InputDeviceCompat;
@ -630,6 +631,18 @@ public class RecyclerView extends ViewGroup implements ScrollingView,
return mChildHelper.getHiddenChildAt(index);
}
public void forAllChild(Consumer<View> callback) {
for (int i = 0; i < getChildCount(); i++) {
callback.accept(getChildAt(i));
}
for (int i = 0; i < getHiddenChildCount(); i++) {
callback.accept(getHiddenChildAt(i));
}
for (int i = 0; i < getAttachedScrapChildCount(); i++) {
callback.accept(getAttachedScrapChildAt(i));
}
}
void applyEdgeEffectColor(EdgeEffect edgeEffect) {
if (edgeEffect != null && Build.VERSION.SDK_INT >= 21 && glowColor != null) {
edgeEffect.setColor(glowColor);

View file

@ -3,6 +3,7 @@ package org.telegram.messenger;
import android.content.SharedPreferences;
import org.telegram.tgnet.ConnectionsManager;
import org.telegram.ui.Components.Paint.PersistColorPalette;
public class AccountInstance {
@ -37,6 +38,10 @@ public class AccountInstance {
return ContactsController.getInstance(currentAccount);
}
public PersistColorPalette getColorPalette() {
return PersistColorPalette.getInstance(currentAccount);
}
public MediaDataController getMediaDataController() {
return MediaDataController.getInstance(currentAccount);
}

View file

@ -81,6 +81,7 @@ import android.view.TextureView;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.ViewPropertyAnimator;
import android.view.Window;
import android.view.WindowInsets;
import android.view.WindowManager;
@ -91,6 +92,7 @@ import android.view.animation.DecelerateInterpolator;
import android.view.animation.OvershootInterpolator;
import android.view.inputmethod.InputMethodManager;
import android.view.inputmethod.InputMethodSubtype;
import android.view.inspector.WindowInspector;
import android.webkit.MimeTypeMap;
import android.widget.EdgeEffect;
import android.widget.HorizontalScrollView;
@ -129,8 +131,10 @@ import org.telegram.ui.ActionBar.BottomSheet;
import org.telegram.ui.ActionBar.INavigationLayout;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Cells.TextDetailSettingsCell;
import org.telegram.ui.ChatActivity;
import org.telegram.ui.Components.AlertsCreator;
import org.telegram.ui.Components.BackgroundGradientDrawable;
import org.telegram.ui.Components.Bulletin;
import org.telegram.ui.Components.CubicBezierInterpolator;
import org.telegram.ui.Components.ForegroundColorSpanThemable;
import org.telegram.ui.Components.ForegroundDetector;
@ -142,6 +146,8 @@ import org.telegram.ui.Components.RecyclerListView;
import org.telegram.ui.Components.ShareAlert;
import org.telegram.ui.Components.TypefaceSpan;
import org.telegram.ui.Components.URLSpanReplacement;
import org.telegram.ui.Components.UndoView;
import org.telegram.ui.LaunchActivity;
import org.telegram.ui.ThemePreviewActivity;
import org.telegram.ui.WallpapersListActivity;
@ -164,6 +170,7 @@ import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
@ -185,6 +192,10 @@ public class AndroidUtilities {
public final static int REPLACING_TAG_TYPE_BOLD = 1;
public final static String TYPEFACE_ROBOTO_MEDIUM = "fonts/rmedium.ttf";
public final static String TYPEFACE_ROBOTO_MEDIUM_ITALIC = "fonts/rmediumitalic.ttf";
public final static String TYPEFACE_ROBOTO_MONO = "fonts/rmono.ttf";
public final static String TYPEFACE_MERRIWEATHER_BOLD = "fonts/mw_bold.ttf";
public final static String TYPEFACE_COURIER_NEW_BOLD = "fonts/courier_new_bold.ttf";
private static final Hashtable<String, Typeface> typefaceCache = new Hashtable<>();
public static float touchSlop;
@ -3698,6 +3709,17 @@ public class AndroidUtilities {
ConnectionsManager.setProxySettings(true, address, p, user, password, secret);
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.proxySettingsChanged);
if (activity instanceof LaunchActivity) {
INavigationLayout layout = ((LaunchActivity) activity).getActionBarLayout();
BaseFragment fragment = layout.getLastFragment();
if (fragment instanceof ChatActivity) {
((ChatActivity) fragment).getUndoView().showWithAction(0, UndoView.ACTION_PROXY_ADDED, null);
} else {
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.showBulletin, Bulletin.TYPE_SUCCESS, LocaleController.getString(R.string.ProxyAddedSuccess));
}
} else {
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.showBulletin, Bulletin.TYPE_SUCCESS, LocaleController.getString(R.string.ProxyAddedSuccess));
}
dismissRunnable.run();
});
builder.show();
@ -3981,10 +4003,19 @@ public class AndroidUtilities {
return (int) (a + f * (b - a));
}
public static float lerpAngle(float a, float b, float f) {
float delta = ((b - a + 360 + 180) % 360) - 180;
return (a + delta * f + 360) % 360;
}
public static float lerp(float a, float b, float f) {
return a + f * (b - a);
}
public static double lerp(double a, double b, float f) {
return a + f * (b - a);
}
public static float lerp(float[] ab, float f) {
return lerp(ab[0], ab[1], f);
}
@ -4443,10 +4474,14 @@ public class AndroidUtilities {
}
public static void updateViewShow(View view, boolean show, boolean scale, boolean animated) {
updateViewShow(view, show, scale, animated, null);
updateViewShow(view, show, scale, 0, animated, null);
}
public static void updateViewShow(View view, boolean show, boolean scale, boolean animated, Runnable onDone) {
updateViewShow(view, show, scale, 0, animated, onDone);
}
public static void updateViewShow(View view, boolean show, boolean scale, float translate, boolean animated, Runnable onDone) {
if (view == null) {
return;
}
@ -4461,6 +4496,9 @@ public class AndroidUtilities {
view.setAlpha(1f);
view.setScaleX(scale && !show ? 0f : 1f);
view.setScaleY(scale && !show ? 0f : 1f);
if (translate != 0) {
view.setTranslationY(show ? 0 : AndroidUtilities.dp(-16) * translate);
}
if (onDone != null) {
onDone.run();
}
@ -4470,10 +4508,23 @@ public class AndroidUtilities {
view.setAlpha(0f);
view.setScaleX(scale ? 0 : 1);
view.setScaleY(scale ? 0 : 1);
if (translate != 0) {
view.setTranslationY(AndroidUtilities.dp(-16) * translate);
}
}
view.animate().alpha(1f).scaleY(1f).scaleX(1f).setInterpolator(CubicBezierInterpolator.EASE_OUT_QUINT).setDuration(340).withEndAction(onDone).start();
ViewPropertyAnimator animate = view.animate();
animate = animate.alpha(1f).scaleY(1f).scaleX(1f).setInterpolator(CubicBezierInterpolator.EASE_OUT_QUINT).setDuration(340).withEndAction(onDone);
if (translate != 0) {
animate.translationY(0);
}
animate.start();
} else {
view.animate().alpha(0).scaleY(scale ? 0 : 1).scaleX(scale ? 0 : 1).setListener(new HideViewAfterAnimation(view)).setInterpolator(CubicBezierInterpolator.EASE_OUT_QUINT).setDuration(340).withEndAction(onDone).start();
ViewPropertyAnimator animate = view.animate();
animate = animate.alpha(0).scaleY(scale ? 0 : 1).scaleX(scale ? 0 : 1).setListener(new HideViewAfterAnimation(view)).setInterpolator(CubicBezierInterpolator.EASE_OUT_QUINT).setDuration(340).withEndAction(onDone);
if (translate != 0) {
animate.translationY(AndroidUtilities.dp(-16) * translate);
}
animate.start();
}
}
@ -4618,4 +4669,149 @@ public class AndroidUtilities {
}
return spannableStringBuilder;
}
public static Bitmap makeBlurBitmap(View view) {
if (view == null) {
return null;
}
int w = (int) (view.getWidth() / 6.0f);
int h = (int) (view.getHeight() / 6.0f);
Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
canvas.scale(1.0f / 6.0f, 1.0f / 6.0f);
canvas.drawColor(Theme.getColor(Theme.key_windowBackgroundWhite));
view.draw(canvas);
Utilities.stackBlurBitmap(bitmap, Math.max(7, Math.max(w, h) / 180));
return bitmap;
}
public static void makeGlobalBlurBitmap(Utilities.Callback<Bitmap> onBitmapDone, float amount) {
if (onBitmapDone == null) {
return;
}
List<View> views = null;
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
views = WindowInspector.getGlobalWindowViews();
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
Class wmgClass = Class.forName("android.view.WindowManagerGlobal");
Object wmgInstance = wmgClass.getMethod("getInstance").invoke(null, (Object[]) null);
Method getViewRootNames = wmgClass.getMethod("getViewRootNames");
Method getRootView = wmgClass.getMethod("getRootView", String.class);
String[] rootViewNames = (String[])getViewRootNames.invoke(wmgInstance, (Object[])null);
views = new ArrayList<>();
for (String viewName : rootViewNames) {
views.add((View) getRootView.invoke(wmgInstance, viewName));
}
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH && Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
Class wmiClass = Class.forName("android.view.WindowManagerImpl");
Object wmiInstance = wmiClass.getMethod("getDefault").invoke(null);
Field viewsField = wmiClass.getDeclaredField("mViews");
viewsField.setAccessible(true);
Object viewsObject = viewsField.get(wmiInstance);
if (viewsObject instanceof List) {
views = (List<View>) viewsField.get(wmiInstance);
} else if (viewsObject instanceof View[]) {
views = Arrays.asList((View[]) viewsField.get(wmiInstance));
}
}
} catch (Exception e) {
FileLog.e("makeGlobalBlurBitmap()", e);
}
if (views == null) {
onBitmapDone.run(null);
return;
}
final List<View> finalViews = views;
//Utilities.themeQueue.postRunnable(() -> {
try {
int w = (int) (AndroidUtilities.displaySize.x / amount);
int h = (int) ((AndroidUtilities.displaySize.y + AndroidUtilities.statusBarHeight) / amount);
Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
canvas.scale(1.0f / amount, 1.0f / amount);
canvas.drawColor(Theme.getColor(Theme.key_windowBackgroundWhite));
int[] location = new int[2];
for (int i = 0; i < finalViews.size(); ++i) {
View view = finalViews.get(i);
ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
if (layoutParams instanceof WindowManager.LayoutParams) {
WindowManager.LayoutParams params = (WindowManager.LayoutParams) layoutParams;
if ((params.flags & WindowManager.LayoutParams.FLAG_DIM_BEHIND) != 0) {
canvas.drawColor(ColorUtils.setAlphaComponent(0xFF000000, (int) (0xFF * params.dimAmount)));
}
}
canvas.save();
view.getLocationOnScreen(location);
canvas.translate(location[0] / amount, location[1] / amount);
try {
view.draw(canvas);
} catch (Exception e) {
}
canvas.restore();
}
Utilities.stackBlurBitmap(bitmap, Math.max((int) amount, Math.max(w, h) / 180));
AndroidUtilities.runOnUIThread(() -> {
onBitmapDone.run(bitmap);
});
} catch (Exception e) {
FileLog.e(e);
AndroidUtilities.runOnUIThread(() -> {
onBitmapDone.run(null);
});
}
// });
}
// rounds percents to be exact 100% in sum
public static int[] roundPercents(float[] percents, int[] output) {
if (percents == null) {
throw new NullPointerException("percents or output is null");
}
if (output == null) {
output = new int[percents.length];
}
if (percents.length != output.length) {
throw new IndexOutOfBoundsException("percents.length != output.length");
}
float sum = 0;
for (int i = 0; i < percents.length; ++i) {
sum += percents[i];
}
int roundedSum = 0;
for (int i = 0; i < percents.length; ++i) {
roundedSum += (output[i] = (int) Math.floor(percents[i] / sum * 100));
}
while (roundedSum < 100) {
float maxError = 0;
int maxErrorIndex = -1;
for (int i = 0; i < percents.length; ++i) {
float error = (percents[i] / sum) - (output[i] / 100f);
if (percents[i] > 0 && error >= maxError) {
maxErrorIndex = i;
maxError = error;
}
}
if (maxErrorIndex < 0) {
break;
}
output[maxErrorIndex]++;
roundedSum++;
}
return output;
}
}

View file

@ -1,6 +1,7 @@
package org.telegram.messenger;
import org.telegram.tgnet.ConnectionsManager;
import org.telegram.ui.Components.Paint.PersistColorPalette;
public class BaseController {
@ -24,6 +25,10 @@ public class BaseController {
return parentAccountInstance.getContactsController();
}
protected final PersistColorPalette getColorPalette() {
return parentAccountInstance.getColorPalette();
}
protected final MediaDataController getMediaDataController() {
return parentAccountInstance.getMediaDataController();
}

View file

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

View file

@ -0,0 +1,195 @@
package org.telegram.messenger;
import android.text.TextUtils;
import android.util.LongSparseArray;
import org.telegram.tgnet.TLRPC;
import java.io.File;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.HashSet;
public class CacheByChatsController {
public static int KEEP_MEDIA_DELETE = 4;
public static int KEEP_MEDIA_FOREVER = 2;
public static int KEEP_MEDIA_ONE_DAY = 3;
public static int KEEP_MEDIA_ONE_WEEK = 0;
public static int KEEP_MEDIA_ONE_MONTH = 1;
//TEST VALUE
public static int KEEP_MEDIA_ONE_MINUTE = 5;
public static final int KEEP_MEDIA_TYPE_USER = 0;
public static final int KEEP_MEDIA_TYPE_GROUP = 1;
public static final int KEEP_MEDIA_TYPE_CHANNEL = 2;
private final int currentAccount;
int[] keepMediaByTypes = {-1, -1, -1};
public CacheByChatsController(int currentAccount) {
this.currentAccount = currentAccount;
for (int i = 0; i < 3; i++) {
keepMediaByTypes[i] = SharedConfig.getPreferences().getInt("keep_media_type_" + i, getDefault(i));
}
}
public static int getDefault(int type) {
if (type == KEEP_MEDIA_TYPE_USER) {
return KEEP_MEDIA_FOREVER;
} else if (type == KEEP_MEDIA_TYPE_GROUP) {
return KEEP_MEDIA_ONE_MONTH;
} else if (type == KEEP_MEDIA_TYPE_CHANNEL) {
return KEEP_MEDIA_ONE_MONTH;
}
return SharedConfig.keepMedia;
}
public static String getKeepMediaString(int keepMedia) {
if (keepMedia == KEEP_MEDIA_ONE_MINUTE) {
return LocaleController.formatPluralString("Minutes", 1);
} else if (keepMedia == KEEP_MEDIA_ONE_DAY) {
return LocaleController.formatPluralString("Days", 1);
} else if (keepMedia == KEEP_MEDIA_ONE_WEEK) {
return LocaleController.formatPluralString("Weeks", 1);
} else if (keepMedia == KEEP_MEDIA_ONE_MONTH) {
return LocaleController.formatPluralString("Months", 1);
}
return LocaleController.getString("AutoDeleteMediaNever", R.string.AutoDeleteMediaNever);
}
public static long getDaysInSeconds(int keepMedia) {
long seconds;
if (keepMedia == CacheByChatsController.KEEP_MEDIA_FOREVER) {
seconds = Long.MAX_VALUE;
} else if (keepMedia == CacheByChatsController.KEEP_MEDIA_ONE_WEEK) {
seconds = 60L * 60L * 24L * 7L;
} else if (keepMedia == CacheByChatsController.KEEP_MEDIA_ONE_MONTH) {
seconds = 60L * 60L * 24L * 30L;
} else if (keepMedia == CacheByChatsController.KEEP_MEDIA_ONE_DAY) {
seconds = 60L * 60L * 24L;
} else { //one min
seconds = 60L;
}
return seconds;
}
public ArrayList<KeepMediaException> getKeepMediaExceptions(int type) {
ArrayList<KeepMediaException> exceptions = new ArrayList<>();
HashSet<Long> idsSet = new HashSet<>();
String exceptionsHash = UserConfig.getInstance(currentAccount).getPreferences().getString("keep_media_exceptions_" + type, "");
if (TextUtils.isEmpty(exceptionsHash)) {
return exceptions;
} else {
ByteBuffer byteBuffer = ByteBuffer.wrap(Utilities.hexToBytes(exceptionsHash));
int n = byteBuffer.getInt();
for (int i = 0; i < n; i++) {
KeepMediaException exception = new KeepMediaException(byteBuffer.getLong(), byteBuffer.getInt());
if (!idsSet.contains(exception.dialogId)) {
idsSet.add(exception.dialogId);
exceptions.add(exception);
}
}
byteBuffer.clear();
}
return exceptions;
}
public void saveKeepMediaExceptions(int type, ArrayList<KeepMediaException> exceptions) {
String key = "keep_media_exceptions_" + type;
if (exceptions.isEmpty()) {
UserConfig.getInstance(currentAccount).getPreferences().edit().remove(key).apply();
} else {
int n = exceptions.size();
ByteBuffer byteBuffer = ByteBuffer.allocate(4 + (8 + 4) * n);
byteBuffer.putInt(n);
for (int i = 0; i < n; i++) {
byteBuffer.putLong(exceptions.get(i).dialogId);
byteBuffer.putInt(exceptions.get(i).keepMedia);
}
UserConfig.getInstance(currentAccount).getPreferences().edit().putString(key, Utilities.bytesToHex(byteBuffer.array())).apply();
byteBuffer.clear();
}
}
public int getKeepMedia(int type) {
if (keepMediaByTypes[type] == -1) {
return SharedConfig.keepMedia;
}
return keepMediaByTypes[type];
}
public void setKeepMedia(int type, int keepMedia) {
keepMediaByTypes[type] = keepMedia;
SharedConfig.getPreferences().edit().putInt("keep_media_type_" + type, keepMedia).apply();
}
public void lookupFiles(ArrayList<KeepMediaFile> keepMediaFiles) {
LongSparseArray<ArrayList<KeepMediaFile>> filesByDialogId = FileLoader.getInstance(currentAccount).getFileDatabase().lookupFiles(keepMediaFiles);
LongSparseArray<KeepMediaException> exceptionsByType = getKeepMediaExceptionsByDialogs();
for (int i = 0; i < filesByDialogId.size(); i++) {
long dialogId = filesByDialogId.keyAt(i);
ArrayList<KeepMediaFile> files = filesByDialogId.valueAt(i);
int type;
if (dialogId >= 0) {
type = KEEP_MEDIA_TYPE_USER;
} else {
TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(-dialogId);
if (chat == null) {
chat = MessagesStorage.getInstance(currentAccount).getChatSync(-dialogId);
}
if (chat == null) {
type = -1;
} else if (ChatObject.isChannel(chat)) {
type = KEEP_MEDIA_TYPE_CHANNEL;
} else {
type = KEEP_MEDIA_TYPE_GROUP;
}
}
KeepMediaException exception = exceptionsByType.get(dialogId);
for (int k = 0; k < files.size(); k++) {
KeepMediaFile file = files.get(k);
if (type >= 0) {
file.dialogType = type;
}
if (exception != null) {
file.keepMedia = exception.keepMedia;
}
}
}
}
public LongSparseArray<KeepMediaException> getKeepMediaExceptionsByDialogs() {
LongSparseArray<KeepMediaException> sparseArray = new LongSparseArray<>();
for (int i = 0; i < 3; i++) {
ArrayList<KeepMediaException> exceptions = getKeepMediaExceptions(i);
if (exceptions != null) {
for (int k = 0; k < exceptions.size(); k++) {
sparseArray.put(exceptions.get(k).dialogId, exceptions.get(k));
}
}
}
return sparseArray;
}
public static class KeepMediaException {
public final long dialogId;
public int keepMedia;
public KeepMediaException(long dialogId, int keepMedia) {
this.dialogId = dialogId;
this.keepMedia = keepMedia;
}
}
public static class KeepMediaFile {
final File file;
int keepMedia = -1;
int dialogType = KEEP_MEDIA_TYPE_CHANNEL;
public KeepMediaFile(File file) {
this.file = file;
}
}
}

View file

@ -23,7 +23,9 @@ import android.net.Uri;
import android.os.Build;
import android.provider.BaseColumns;
import android.provider.ContactsContract;
import android.telephony.PhoneNumberUtils;
import android.text.TextUtils;
import android.util.Log;
import android.util.SparseArray;
import androidx.collection.LongSparseArray;
@ -38,6 +40,8 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ContactsController extends BaseController {
@ -556,7 +560,7 @@ public class ContactsController extends BaseController {
return count > 3;
}
private HashMap<String, Contact> readContactsFromPhoneBook() {
public HashMap<String, Contact> readContactsFromPhoneBook() {
if (!getUserConfig().syncContacts) {
if (BuildVars.LOGS_ENABLED) {
FileLog.d("contacts sync disabled");
@ -748,6 +752,66 @@ public class ContactsController extends BaseController {
}
pCur = null;
}
//TODO optimize
Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null,ContactsContract.Contacts.HAS_PHONE_NUMBER + " = ?", new String[]{"0"}, null);
if (cur != null) {
String[] metadata = new String[5];
Pattern phonePattern = Pattern.compile(".*(\\+[0-9 \\-]+).*");
while (cur.moveToNext()) {
String id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
String lookup_key = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY));
String name = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
String phone = null;
if (contactsMap.get(lookup_key) != null || TextUtils.isEmpty(name)) {
continue;
}
pCur = cr.query(
ContactsContract.Data.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?",
new String[]{id}, null);
loop : while (pCur.moveToNext()) {
metadata[0] = pCur.getString(pCur.getColumnIndex(ContactsContract.Data.DATA1));
metadata[1] = pCur.getString(pCur.getColumnIndex(ContactsContract.Data.DATA2));
metadata[2] = pCur.getString(pCur.getColumnIndex(ContactsContract.Data.DATA3));
metadata[3] = pCur.getString(pCur.getColumnIndex(ContactsContract.Data.DATA4));
metadata[4] = pCur.getString(pCur.getColumnIndex(ContactsContract.Data.DATA5));
for (int i = 0; i < metadata.length; i++) {
if (metadata[i] == null) {
continue;
}
Matcher matcher = phonePattern.matcher(metadata[i]);
if (matcher.matches()) {
phone = matcher.group(1).replace(" ", "").replace("-", "");
break loop;
}
}
}
if (phone != null) {
String shortNumber = phone;
if (phone.startsWith("+")) {
shortNumber = phone.substring(1);
}
Contact contact = new Contact();
contact.first_name = name;
contact.last_name = "";
contact.contact_id = lastContactId++;
contact.key = lookup_key;
contact.phones.add(phone);
contact.shortPhones.add(shortNumber);
contact.phoneDeleted.add(0);
contact.phoneTypes.add(LocaleController.getString("PhoneOther", R.string.PhoneOther));
// contact.provider = accountType;
// contact.isGoodProvider = isGoodAccountType;
contactsMap.put(lookup_key, contact);
}
}
}
} catch (Throwable e) {
FileLog.e(e);
if (contactsMap != null) {
@ -2169,13 +2233,14 @@ public class ContactsController extends BaseController {
return;
}
final TLRPC.Updates res = (TLRPC.Updates) response;
getMessagesController().processUpdates(res, false);
/*if (BuildVars.DEBUG_VERSION) {
for (TLRPC.User user : res.users) {
FileLog.e("received user " + user.first_name + " " + user.last_name + " " + user.phone);
if (user.photo != null && user.photo.personal) {
for (int i = 0; i < res.users.size(); i++) {
if (res.users.get(i).id == user.id) {
res.users.get(i).photo = user.photo;
}
}
}*/
}
getMessagesController().processUpdates(res, false);
for (int a = 0; a < res.users.size(); a++) {
final TLRPC.User u = res.users.get(a);

View file

@ -109,8 +109,11 @@ public class DispatchQueuePoolBackground {
}
@UiThread
public static void execute(Runnable runnable, boolean now) {
if (BuildVars.DEBUG_PRIVATE_VERSION && Thread.currentThread() != ApplicationLoader.applicationHandler.getLooper().getThread()) {
throw new RuntimeException("wrong thread");
if (Thread.currentThread() != ApplicationLoader.applicationHandler.getLooper().getThread()) {
if (BuildVars.DEBUG_PRIVATE_VERSION) {
FileLog.e(new RuntimeException("wrong thread"));
}
return;
}
if (updateTaskCollection == null) {
if (!freeCollections.isEmpty()) {

View file

@ -1255,8 +1255,10 @@ public class DownloadController extends BaseController implements NotificationCe
AndroidUtilities.runOnUIThread(() -> {
boolean removed = false;
TLRPC.Document parentDocument = parentObject.getDocument();
for (int i = 0; i < downloadingFiles.size(); i++) {
if (downloadingFiles.get(i).getDocument().id == parentObject.getDocument().id) {
TLRPC.Document downloadingDocument = downloadingFiles.get(i).getDocument();
if (downloadingDocument == null || parentDocument != null && downloadingDocument.id == parentDocument.id) {
downloadingFiles.remove(i);
removed = true;
break;

View file

@ -485,6 +485,10 @@ public class Emoji {
return emojis;
}
public static CharSequence replaceEmoji(CharSequence cs, Paint.FontMetricsInt fontMetrics, boolean createNew) {
return replaceEmoji(cs, fontMetrics, AndroidUtilities.dp(16), createNew, null);
}
public static CharSequence replaceEmoji(CharSequence cs, Paint.FontMetricsInt fontMetrics, int size, boolean createNew) {
return replaceEmoji(cs, fontMetrics, size, createNew, null);
}
@ -565,6 +569,16 @@ public class Emoji {
size = newSize;
}
public void replaceFontMetrics(Paint.FontMetricsInt newMetrics) {
fontMetrics = newMetrics;
if (fontMetrics != null) {
size = Math.abs(fontMetrics.descent) + Math.abs(fontMetrics.ascent);
if (size == 0) {
size = AndroidUtilities.dp(20);
}
}
}
@Override
public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) {
if (fm == null) {

View file

@ -13,6 +13,7 @@ import org.telegram.tgnet.NativeByteBuffer;
import org.telegram.tgnet.TLObject;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.LaunchActivity;
import org.telegram.ui.Storage.CacheModel;
import java.io.File;
import java.io.FileInputStream;
@ -189,7 +190,7 @@ public class FileLoadOperation {
private File tempPath;
private boolean isForceRequest;
private int priority;
private long fileDialogId;
private FilePathDatabase.FileMeta fileMetadata;
private boolean ungzip;
@ -222,7 +223,7 @@ public class FileLoadOperation {
public FileLoadOperation(ImageLocation imageLocation, Object parent, String extension, long size) {
updateParams();
parentObject = parent;
fileDialogId = FileLoader.getDialogIdFromParent(currentAccount, parentObject);
fileMetadata = FileLoader.getFileMetadataFromParent(currentAccount, parentObject);
isStream = imageLocation.imageType == FileLoader.IMAGE_TYPE_ANIMATION;
if (imageLocation.isEncrypted()) {
location = new TLRPC.TL_inputEncryptedFileLocation();
@ -329,7 +330,7 @@ public class FileLoadOperation {
updateParams();
try {
parentObject = parent;
fileDialogId = FileLoader.getDialogIdFromParent(currentAccount, parentObject);
fileMetadata = FileLoader.getFileMetadataFromParent(currentAccount, parentObject);
if (documentLocation instanceof TLRPC.TL_documentEncrypted) {
location = new TLRPC.TL_inputEncryptedFileLocation();
location.id = documentLocation.id;
@ -971,9 +972,9 @@ public class FileLoadOperation {
}
}
if (fileDialogId != 0) {
FileLoader.getInstance(currentAccount).getFileDatabase().saveFileDialogId(cacheFileParts, fileDialogId);
FileLoader.getInstance(currentAccount).getFileDatabase().saveFileDialogId(cacheFileTemp, fileDialogId);
if (fileMetadata != null) {
FileLoader.getInstance(currentAccount).getFileDatabase().saveFileDialogId(cacheFileParts, fileMetadata);
FileLoader.getInstance(currentAccount).getFileDatabase().saveFileDialogId(cacheFileTemp, fileMetadata);
}
if (cacheFileTemp.exists()) {
@ -1293,12 +1294,12 @@ public class FileLoadOperation {
if (BuildVars.DEBUG_VERSION) {
FileLog.d("finished preloading file to " + cacheFileTemp + " loaded " + totalPreloadedBytes + " of " + totalBytesCount);
}
if (fileDialogId != 0) {
if (fileMetadata != null) {
if (cacheFileTemp != null) {
FileLoader.getInstance(currentAccount).getFileDatabase().removeFiles(Collections.singletonList(cacheFileTemp));
FileLoader.getInstance(currentAccount).getFileDatabase().removeFiles(Collections.singletonList(new CacheModel.FileInfo(cacheFileTemp)));
}
if (cacheFileParts != null) {
FileLoader.getInstance(currentAccount).getFileDatabase().removeFiles(Collections.singletonList(cacheFileParts));
FileLoader.getInstance(currentAccount).getFileDatabase().removeFiles(Collections.singletonList(new CacheModel.FileInfo(cacheFileParts)));
}
}
delegate.didFinishLoadingFile(FileLoadOperation.this, cacheFileFinal);

View file

@ -40,26 +40,35 @@ public class FileLoader extends BaseController {
private static Pattern sentPattern;
public static long getDialogIdFromParent(int currentAccount, Object parentObject) {
public static FilePathDatabase.FileMeta getFileMetadataFromParent(int currentAccount, Object parentObject) {
if (parentObject instanceof String) {
String str = (String) parentObject;
if (str.startsWith("sent_")) {
if (sentPattern == null) {
sentPattern = Pattern.compile("sent_.*_.*_([0-9]+)");
sentPattern = Pattern.compile("sent_.*_([0-9]+)_([0-9]+)_([0-9]+)");
}
try {
Matcher matcher = sentPattern.matcher(str);
if (matcher.matches()) {
return Long.parseLong(matcher.group(1));
FilePathDatabase.FileMeta fileMeta = new FilePathDatabase.FileMeta();
fileMeta.messageId = Integer.parseInt(matcher.group(1));
fileMeta.dialogId = Long.parseLong(matcher.group(2));
fileMeta.messageType = Integer.parseInt(matcher.group(3));
return fileMeta;
}
} catch (Exception e) {
FileLog.e(e);
}
}
} else if (parentObject instanceof MessageObject) {
return ((MessageObject) parentObject).getDialogId();
MessageObject messageObject = (MessageObject) parentObject;
FilePathDatabase.FileMeta fileMeta = new FilePathDatabase.FileMeta();
fileMeta.messageId = messageObject.getId();
fileMeta.dialogId = messageObject.getDialogId();
fileMeta.messageType = messageObject.type;
return fileMeta;
}
return 0;
return null;
}
private int getPriorityValue(int priorityType) {
@ -767,9 +776,9 @@ public class FileLoader extends BaseController {
if (!operation.isPreloadVideoOperation() && operation.isPreloadFinished()) {
return;
}
long dialogId = getDialogIdFromParent(currentAccount, parentObject);
if (dialogId != 0) {
getFileLoader().getFileDatabase().saveFileDialogId(finalFile, dialogId);
FilePathDatabase.FileMeta fileMeta = getFileMetadataFromParent(currentAccount, parentObject);
if (fileMeta != null) {
getFileLoader().getFileDatabase().saveFileDialogId(finalFile, fileMeta);
}
if (parentObject instanceof MessageObject) {
MessageObject messageObject = (MessageObject) parentObject;

View file

@ -1,11 +1,13 @@
package org.telegram.messenger;
import android.os.Looper;
import android.util.LongSparseArray;
import org.telegram.SQLite.SQLiteCursor;
import org.telegram.SQLite.SQLiteDatabase;
import org.telegram.SQLite.SQLiteException;
import org.telegram.SQLite.SQLitePreparedStatement;
import org.telegram.ui.Storage.CacheModel;
import java.io.File;
import java.io.IOException;
@ -22,11 +24,15 @@ public class FilePathDatabase {
private File cacheFile;
private File shmCacheFile;
private final static int LAST_DB_VERSION = 3;
private final static int LAST_DB_VERSION = 4;
private final static String DATABASE_NAME = "file_to_path";
private final static String DATABASE_BACKUP_NAME = "file_to_path_backup";
public final static int MESSAGE_TYPE_VIDEO_MESSAGE = 0;
private final FileMeta metaTmp = new FileMeta();
public FilePathDatabase(int currentAccount) {
this.currentAccount = currentAccount;
dispatchQueue = new DispatchQueue("files_database_queue_" + currentAccount);
@ -58,7 +64,7 @@ public class FilePathDatabase {
database.executeFast("CREATE TABLE paths(document_id INTEGER, dc_id INTEGER, type INTEGER, path TEXT, PRIMARY KEY(document_id, dc_id, type));").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS path_in_paths ON paths(path);").stepThis().dispose();
database.executeFast("CREATE TABLE paths_by_dialog_id(path TEXT PRIMARY KEY, dialog_id INTEGER);").stepThis().dispose();
database.executeFast("CREATE TABLE paths_by_dialog_id(path TEXT PRIMARY KEY, dialog_id INTEGER, message_id INTEGER, message_type INTEGER);").stepThis().dispose();
database.executeFast("PRAGMA user_version = " + LAST_DB_VERSION).stepThis().dispose();
} else {
@ -104,6 +110,11 @@ public class FilePathDatabase {
database.executeFast("PRAGMA user_version = " + 3).stepThis().dispose();
version = 3;
}
if (version == 3) {
database.executeFast("ALTER TABLE paths_by_dialog_id ADD COLUMN message_id INTEGER default 0").stepThis().dispose();
database.executeFast("ALTER TABLE paths_by_dialog_id ADD COLUMN message_type INTEGER default 0").stepThis().dispose();
database.executeFast("PRAGMA user_version = " + 4).stepThis().dispose();
}
}
private void createBackup() {
@ -310,17 +321,19 @@ public class FilePathDatabase {
return res[0];
}
public void saveFileDialogId(File file, long dialogId) {
if (file == null) {
public void saveFileDialogId(File file,FileMeta fileMeta) {
if (file == null || fileMeta == null) {
return;
}
dispatchQueue.postRunnable(() -> {
SQLitePreparedStatement state = null;
try {
state = database.executeFast("REPLACE INTO paths_by_dialog_id VALUES(?, ?)");
state = database.executeFast("REPLACE INTO paths_by_dialog_id VALUES(?, ?, ?, ?)");
state.requery();
state.bindString(1, file.getPath());
state.bindLong(2, dialogId);
state.bindString(1, shield(file.getPath()));
state.bindLong(2, fileMeta.dialogId);
state.bindInteger(3, fileMeta.messageId);
state.bindInteger(4, fileMeta.messageType);
state.step();
} catch (Exception e) {
FileLog.e(e);
@ -332,16 +345,23 @@ public class FilePathDatabase {
});
}
public long getFileDialogId(File file) {
public FileMeta getFileDialogId(File file, FileMeta metaTmp) {
if (file == null) {
return 0;
return null;
}
if (metaTmp == null) {
metaTmp = this.metaTmp;
}
long dialogId = 0;
int messageId = 0;
int messageType = 0;
SQLiteCursor cursor = null;
try {
cursor = database.queryFinalized("SELECT dialog_id FROM paths_by_dialog_id WHERE path = '" + file.getPath() + "'");
cursor = database.queryFinalized("SELECT dialog_id, message_id, message_type FROM paths_by_dialog_id WHERE path = '" + shield(file.getPath()) + "'");
if (cursor.next()) {
dialogId = cursor.longValue(0);
messageId = cursor.intValue(1);
messageType = cursor.intValue(2);
}
} catch (Exception e) {
FileLog.e(e);
@ -350,19 +370,26 @@ public class FilePathDatabase {
cursor.dispose();
}
}
return dialogId;
metaTmp.dialogId = dialogId;
metaTmp.messageId = messageId;
metaTmp.messageType = messageType;
return metaTmp;
}
private String shield(String path) {
return path.replace("'","").replace("\"","");
}
public DispatchQueue getQueue() {
return dispatchQueue;
}
public void removeFiles(List<File> filesToRemove) {
public void removeFiles(List<CacheModel.FileInfo> filesToRemove) {
dispatchQueue.postRunnable(() -> {
try {
database.beginTransaction();
for (int i = 0; i < filesToRemove.size(); i++) {
database.executeFast("DELETE FROM paths_by_dialog_id WHERE path = '" + filesToRemove.get(i).getPath() + "'").stepThis().dispose();
database.executeFast("DELETE FROM paths_by_dialog_id WHERE path = '" + shield(filesToRemove.get(i).file.getPath()) + "'").stepThis().dispose();
}
} catch (Exception e) {
FileLog.e(e);
@ -372,6 +399,36 @@ public class FilePathDatabase {
});
}
public LongSparseArray<ArrayList<CacheByChatsController.KeepMediaFile>> lookupFiles(ArrayList<CacheByChatsController.KeepMediaFile> keepMediaFiles) {
CountDownLatch syncLatch = new CountDownLatch(1);
LongSparseArray<ArrayList<CacheByChatsController.KeepMediaFile>> filesByDialogId = new LongSparseArray<>();
dispatchQueue.postRunnable(() -> {
try {
FileMeta fileMetaTmp = new FileMeta();
for (int i = 0; i < keepMediaFiles.size(); i++) {
FileMeta fileMeta = getFileDialogId(keepMediaFiles.get(i).file, fileMetaTmp);
if (fileMeta != null && fileMeta.dialogId != 0) {
ArrayList<CacheByChatsController.KeepMediaFile> list = filesByDialogId.get(fileMeta.dialogId);
if (list == null) {
list = new ArrayList<>();
filesByDialogId.put(fileMeta.dialogId, list);
}
list.add(keepMediaFiles.get(i));
}
}
} catch (Exception e) {
FileLog.e(e);
}
syncLatch.countDown();
});
try {
syncLatch.await();
} catch (InterruptedException e) {
FileLog.e(e);
}
return filesByDialogId;
}
public static class PathData {
public final long id;
public final int dc;
@ -383,4 +440,10 @@ public class FilePathDatabase {
this.type = type;
}
}
public static class FileMeta {
public long dialogId;
public int messageId;
public int messageType;
}
}

View file

@ -752,7 +752,7 @@ public class FileRefController extends BaseController {
} else if (message.media.webpage != null) {
result = getFileReference(message.media.webpage, requester.location, needReplacement, locationReplacement);
}
} else if (message.action instanceof TLRPC.TL_messageActionChatEditPhoto) {
} else if (message.action instanceof TLRPC.TL_messageActionChatEditPhoto || message.action instanceof TLRPC.TL_messageActionSuggestProfilePhoto) {
result = getFileReference(message.action.photo, requester.location, needReplacement, locationReplacement);
}
if (result != null) {

View file

@ -1020,7 +1020,8 @@ public class ImageLoader {
cacheOptions.compressQuality = BitmapsCache.COMPRESS_QUALITY_DEFAULT;
}
}
fileDrawable = new AnimatedFileDrawable(cacheImage.finalFilePath, false, size, document, document == null ? cacheImage.imageLocation : null, cacheImage.parentObject, seekTo, cacheImage.currentAccount, false, cacheOptions);
boolean notCreateStream = cacheImage.filter != null && cacheImage.filter.contains("nostream");
fileDrawable = new AnimatedFileDrawable(cacheImage.finalFilePath, false, notCreateStream ? 0 : size, notCreateStream ? null : document, document == null && !notCreateStream ? cacheImage.imageLocation : null, cacheImage.parentObject, seekTo, cacheImage.currentAccount, false, cacheOptions);
fileDrawable.setIsWebmSticker(MessageObject.isWebM(document) || MessageObject.isVideoSticker(document) || isAnimatedAvatar(cacheImage.filter));
} else {
@ -1042,7 +1043,9 @@ public class ImageLoader {
cacheOptions.compressQuality = BitmapsCache.COMPRESS_QUALITY_DEFAULT;
}
}
fileDrawable = new AnimatedFileDrawable(cacheImage.finalFilePath, "d".equals(cacheImage.filter), 0, cacheImage.imageLocation.document, null, null, seekTo, cacheImage.currentAccount, false, w, h, cacheOptions);
boolean createDecoder = cacheImage.filter != null && ("d".equals(cacheImage.filter) || cacheImage.filter.contains("_d"));
boolean notCreateStream = cacheImage.filter != null && cacheImage.filter.contains("nostream");
fileDrawable = new AnimatedFileDrawable(cacheImage.finalFilePath, createDecoder, 0, notCreateStream ? null : cacheImage.imageLocation.document, null, null, seekTo, cacheImage.currentAccount, false, w, h, cacheOptions);
fileDrawable.setIsWebmSticker(MessageObject.isWebM(cacheImage.imageLocation.document) || MessageObject.isVideoSticker(cacheImage.imageLocation.document) || isAnimatedAvatar(cacheImage.filter));
}
fileDrawable.setLimitFps(limitFps);
@ -1380,7 +1383,13 @@ public class ImageLoader {
opts.inDither = false;
if (mediaId != null && mediaThumbPath == null) {
if (mediaIsVideo) {
image = MediaStore.Video.Thumbnails.getThumbnail(ApplicationLoader.applicationContext.getContentResolver(), mediaId, MediaStore.Video.Thumbnails.MINI_KIND, opts);
if (mediaId == 0) {
AnimatedFileDrawable fileDrawable = new AnimatedFileDrawable(cacheFileFinal, true, 0, null, null, null, 0, 0, true, null);
image = fileDrawable.getFrameAtTime(0, true);
fileDrawable.recycle();
} else {
image = MediaStore.Video.Thumbnails.getThumbnail(ApplicationLoader.applicationContext.getContentResolver(), mediaId, MediaStore.Video.Thumbnails.MINI_KIND, opts);
}
} else {
image = MediaStore.Images.Thumbnails.getThumbnail(ApplicationLoader.applicationContext.getContentResolver(), mediaId, MediaStore.Images.Thumbnails.MINI_KIND, opts);
}

View file

@ -137,7 +137,7 @@ public class ImageLocation {
int currentAccount = UserConfig.selectedAccount;
if (MessagesController.getInstance(currentAccount).isPremiumUser(user) && user.photo.has_video) {
final TLRPC.UserFull userFull = MessagesController.getInstance(currentAccount).getUserFull(user.id);
if (userFull != null && userFull.profile_photo !=null && userFull.profile_photo.video_sizes != null && !userFull.profile_photo.video_sizes.isEmpty()) {
if (userFull != null && userFull.profile_photo != null && userFull.profile_photo.video_sizes != null && !userFull.profile_photo.video_sizes.isEmpty()) {
TLRPC.VideoSize videoSize = userFull.profile_photo.video_sizes.get(0);
for (int i = 0; i < userFull.profile_photo.video_sizes.size(); i++) {
if ("p".equals(userFull.profile_photo.video_sizes.get(i).type)) {

View file

@ -48,7 +48,8 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
if (currentThumbDrawable != null && thumbShader != null) {
drawDrawable(null, currentThumbDrawable, 255, thumbShader, 0, 0, null);
return true;
} if (staticThumbDrawable != null && thumbShader != null) {
}
if (staticThumbDrawable != null && thumbShader != null) {
drawDrawable(null, staticThumbDrawable, 255, thumbShader, 0, 0, null);
return true;
}
@ -190,6 +191,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
private int fileLoadingPriority = FileLoader.PRIORITY_NORMAL;
private int currentLayerNum;
public boolean ignoreNotifications;
private int currentOpenedLayerFlags;
private int isLastFrame;
@ -384,7 +386,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
if (user.photo != null) {
strippedBitmap = user.photo.strippedBitmap;
hasStripped = user.photo.stripped_thumb != null;
if (animationEnabled && MessagesController.getInstance(currentAccount).isPremiumUser(user) && user.photo.has_video) {
if (animationEnabled && MessagesController.getInstance(currentAccount).isPremiumUser(user) && user.photo.has_video && !SharedConfig.getLiteMode().enabled()) {
final TLRPC.UserFull userFull = MessagesController.getInstance(currentAccount).getUserFull(user.id);
if (userFull == null) {
MessagesController.getInstance(currentAccount).loadFullUser(user, currentGuid, false);
@ -417,7 +419,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
ImageLocation location = ImageLocation.getForUserOrChat(object, ImageLocation.TYPE_SMALL);
String filter = "50_50";
if (videoLocation != null) {
setImage(videoLocation, "avatar", location, filter, null, null,strippedBitmap, 0, null, parentObject, 0);
setImage(videoLocation, "avatar", location, filter, null, null, strippedBitmap, 0, null, parentObject, 0);
animatedFileDrawableRepeatMaxCount = 3;
} else {
if (strippedBitmap != null) {
@ -958,9 +960,11 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
setImageBackup.cacheType = currentCacheType;
setImageBackup.parentObject = currentParentObject;
}
NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.didReplacedPhotoInMemCache);
NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.stopAllHeavyOperations);
NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.startAllHeavyOperations);
if (!ignoreNotifications) {
NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.didReplacedPhotoInMemCache);
NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.stopAllHeavyOperations);
NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.startAllHeavyOperations);
}
if (staticThumbDrawable != null) {
staticThumbDrawable = null;
@ -1001,13 +1005,34 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
return false;
}
private int bufferedFrame;
public void incrementFrames(int inc) {
if (currentMediaDrawable instanceof RLottieDrawable) {
// RLottieDrawable rlottie = (RLottieDrawable) currentMediaDrawable;
// inc = (int) Math.round((float) rlottie.getFramesCount() / rlottie.getDuration() * (1f / 30f));
// rlottie.setCurrentFrame(
// (rlottie.getCurrentFrame() + inc) % (int) rlottie.getFramesCount()
// );
} else if (currentMediaDrawable instanceof AnimatedFileDrawable) {
int lastFrame = (int) bufferedFrame;
bufferedFrame += inc;
int currentFrame = (int) bufferedFrame;
while (lastFrame != currentFrame) {
((AnimatedFileDrawable) currentMediaDrawable).getNextFrame();
currentFrame--;
}
}
}
public boolean onAttachedToWindow() {
attachedToWindow = true;
currentOpenedLayerFlags = NotificationCenter.getGlobalInstance().getCurrentHeavyOperationFlags();
currentOpenedLayerFlags &= ~currentLayerNum;
NotificationCenter.getGlobalInstance().addObserver(this, NotificationCenter.didReplacedPhotoInMemCache);
NotificationCenter.getGlobalInstance().addObserver(this, NotificationCenter.stopAllHeavyOperations);
NotificationCenter.getGlobalInstance().addObserver(this, NotificationCenter.startAllHeavyOperations);
if (!ignoreNotifications) {
NotificationCenter.getGlobalInstance().addObserver(this, NotificationCenter.didReplacedPhotoInMemCache);
NotificationCenter.getGlobalInstance().addObserver(this, NotificationCenter.stopAllHeavyOperations);
NotificationCenter.getGlobalInstance().addObserver(this, NotificationCenter.startAllHeavyOperations);
}
if (setBackupImage()) {
return true;
}

View file

@ -348,6 +348,10 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
public boolean isVideo;
public boolean isMuted;
public boolean canDeleteAfter;
public boolean hasSpoiler;
public boolean isChatPreviewSpoilerRevealed;
public boolean isAttachSpoilerRevealed;
public PhotoEntry(int bucketId, int imageId, long dateTaken, String path, int orientation, boolean isVideo, int width, int height, long size) {
this.bucketId = bucketId;
@ -365,6 +369,12 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
this.isVideo = isVideo;
}
@Override
public void copyFrom(MediaEditState state) {
super.copyFrom(state);
this.hasSpoiler = state instanceof PhotoEntry && ((PhotoEntry) state).hasSpoiler;
}
@Override
public String getPath() {
return path;
@ -378,6 +388,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
filterPath = null;
}
}
hasSpoiler = false;
super.reset();
}
}
@ -3762,7 +3773,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
currentAccount.getNotificationCenter().addObserver(this, NotificationCenter.fileLoaded);
currentAccount.getNotificationCenter().addObserver(this, NotificationCenter.fileLoadProgressChanged);
currentAccount.getNotificationCenter().addObserver(this, NotificationCenter.fileLoadFailed);
progressDialog = new AlertDialog(context, 2);
progressDialog = new AlertDialog(context, AlertDialog.ALERT_TYPE_LOADING);
progressDialog.setMessage(LocaleController.getString("Loading", R.string.Loading));
progressDialog.setCanceledOnTouchOutside(false);
progressDialog.setCancelable(true);
@ -4045,7 +4056,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
final boolean[] finished = new boolean[1];
if (context != null && type != 0) {
try {
final AlertDialog dialog = new AlertDialog(context, 2);
final AlertDialog dialog = new AlertDialog(context, AlertDialog.ALERT_TYPE_LOADING);
dialog.setMessage(LocaleController.getString("Loading", R.string.Loading));
dialog.setCanceledOnTouchOutside(false);
dialog.setCancelable(true);

View file

@ -65,7 +65,6 @@ import org.telegram.ui.Components.AvatarDrawable;
import org.telegram.ui.Components.Bulletin;
import org.telegram.ui.Components.ChatThemeBottomSheet;
import org.telegram.ui.Components.RLottieDrawable;
import org.telegram.ui.Components.Reactions.ReactionsEffectOverlay;
import org.telegram.ui.Components.StickerSetBulletinLayout;
import org.telegram.ui.Components.StickersArchiveAlert;
import org.telegram.ui.Components.TextStyleSpan;
@ -652,7 +651,7 @@ public class MediaDataController extends BaseController {
}
public void preloadDefaultReactions() {
if (reactionsList == null || reactionsCacheGenerated) {
if (reactionsList == null || reactionsCacheGenerated || SharedConfig.getLiteMode().enabled()) {
return;
}
reactionsCacheGenerated = true;
@ -665,8 +664,6 @@ public class MediaDataController extends BaseController {
for (int i = 0; i < arrayList.size(); i++) {
TLRPC.TL_availableReaction reaction = arrayList.get(i);
int size = ReactionsEffectOverlay.sizeForBigReaction();
preloadImage(ImageLocation.getForDocument(reaction.around_animation), ReactionsEffectOverlay.getFilterForAroundAnimation(), true);
preloadImage(ImageLocation.getForDocument(reaction.effect_animation), null);
}
}
@ -699,6 +696,14 @@ public class MediaDataController extends BaseController {
imageReceiver.setImage(location, filter, null, null, 0, FileLoader.PRELOAD_CACHE_TYPE);
}
public void preloadImage(ImageReceiver imageReceiver, ImageLocation location, String filter) {
if (SharedConfig.getLiteMode().enabled()) {
return;
}
imageReceiver.setUniqKeyPrefix("preload");
imageReceiver.setImage(location, filter, null, null, 0, FileLoader.PRELOAD_CACHE_TYPE);
}
private void putReactionsToCache(List<TLRPC.TL_availableReaction> reactions, int hash, int date) {
ArrayList<TLRPC.TL_availableReaction> reactionsFinal = reactions != null ? new ArrayList<>(reactions) : null;
getMessagesStorage().getStorageQueue().postRunnable(() -> {
@ -1067,6 +1072,16 @@ public class MediaDataController extends BaseController {
groupStickerSets.put(stickerSet.set.id, stickerSet);
}
public static TLRPC.InputStickerSet getInputStickerSet(TLRPC.StickerSet set) {
if (set != null) {
TLRPC.TL_inputStickerSetID inputStickerSetID = new TLRPC.TL_inputStickerSetID();
inputStickerSetID.id = set.id;
inputStickerSetID.access_hash = set.access_hash;
return inputStickerSetID;
}
return null;
}
public TLRPC.TL_messages_stickerSet getStickerSet(TLRPC.InputStickerSet inputStickerSet, boolean cacheOnly) {
return getStickerSet(inputStickerSet, cacheOnly, null);
}

View file

@ -98,6 +98,7 @@ public class MessageObject {
public static final int TYPE_GIFT_PREMIUM = 18;
public static final int TYPE_EMOJIS = 19;
public static final int TYPE_EXTENDED_MEDIA_PREVIEW = 20;
public static final int TYPE_SUGGEST_PHOTO = 21;
public int localType;
public String localName;
@ -112,6 +113,7 @@ public class MessageObject {
public TLRPC.Document emojiAnimatedSticker;
public Long emojiAnimatedStickerId;
public boolean isTopicMainMessage;
public boolean settingAvatar;
private boolean emojiAnimatedStickerLoading;
public String emojiAnimatedStickerColor;
public CharSequence messageText;
@ -164,6 +166,9 @@ public class MessageObject {
public long loadedFileSize;
public boolean isSpoilersRevealed;
public boolean isMediaSpoilersRevealed;
public boolean isMediaSpoilersRevealedInSharedMedia;
public boolean revealingMediaSpoilers;
public byte[] sponsoredId;
public int sponsoredChannelPost;
public TLRPC.ChatInvite sponsoredChatInvite;
@ -340,6 +345,10 @@ public class MessageObject {
return emojiOnlyCount;
}
public boolean hasMediaSpoilers() {
return messageOwner.media != null && messageOwner.media.spoiler;
}
public boolean shouldDrawReactionsInLayout() {
if (getDialogId() < 0 || UserConfig.getInstance(currentAccount).isPremium()) {
return true;
@ -3299,6 +3308,12 @@ public class MessageObject {
SpannableStringBuilder sb = SpannableStringBuilder.valueOf(messageText);
messageText = sb.replace(i, i + 3, BillingController.getInstance().formatCurrency(messageOwner.action.amount, messageOwner.action.currency));
}
} else if (messageOwner.action instanceof TLRPC.TL_messageActionSuggestProfilePhoto) {
if (messageOwner.action.photo != null && messageOwner.action.photo.video_sizes != null && !messageOwner.action.photo.video_sizes.isEmpty()) {
messageText = LocaleController.getString(R.string.ActionSuggestVideoShort);
} else {
messageText = LocaleController.getString(R.string.ActionSuggestPhotoShort);
}
} else if (messageOwner.action instanceof TLRPC.TL_messageActionChatEditPhoto) {
TLRPC.Chat chat = messageOwner.peer_id != null && messageOwner.peer_id.channel_id != 0 ? getChat(chats, sChats, messageOwner.peer_id.channel_id) : null;
if (ChatObject.isChannel(chat) && !chat.megagroup) {
@ -3358,6 +3373,8 @@ public class MessageObject {
messageText = LocaleController.formatString("MessageLifetimeRemoved", R.string.MessageLifetimeRemoved, UserObject.getFirstName(fromUser));
}
}
} else if (messageOwner.action instanceof TLRPC.TL_messageActionAttachMenuBotAllowed) {
messageText = LocaleController.getString(R.string.ActionAttachMenuBotAllowed);
} else if (messageOwner.action instanceof TLRPC.TL_messageActionSetMessagesTTL) {
TLRPC.TL_messageActionSetMessagesTTL action = (TLRPC.TL_messageActionSetMessagesTTL) messageOwner.action;
TLRPC.Chat chat = messageOwner.peer_id != null && messageOwner.peer_id.channel_id != 0 ? getChat(chats, sChats, messageOwner.peer_id.channel_id) : null;
@ -3872,7 +3889,13 @@ public class MessageObject {
type = TYPE_TEXT;
}
} else if (messageOwner instanceof TLRPC.TL_messageService) {
if (messageOwner.action instanceof TLRPC.TL_messageActionLoginUnknownLocation) {
if (messageOwner.action instanceof TLRPC.TL_messageActionSuggestProfilePhoto) {
contentType = 1;
type = TYPE_SUGGEST_PHOTO;
photoThumbs = new ArrayList<>();
photoThumbs.addAll(messageOwner.action.photo.sizes);
photoThumbsObject = messageOwner.action.photo;
} else if (messageOwner.action instanceof TLRPC.TL_messageActionLoginUnknownLocation) {
type = TYPE_TEXT;
} else if (messageOwner.action instanceof TLRPC.TL_messageActionGiftPremium) {
contentType = 1;
@ -5505,7 +5528,7 @@ public class MessageObject {
return isOutOwnerCached = false;
}
if (messageOwner.fwd_from == null) {
return isOutOwnerCached= true;
return isOutOwnerCached = true;
}
long selfUserId = UserConfig.getInstance(currentAccount).getClientUserId();
if (getDialogId() == selfUserId) {
@ -5971,7 +5994,7 @@ public class MessageObject {
}
public static boolean canAutoplayAnimatedSticker(TLRPC.Document document) {
return (isAnimatedStickerDocument(document, true) || isVideoStickerDocument(document)) && SharedConfig.getDevicePerformanceClass() != SharedConfig.PERFORMANCE_CLASS_LOW;
return (isAnimatedStickerDocument(document, true) || isVideoStickerDocument(document)) && SharedConfig.getDevicePerformanceClass() != SharedConfig.PERFORMANCE_CLASS_LOW && !SharedConfig.getLiteMode().enabled();
}
public static boolean isMaskDocument(TLRPC.Document document) {
@ -6135,6 +6158,9 @@ public class MessageObject {
if (getMedia(message) instanceof TLRPC.TL_messageMediaWebPage) {
return getMedia(message).webpage.photo instanceof TLRPC.TL_photo && !(getMedia(message).webpage.document instanceof TLRPC.TL_document);
}
if (message != null && message.action != null && message.action.photo != null) {
return message.action.photo instanceof TLRPC.TL_photo;
}
return getMedia(message) instanceof TLRPC.TL_messageMediaPhoto;
}
@ -6355,7 +6381,7 @@ public class MessageObject {
return AndroidUtilities.dp(82);
} else if (type == 10) {
return AndroidUtilities.dp(30);
} else if (type == TYPE_ACTION_PHOTO || type == TYPE_GIFT_PREMIUM) {
} else if (type == TYPE_ACTION_PHOTO || type == TYPE_GIFT_PREMIUM || type == TYPE_SUGGEST_PHOTO) {
return AndroidUtilities.dp(50);
} else if (type == TYPE_ROUND_VIDEO) {
return AndroidUtilities.roundMessageSize;
@ -7026,6 +7052,10 @@ public class MessageObject {
return messageOwner.reply_to != null ? messageOwner.reply_to.reply_to_top_id : 0;
}
public int getReplyTopMsgId(boolean sureIsForum) {
return messageOwner.reply_to != null ? (sureIsForum && (messageOwner.reply_to.flags & 2) > 0 && messageOwner.reply_to.reply_to_top_id == 0 ? 1 : messageOwner.reply_to.reply_to_top_id) : 0;
}
public static long getReplyToDialogId(TLRPC.Message message) {
if (message.reply_to == null) {
return 0;

View file

@ -38,6 +38,7 @@ import androidx.core.util.Consumer;
import org.telegram.SQLite.SQLiteCursor;
import org.telegram.SQLite.SQLiteException;
import org.telegram.SQLite.SQLitePreparedStatement;
import org.telegram.messenger.browser.Browser;
import org.telegram.messenger.support.LongSparseIntArray;
import org.telegram.messenger.support.LongSparseLongArray;
import org.telegram.messenger.voip.VoIPService;
@ -56,6 +57,7 @@ import org.telegram.ui.ChatRightsEditActivity;
import org.telegram.ui.Components.AlertsCreator;
import org.telegram.ui.Components.AnimatedEmojiDrawable;
import org.telegram.ui.Components.BulletinFactory;
import org.telegram.ui.Components.ImageUpdater;
import org.telegram.ui.Components.JoinCallAlert;
import org.telegram.ui.Components.MotionBackgroundDrawable;
import org.telegram.ui.Components.SwipeGestureSettingsView;
@ -84,6 +86,7 @@ import java.util.concurrent.CountDownLatch;
public class MessagesController extends BaseController implements NotificationCenter.NotificationCenterDelegate {
public int lastKnownSessionsCount;
private ConcurrentHashMap<Long, TLRPC.Chat> chats = new ConcurrentHashMap<>(100, 1.0f, 2);
private ConcurrentHashMap<Integer, TLRPC.EncryptedChat> encryptedChats = new ConcurrentHashMap<>(10, 1.0f, 2);
private ConcurrentHashMap<Long, TLRPC.User> users = new ConcurrentHashMap<>(100, 1.0f, 2);
@ -373,6 +376,7 @@ public class MessagesController extends BaseController implements NotificationCe
public int topicsPinnedLimit;
public long telegramAntispamUserId;
public int telegramAntispamGroupSizeMin;
public int hiddenMembersGroupSizeMin;
public int uploadMaxFileParts;
public int uploadMaxFilePartsPremium;
@ -396,6 +400,7 @@ public class MessagesController extends BaseController implements NotificationCe
private Runnable recentEmojiStatusUpdateRunnable;
private LongSparseArray<Integer> emojiStatusUntilValues = new LongSparseArray<>();
private TopicsController topicsController;
private CacheByChatsController cacheByChatsController;
public void getNextReactionMention(long dialogId, int topicId, int count, Consumer<Integer> callback) {
final MessagesStorage messagesStorage = getMessagesStorage();
@ -619,6 +624,23 @@ public class MessagesController extends BaseController implements NotificationCe
});
}
public SparseArray<ImageUpdater> photoSuggestion = new SparseArray<>();
public String getFullName(long dialogId) {
if (dialogId > 0) {
TLRPC.User user = getUser(dialogId);
if (user != null) {
return ContactsController.formatName(user.first_name, user.last_name);
}
} else {
TLRPC.Chat chat = getChat(-dialogId);
if (chat != null) {
return chat.title;
}
}
return null;
}
public class SponsoredMessagesInfo {
public ArrayList<MessageObject> messages;
public Integer posts_between;
@ -1129,6 +1151,7 @@ public class MessagesController extends BaseController implements NotificationCe
topicsPinnedLimit = mainPreferences.getInt("topicsPinnedLimit", 3);
telegramAntispamUserId = mainPreferences.getLong("telegramAntispamUserId", -1);
telegramAntispamGroupSizeMin = mainPreferences.getInt("telegramAntispamGroupSizeMin", 100);
hiddenMembersGroupSizeMin = mainPreferences.getInt("hiddenMembersGroupSizeMin", 100);
BuildVars.GOOGLE_AUTH_CLIENT_ID = mainPreferences.getString("googleAuthClientId", BuildVars.GOOGLE_AUTH_CLIENT_ID);
Set<String> currencySet = mainPreferences.getStringSet("directPaymentsCurrency", null);
@ -1266,6 +1289,7 @@ public class MessagesController extends BaseController implements NotificationCe
}
topicsController = new TopicsController(num);
cacheByChatsController = new CacheByChatsController(num);
}
@ -2654,6 +2678,7 @@ public class MessagesController extends BaseController implements NotificationCe
changed = true;
}
}
break;
}
case "telegram_antispam_user_id": {
if (value.value instanceof TLRPC.TL_jsonString) {
@ -2669,6 +2694,7 @@ public class MessagesController extends BaseController implements NotificationCe
FileLog.e(e);
}
}
break;
}
case "telegram_antispam_group_size_min": {
if (value.value instanceof TLRPC.TL_jsonNumber) {
@ -2679,6 +2705,18 @@ public class MessagesController extends BaseController implements NotificationCe
changed = true;
}
}
break;
}
case "hidden_members_group_size_min": {
if (value.value instanceof TLRPC.TL_jsonNumber) {
TLRPC.TL_jsonNumber number = (TLRPC.TL_jsonNumber) value.value;
if (number.value != hiddenMembersGroupSizeMin) {
hiddenMembersGroupSizeMin = (int) number.value;
editor.putInt("hiddenMembersGroupSizeMin", hiddenMembersGroupSizeMin);
changed = true;
}
}
break;
}
}
}
@ -3411,6 +3449,7 @@ public class MessagesController extends BaseController implements NotificationCe
getSecretChatHelper().cleanup();
getLocationController().cleanup();
getMediaDataController().cleanup();
getColorPalette().cleanup();
showFiltersTooltip = false;
@ -10309,7 +10348,7 @@ public class MessagesController extends BaseController implements NotificationCe
public void convertToMegaGroup(Context context, long chatId, BaseFragment fragment, MessagesStorage.LongCallback convertRunnable, Runnable errorRunnable) {
TLRPC.TL_messages_migrateChat req = new TLRPC.TL_messages_migrateChat();
req.chat_id = chatId;
AlertDialog progressDialog = context != null ? new AlertDialog(context, 3) : null;
AlertDialog progressDialog = context != null ? new AlertDialog(context, AlertDialog.ALERT_TYPE_SPINNER) : null;
int reqId = getConnectionsManager().sendRequest(req, (response, error) -> {
if (error == null) {
if (context != null) {
@ -10370,7 +10409,7 @@ public class MessagesController extends BaseController implements NotificationCe
public void convertToGigaGroup(final Context context, TLRPC.Chat chat, BaseFragment fragment, MessagesStorage.BooleanCallback convertRunnable) {
TLRPC.TL_channels_convertToGigagroup req = new TLRPC.TL_channels_convertToGigagroup();
req.channel = getInputChannel(chat);
AlertDialog progressDialog = context != null ? new AlertDialog(context, 3) : null;
AlertDialog progressDialog = context != null ? new AlertDialog(context, AlertDialog.ALERT_TYPE_SPINNER) : null;
int reqId = getConnectionsManager().sendRequest(req, (response, error) -> {
if (error == null) {
if (context != null) {
@ -13793,7 +13832,15 @@ public class MessagesController extends BaseController implements NotificationCe
updatesOnMainThread = new ArrayList<>();
}
updatesOnMainThread.add(baseUpdate);
} else if (baseUpdate instanceof TLRPC.TL_updateUserPhone) {
} else if (baseUpdate instanceof TLRPC.TL_updateUser) {
TLRPC.TL_updateUser update = (TLRPC.TL_updateUser) baseUpdate;
interfaceUpdateMask |= UPDATE_MASK_AVATAR;
getMessagesStorage().clearUserPhotos(update.user_id);
if (updatesOnMainThread == null) {
updatesOnMainThread = new ArrayList<>();
}
updatesOnMainThread.add(baseUpdate);
}else if (baseUpdate instanceof TLRPC.TL_updateUserPhone) {
interfaceUpdateMask |= UPDATE_MASK_PHONE;
if (updatesOnMainThread == null) {
updatesOnMainThread = new ArrayList<>();
@ -14741,6 +14788,31 @@ public class MessagesController extends BaseController implements NotificationCe
if (UserObject.isUserSelf(currentUser)) {
getNotificationCenter().postNotificationName(NotificationCenter.mainUserInfoChanged);
}
} else if (baseUpdate instanceof TLRPC.TL_updateUser) {
TLRPC.TL_updateUser update = (TLRPC.TL_updateUser) baseUpdate;
TLRPC.User currentUser = getUser(update.user_id);
TLRPC.User updated = null;
if (usersArr != null) {
for (int i = 0; i < usersArr.size(); ++i) {
TLRPC.User user = usersArr.get(i);
if (user != null && user.id == update.user_id) {
updated = user;
break;
}
}
}
if (updated != null && updated.photo != null) {
if (currentUser != null) {
currentUser.photo = updated.photo;
}
TLRPC.User toDbUser = new TLRPC.TL_user();
toDbUser.id = updated.id;
toDbUser.photo = updated.photo;
dbUsers.add(toDbUser);
}
if (UserObject.isUserSelf(currentUser)) {
getNotificationCenter().postNotificationName(NotificationCenter.mainUserInfoChanged);
}
} else if (baseUpdate instanceof TLRPC.TL_updateUserPhone) {
TLRPC.TL_updateUserPhone update = (TLRPC.TL_updateUserPhone) baseUpdate;
TLRPC.User currentUser = getUser(update.user_id);
@ -16058,7 +16130,7 @@ public class MessagesController extends BaseController implements NotificationCe
return false;
}
protected boolean updateInterfaceWithMessages(long dialogId, ArrayList<MessageObject> messages, boolean scheduled) {
public boolean updateInterfaceWithMessages(long dialogId, ArrayList<MessageObject> messages, boolean scheduled) {
if (messages == null || messages.isEmpty()) {
return false;
}
@ -16573,7 +16645,7 @@ public class MessagesController extends BaseController implements NotificationCe
if (messageId != 0 && originalMessage != null && chat != null && chat.access_hash == 0) {
long did = originalMessage.getDialogId();
if (!DialogObject.isEncryptedDialog(did)) {
AlertDialog progressDialog = new AlertDialog(fragment.getParentActivity(), 3);
AlertDialog progressDialog = new AlertDialog(fragment.getParentActivity(), AlertDialog.ALERT_TYPE_SPINNER);
TLObject req;
if (did < 0) {
chat = getChat(-did);
@ -16659,6 +16731,10 @@ public class MessagesController extends BaseController implements NotificationCe
}
public void openByUserName(String username, BaseFragment fragment, int type) {
openByUserName(username, fragment, type, null);
}
public void openByUserName(String username, BaseFragment fragment, int type, Browser.Progress progress) {
if (username == null || fragment == null) {
return;
}
@ -16684,16 +16760,20 @@ public class MessagesController extends BaseController implements NotificationCe
if (fragment.getParentActivity() == null) {
return;
}
AlertDialog[] progressDialog = new AlertDialog[]{new AlertDialog(fragment.getParentActivity(), 3)};
AlertDialog[] progressDialog = new AlertDialog[] {
new AlertDialog(fragment.getParentActivity(), AlertDialog.ALERT_TYPE_SPINNER)
};
TLRPC.TL_contacts_resolveUsername req = new TLRPC.TL_contacts_resolveUsername();
req.username = username;
int reqId = getConnectionsManager().sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> {
try {
progressDialog[0].dismiss();
} catch (Exception ignored) {
}
if (progress != null) {
progress.end();
} else {
progressDialog[0].dismiss();
}
} catch (Exception ignored) {}
progressDialog[0] = null;
fragment.setVisibleDialog(null);
if (error == null) {
@ -16719,13 +16799,18 @@ public class MessagesController extends BaseController implements NotificationCe
}
}
}));
AndroidUtilities.runOnUIThread(() -> {
if (progressDialog[0] == null) {
return;
}
progressDialog[0].setOnCancelListener(dialog -> getConnectionsManager().cancelRequest(reqId, true));
fragment.showDialog(progressDialog[0]);
}, 500);
if (progress != null) {
progress.onCancel(() -> getConnectionsManager().cancelRequest(reqId, true));
progress.init();
} else {
AndroidUtilities.runOnUIThread(() -> {
if (progressDialog[0] == null) {
return;
}
progressDialog[0].setOnCancelListener(dialog -> getConnectionsManager().cancelRequest(reqId, true));
fragment.showDialog(progressDialog[0]);
}, 500);
}
}
}
@ -17077,4 +17162,7 @@ public class MessagesController extends BaseController implements NotificationCe
});
}
public CacheByChatsController getCacheByChatsController() {
return cacheByChatsController;
}
}

View file

@ -3924,6 +3924,9 @@ public class MessagesStorage extends BaseController {
if (photo instanceof TLRPC.TL_photoEmpty) {
continue;
}
if (photo.file_reference == null) {
photo.file_reference = new byte[0];
}
state.requery();
int size = photo.getObjectSize();
if (messages != null) {
@ -3952,6 +3955,33 @@ public class MessagesStorage extends BaseController {
});
}
public void addDialogPhoto(long did, TLRPC.Photo photo) {
storageQueue.postRunnable(() -> {
SQLitePreparedStatement state = null;
try {
state = database.executeFast("REPLACE INTO user_photos VALUES(?, ?, ?)");
state.requery();
int size = photo.getObjectSize();
NativeByteBuffer data = new NativeByteBuffer(size);
photo.serializeToStream(data);
state.bindLong(1, did);
state.bindLong(2, photo.id);
state.bindByteBuffer(3, data);
state.step();
data.reuse();
state.dispose();
state = null;
} catch (Exception e) {
FileLog.e(e);
} finally {
if (state != null) {
state.dispose();
}
}
});
}
public void emptyMessagesMedia(long dialogId, ArrayList<Integer> mids) {
storageQueue.postRunnable(() -> {
SQLiteCursor cursor = null;
@ -10650,6 +10680,7 @@ public class MessagesStorage extends BaseController {
object.ttl_seconds = message.media.ttl_seconds;
object.flags |= 4;
}
MessageObject messageObject = new MessageObject(currentAccount, message, false, false);
downloadMediaMask |= type;
state_download.requery();
data = new NativeByteBuffer(object.getObjectSize());
@ -10658,7 +10689,7 @@ public class MessagesStorage extends BaseController {
state_download.bindInteger(2, type);
state_download.bindInteger(3, message.date);
state_download.bindByteBuffer(4, data);
state_download.bindString(5, "sent_" + (message.peer_id != null ? message.peer_id.channel_id : 0) + "_" + message.id + "_" + DialogObject.getPeerDialogId(message.peer_id));
state_download.bindString(5, "sent_" + (message.peer_id != null ? message.peer_id.channel_id : 0) + "_" + message.id + "_" + DialogObject.getPeerDialogId(message.peer_id) + "_" + messageObject.type);
state_download.step();
data.reuse();
}

View file

@ -3853,7 +3853,7 @@ public class NotificationsController extends BaseController {
}
if (silent != 1 && !notifyDisabled) {
if (!isInApp || preferences.getBoolean("EnableInAppPreview", true)) {
if (!isInApp || preferences.getBoolean("EnableInAppPreview", true) && lastMessage != null) {
if (lastMessage.length() > 100) {
lastMessage = lastMessage.substring(0, 100).replace('\n', ' ').trim() + "...";
}

View file

@ -66,7 +66,7 @@ public class SecretChatHelper extends BaseController {
}
}
public static int CURRENT_SECRET_CHAT_LAYER = 101;
public static int CURRENT_SECRET_CHAT_LAYER = 151;
private ArrayList<Integer> sendingNotifyLayer = new ArrayList<>();
private SparseArray<ArrayList<TL_decryptedMessageHolder>> secretHolesQueue = new SparseArray<>();
@ -1926,7 +1926,7 @@ public class SecretChatHelper extends BaseController {
return;
}
startingSecretChat = true;
AlertDialog progressDialog = new AlertDialog(context, 3);
AlertDialog progressDialog = new AlertDialog(context, AlertDialog.ALERT_TYPE_SPINNER);
TLRPC.TL_messages_getDhConfig req = new TLRPC.TL_messages_getDhConfig();
req.random_length = 256;
req.version = getMessagesStorage().getLastSecretVersion();

View file

@ -8,6 +8,7 @@
package org.telegram.messenger;
import android.annotation.SuppressLint;
import android.content.ClipDescription;
import android.content.Context;
import android.content.Intent;
@ -517,8 +518,10 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
public boolean canDeleteAfter;
public boolean forceImage;
public boolean updateStickersOrder;
public boolean hasMediaSpoilers;
}
@SuppressLint("MissingPermission")
public static class LocationProvider {
public interface LocationProviderDelegate {
@ -1379,7 +1382,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
public boolean retrySendMessage(MessageObject messageObject, boolean unsent) {
if (messageObject.getId() >= 0) {
if (messageObject.isEditing()) {
editMessage(messageObject, null, null, null, null, null, true, messageObject);
editMessage(messageObject, null, null, null, null, null, true, messageObject.hasMediaSpoilers(), messageObject);
}
return false;
}
@ -1451,7 +1454,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
HashMap<String, String> params = null;
if (DialogObject.isEncryptedDialog(did) && messageObject.messageOwner.peer_id != null && (messageObject.messageOwner.media.photo instanceof TLRPC.TL_photo || messageObject.messageOwner.media.document instanceof TLRPC.TL_document)) {
params = new HashMap<>();
params.put("parentObject", "sent_" + messageObject.messageOwner.peer_id.channel_id + "_" + messageObject.getId() + "_" + messageObject.getDialogId());
params.put("parentObject", "sent_" + messageObject.messageOwner.peer_id.channel_id + "_" + messageObject.getId() + "_" + messageObject.getDialogId() + "_" + messageObject.type);
}
if (messageObject.messageOwner.media.photo instanceof TLRPC.TL_photo) {
sendMessage((TLRPC.TL_photo) messageObject.messageOwner.media.photo, null, did, messageObject.replyMessageObject, null, messageObject.messageOwner.message, messageObject.messageOwner.entities, null, params, true, 0, messageObject.messageOwner.media.ttl_seconds, messageObject, false);
@ -2233,7 +2236,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
}
}
public void editMessage(MessageObject messageObject, TLRPC.TL_photo photo, VideoEditedInfo videoEditedInfo, TLRPC.TL_document document, String path, HashMap<String, String> params, boolean retry, Object parentObject) {
public void editMessage(MessageObject messageObject, TLRPC.TL_photo photo, VideoEditedInfo videoEditedInfo, TLRPC.TL_document document, String path, HashMap<String, String> params, boolean retry, boolean hasMediaSpoilers, Object parentObject) {
if (messageObject == null) {
return;
}
@ -2303,6 +2306,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
newMsg.media = new TLRPC.TL_messageMediaPhoto();
newMsg.media.flags |= 3;
newMsg.media.photo = photo;
newMsg.media.spoiler = hasMediaSpoilers;
type = 2;
if (path != null && path.length() > 0 && path.startsWith("http")) {
newMsg.attachPath = path;
@ -2314,6 +2318,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
newMsg.media = new TLRPC.TL_messageMediaDocument();
newMsg.media.flags |= 3;
newMsg.media.document = document;
newMsg.media.spoiler = hasMediaSpoilers;
if (MessageObject.isVideoDocument(document) || videoEditedInfo != null) {
type = 3;
} else {
@ -2406,6 +2411,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
} else if (type == 2) {
TLRPC.TL_inputMediaUploadedPhoto uploadedPhoto = new TLRPC.TL_inputMediaUploadedPhoto();
uploadedPhoto.spoiler = hasMediaSpoilers;
if (params != null) {
String masks = params.get("masks");
if (masks != null) {
@ -2431,6 +2437,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
if (media.id.file_reference == null) {
media.id.file_reference = new byte[0];
}
media.spoiler = hasMediaSpoilers;
inputMedia = media;
}
@ -2449,6 +2456,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
}
} else if (type == 3) {
TLRPC.TL_inputMediaUploadedDocument uploadedDocument = new TLRPC.TL_inputMediaUploadedDocument();
uploadedDocument.spoiler = hasMediaSpoilers;
if (params != null) {
String masks = params.get("masks");
if (masks != null) {
@ -2481,6 +2489,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
if (media.id.file_reference == null) {
media.id.file_reference = new byte[0];
}
media.spoiler = hasMediaSpoilers;
inputMedia = media;
}
@ -2504,6 +2513,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
TLRPC.InputMedia uploadedDocument = new TLRPC.TL_inputMediaUploadedDocument();
uploadedDocument.mime_type = document.mime_type;
uploadedDocument.attributes = document.attributes;
uploadedDocument.spoiler = hasMediaSpoilers;
if (document.access_hash == 0) {
inputMedia = uploadedDocument;
@ -2517,6 +2527,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
if (media.id.file_reference == null) {
media.id.file_reference = new byte[0];
}
media.spoiler = hasMediaSpoilers;
inputMedia = media;
}
if (!http) {
@ -3212,6 +3223,10 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
sendMessage(null, caption, null, null, videoEditedInfo, null, document, null, null, null, peer, path, replyToMsg, replyToTopMsg, null, true, null, entities, replyMarkup, params, notify, scheduleDate, ttl, parentObject, sendAnimationData, updateStickersOrder);
}
public void sendMessage(TLRPC.TL_document document, VideoEditedInfo videoEditedInfo, String path, long peer, MessageObject replyToMsg, MessageObject replyToTopMsg, String caption, ArrayList<TLRPC.MessageEntity> entities, TLRPC.ReplyMarkup replyMarkup, HashMap<String, String> params, boolean notify, int scheduleDate, int ttl, Object parentObject, MessageObject.SendAnimationData sendAnimationData, boolean updateStickersOrder, boolean hasMediaSpoilers) {
sendMessage(null, caption, null, null, videoEditedInfo, null, document, null, null, null, peer, path, replyToMsg, replyToTopMsg, null, true, null, entities, replyMarkup, params, notify, scheduleDate, ttl, parentObject, sendAnimationData, updateStickersOrder, hasMediaSpoilers);
}
public void sendMessage(String message, long peer, MessageObject replyToMsg, MessageObject replyToTopMsg, TLRPC.WebPage webPage, boolean searchLinks, ArrayList<TLRPC.MessageEntity> entities, TLRPC.ReplyMarkup replyMarkup, HashMap<String, String> params, boolean notify, int scheduleDate, MessageObject.SendAnimationData sendAnimationData, boolean updateStickersOrder) {
sendMessage(message, null, null, null, null, null, null, null, null, null, peer, null, replyToMsg, replyToTopMsg, webPage, searchLinks, null, entities, replyMarkup, params, notify, scheduleDate, 0, null, sendAnimationData, updateStickersOrder);
}
@ -3224,8 +3239,12 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
sendMessage(null, null, null, null, null, null, null, null, poll, null, peer, null, replyToMsg, replyToTopMsg, null, true, null, null, replyMarkup, params, notify, scheduleDate, 0, null, null, false);
}
public void sendMessage(TLRPC.TL_game game, long peer, TLRPC.ReplyMarkup replyMarkup, HashMap<String, String> params, boolean notify, int scheduleDate) {
sendMessage(null, null, null, null, null, null, null, game, null, null, peer, null, null, null, null, true, null, null, replyMarkup, params, notify, scheduleDate, 0, null, null, false);
public void sendMessage(TLRPC.TL_game game, long peer, MessageObject replyToMsg, MessageObject replyToTopMsg, TLRPC.ReplyMarkup replyMarkup, HashMap<String, String> params, boolean notify, int scheduleDate) {
sendMessage(null, null, null, null, null, null, null, game, null, null, peer, null, replyToMsg, replyToTopMsg, null, true, null, null, replyMarkup, params, notify, scheduleDate, 0, null, null, false);
}
public void sendMessage(TLRPC.TL_photo photo, String path, long peer, MessageObject replyToMsg, MessageObject replyToTopMsg, String caption, ArrayList<TLRPC.MessageEntity> entities, TLRPC.ReplyMarkup replyMarkup, HashMap<String, String> params, boolean notify, int scheduleDate, int ttl, Object parentObject, boolean updateStickersOrder, boolean hasMediaSpoilers) {
sendMessage(null, caption, null, photo, null, null, null, null, null, null, peer, path, replyToMsg, replyToTopMsg, null, true, null, entities, replyMarkup, params, notify, scheduleDate, ttl, parentObject, null, updateStickersOrder, hasMediaSpoilers);
}
public void sendMessage(TLRPC.TL_photo photo, String path, long peer, MessageObject replyToMsg, MessageObject replyToTopMsg, String caption, ArrayList<TLRPC.MessageEntity> entities, TLRPC.ReplyMarkup replyMarkup, HashMap<String, String> params, boolean notify, int scheduleDate, int ttl, Object parentObject, boolean updateStickersOrder) {
@ -3233,6 +3252,10 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
}
private void sendMessage(String message, String caption, TLRPC.MessageMedia location, TLRPC.TL_photo photo, VideoEditedInfo videoEditedInfo, TLRPC.User user, TLRPC.TL_document document, TLRPC.TL_game game, TLRPC.TL_messageMediaPoll poll, TLRPC.TL_messageMediaInvoice invoice, long peer, String path, MessageObject replyToMsg, MessageObject replyToTopMsg, TLRPC.WebPage webPage, boolean searchLinks, MessageObject retryMessageObject, ArrayList<TLRPC.MessageEntity> entities, TLRPC.ReplyMarkup replyMarkup, HashMap<String, String> params, boolean notify, int scheduleDate, int ttl, Object parentObject, MessageObject.SendAnimationData sendAnimationData, boolean updateStickersOreder) {
sendMessage(message, caption, location, photo, videoEditedInfo, user, document, game, poll, invoice, peer, path, replyToMsg, replyToTopMsg, webPage, searchLinks, retryMessageObject, entities, replyMarkup, params, notify, scheduleDate, ttl, parentObject, sendAnimationData, updateStickersOreder, false);
}
private void sendMessage(String message, String caption, TLRPC.MessageMedia location, TLRPC.TL_photo photo, VideoEditedInfo videoEditedInfo, TLRPC.User user, TLRPC.TL_document document, TLRPC.TL_game game, TLRPC.TL_messageMediaPoll poll, TLRPC.TL_messageMediaInvoice invoice, long peer, String path, MessageObject replyToMsg, MessageObject replyToTopMsg, TLRPC.WebPage webPage, boolean searchLinks, MessageObject retryMessageObject, ArrayList<TLRPC.MessageEntity> entities, TLRPC.ReplyMarkup replyMarkup, HashMap<String, String> params, boolean notify, int scheduleDate, int ttl, Object parentObject, MessageObject.SendAnimationData sendAnimationData, boolean updateStickersOreder, boolean hasMediaSpoilers) {
if (user != null && user.phone == null) {
return;
}
@ -3431,6 +3454,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
}
newMsg.media = new TLRPC.TL_messageMediaPhoto();
newMsg.media.flags |= 3;
newMsg.media.spoiler = hasMediaSpoilers;
if (entities != null) {
newMsg.entities = entities;
}
@ -3509,6 +3533,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
}
newMsg.media = new TLRPC.TL_messageMediaDocument();
newMsg.media.flags |= 3;
newMsg.media.spoiler = hasMediaSpoilers;
if (ttl != 0) {
newMsg.ttl = newMsg.media.ttl_seconds = ttl;
newMsg.media.flags |= 4;
@ -3642,7 +3667,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
}
newMsg.flags |= TLRPC.MESSAGE_FLAG_HAS_MEDIA;
newMsg.dialog_id = peer;
if (replyToMsg != null) {
if (replyToMsg != null && (replyToTopMsg == null || replyToMsg != replyToTopMsg || replyToTopMsg.getId() != 1)) {
newMsg.reply_to = new TLRPC.TL_messageReplyHeader();
if (encryptedChat != null && replyToMsg.messageOwner.random_id != 0) {
newMsg.reply_to.reply_to_random_id = replyToMsg.messageOwner.random_id;
@ -3651,7 +3676,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
newMsg.flags |= TLRPC.MESSAGE_FLAG_REPLY;
}
newMsg.reply_to.reply_to_msg_id = replyToMsg.getId();
if (replyToTopMsg != null && replyToTopMsg != replyToMsg) {
if (replyToTopMsg != null && replyToTopMsg != replyToMsg && replyToTopMsg.getId() != 1) {
newMsg.reply_to.reply_to_top_id = replyToTopMsg.getId();
newMsg.reply_to.flags |= 2;
if (replyToTopMsg.isTopicMainMessage) {
@ -3754,7 +3779,11 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
isFinalGroupMedia = params.get("final") != null;
}
newMsgObj = new MessageObject(currentAccount, newMsg, replyToMsg, true, true);
MessageObject reply = replyToMsg;
if (replyToTopMsg != null && replyToTopMsg == reply && replyToTopMsg.getId() == 1) {
reply = null;
}
newMsgObj = new MessageObject(currentAccount, newMsg, reply, true, true);
newMsgObj.sendAnimationData = sendAnimationData;
newMsgObj.wasJustSent = true;
newMsgObj.scheduled = scheduleDate != 0;
@ -3903,6 +3932,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
inputMedia.geo_point._long = location.geo._long;
} else if (type == 2 || type == 9 && photo != null) {
TLRPC.TL_inputMediaUploadedPhoto uploadedPhoto = new TLRPC.TL_inputMediaUploadedPhoto();
uploadedPhoto.spoiler = hasMediaSpoilers;
if (ttl != 0) {
newMsg.ttl = uploadedPhoto.ttl_seconds = ttl;
uploadedPhoto.flags |= 2;
@ -3931,6 +3961,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
if (media.id.file_reference == null) {
media.id.file_reference = new byte[0];
}
media.spoiler = hasMediaSpoilers;
inputMedia = media;
}
if (delayedMessage == null) {
@ -3952,6 +3983,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
TLRPC.TL_inputMediaUploadedDocument uploadedDocument = new TLRPC.TL_inputMediaUploadedDocument();
uploadedDocument.mime_type = document.mime_type;
uploadedDocument.attributes = document.attributes;
uploadedDocument.spoiler = hasMediaSpoilers;
if (forceNoSoundVideo || !MessageObject.isRoundVideoDocument(document) && (videoEditedInfo == null || !videoEditedInfo.muted && !videoEditedInfo.roundVideo)) {
uploadedDocument.nosound_video = true;
if (BuildVars.DEBUG_VERSION) {
@ -3990,6 +4022,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
media.query = params.get("query");
media.flags |= 2;
}
media.spoiler = hasMediaSpoilers;
inputMedia = media;
}
if (delayedMessage == null) {
@ -4025,6 +4058,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
TLRPC.InputMedia uploadedMedia;
if (originalPath != null || path != null || document.access_hash == 0) {
uploadedMedia = new TLRPC.TL_inputMediaUploadedDocument();
uploadedMedia.spoiler = hasMediaSpoilers;
if (ttl != 0) {
newMsg.ttl = uploadedMedia.ttl_seconds = ttl;
uploadedMedia.flags |= 2;
@ -4055,6 +4089,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
media.query = params.get("query");
media.flags |= 2;
}
media.spoiler = hasMediaSpoilers;
inputMedia = media;
}
if (!http && uploadedMedia != null) {
@ -4080,6 +4115,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
TLRPC.TL_inputMediaUploadedDocument uploadedDocument = new TLRPC.TL_inputMediaUploadedDocument();
uploadedDocument.mime_type = document.mime_type;
uploadedDocument.attributes = document.attributes;
uploadedDocument.spoiler = hasMediaSpoilers;
if (ttl != 0) {
newMsg.ttl = uploadedDocument.ttl_seconds = ttl;
uploadedDocument.flags |= 2;
@ -4101,6 +4137,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
media.query = params.get("query");
media.flags |= 2;
}
media.spoiler = hasMediaSpoilers;
inputMedia = media;
}
delayedMessage = new DelayedMessage(peer);
@ -4965,6 +5002,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
inputMediaPhoto.id.id = messageMedia.photo.id;
inputMediaPhoto.id.access_hash = messageMedia.photo.access_hash;
inputMediaPhoto.id.file_reference = messageMedia.photo.file_reference;
inputMediaPhoto.spoiler = inputMedia.spoiler;
newInputMedia = inputMediaPhoto;
if (BuildVars.DEBUG_VERSION) {
FileLog.d("set uploaded photo");
@ -4975,6 +5013,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
inputMediaDocument.id.id = messageMedia.document.id;
inputMediaDocument.id.access_hash = messageMedia.document.access_hash;
inputMediaDocument.id.file_reference = messageMedia.document.file_reference;
inputMediaDocument.spoiler = inputMedia.spoiler;
newInputMedia = inputMediaDocument;
if (BuildVars.DEBUG_VERSION) {
FileLog.d("set uploaded document");
@ -5783,7 +5822,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
}
if (sentMessage.media instanceof TLRPC.TL_messageMediaPhoto && sentMessage.media.photo != null && newMsg.media instanceof TLRPC.TL_messageMediaPhoto && newMsg.media.photo != null) {
if (sentMessage.media.ttl_seconds == 0 && !newMsgObj.scheduled) {
getMessagesStorage().putSentFile(originalPath, sentMessage.media.photo, 0, "sent_" + sentMessage.peer_id.channel_id + "_" + sentMessage.id + "_" + DialogObject.getPeerDialogId(sentMessage.peer_id));
getMessagesStorage().putSentFile(originalPath, sentMessage.media.photo, 0, "sent_" + sentMessage.peer_id.channel_id + "_" + sentMessage.id + "_" + DialogObject.getPeerDialogId(sentMessage.peer_id) + "_" + MessageObject.TYPE_PHOTO);
}
if (newMsg.media.photo.sizes.size() == 1 && newMsg.media.photo.sizes.get(0).location instanceof TLRPC.TL_fileLocationUnavailable) {
@ -5843,13 +5882,15 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
boolean isVideo = MessageObject.isVideoMessage(sentMessage);
if ((isVideo || MessageObject.isGifMessage(sentMessage)) && MessageObject.isGifDocument(sentMessage.media.document) == MessageObject.isGifDocument(newMsg.media.document)) {
if (!newMsgObj.scheduled) {
getMessagesStorage().putSentFile(originalPath, sentMessage.media.document, 2, "sent_" + sentMessage.peer_id.channel_id + "_" + sentMessage.id + "_" + DialogObject.getPeerDialogId(sentMessage.peer_id));
MessageObject messageObject = new MessageObject(currentAccount, sentMessage, false, false);
getMessagesStorage().putSentFile(originalPath, sentMessage.media.document, 2, "sent_" + sentMessage.peer_id.channel_id + "_" + sentMessage.id + "_" + DialogObject.getPeerDialogId(sentMessage.peer_id) + "_" + messageObject.type);
}
if (isVideo) {
sentMessage.attachPath = newMsg.attachPath;
}
} else if (!MessageObject.isVoiceMessage(sentMessage) && !MessageObject.isRoundVideoMessage(sentMessage) && !newMsgObj.scheduled) {
getMessagesStorage().putSentFile(originalPath, sentMessage.media.document, 1, "sent_" + sentMessage.peer_id.channel_id + "_" + sentMessage.id + "_" + DialogObject.getPeerDialogId(sentMessage.peer_id));
MessageObject messageObject = new MessageObject(currentAccount, sentMessage, false, false);
getMessagesStorage().putSentFile(originalPath, sentMessage.media.document, 1, "sent_" + sentMessage.peer_id.channel_id + "_" + sentMessage.id + "_" + DialogObject.getPeerDialogId(sentMessage.peer_id) + "_" + messageObject.type);
}
}
@ -5974,7 +6015,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
return delayedMessages.get(location);
}
protected long getNextRandomId() {
public long getNextRandomId() {
long val = 0;
while (val == 0) {
val = Utilities.random.nextLong();
@ -6477,7 +6518,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
AndroidUtilities.runOnUIThread(() -> {
if (editingMessageObject != null) {
accountInstance.getSendMessagesHelper().editMessage(editingMessageObject, null, null, documentFinal, pathFinal, params, false, parentFinal);
accountInstance.getSendMessagesHelper().editMessage(editingMessageObject, null, null, documentFinal, pathFinal, params, false, false, parentFinal);
} else {
accountInstance.getSendMessagesHelper().sendMessage(documentFinal, null, pathFinal, dialogId, replyToMsg, replyToTopMsg, captionFinal, entities, null, params, notify, scheduleDate, 0, parentFinal, null, false);
}
@ -6590,9 +6631,9 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
}
AndroidUtilities.runOnUIThread(() -> {
if (editingMessageObject != null) {
accountInstance.getSendMessagesHelper().editMessage(editingMessageObject, null, null, documentFinal, messageObject.messageOwner.attachPath, params, false, parentFinal);
accountInstance.getSendMessagesHelper().editMessage(editingMessageObject, null, null, documentFinal, messageObject.messageOwner.attachPath, params, false, false, parentFinal);
} else {
accountInstance.getSendMessagesHelper().sendMessage(documentFinal, null, messageObject.messageOwner.attachPath, dialogId, replyToMsg, replyToTopMsg, captionFinal, entities, null, params, notify, scheduleDate, 0, parentFinal, null, false);
accountInstance.getSendMessagesHelper().sendMessage(documentFinal, null, messageObject.messageOwner.attachPath, dialogId, replyToMsg, replyToTopMsg, captionFinal, entities, null, params, notify, scheduleDate, 0, parentFinal, null, false, false);
}
});
}
@ -6998,7 +7039,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
} else if (finalPhoto != null) {
accountInstance.getSendMessagesHelper().sendMessage(finalPhoto, result.content != null ? result.content.url : null, dialogId, replyToMsg, replyToTopMsg, result.send_message.message, result.send_message.entities, result.send_message.reply_markup, params, notify, scheduleDate, 0, result, false);
} else if (finalGame != null) {
accountInstance.getSendMessagesHelper().sendMessage(finalGame, dialogId, result.send_message.reply_markup, params, notify, scheduleDate);
accountInstance.getSendMessagesHelper().sendMessage(finalGame, dialogId, replyToMsg, replyToTopMsg, result.send_message.reply_markup, params, notify, scheduleDate);
}
});
}).run();
@ -7430,9 +7471,9 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
}
AndroidUtilities.runOnUIThread(() -> {
if (editingMessageObject != null) {
accountInstance.getSendMessagesHelper().editMessage(editingMessageObject, null, null, documentFinal, pathFinal, params, false, parentFinal);
accountInstance.getSendMessagesHelper().editMessage(editingMessageObject, null, null, documentFinal, pathFinal, params, false, info.hasMediaSpoilers, parentFinal);
} else {
accountInstance.getSendMessagesHelper().sendMessage(documentFinal, null, pathFinal, dialogId, replyToMsg, replyToTopMsg, info.caption, info.entities, null, params, notify, scheduleDate, 0, parentFinal, null, false);
accountInstance.getSendMessagesHelper().sendMessage(documentFinal, null, pathFinal, dialogId, replyToMsg, replyToTopMsg, info.caption, info.entities, null, params, notify, scheduleDate, 0, parentFinal, null, false, info.hasMediaSpoilers);
}
});
} else {
@ -7501,9 +7542,9 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
}
AndroidUtilities.runOnUIThread(() -> {
if (editingMessageObject != null) {
accountInstance.getSendMessagesHelper().editMessage(editingMessageObject, photoFinal, null, null, needDownloadHttpFinal ? info.searchImage.imageUrl : null, params, false, parentFinal);
accountInstance.getSendMessagesHelper().editMessage(editingMessageObject, photoFinal, null, null, needDownloadHttpFinal ? info.searchImage.imageUrl : null, params, false, info.hasMediaSpoilers, parentFinal);
} else {
accountInstance.getSendMessagesHelper().sendMessage(photoFinal, needDownloadHttpFinal ? info.searchImage.imageUrl : null, dialogId, replyToMsg, replyToTopMsg, info.caption, info.entities, null, params, notify, scheduleDate, info.ttl, parentFinal, false);
accountInstance.getSendMessagesHelper().sendMessage(photoFinal, needDownloadHttpFinal ? info.searchImage.imageUrl : null, dialogId, replyToMsg, replyToTopMsg, info.caption, info.entities, null, params, notify, scheduleDate, info.ttl, parentFinal, false, info.hasMediaSpoilers);
}
});
}
@ -7681,9 +7722,9 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
ImageLoader.getInstance().putImageToCache(new BitmapDrawable(thumbFinal), thumbKeyFinal, false);
}
if (editingMessageObject != null) {
accountInstance.getSendMessagesHelper().editMessage(editingMessageObject, null, videoEditedInfo, videoFinal, finalPath, params, false, parentFinal);
accountInstance.getSendMessagesHelper().editMessage(editingMessageObject, null, videoEditedInfo, videoFinal, finalPath, params, false, info.hasMediaSpoilers, parentFinal);
} else {
accountInstance.getSendMessagesHelper().sendMessage(videoFinal, videoEditedInfo, finalPath, dialogId, replyToMsg, replyToTopMsg, info.caption, info.entities, null, params, notify, scheduleDate, info.ttl, parentFinal, null, false);
accountInstance.getSendMessagesHelper().sendMessage(videoFinal, videoEditedInfo, finalPath, dialogId, replyToMsg, replyToTopMsg, info.caption, info.entities, null, params, notify, scheduleDate, info.ttl, parentFinal, null, false, info.hasMediaSpoilers);
}
});
} else {
@ -7878,9 +7919,9 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
ImageLoader.getInstance().putImageToCache(new BitmapDrawable(bitmapFinal[0]), keyFinal[0], false);
}
if (editingMessageObject != null) {
accountInstance.getSendMessagesHelper().editMessage(editingMessageObject, photoFinal, null, null, null, params, false, parentFinal);
accountInstance.getSendMessagesHelper().editMessage(editingMessageObject, photoFinal, null, null, null, params, false, info.hasMediaSpoilers, parentFinal);
} else {
accountInstance.getSendMessagesHelper().sendMessage(photoFinal, null, dialogId, replyToMsg, replyToTopMsg, info.caption, info.entities, null, params, notify, scheduleDate, info.ttl, parentFinal, updateStikcersOrder);
accountInstance.getSendMessagesHelper().sendMessage(photoFinal, null, dialogId, replyToMsg, replyToTopMsg, info.caption, info.entities, null, params, notify, scheduleDate, info.ttl, parentFinal, updateStikcersOrder, info.hasMediaSpoilers);
}
});
} else {
@ -8178,7 +8219,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
}
@UiThread
public static void prepareSendingVideo(AccountInstance accountInstance, String videoPath, VideoEditedInfo info, long dialogId, MessageObject replyToMsg, MessageObject replyToTopMsg, CharSequence caption, ArrayList<TLRPC.MessageEntity> entities, int ttl, MessageObject editingMessageObject, boolean notify, int scheduleDate, boolean forceDocument) {
public static void prepareSendingVideo(AccountInstance accountInstance, String videoPath, VideoEditedInfo info, long dialogId, MessageObject replyToMsg, MessageObject replyToTopMsg, CharSequence caption, ArrayList<TLRPC.MessageEntity> entities, int ttl, MessageObject editingMessageObject, boolean notify, int scheduleDate, boolean forceDocument, boolean hasMediaSpoilers) {
if (videoPath == null || videoPath.length() == 0) {
return;
}
@ -8323,9 +8364,9 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
ImageLoader.getInstance().putImageToCache(new BitmapDrawable(thumbFinal), thumbKeyFinal, false);
}
if (editingMessageObject != null) {
accountInstance.getSendMessagesHelper().editMessage(editingMessageObject, null, videoEditedInfo, videoFinal, finalPath, params, false, parentFinal);
accountInstance.getSendMessagesHelper().editMessage(editingMessageObject, null, videoEditedInfo, videoFinal, finalPath, params, false, hasMediaSpoilers, parentFinal);
} else {
accountInstance.getSendMessagesHelper().sendMessage(videoFinal, videoEditedInfo, finalPath, dialogId, replyToMsg, replyToTopMsg, captionFinal, entities, null, params, notify, scheduleDate, ttl, parentFinal, null, false);
accountInstance.getSendMessagesHelper().sendMessage(videoFinal, videoEditedInfo, finalPath, dialogId, replyToMsg, replyToTopMsg, captionFinal, entities, null, params, notify, scheduleDate, ttl, parentFinal, null, false, hasMediaSpoilers);
}
});
} else {

View file

@ -28,13 +28,17 @@ import org.json.JSONObject;
import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.SerializedData;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.Components.AnimatedEmojiDrawable;
import org.telegram.ui.Components.SwipeGestureSettingsView;
import java.io.File;
import java.io.RandomAccessFile;
import java.io.UnsupportedEncodingException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
@ -43,6 +47,17 @@ public class SharedConfig {
public final static int PASSCODE_TYPE_PIN = 0,
PASSCODE_TYPE_PASSWORD = 1;
public static LiteMode getLiteMode() {
if (liteMode == null) {
liteMode = new LiteMode();
}
return liteMode;
}
public static boolean loopStickers() {
return loopStickers && !getLiteMode().enabled;
}
@Retention(RetentionPolicy.SOURCE)
@IntDef({
PASSCODE_TYPE_PIN,
@ -85,7 +100,7 @@ public class SharedConfig {
public static int suggestStickers;
public static boolean suggestAnimatedEmoji;
public static boolean loopStickers;
public static int keepMedia = 2;
public static int keepMedia = CacheByChatsController.KEEP_MEDIA_ONE_MONTH; //deprecated
public static int lastKeepMediaCheckTime;
public static int lastLogsCheckTime;
public static int searchMessagesAsListHintShows;
@ -170,6 +185,7 @@ public class SharedConfig {
public static boolean dontAskManageStorage;
public static boolean isFloatingDebugActive;
public static LiteMode liteMode;
static {
loadConfig();
@ -208,6 +224,23 @@ public class SharedConfig {
secret = "";
}
}
public String getLink() {
StringBuilder url = new StringBuilder(!TextUtils.isEmpty(secret) ? "https://t.me/proxy?" : "https://t.me/socks?");
try {
url.append("server=").append(URLEncoder.encode(address, "UTF-8")).append("&").append("port=").append(port);
if (!TextUtils.isEmpty(username)) {
url.append("&user=").append(URLEncoder.encode(username, "UTF-8"));
}
if (!TextUtils.isEmpty(password)) {
url.append("&pass=").append(URLEncoder.encode(password, "UTF-8"));
}
if (!TextUtils.isEmpty(secret)) {
url.append("&secret=").append(URLEncoder.encode(secret, "UTF-8"));
}
} catch (UnsupportedEncodingException ignored) {}
return url.toString();
}
}
public static ArrayList<ProxyInfo> proxyList = new ArrayList<>();
@ -411,7 +444,7 @@ public class SharedConfig {
distanceSystemType = preferences.getInt("distanceSystemType", 0);
devicePerformanceClass = preferences.getInt("devicePerformanceClass", -1);
loopStickers = preferences.getBoolean("loopStickers", true);
keepMedia = preferences.getInt("keep_media", 2);
keepMedia = preferences.getInt("keep_media", CacheByChatsController.KEEP_MEDIA_ONE_MONTH);
noStatusBar = preferences.getBoolean("noStatusBar", true);
forceRtmpStream = preferences.getBoolean("forceRtmpStream", false);
debugWebView = preferences.getBoolean("debugWebView", false);
@ -733,34 +766,143 @@ public class SharedConfig {
public static void checkKeepMedia() {
int time = (int) (System.currentTimeMillis() / 1000);
if (Math.abs(time - lastKeepMediaCheckTime) < 60 * 60) {
if (!BuildVars.DEBUG_PRIVATE_VERSION && Math.abs(time - lastKeepMediaCheckTime) < 60 * 60) {
return;
}
lastKeepMediaCheckTime = time;
File cacheDir = FileLoader.checkDirectory(FileLoader.MEDIA_DIR_CACHE);
Utilities.cacheClearQueue.postRunnable(() -> {
if (keepMedia != 2) {
int days;
if (keepMedia == 0) {
days = 7;
} else if (keepMedia == 1) {
days = 30;
} else {
days = 3;
boolean hasExceptions = false;
ArrayList<CacheByChatsController> cacheByChatsControllers = new ArrayList<>();
for (int account = 0; account < UserConfig.MAX_ACCOUNT_COUNT; account++) {
if (UserConfig.getInstance(account).isClientActivated()) {
CacheByChatsController cacheByChatsController = UserConfig.getInstance(account).getMessagesController().getCacheByChatsController();
cacheByChatsControllers.add(cacheByChatsController);
if (cacheByChatsController.getKeepMediaExceptionsByDialogs().size() > 0) {
hasExceptions = true;
}
}
long currentTime = time - 60 * 60 * 24 * days;
}
int[] keepMediaByTypes = new int[3];
boolean allKeepMediaTypesForever = true;
long keepMediaMinSeconds = Long.MAX_VALUE;
for (int i = 0; i < 3; i++) {
keepMediaByTypes[i] = SharedConfig.getPreferences().getInt("keep_media_type_" + i, CacheByChatsController.getDefault(i));
if (keepMediaByTypes[i] != CacheByChatsController.KEEP_MEDIA_FOREVER) {
allKeepMediaTypesForever = false;
}
long days = CacheByChatsController.getDaysInSeconds(keepMediaByTypes[i]);
if (days < keepMediaMinSeconds) {
keepMediaMinSeconds = days;
}
}
if (hasExceptions) {
allKeepMediaTypesForever = false;
}
if (!allKeepMediaTypesForever) {
//long currentTime = time - 60 * 60 * 24 * days;
final SparseArray<File> paths = ImageLoader.getInstance().createMediaPaths();
for (int a = 0; a < paths.size(); a++) {
boolean isCacheDir = false;
if (paths.keyAt(a) == FileLoader.MEDIA_DIR_CACHE) {
continue;
isCacheDir = true;
}
File dir = paths.valueAt(a);
try {
Utilities.clearDir(paths.valueAt(a).getAbsolutePath(), 0, currentTime, false);
File[] files = dir.listFiles();
ArrayList<CacheByChatsController.KeepMediaFile> keepMediaFiles = new ArrayList<>();
for (int i = 0; i < files.length; i++) {
keepMediaFiles.add(new CacheByChatsController.KeepMediaFile(files[i]));
}
for (int i = 0; i < cacheByChatsControllers.size(); i++) {
cacheByChatsControllers.get(i).lookupFiles(keepMediaFiles);
}
for (int i = 0; i < keepMediaFiles.size(); i++) {
CacheByChatsController.KeepMediaFile file = keepMediaFiles.get(i);
if (file.keepMedia == CacheByChatsController.KEEP_MEDIA_FOREVER) {
continue;
}
long seconds;
boolean isException = false;
if (file.keepMedia >= 0) {
isException = true;
seconds = CacheByChatsController.getDaysInSeconds(file.keepMedia);
} else if (file.dialogType >= 0) {
seconds = CacheByChatsController.getDaysInSeconds(keepMediaByTypes[file.dialogType]);
} else if (isCacheDir) {
continue;
} else {
seconds = keepMediaMinSeconds;
}
if (seconds == Long.MAX_VALUE) {
continue;
}
long lastUsageTime = Utilities.getLastUsageFileTime(file.file.getAbsolutePath());
long timeLocal = time - seconds;
boolean needDelete = lastUsageTime < timeLocal;
if (needDelete) {
try {
file.file.delete();
} catch (Exception exception) {
FileLog.e(exception);
}
}
}
} catch (Throwable e) {
FileLog.e(e);
}
}
}
int maxCacheGb = SharedConfig.getPreferences().getInt("cache_limit", Integer.MAX_VALUE);
if (maxCacheGb != Integer.MAX_VALUE) {
long maxCacheSize;
if (maxCacheGb == 1) {
maxCacheSize = 1024L * 1024L * 300L;
} else {
maxCacheSize = maxCacheGb * 1024L * 1024L * 1000L;
}
final SparseArray<File> paths = ImageLoader.getInstance().createMediaPaths();
long totalSize = 0;
for (int a = 0; a < paths.size(); a++) {
totalSize += Utilities.getDirSize(paths.valueAt(a).getAbsolutePath(), 0, true);
}
if (totalSize > maxCacheSize) {
ArrayList<FileInfoInternal> allFiles = new ArrayList<>();
for (int a = 0; a < paths.size(); a++) {
File dir = paths.valueAt(a);
fillFilesRecursive(dir, allFiles);
}
Collections.sort(allFiles, (o1, o2) -> {
if (o2.lastUsageDate > o1.lastUsageDate) {
return -1;
} else if (o2.lastUsageDate < o1.lastUsageDate) {
return 1;
}
return 0;
});
for (int i = 0; i < allFiles.size(); i++) {
long size = allFiles.get(i).file.length();
totalSize -= size;
try {
allFiles.get(i).file.delete();
} catch (Exception e) {
}
if (totalSize < maxCacheSize) {
break;
}
}
}
}
//TODO now every day generating cache for reactions and cleared it after one day -\_(-_-)_/-
//need fix
File stickersPath = new File(cacheDir, "acache");
if (stickersPath.exists()) {
long currentTime = time - 60 * 60 * 24;
@ -770,13 +912,32 @@ public class SharedConfig {
FileLog.e(e);
}
}
SharedPreferences preferences = MessagesController.getGlobalMainSettings();
SharedPreferences.Editor editor = preferences.edit();
editor.putInt("lastKeepMediaCheckTime", lastKeepMediaCheckTime);
editor.commit();
MessagesController.getGlobalMainSettings().edit()
.putInt("lastKeepMediaCheckTime", lastKeepMediaCheckTime)
.apply();
});
}
private static void fillFilesRecursive(final File fromFolder, ArrayList<FileInfoInternal> fileInfoList) {
if (fromFolder == null) {
return;
}
File[] files = fromFolder.listFiles();
if (files == null) {
return;
}
for (final File fileEntry : files) {
if (fileEntry.isDirectory()) {
fillFilesRecursive(fileEntry, fileInfoList);
} else {
if (fileEntry.getName().equals(".nomedia")) {
continue;
}
fileInfoList.add(new FileInfoInternal(fileEntry));
}
}
}
public static void toggleDisableVoiceAudioEffects() {
disableVoiceAudioEffects = !disableVoiceAudioEffects;
SharedPreferences preferences = MessagesController.getGlobalMainSettings();
@ -1337,4 +1498,55 @@ public class SharedConfig {
}
return animationsEnabled;
}
public static SharedPreferences getPreferences() {
return ApplicationLoader.applicationContext.getSharedPreferences("userconfing", Context.MODE_PRIVATE);
}
private static class FileInfoInternal {
final File file;
final long lastUsageDate;
private FileInfoInternal(File file) {
this.file = file;
this.lastUsageDate = Utilities.getLastUsageFileTime(file.getAbsolutePath());
}
}
public static class LiteMode {
private boolean enabled;
LiteMode() {
loadPreference();
}
public boolean enabled() {
return enabled;
}
public void toggleMode() {
enabled = !enabled;
savePreference();
AnimatedEmojiDrawable.lightModeChanged();
}
private void loadPreference() {
int flags = MessagesController.getGlobalMainSettings().getInt("light_mode", getDevicePerformanceClass() == PERFORMANCE_CLASS_LOW ? 1 : 0) ;
enabled = (flags & 1) != 0;
}
public void savePreference() {
int flags = 0;
if (enabled) {
flags |= 1;
}
MessagesController.getGlobalMainSettings().edit().putInt("light_mode", flags).apply();
}
public boolean animatedEmojiEnabled() {
return !enabled;
}
}
}

View file

@ -41,6 +41,8 @@ import android.graphics.drawable.Drawable;
import android.os.Build;
import android.util.SparseArray;
import androidx.core.graphics.ColorUtils;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.DrawingInBackgroundThreadDrawable;
import org.xml.sax.Attributes;
@ -164,7 +166,7 @@ public class SvgHelper {
}
float scale = getScale((int) w, (int) h);
if (placeholderGradient[threadIndex] != null && gradientWidth > 0) {
if (placeholderGradient[threadIndex] != null && gradientWidth > 0 && !SharedConfig.getLiteMode().enabled()) {
if (drawInBackground) {
long dt = time - lastUpdateTime;
if (dt > 64) {
@ -324,6 +326,22 @@ public class SvgHelper {
currentColorKey = colorKey;
currentColor[index] = color;
gradientWidth = AndroidUtilities.displaySize.x * 2;
if (SharedConfig.getLiteMode().enabled()) {
int color2 = ColorUtils.setAlphaComponent(currentColor[index], 70);
if (drawInBackground) {
if (backgroundPaint == null) {
backgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
}
backgroundPaint.setShader(null);
backgroundPaint.setColor(color2);
} else {
for (Paint paint : paints.values()) {
paint.setShader(null);
paint.setColor(color2);
}
}
return;
}
float w = AndroidUtilities.dp(180) / gradientWidth;
color = Color.argb((int) (Color.alpha(color) / 2 * colorAlpha), Color.red(color), Color.green(color), Color.blue(color));
float centerX = (1.0f - w) / 2;
@ -452,7 +470,7 @@ public class SvgHelper {
}
}
public static SvgDrawable getDrawable(int resId, int color) {
public static SvgDrawable getDrawable(int resId, Integer color) {
try {
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();

View file

@ -65,6 +65,24 @@ public class UserObject {
return getPublicUsername(user, false);
}
public static boolean hasPublicUsername(TLRPC.User user, String username) {
if (user == null || username == null) {
return false;
}
if (username.equalsIgnoreCase(user.username)) {
return true;
}
if (user.usernames != null) {
for (int i = 0; i < user.usernames.size(); ++i) {
TLRPC.TL_username u = user.usernames.get(i);
if (u != null && u.active && username.equalsIgnoreCase(u.username)) {
return true;
}
}
}
return false;
}
public static String getFirstName(TLRPC.User user) {
return getFirstName(user, true);
}
@ -89,4 +107,8 @@ public class UserObject {
public static TLRPC.UserProfilePhoto getPhoto(TLRPC.User user) {
return hasPhoto(user) ? user.photo : null;
}
public static boolean hasFallbackPhoto(TLRPC.UserFull userInfo) {
return userInfo != null && userInfo.fallback_photo != null && !(userInfo.fallback_photo instanceof TLRPC.TL_photoEmpty);
}
}

View file

@ -73,6 +73,7 @@ public class Utilities {
public native static String readlink(String path);
public native static String readlinkFd(int fd);
public native static long getDirSize(String path, int docType, boolean subdirs);
public native static long getLastUsageFileTime(String path);
public native static void clearDir(String path, int docType, long time, boolean subdirs);
private native static int pbkdf2(byte[] password, byte[] salt, byte[] dst, int iterations);
public static native void stackBlurBitmap(Bitmap bitmap, int radius);
@ -80,6 +81,32 @@ public class Utilities {
public static native int saveProgressiveJpeg(Bitmap bitmap, int width, int height, int stride, int quality, String path);
public static native void generateGradient(Bitmap bitmap, boolean unpin, int phase, float progress, int width, int height, int stride, int[] colors);
public static Bitmap stackBlurBitmapMax(Bitmap bitmap) {
int w = AndroidUtilities.dp(20);
int h = (int) (AndroidUtilities.dp(20) * (float) bitmap.getHeight() / bitmap.getWidth());
Bitmap scaledBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(scaledBitmap);
canvas.save();
canvas.scale((float) scaledBitmap.getWidth() / bitmap.getWidth(), (float) scaledBitmap.getHeight() / bitmap.getHeight());
canvas.drawBitmap(bitmap, 0, 0, null);
canvas.restore();
Utilities.stackBlurBitmap(scaledBitmap, Math.max(10, Math.max(w, h) / 150));
return scaledBitmap;
}
public static Bitmap stackBlurBitmapWithScaleFactor(Bitmap bitmap, float scaleFactor) {
int w = (int) Math.max(AndroidUtilities.dp(20), bitmap.getWidth() / scaleFactor);
int h = (int) Math.max(AndroidUtilities.dp(20) * (float) bitmap.getHeight() / bitmap.getWidth(), bitmap.getHeight() / scaleFactor);
Bitmap scaledBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(scaledBitmap);
canvas.save();
canvas.scale((float) scaledBitmap.getWidth() / bitmap.getWidth(), (float) scaledBitmap.getHeight() / bitmap.getHeight());
canvas.drawBitmap(bitmap, 0, 0, null);
canvas.restore();
Utilities.stackBlurBitmap(scaledBitmap, Math.max(10, Math.max(w, h) / 150));
return scaledBitmap;
}
public static Bitmap blurWallpaper(Bitmap src) {
if (src == null) {
return null;
@ -466,10 +493,27 @@ public class Utilities {
return sb.toString();
}
public static String getExtension(String fileName) {
int idx = fileName.lastIndexOf('.');
String ext = null;
if (idx != -1) {
ext = fileName.substring(idx + 1);
}
if (ext == null) {
return null;
}
ext = ext.toUpperCase();
return ext;
}
public static interface Callback<T> {
public void run(T arg);
}
public static interface Callback2<T, T2> {
public void run(T arg, T2 arg2);
}
public static <Key, Value> Value getOrDefault(HashMap<Key, Value> map, Key key, Value defaultValue) {
Value v = map.get(key);
if (v == null) {

View file

@ -9,11 +9,16 @@
package org.telegram.messenger;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import org.telegram.tgnet.AbstractSerializedData;
import org.telegram.tgnet.SerializedData;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.Components.AnimatedFileDrawable;
import org.telegram.ui.Components.Paint.PaintTypeface;
import org.telegram.ui.Components.PhotoFilterView;
import org.telegram.ui.Components.Point;
@ -57,6 +62,32 @@ public class VideoEditedInfo {
public boolean needUpdateProgress = false;
public boolean shouldLimitFps = true;
public static class EmojiEntity extends TLRPC.TL_messageEntityCustomEmoji {
public String documentAbsolutePath;
@Override
public void readParams(AbstractSerializedData stream, boolean exception) {
super.readParams(stream, exception);
boolean hasPath = stream.readBool(exception);
if (hasPath) {
documentAbsolutePath = stream.readString(exception);
}
if (TextUtils.isEmpty(documentAbsolutePath)) {
documentAbsolutePath = null;
}
}
@Override
public void serializeToStream(AbstractSerializedData stream) {
super.serializeToStream(stream);
stream.writeBool(!TextUtils.isEmpty(documentAbsolutePath));
if (!TextUtils.isEmpty(documentAbsolutePath)) {
stream.writeString(documentAbsolutePath);
}
}
}
public static class MediaEntity {
public byte type;
public byte subType;
@ -66,8 +97,11 @@ public class VideoEditedInfo {
public float width;
public float height;
public String text;
public ArrayList<EmojiEntity> entities = new ArrayList<>();
public int color;
public int fontSize;
public PaintTypeface textTypeface;
public int textAlign;
public int viewWidth;
public int viewHeight;
@ -87,6 +121,7 @@ public class VideoEditedInfo {
public Bitmap bitmap;
public View view;
public Canvas canvas;
public AnimatedFileDrawable animatedFileDrawable;
public MediaEntity() {
@ -102,10 +137,18 @@ public class VideoEditedInfo {
width = data.readFloat(false);
height = data.readFloat(false);
text = data.readString(false);
int count = data.readInt32(false);
for (int i = 0; i < count; ++i) {
EmojiEntity entity = new EmojiEntity();
data.readInt32(false);
entity.readParams(data, false);
entities.add(entity);
}
color = data.readInt32(false);
fontSize = data.readInt32(false);
viewWidth = data.readInt32(false);
viewHeight = data.readInt32(false);
textAlign = data.readInt32(false);
}
private void serializeTo(SerializedData data) {
@ -117,10 +160,15 @@ public class VideoEditedInfo {
data.writeFloat(width);
data.writeFloat(height);
data.writeString(text);
data.writeInt32(entities.size());
for (int i = 0; i < entities.size(); ++i) {
entities.get(i).serializeToStream(data);
}
data.writeInt32(color);
data.writeInt32(fontSize);
data.writeInt32(viewWidth);
data.writeInt32(viewHeight);
data.writeInt32(textAlign);
}
public MediaEntity copy() {
@ -133,6 +181,7 @@ public class VideoEditedInfo {
entity.width = width;
entity.height = height;
entity.text = text;
entity.entities.addAll(entities);
entity.color = color;
entity.fontSize = fontSize;
entity.viewWidth = viewWidth;
@ -142,6 +191,7 @@ public class VideoEditedInfo {
entity.textViewHeight = textViewHeight;
entity.textViewX = textViewX;
entity.textViewY = textViewY;
entity.textAlign = textAlign;
return entity;
}
}

View file

@ -213,7 +213,33 @@ public class Browser {
);
}
public static class Progress {
public void init() {}
public void end() {
end(false);
}
public void end(boolean replaced) {}
private Runnable onCancelListener;
public void cancel() {
cancel(false);
}
public void cancel(boolean replaced) {
if (onCancelListener != null) {
onCancelListener.run();
}
end(replaced);
}
public void onCancel(Runnable onCancelListener) {
this.onCancelListener = onCancelListener;
}
}
public static void openUrl(final Context context, Uri uri, final boolean allowCustom, boolean tryTelegraph) {
openUrl(context, uri, allowCustom, tryTelegraph, null);
}
public static void openUrl(final Context context, Uri uri, final boolean allowCustom, boolean tryTelegraph, Progress inCaseLoading) {
if (context == null || uri == null) {
return;
}
@ -224,18 +250,22 @@ public class Browser {
try {
String host = uri.getHost().toLowerCase();
if (isTelegraphUrl(host, true) || uri.toString().toLowerCase().contains("telegram.org/faq") || uri.toString().toLowerCase().contains("telegram.org/privacy")) {
final AlertDialog[] progressDialog = new AlertDialog[]{new AlertDialog(context, 3)};
final AlertDialog[] progressDialog = new AlertDialog[] {
new AlertDialog(context, AlertDialog.ALERT_TYPE_SPINNER)
};
Uri finalUri = uri;
TLRPC.TL_messages_getWebPagePreview req = new TLRPC.TL_messages_getWebPagePreview();
req.message = uri.toString();
final int reqId = ConnectionsManager.getInstance(UserConfig.selectedAccount).sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> {
try {
progressDialog[0].dismiss();
} catch (Throwable ignore) {
if (inCaseLoading != null) {
inCaseLoading.end();
} else {
try {
progressDialog[0].dismiss();
} catch (Throwable ignore) {}
progressDialog[0] = null;
}
progressDialog[0] = null;
boolean ok = false;
if (response instanceof TLRPC.TL_messageMediaWebPage) {
@ -249,17 +279,19 @@ public class Browser {
openUrl(context, finalUri, allowCustom, false);
}
}));
AndroidUtilities.runOnUIThread(() -> {
if (progressDialog[0] == null) {
return;
}
try {
progressDialog[0].setOnCancelListener(dialog -> ConnectionsManager.getInstance(UserConfig.selectedAccount).cancelRequest(reqId, true));
progressDialog[0].show();
} catch (Exception ignore) {
}
}, 1000);
if (inCaseLoading != null) {
inCaseLoading.init();
} else {
AndroidUtilities.runOnUIThread(() -> {
if (progressDialog[0] == null) {
return;
}
try {
progressDialog[0].setOnCancelListener(dialog -> ConnectionsManager.getInstance(UserConfig.selectedAccount).cancelRequest(reqId, true));
progressDialog[0].show();
} catch (Exception ignore) {}
}, 1000);
}
return;
}
} catch (Exception ignore) {
@ -372,7 +404,7 @@ public class Browser {
intent.putExtra(android.provider.Browser.EXTRA_CREATE_NEW_TAB, true);
intent.putExtra(android.provider.Browser.EXTRA_APPLICATION_ID, context.getPackageName());
if (internalUri && context instanceof LaunchActivity) {
((LaunchActivity) context).onNewIntent(intent);
((LaunchActivity) context).onNewIntent(intent, inCaseLoading);
} else {
context.startActivity(intent);
}

View file

@ -471,6 +471,7 @@ public class BitmapsCache {
}
options.inBitmap = bitmap;
BitmapFactory.decodeByteArray(bufferTmp, 0, selectedFrame.frameSize, options);
options.inBitmap = null;
return FRAME_RESULT_OK;
} catch (FileNotFoundException e) {

View file

@ -0,0 +1,148 @@
package org.telegram.messenger.utils;
import android.os.Bundle;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.FileLoader;
import org.telegram.messenger.ImageLoader;
import org.telegram.messenger.ImageLocation;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MediaController;
import org.telegram.messenger.MessagesController;
import org.telegram.messenger.R;
import org.telegram.messenger.UserConfig;
import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.ActionBar.INavigationLayout;
import org.telegram.ui.Components.BulletinFactory;
import org.telegram.ui.Components.ImageUpdater;
import org.telegram.ui.ProfileActivity;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
public class PhotoUtilities {
public static void applyPhotoToUser(TLRPC.Photo photo, TLRPC.User user, boolean personal) {
ArrayList<TLRPC.PhotoSize> sizes = photo.sizes;
TLRPC.PhotoSize smallSize2 = FileLoader.getClosestPhotoSizeWithSize(sizes, 100);
TLRPC.PhotoSize bigSize2 = FileLoader.getClosestPhotoSizeWithSize(sizes, 1000);
user.flags |= 32;
user.photo = new TLRPC.TL_userProfilePhoto();
user.photo.personal = personal;
user.photo.photo_id = photo.id;
user.photo.has_video = photo.video_sizes != null && photo.video_sizes.size() > 0;
if (smallSize2 != null) {
user.photo.photo_small = smallSize2.location;
}
if (bigSize2 != null) {
user.photo.photo_big = bigSize2.location;
}
}
public static void setImageAsAvatar(MediaController.PhotoEntry entry, BaseFragment baseFragment, Runnable onDone) {
INavigationLayout layout = baseFragment.getParentLayout();
int currentAccount = baseFragment.getCurrentAccount();
ImageUpdater imageUpdater = new ImageUpdater(true);
imageUpdater.parentFragment = baseFragment;
imageUpdater.processEntry(entry);
imageUpdater.setDelegate((photo, video, videoStartTimestamp, videoPath, bigSize, smallSize, isVideo) -> AndroidUtilities.runOnUIThread(() -> {
TLRPC.TL_photos_uploadProfilePhoto req = new TLRPC.TL_photos_uploadProfilePhoto();
if (photo != null) {
req.file = photo;
req.flags |= 1;
}
if (video != null) {
req.video = video;
req.flags |= 2;
req.video_start_ts = videoStartTimestamp;
req.flags |= 4;
}
ConnectionsManager.getInstance(currentAccount).sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> {
if (response instanceof TLRPC.TL_photos_photo) {
TLRPC.TL_photos_photo photos_photo = (TLRPC.TL_photos_photo) response;
MessagesController.getInstance(currentAccount).putUsers(photos_photo.users, false);
TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(UserConfig.getInstance(currentAccount).clientUserId);
if (photos_photo.photo instanceof TLRPC.TL_photo) {
if (user != null) {
TLRPC.PhotoSize smallSize2 = FileLoader.getClosestPhotoSizeWithSize(photos_photo.photo.sizes, 100);
TLRPC.PhotoSize bigSize2 = FileLoader.getClosestPhotoSizeWithSize(photos_photo.photo.sizes, 1000);
if (smallSize2 != null && smallSize != null && smallSize.location != null) {
File destFile = FileLoader.getInstance(currentAccount).getPathToAttach(smallSize2, true);
File src = FileLoader.getInstance(currentAccount).getPathToAttach(smallSize.location, true);
src.renameTo(destFile);
String oldKey = smallSize.location.volume_id + "_" + smallSize.location.local_id + "@50_50";
String newKey = smallSize2.location.volume_id + "_" + smallSize2.location.local_id + "@50_50";
ImageLoader.getInstance().replaceImageInCache(oldKey, newKey, ImageLocation.getForUser(user, ImageLocation.TYPE_SMALL), false);
}
if (bigSize2 != null && smallSize != null && smallSize.location != null) {
File destFile = FileLoader.getInstance(currentAccount).getPathToAttach(bigSize2, true);
File src = FileLoader.getInstance(currentAccount).getPathToAttach(smallSize.location, true);
src.renameTo(destFile);
}
PhotoUtilities.applyPhotoToUser(photos_photo.photo, user, false);
UserConfig.getInstance(currentAccount).setCurrentUser(user);
UserConfig.getInstance(currentAccount).saveConfig(true);
if (onDone != null) {
onDone.run();
}
CharSequence title = AndroidUtilities.replaceTags(LocaleController.getString("ApplyAvatarHint", R.string.ApplyAvatarHintTitle));
CharSequence subtitle = AndroidUtilities.replaceSingleTag(LocaleController.getString("ApplyAvatarHint", R.string.ApplyAvatarHint), () -> {
Bundle args = new Bundle();
args.putLong("user_id", UserConfig.getInstance(currentAccount).clientUserId);
layout.getLastFragment().presentFragment(new ProfileActivity(args));
});
BulletinFactory.of(layout.getLastFragment()).createUsersBulletin(Collections.singletonList(user), title, subtitle).show();
}
}
}
}));
imageUpdater.onPause();
}));
}
public static void replacePhotoImagesInCache(int currentAccount, TLRPC.Photo photo, TLRPC.Photo photoToReplace) {
TLRPC.PhotoSize smallSize = FileLoader.getClosestPhotoSizeWithSize(photo.sizes, 100);
TLRPC.PhotoSize bigSize = FileLoader.getClosestPhotoSizeWithSize(photo.sizes, 1000);
TLRPC.PhotoSize smallSize2 = FileLoader.getClosestPhotoSizeWithSize(photoToReplace.sizes, 100);
TLRPC.PhotoSize bigSize2 = FileLoader.getClosestPhotoSizeWithSize(photoToReplace.sizes, 1000);
if (smallSize2 != null && smallSize != null) {
File destFile = FileLoader.getInstance(currentAccount).getPathToAttach(smallSize2, true);
File src = FileLoader.getInstance(currentAccount).getPathToAttach(smallSize, true);
src.renameTo(destFile);
String oldKey = smallSize.location.volume_id + "_" + smallSize.location.local_id + "@50_50";
String newKey = smallSize2.location.volume_id + "_" + smallSize2.location.local_id + "@50_50";
ImageLoader.getInstance().replaceImageInCache(oldKey, newKey, ImageLocation.getForPhoto(smallSize, photo), false);
}
if (bigSize2 != null && bigSize != null) {
File destFile = FileLoader.getInstance(currentAccount).getPathToAttach(bigSize2, true);
File src = FileLoader.getInstance(currentAccount).getPathToAttach(bigSize, true);
src.renameTo(destFile);
String oldKey = bigSize.location.volume_id + "_" + bigSize.location.local_id + "@150_150";
String newKey = bigSize2.location.volume_id + "_" + bigSize2.location.local_id + "@150_150";
ImageLoader.getInstance().replaceImageInCache(oldKey, newKey, ImageLocation.getForPhoto(bigSize, photo), false);
}
}
public static void applyPhotoToUser(TLRPC.PhotoSize smallSize, TLRPC.PhotoSize bigSize, boolean hasVideo, TLRPC.User user, boolean personal) {
user.flags |= 32;
user.photo = new TLRPC.TL_userProfilePhoto();
user.photo.personal = personal;
user.photo.photo_id = 0;
user.photo.has_video = hasVideo;
if (smallSize != null) {
user.photo.photo_small = smallSize.location;
}
if (bigSize != null) {
user.photo.photo_big = bigSize.location;
}
}
}

View file

@ -3,12 +3,14 @@ package org.telegram.messenger.video;
import android.annotation.TargetApi;
import android.media.MediaCodec;
import android.media.MediaCodecInfo;
import android.media.MediaCodecList;
import android.media.MediaExtractor;
import android.media.MediaFormat;
import android.os.Build;
import com.google.android.exoplayer2.util.Log;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.BuildVars;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.MediaController;
@ -341,7 +343,7 @@ public class MediaCodecVideoConvertor {
extractor.selectTrack(videoIndex);
MediaFormat videoFormat = extractor.getTrackFormat(videoIndex);
String encoderName = null;
if (avatarStartTime >= 0) {
if (durationS <= 2000) {
bitrate = 2600000;
@ -351,6 +353,8 @@ public class MediaCodecVideoConvertor {
bitrate = 1560000;
}
avatarStartTime = 0;
//this encoder work with bitrate better, prevent case when result video max 2MB
encoderName = "OMX.google.h264.encoder";
} else if (bitrate <= 0) {
bitrate = 921600;
}
@ -386,7 +390,7 @@ public class MediaCodecVideoConvertor {
h = resultHeight;
}
if (BuildVars.LOGS_ENABLED) {
FileLog.d("create encoder with w = " + w + " h = " + h);
FileLog.d("create encoder with w = " + w + " h = " + h + " bitrate = " + bitrate);
}
MediaFormat outputFormat = MediaFormat.createVideoFormat(MediaController.VIDEO_MIME_TYPE, w, h);
outputFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
@ -401,7 +405,16 @@ public class MediaCodecVideoConvertor {
outputFormat.setInteger(MediaFormat.KEY_BIT_RATE, bitrate);
}
encoder = MediaCodec.createEncoderByType(MediaController.VIDEO_MIME_TYPE);
if (encoderName != null) {
try {
encoder = MediaCodec.createByCodecName(encoderName);
} catch (Exception e) {
}
}
if (encoder == null) {
encoder = MediaCodec.createEncoderByType(MediaController.VIDEO_MIME_TYPE);
}
encoder.configure(outputFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
inputSurface = new InputSurface(encoder.createInputSurface());
inputSurface.makeCurrent();

View file

@ -22,6 +22,9 @@ import android.opengl.GLUtils;
import android.opengl.Matrix;
import android.os.Build;
import android.text.Layout;
import android.text.SpannableString;
import android.text.Spanned;
import android.util.Log;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
@ -34,14 +37,20 @@ import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.Bitmaps;
import org.telegram.messenger.BuildVars;
import org.telegram.messenger.Emoji;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MediaController;
import org.telegram.messenger.UserConfig;
import org.telegram.messenger.Utilities;
import org.telegram.messenger.VideoEditedInfo;
import org.telegram.ui.Components.AnimatedEmojiDrawable;
import org.telegram.ui.Components.AnimatedEmojiSpan;
import org.telegram.ui.Components.AnimatedFileDrawable;
import org.telegram.ui.Components.EditTextEffects;
import org.telegram.ui.Components.FilterShaders;
import org.telegram.ui.Components.Paint.Views.EditTextOutline;
import org.telegram.ui.Components.Paint.Views.PaintTextOptionsView;
import org.telegram.ui.Components.RLottieDrawable;
import java.io.File;
@ -72,6 +81,7 @@ public class TextureRenderer {
private String paintPath;
private String imagePath;
private ArrayList<VideoEditedInfo.MediaEntity> mediaEntities;
private ArrayList<AnimatedEmojiDrawable> emojiDrawables;
private int originalWidth;
private int originalHeight;
private int transformedWidth;
@ -420,6 +430,17 @@ public class TextureRenderer {
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, stickerBitmap, 0);
drawTexture(false, stickerTexture[0], entity.x, entity.y, entity.width, entity.height, entity.rotation, (entity.subType & 2) != 0);
}
} else if (entity.view != null && entity.canvas != null && entity.bitmap != null) {
entity.bitmap.eraseColor(Color.TRANSPARENT);
int lastFrame = (int) entity.currentFrame;
entity.currentFrame += entity.framesPerDraw;
int currentFrame = (int) entity.currentFrame;
EditTextEffects editTextEffects = (EditTextEffects) entity.view;
editTextEffects.incrementFrames(currentFrame - lastFrame);
entity.view.draw(entity.canvas);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, stickerTexture[0]);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, entity.bitmap, 0);
drawTexture(false, stickerTexture[0], entity.x, entity.y, entity.width, entity.height, entity.rotation, (entity.subType & 2) != 0);
} else {
if (entity.bitmap != null) {
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, stickerTexture[0]);
@ -664,14 +685,69 @@ public class TextureRenderer {
}
}
} else if (entity.type == 1) {
EditTextOutline editText = new EditTextOutline(ApplicationLoader.applicationContext);
EditTextOutline editText = new EditTextOutline(ApplicationLoader.applicationContext) {
{
animatedEmojiOffsetX = AndroidUtilities.dp(8);
animatedEmojiRawDraw = true;
animatedEmojiRawDrawFps = (int) videoFps;
}
};
editText.setBackgroundColor(Color.TRANSPARENT);
editText.setPadding(AndroidUtilities.dp(7), AndroidUtilities.dp(7), AndroidUtilities.dp(7), AndroidUtilities.dp(7));
Typeface typeface;
if (entity.textTypeface != null && (typeface = entity.textTypeface.getTypeface()) != null) {
editText.setTypeface(typeface);
}
editText.setTextSize(TypedValue.COMPLEX_UNIT_PX, entity.fontSize);
editText.setText(entity.text);
SpannableString text = new SpannableString(entity.text);
boolean containsAnimated = false;
for (VideoEditedInfo.EmojiEntity e : entity.entities) {
containsAnimated = true;
AnimatedEmojiSpan span;
if (e.document != null) {
span = new AnimatedEmojiSpan(e.document, editText.getPaint().getFontMetricsInt());
} else {
span = new AnimatedEmojiSpan(e.document_id, editText.getPaint().getFontMetricsInt());
}
span.cacheType = AnimatedEmojiDrawable.CACHE_TYPE_RENDERING_VIDEO;
span.documentAbsolutePath = e.documentAbsolutePath;
text.setSpan(span, e.offset, e.offset + e.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
editText.setText(Emoji.replaceEmoji(text, editText.getPaint().getFontMetricsInt(), (int) (editText.getTextSize() * .8f), false));
editText.setTextColor(entity.color);
editText.setTypeface(null, Typeface.BOLD);
editText.setGravity(Gravity.CENTER);
int gravity;
switch (entity.textAlign) {
default:
case PaintTextOptionsView.ALIGN_LEFT:
gravity = Gravity.LEFT | Gravity.CENTER_VERTICAL;
break;
case PaintTextOptionsView.ALIGN_CENTER:
gravity = Gravity.CENTER;
break;
case PaintTextOptionsView.ALIGN_RIGHT:
gravity = Gravity.RIGHT | Gravity.CENTER_VERTICAL;
break;
}
editText.setGravity(gravity);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
int textAlign;
switch (entity.textAlign) {
default:
case PaintTextOptionsView.ALIGN_LEFT:
textAlign = LocaleController.isRTL ? View.TEXT_ALIGNMENT_TEXT_END : View.TEXT_ALIGNMENT_TEXT_START;
break;
case PaintTextOptionsView.ALIGN_CENTER:
textAlign = View.TEXT_ALIGNMENT_CENTER;
break;
case PaintTextOptionsView.ALIGN_RIGHT:
textAlign = LocaleController.isRTL ? View.TEXT_ALIGNMENT_TEXT_START : View.TEXT_ALIGNMENT_TEXT_END;
break;
}
editText.setTextAlignment(textAlign);
}
editText.setHorizontallyScrolling(false);
editText.setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI);
editText.setFocusableInTouchMode(true);
@ -701,6 +777,12 @@ public class TextureRenderer {
entity.bitmap = Bitmap.createBitmap(entity.viewWidth, entity.viewHeight, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(entity.bitmap);
editText.draw(canvas);
if (containsAnimated) {
entity.view = editText;
entity.canvas = canvas;
entity.framesPerDraw = videoFps / 30f;
entity.currentFrame = 0;
}
}
}
} catch (Throwable e) {
@ -744,6 +826,9 @@ public class TextureRenderer {
if (entity.animatedFileDrawable != null) {
entity.animatedFileDrawable.recycle();
}
if (entity.view instanceof EditTextEffects) {
((EditTextEffects) entity.view).recycleEmojis();
}
}
}
}

View file

@ -68,7 +68,7 @@ public class TLRPC {
public static final int MESSAGE_FLAG_HAS_BOT_ID = 0x00000800;
public static final int MESSAGE_FLAG_EDITED = 0x00008000;
public static final int LAYER = 150;
public static final int LAYER = 151;
public static class TL_stats_megagroupStats extends TLObject {
public static int constructor = 0xef7ff916;
@ -8054,6 +8054,7 @@ public class TLRPC {
public void readParams(AbstractSerializedData stream, boolean exception) {
flags = stream.readInt32(exception);
nopremium = (flags & 8) != 0;
spoiler = (flags & 16) != 0;
if ((flags & 1) != 0) {
document = Document.TLdeserialize(stream, stream.readInt32(exception), exception);
} else {
@ -8067,6 +8068,7 @@ public class TLRPC {
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
flags = nopremium ? (flags | 8) : (flags &~ 8);
flags = spoiler ? (flags | 16) : (flags &~ 16);
flags = document != null ? (flags | 1) : (flags &~ 1);
stream.writeInt32(flags);
if ((flags & 1) != 0) {
@ -8147,6 +8149,7 @@ public class TLRPC {
public void readParams(AbstractSerializedData stream, boolean exception) {
flags = stream.readInt32(exception);
spoiler = (flags & 8) != 0;
if ((flags & 1) != 0) {
photo = Photo.TLdeserialize(stream, stream.readInt32(exception), exception);
} else {
@ -8159,6 +8162,7 @@ public class TLRPC {
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
flags = spoiler ? (flags | 8) : (flags &~ 8);
stream.writeInt32(flags);
if ((flags & 1) != 0) {
photo.serializeToStream(stream);
@ -12084,6 +12088,7 @@ public class TLRPC {
public int flags2;
public boolean can_delete_channel;
public boolean antispam;
public boolean participants_hidden;
public ChatReactions available_reactions;
public long inviterId; //custom
@ -14558,6 +14563,7 @@ public class TLRPC {
flags2 = stream.readInt32(exception);
can_delete_channel = (flags2 & 1) != 0;
antispam = (flags2 & 2) != 0;
participants_hidden = (flags2 & 4) != 0;
id = stream.readInt64(exception);
about = stream.readString(exception);
if ((flags & 1) != 0) {
@ -14694,6 +14700,7 @@ public class TLRPC {
stream.writeInt32(flags);
flags2 = can_delete_channel ? (flags2 | 1) : (flags2 &~ 1);
flags2 = antispam ? (flags2 | 2) : (flags2 &~ 2);
flags2 = participants_hidden ? (flags2 | 4) : (flags2 &~ 4);
stream.writeInt32(flags2);
stream.writeInt64(id);
stream.writeString(about);
@ -24095,6 +24102,12 @@ public class TLRPC {
case 0x98e0d697:
result = new TL_messageActionGeoProximityReached();
break;
case 0x57de635e:
result = new TL_messageActionSuggestProfilePhoto();
break;
case 0xe7e75f97:
result = new TL_messageActionAttachMenuBotAllowed();
break;
case 0x95e3fbef:
result = new TL_messageActionChatDeletePhoto();
break;
@ -29247,6 +29260,7 @@ public class TLRPC {
public String mime_type;
public ArrayList<DocumentAttribute> attributes = new ArrayList<>();
public int proximity_notification_radius;
public boolean spoiler;
public static InputMedia TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
InputMedia result = null;
@ -29331,6 +29345,7 @@ public class TLRPC {
public void readParams(AbstractSerializedData stream, boolean exception) {
flags = stream.readInt32(exception);
spoiler = (flags & 4) != 0;
id = InputDocument.TLdeserialize(stream, stream.readInt32(exception), exception);
if ((flags & 1) != 0) {
ttl_seconds = stream.readInt32(exception);
@ -29342,6 +29357,7 @@ public class TLRPC {
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
flags = spoiler ? (flags | 4) : (flags &~ 4);
stream.writeInt32(flags);
id.serializeToStream(stream);
if ((flags & 1) != 0) {
@ -29404,6 +29420,7 @@ public class TLRPC {
public void readParams(AbstractSerializedData stream, boolean exception) {
flags = stream.readInt32(exception);
spoiler = (flags & 2) != 0;
url = stream.readString(exception);
if ((flags & 1) != 0) {
ttl_seconds = stream.readInt32(exception);
@ -29412,6 +29429,7 @@ public class TLRPC {
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
flags = spoiler ? (flags | 2) : (flags &~ 2);
stream.writeInt32(flags);
stream.writeString(url);
if ((flags & 1) != 0) {
@ -29507,6 +29525,7 @@ public class TLRPC {
public void readParams(AbstractSerializedData stream, boolean exception) {
flags = stream.readInt32(exception);
spoiler = (flags & 4) != 0;
file = InputFile.TLdeserialize(stream, stream.readInt32(exception), exception);
if ((flags & 1) != 0) {
int magic = stream.readInt32(exception);
@ -29532,6 +29551,7 @@ public class TLRPC {
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
flags = spoiler ? (flags | 4) : (flags &~ 4);
stream.writeInt32(flags);
file.serializeToStream(stream);
if ((flags & 1) != 0) {
@ -29616,6 +29636,7 @@ public class TLRPC {
flags = stream.readInt32(exception);
nosound_video = (flags & 8) != 0;
force_file = (flags & 16) != 0;
spoiler = (flags & 32) != 0;
file = InputFile.TLdeserialize(stream, stream.readInt32(exception), exception);
if ((flags & 4) != 0) {
thumb = InputFile.TLdeserialize(stream, stream.readInt32(exception), exception);
@ -29662,6 +29683,7 @@ public class TLRPC {
stream.writeInt32(constructor);
flags = nosound_video ? (flags | 8) : (flags &~ 8);
flags = force_file ? (flags | 16) : (flags &~ 16);
flags = spoiler ? (flags | 32) : (flags &~ 32);
stream.writeInt32(flags);
file.serializeToStream(stream);
if ((flags & 4) != 0) {
@ -29695,6 +29717,7 @@ public class TLRPC {
public void readParams(AbstractSerializedData stream, boolean exception) {
flags = stream.readInt32(exception);
spoiler = (flags & 2) != 0;
url = stream.readString(exception);
if ((flags & 1) != 0) {
ttl_seconds = stream.readInt32(exception);
@ -29703,6 +29726,7 @@ public class TLRPC {
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
flags = spoiler ? (flags | 2) : (flags &~ 2);
stream.writeInt32(flags);
stream.writeString(url);
if ((flags & 1) != 0) {
@ -29718,6 +29742,7 @@ public class TLRPC {
public void readParams(AbstractSerializedData stream, boolean exception) {
flags = stream.readInt32(exception);
spoiler = (flags & 2) != 0;
id = InputPhoto.TLdeserialize(stream, stream.readInt32(exception), exception);
if ((flags & 1) != 0) {
ttl_seconds = stream.readInt32(exception);
@ -29726,6 +29751,7 @@ public class TLRPC {
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
flags = spoiler ? (flags | 2) : (flags &~ 2);
stream.writeInt32(flags);
id.serializeToStream(stream);
if ((flags & 1) != 0) {
@ -29751,6 +29777,9 @@ public class TLRPC {
case 0x40d13c0e:
result = new TL_stickerSetFullCovered();
break;
case 0x77b15d1c:
result = new TL_stickerSetNoCovered();
break;
case 0x6410a5d2:
result = new TL_stickerSetCovered();
break;
@ -29901,6 +29930,19 @@ public class TLRPC {
}
}
public static class TL_stickerSetNoCovered extends StickerSetCovered {
public static int constructor = 0x77b15d1c;
public void readParams(AbstractSerializedData stream, boolean exception) {
set = StickerSet.TLdeserialize(stream, stream.readInt32(exception), exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
set.serializeToStream(stream);
}
}
public static class TL_stickerSetFullCovered extends StickerSetCovered {
public static int constructor = 0x40d13c0e;
@ -31028,6 +31070,9 @@ public class TLRPC {
case 0xf227868c:
result = new TL_updateUserPhoto();
break;
case 0x20529438:
result = new TL_updateUser();
break;
case 0x17b7a20b:
result = new TL_updateAttachMenuBots();
break;
@ -32963,6 +33008,21 @@ public class TLRPC {
}
}
public static class TL_updateUser extends Update {
public static int constructor = 0x20529438;
public long user_id;
public void readParams(AbstractSerializedData stream, boolean exception) {
user_id = stream.readInt64(exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt64(user_id);
}
}
public static class TL_updateDialogFilters extends Update {
public static int constructor = 0x3504914f;
@ -34232,6 +34292,7 @@ public class TLRPC {
public FileLocation photo_big;
public byte[] stripped_thumb;
public int dc_id;
public boolean personal;
public BitmapDrawable strippedBitmap;
public static UserProfilePhoto TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
@ -34400,6 +34461,7 @@ public class TLRPC {
public void readParams(AbstractSerializedData stream, boolean exception) {
flags = stream.readInt32(exception);
has_video = (flags & 1) != 0;
personal = (flags & 4) != 0;
photo_id = stream.readInt64(exception);
if ((flags & 2) != 0) {
stripped_thumb = stream.readByteArray(exception);
@ -34424,6 +34486,7 @@ public class TLRPC {
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
flags = has_video ? (flags | 1) : (flags &~ 1);
flags = personal ? (flags | 4) : (flags &~ 4);
stream.writeInt32(flags);
stream.writeInt64(photo_id);
if ((flags & 2) != 0) {
@ -46232,6 +46295,7 @@ public class TLRPC {
public User user;
public String about;
public TL_contacts_link_layer101 link;
public Photo personal_photo;
public Photo profile_photo;
public PeerNotifySettings notify_settings;
public BotInfo bot_info;
@ -46246,13 +46310,20 @@ public class TLRPC {
public TL_chatAdminRights bot_group_admin_rights;
public TL_chatAdminRights bot_broadcast_admin_rights;
public ArrayList<TL_premiumGiftOption> premium_gifts = new ArrayList<>();
public Photo fallback_photo;
public static UserFull TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
UserFull result = null;
switch (constructor) {
case 0xc4b1fc3f:
case 0xf8d32aed:
result = new TL_userFull();
break;
case 0xec6d41e3:
result = new TL_userFull_layer150_rev2();
break;
case 0xc4b1fc3f:
result = new TL_userFull_layer150();
break;
case 0x8c72ea81:
result = new TL_userFull_layer143();
break;
@ -46286,6 +46357,264 @@ public class TLRPC {
}
public static class TL_userFull extends UserFull {
public static int constructor = 0xf8d32aed;
public void readParams(AbstractSerializedData stream, boolean exception) {
flags = stream.readInt32(exception);
blocked = (flags & 1) != 0;
phone_calls_available = (flags & 16) != 0;
phone_calls_private = (flags & 32) != 0;
can_pin_message = (flags & 128) != 0;
has_scheduled = (flags & 4096) != 0;
video_calls_available = (flags & 8192) != 0;
voice_messages_forbidden = (flags & 1048576) != 0;
id = stream.readInt64(exception);
if ((flags & 2) != 0) {
about = stream.readString(exception);
}
settings = TL_peerSettings.TLdeserialize(stream, stream.readInt32(exception), exception);
if ((flags & 2097152) != 0) {
personal_photo = Photo.TLdeserialize(stream, stream.readInt32(exception), exception);
}
if ((flags & 4) != 0) {
profile_photo = Photo.TLdeserialize(stream, stream.readInt32(exception), exception);
}
if ((flags & 4194304) != 0) {
fallback_photo = Photo.TLdeserialize(stream, stream.readInt32(exception), exception);
}
notify_settings = PeerNotifySettings.TLdeserialize(stream, stream.readInt32(exception), exception);
if ((flags & 8) != 0) {
bot_info = BotInfo.TLdeserialize(stream, stream.readInt32(exception), exception);
}
if ((flags & 64) != 0) {
pinned_msg_id = stream.readInt32(exception);
}
common_chats_count = stream.readInt32(exception);
if ((flags & 2048) != 0) {
folder_id = stream.readInt32(exception);
}
if ((flags & 16384) != 0) {
ttl_period = stream.readInt32(exception);
}
if ((flags & 32768) != 0) {
theme_emoticon = stream.readString(exception);
}
if ((flags & 65536) != 0) {
private_forward_name = stream.readString(exception);
}
if ((flags & 131072) != 0) {
bot_group_admin_rights = TL_chatAdminRights.TLdeserialize(stream, stream.readInt32(exception), exception);
}
if ((flags & 262144) != 0) {
bot_broadcast_admin_rights = TL_chatAdminRights.TLdeserialize(stream, stream.readInt32(exception), exception);
}
if ((flags & 524288) != 0) {
int magic = stream.readInt32(exception);
if (magic != 0x1cb5c415) {
if (exception) {
throw new RuntimeException(String.format("wrong Vector magic, got %x", magic));
}
return;
}
int count = stream.readInt32(exception);
for (int a = 0; a < count; a++) {
TL_premiumGiftOption object = TL_premiumGiftOption.TLdeserialize(stream, stream.readInt32(exception), exception);
if (object == null) {
return;
}
premium_gifts.add(object);
}
}
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
flags = blocked ? (flags | 1) : (flags &~ 1);
flags = phone_calls_available ? (flags | 16) : (flags &~ 16);
flags = phone_calls_private ? (flags | 32) : (flags &~ 32);
flags = can_pin_message ? (flags | 128) : (flags &~ 128);
flags = has_scheduled ? (flags | 4096) : (flags &~ 4096);
flags = video_calls_available ? (flags | 8192) : (flags &~ 8192);
flags = voice_messages_forbidden ? (flags | 1048576) : (flags &~ 1048576);
stream.writeInt32(flags);
stream.writeInt64(id);
if ((flags & 2) != 0) {
stream.writeString(about);
}
settings.serializeToStream(stream);
if ((flags & 2097152) != 0) {
personal_photo.serializeToStream(stream);
}
if ((flags & 4) != 0) {
profile_photo.serializeToStream(stream);
}
if ((flags & 4194304) != 0) {
fallback_photo.serializeToStream(stream);
}
notify_settings.serializeToStream(stream);
if ((flags & 8) != 0) {
bot_info.serializeToStream(stream);
}
if ((flags & 64) != 0) {
stream.writeInt32(pinned_msg_id);
}
stream.writeInt32(common_chats_count);
if ((flags & 2048) != 0) {
stream.writeInt32(folder_id);
}
if ((flags & 16384) != 0) {
stream.writeInt32(ttl_period);
}
if ((flags & 32768) != 0) {
stream.writeString(theme_emoticon);
}
if ((flags & 65536) != 0) {
stream.writeString(private_forward_name);
}
if ((flags & 131072) != 0) {
bot_group_admin_rights.serializeToStream(stream);
}
if ((flags & 262144) != 0) {
bot_broadcast_admin_rights.serializeToStream(stream);
}
if ((flags & 524288) != 0) {
stream.writeInt32(0x1cb5c415);
int count = premium_gifts.size();
stream.writeInt32(count);
for (int a = 0; a < count; a++) {
premium_gifts.get(a).serializeToStream(stream);
}
}
}
}
public static class TL_userFull_layer150_rev2 extends UserFull {
public static int constructor = 0xec6d41e3;
public void readParams(AbstractSerializedData stream, boolean exception) {
flags = stream.readInt32(exception);
blocked = (flags & 1) != 0;
phone_calls_available = (flags & 16) != 0;
phone_calls_private = (flags & 32) != 0;
can_pin_message = (flags & 128) != 0;
has_scheduled = (flags & 4096) != 0;
video_calls_available = (flags & 8192) != 0;
voice_messages_forbidden = (flags & 1048576) != 0;
id = stream.readInt64(exception);
if ((flags & 2) != 0) {
about = stream.readString(exception);
}
settings = TL_peerSettings.TLdeserialize(stream, stream.readInt32(exception), exception);
if ((flags & 2097152) != 0) {
personal_photo = Photo.TLdeserialize(stream, stream.readInt32(exception), exception);
}
if ((flags & 4) != 0) {
profile_photo = Photo.TLdeserialize(stream, stream.readInt32(exception), exception);
}
notify_settings = PeerNotifySettings.TLdeserialize(stream, stream.readInt32(exception), exception);
if ((flags & 8) != 0) {
bot_info = BotInfo.TLdeserialize(stream, stream.readInt32(exception), exception);
}
if ((flags & 64) != 0) {
pinned_msg_id = stream.readInt32(exception);
}
common_chats_count = stream.readInt32(exception);
if ((flags & 2048) != 0) {
folder_id = stream.readInt32(exception);
}
if ((flags & 16384) != 0) {
ttl_period = stream.readInt32(exception);
}
if ((flags & 32768) != 0) {
theme_emoticon = stream.readString(exception);
}
if ((flags & 65536) != 0) {
private_forward_name = stream.readString(exception);
}
if ((flags & 131072) != 0) {
bot_group_admin_rights = TL_chatAdminRights.TLdeserialize(stream, stream.readInt32(exception), exception);
}
if ((flags & 262144) != 0) {
bot_broadcast_admin_rights = TL_chatAdminRights.TLdeserialize(stream, stream.readInt32(exception), exception);
}
if ((flags & 524288) != 0) {
int magic = stream.readInt32(exception);
if (magic != 0x1cb5c415) {
if (exception) {
throw new RuntimeException(String.format("wrong Vector magic, got %x", magic));
}
return;
}
int count = stream.readInt32(exception);
for (int a = 0; a < count; a++) {
TL_premiumGiftOption object = TL_premiumGiftOption.TLdeserialize(stream, stream.readInt32(exception), exception);
if (object == null) {
return;
}
premium_gifts.add(object);
}
}
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
flags = blocked ? (flags | 1) : (flags &~ 1);
flags = phone_calls_available ? (flags | 16) : (flags &~ 16);
flags = phone_calls_private ? (flags | 32) : (flags &~ 32);
flags = can_pin_message ? (flags | 128) : (flags &~ 128);
flags = has_scheduled ? (flags | 4096) : (flags &~ 4096);
flags = video_calls_available ? (flags | 8192) : (flags &~ 8192);
flags = voice_messages_forbidden ? (flags | 1048576) : (flags &~ 1048576);
stream.writeInt32(flags);
stream.writeInt64(id);
if ((flags & 2) != 0) {
stream.writeString(about);
}
settings.serializeToStream(stream);
if ((flags & 2097152) != 0) {
personal_photo.serializeToStream(stream);
}
if ((flags & 4) != 0) {
profile_photo.serializeToStream(stream);
}
notify_settings.serializeToStream(stream);
if ((flags & 8) != 0) {
bot_info.serializeToStream(stream);
}
if ((flags & 64) != 0) {
stream.writeInt32(pinned_msg_id);
}
stream.writeInt32(common_chats_count);
if ((flags & 2048) != 0) {
stream.writeInt32(folder_id);
}
if ((flags & 16384) != 0) {
stream.writeInt32(ttl_period);
}
if ((flags & 32768) != 0) {
stream.writeString(theme_emoticon);
}
if ((flags & 65536) != 0) {
stream.writeString(private_forward_name);
}
if ((flags & 131072) != 0) {
bot_group_admin_rights.serializeToStream(stream);
}
if ((flags & 262144) != 0) {
bot_broadcast_admin_rights.serializeToStream(stream);
}
if ((flags & 524288) != 0) {
stream.writeInt32(0x1cb5c415);
int count = premium_gifts.size();
stream.writeInt32(count);
for (int a = 0; a < count; a++) {
premium_gifts.get(a).serializeToStream(stream);
}
}
}
}
public static class TL_userFull_layer150 extends UserFull {
public static int constructor = 0xc4b1fc3f;
public void readParams(AbstractSerializedData stream, boolean exception) {
@ -51512,6 +51841,7 @@ public class TLRPC {
public static int constructor = 0x89f30f69;
public int flags;
public boolean fallback;
public InputFile file;
public InputFile video;
public double video_start_ts;
@ -51522,6 +51852,7 @@ public class TLRPC {
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
flags = fallback ? (flags | 8) : (flags &~ 8);
stream.writeInt32(flags);
if ((flags & 1) != 0) {
file.serializeToStream(stream);
@ -58121,6 +58452,7 @@ public class TLRPC {
public int proximity_notification_radius;
public boolean nopremium;
public MessageExtendedMedia extended_media;
public boolean spoiler;
public static MessageMedia TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
MessageMedia result = null;
@ -62694,6 +63026,7 @@ public class TLRPC {
public int flags;
public boolean inactive;
public boolean has_settings;
public boolean request_write_access;
public long bot_id;
public String short_name;
public ArrayList<AttachMenuPeerType> peer_types = new ArrayList<>();
@ -62703,6 +63036,7 @@ public class TLRPC {
flags = stream.readInt32(exception);
inactive = (flags & 1) != 0;
has_settings = (flags & 2) != 0;
request_write_access = (flags & 4) != 0;
bot_id = stream.readInt64(exception);
short_name = stream.readString(exception);
int magic = stream.readInt32(exception);
@ -62741,6 +63075,7 @@ public class TLRPC {
stream.writeInt32(constructor);
flags = inactive ? (flags | 1) : (flags &~ 1);
flags = has_settings ? (flags | 2) : (flags &~ 2);
flags = request_write_access ? (flags | 4) : (flags &~ 4);
stream.writeInt32(flags);
stream.writeInt64(bot_id);
stream.writeString(short_name);
@ -62961,8 +63296,10 @@ public class TLRPC {
}
public static class TL_messages_toggleBotInAttachMenu extends TLObject {
public static int constructor = 0x1aee33af;
public static int constructor = 0x69f59d69;
public int flags;
public boolean write_allowed;
public InputUser bot;
public boolean enabled;
@ -62972,6 +63309,8 @@ public class TLRPC {
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
flags = write_allowed ? (flags | 1) : (flags &~ 1);
stream.writeInt32(flags);
bot.serializeToStream(stream);
stream.writeBool(enabled);
}
@ -64980,6 +65319,23 @@ public class TLRPC {
}
}
public static class TL_channels_toggleParticipantsHidden extends TLObject {
public static int constructor = 0x6a6e7854;
public InputChannel channel;
public boolean enabled;
public TLObject deserializeResponse(AbstractSerializedData stream, int constructor, boolean exception) {
return Updates.TLdeserialize(stream, constructor, exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
channel.serializeToStream(stream);
stream.writeBool(enabled);
}
}
public static class TL_messages_setDefaultHistoryTTL extends TLObject {
public static int constructor = 0x9eb51445;
@ -65063,6 +65419,64 @@ public class TLRPC {
}
}
public static class TL_messageActionSuggestProfilePhoto extends MessageAction {
public static int constructor = 0x57de635e;
public void readParams(AbstractSerializedData stream, boolean exception) {
photo = Photo.TLdeserialize(stream, stream.readInt32(exception), exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
photo.serializeToStream(stream);
}
}
public static class TL_messageActionAttachMenuBotAllowed extends MessageAction {
public static int constructor = 0xe7e75f97;
public void readParams(AbstractSerializedData stream, boolean exception) {
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
}
}
public static class TL_photos_uploadContactProfilePhoto extends TLObject {
public static int constructor = 0xb91a83bf;
public int flags;
public boolean suggest;
public boolean save;
public InputUser user_id;
public InputFile file;
public InputFile video;
public double video_start_ts;
public TLObject deserializeResponse(AbstractSerializedData stream, int constructor, boolean exception) {
return TL_photos_photo.TLdeserialize(stream, constructor, exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
flags = suggest ? (flags | 8) : (flags &~ 8);
flags = save ? (flags | 16) : (flags &~ 16);
stream.writeInt32(flags);
user_id.serializeToStream(stream);
if ((flags & 1) != 0) {
file.serializeToStream(stream);
}
if ((flags & 2) != 0) {
video.serializeToStream(stream);
}
if ((flags & 4) != 0) {
stream.writeDouble(video_start_ts);
}
}
}
//functions
public static class Vector extends TLObject {

View file

@ -415,6 +415,10 @@ public class ActionBarMenuItem extends FrameLayout {
popupLayout.setShownFromBottom(value);
}
public void setFitSubItems(boolean fit) {
popupLayout.setFitItems(fit);
}
public void addSubItem(View view, int width, int height) {
createPopupLayout();
popupLayout.addView(view, new LinearLayout.LayoutParams(width, height));

View file

@ -4,12 +4,9 @@ import android.content.Context;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.RippleDrawable;
import android.os.Build;
import android.text.TextUtils;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.FrameLayout;
@ -18,15 +15,15 @@ import android.widget.TextView;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.R;
import org.telegram.ui.Components.CheckBox2;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.RLottieImageView;
public class ActionBarMenuSubItem extends FrameLayout {
private TextView textView;
private TextView subtextView;
private ImageView imageView;
private RLottieImageView imageView;
private CheckBox2 checkView;
private ImageView rightIcon;
@ -67,7 +64,7 @@ public class ActionBarMenuSubItem extends FrameLayout {
updateBackground();
setPadding(AndroidUtilities.dp(18), 0, AndroidUtilities.dp(18), 0);
imageView = new ImageView(context);
imageView = new RLottieImageView(context);
imageView.setScaleType(ImageView.ScaleType.CENTER);
imageView.setColorFilter(new PorterDuffColorFilter(iconColor, PorterDuff.Mode.MULTIPLY));
addView(imageView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, 40, Gravity.CENTER_VERTICAL | (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT)));
@ -184,7 +181,17 @@ public class ActionBarMenuSubItem extends FrameLayout {
imageView.setImageResource(resId);
}
public void setText(String text) {
public void setAnimatedIcon(int resId) {
imageView.setAnimation(resId, 24, 24);
}
public void onItemShown() {
if (imageView.getAnimatedDrawable() != null) {
imageView.getAnimatedDrawable().start();
}
}
public void setText(CharSequence text) {
textView.setText(text);
}

View file

@ -16,8 +16,6 @@ import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.Rect;
@ -45,12 +43,14 @@ import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R;
import org.telegram.messenger.UserConfig;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.Paint.Views.LPhotoPaintView;
import org.telegram.ui.Components.PopupSwipeBackLayout;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Locale;
public class ActionBarPopupWindow extends PopupWindow {
@ -125,6 +125,7 @@ public class ActionBarPopupWindow extends PopupWindow {
private boolean fitItems;
private final Theme.ResourcesProvider resourcesProvider;
private View topView;
protected ActionBarPopupWindow window;
public int subtractBackgroundHeight;
@ -311,7 +312,7 @@ public class ActionBarPopupWindow extends PopupWindow {
if (shownFromBottom) {
for (int a = lastStartedChild; a >= 0; a--) {
View child = getItemAt(a);
if (child.getVisibility() != VISIBLE || child instanceof GapView) {
if (child == null || child.getVisibility() != VISIBLE || child instanceof GapView) {
continue;
}
Integer position = positions.get(child);
@ -368,6 +369,10 @@ public class ActionBarPopupWindow extends PopupWindow {
@Override
public void onAnimationEnd(Animator animation) {
itemAnimators.remove(animatorSet);
if (child instanceof ActionBarMenuSubItem) {
((ActionBarMenuSubItem) child).onItemShown();
}
}
});
animatorSet.setInterpolator(decelerateInterpolator);
@ -609,6 +614,10 @@ public class ActionBarPopupWindow extends PopupWindow {
swipeBackLayout.invalidateTransforms(!startAnimationPending);
}
}
public void setParentWindow(ActionBarPopupWindow popupWindow) {
window = popupWindow;
}
}
public ActionBarPopupWindow() {
@ -763,6 +772,9 @@ public class ActionBarPopupWindow extends PopupWindow {
int visibleCount = 0;
for (int a = 0; a < count; a++) {
View child = content.getItemAt(a);
if (child instanceof GapView) {
continue;
}
child.setAlpha(0.0f);
if (child.getVisibility() != View.VISIBLE) {
continue;
@ -790,9 +802,9 @@ public class ActionBarPopupWindow extends PopupWindow {
if (child instanceof GapView) {
continue;
}
float at = AndroidUtilities.cascade(t, a, count2, 2);
child.setTranslationY((1f - at) * AndroidUtilities.dp(-12));
child.setAlpha(at);
float at = AndroidUtilities.cascade(t, content.shownFromBottom ? count2 - 1 - a : a, count2, 4);
child.setTranslationY((1f - at) * AndroidUtilities.dp(-6));
// child.setAlpha(at * (child.isEnabled() ? 1f : 0.5f));
}
});
content.updateAnimation = true;
@ -801,7 +813,7 @@ public class ActionBarPopupWindow extends PopupWindow {
ObjectAnimator.ofInt(content, "backAlpha", 0, 255),
childtranslations
);
windowAnimatorSet.setDuration(150 + 16 * visibleCount + 1000);
windowAnimatorSet.setDuration(150 + 16 * visibleCount);
windowAnimatorSet.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {

View file

@ -34,6 +34,7 @@ import java.util.List;
public class AdjustPanLayoutHelper {
public static boolean USE_ANDROID11_INSET_ANIMATOR = false;
private boolean useInsetsAnimator;
public final static Interpolator keyboardInterpolator = ChatListItemAnimator.DEFAULT_INTERPOLATOR;
public final static long keyboardDuration = 250;
@ -178,7 +179,7 @@ public class AdjustPanLayoutHelper {
setViewHeight(Math.max(previousHeight, contentHeight + additionalContentHeight));
resizableView.requestLayout();
onTransitionStart(isKeyboardVisible, contentHeight);
onTransitionStart(isKeyboardVisible, previousHeight, contentHeight);
float dy = contentHeight - previousHeight;
keyboardSize = Math.abs(dy);
@ -269,12 +270,11 @@ public class AdjustPanLayoutHelper {
}
public AdjustPanLayoutHelper(View parent) {
this.parent = parent;
onAttach();
this(parent, USE_ANDROID11_INSET_ANIMATOR);
}
public AdjustPanLayoutHelper(View parent, boolean useInsetsAnimator) {
USE_ANDROID11_INSET_ANIMATOR = USE_ANDROID11_INSET_ANIMATOR && useInsetsAnimator;
this.useInsetsAnimator = useInsetsAnimator;
this.parent = parent;
onAttach();
}
@ -295,7 +295,7 @@ public class AdjustPanLayoutHelper {
parentForListener = resizableView;
resizableView.getViewTreeObserver().addOnPreDrawListener(onPreDrawListener);
}
if (USE_ANDROID11_INSET_ANIMATOR && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
if (useInsetsAnimator && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
setupNewCallback();
}
}
@ -335,7 +335,7 @@ public class AdjustPanLayoutHelper {
parentForListener.getViewTreeObserver().removeOnPreDrawListener(onPreDrawListener);
parentForListener = null;
}
if (parent != null && USE_ANDROID11_INSET_ANIMATOR && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
if (parent != null && useInsetsAnimator && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
parent.setWindowInsetsAnimationCallback(null);
}
}
@ -368,6 +368,10 @@ public class AdjustPanLayoutHelper {
}
protected void onTransitionStart(boolean keyboardVisible, int previousHeight, int contentHeight) {
onTransitionStart(keyboardVisible, contentHeight);
}
protected void onTransitionStart(boolean keyboardVisible, int contentHeight) {
}

View file

@ -14,14 +14,22 @@ import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.Rect;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.RoundRectShape;
import android.os.Build;
import android.os.Bundle;
import android.text.TextPaint;
@ -34,6 +42,7 @@ import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.Window;
import android.view.WindowManager;
import android.view.animation.OvershootInterpolator;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
@ -42,6 +51,7 @@ import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.graphics.ColorUtils;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.Emoji;
@ -49,18 +59,26 @@ import org.telegram.messenger.FileLog;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R;
import org.telegram.messenger.SharedConfig;
import org.telegram.ui.Components.AnimatedFloat;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.LineProgressView;
import org.telegram.ui.Components.RLottieDrawable;
import org.telegram.ui.Components.RLottieImageView;
import org.telegram.ui.Components.RadialProgressView;
import org.telegram.ui.Components.spoilers.SpoilersTextView;
import org.telegram.ui.LaunchActivity;
import java.util.ArrayList;
import java.util.Map;
public class AlertDialog extends Dialog implements Drawable.Callback, NotificationCenter.NotificationCenterDelegate {
public static final int ALERT_TYPE_MESSAGE = 0;
public static final int ALERT_TYPE_SPINNER_DETAIL = 1; // not used?
public static final int ALERT_TYPE_LOADING = 2;
public static final int ALERT_TYPE_SPINNER = 3;
private View customView;
private int customViewHeight = LayoutHelper.WRAP_CONTENT;
private TextView titleTextView;
@ -104,7 +122,7 @@ public class AlertDialog extends Dialog implements Drawable.Callback, Notificati
private int topHeight = 132;
private Drawable topDrawable;
private int topBackgroundColor;
private int progressViewStyle; // TODO: Use constants here
private int progressViewStyle;
private int currentProgress;
private boolean messageTextViewClickable = true;
@ -125,12 +143,20 @@ public class AlertDialog extends Dialog implements Drawable.Callback, Notificati
private LineProgressView lineProgressView;
private TextView lineProgressViewPercent;
private OnClickListener onBackButtonListener;
private int[] containerViewLocation = new int[2];
private boolean checkFocusable = true;
private Drawable shadowDrawable;
private Rect backgroundPaddings;
private float blurOpacity;
private Bitmap blurBitmap;
private Matrix blurMatrix;
private BitmapShader blurShader;
private Paint blurPaint;
private Paint dimBlurPaint;
private boolean focusable;
private boolean verticalButtons;
@ -154,6 +180,29 @@ public class AlertDialog extends Dialog implements Drawable.Callback, Notificati
private boolean dimCustom = false;
private final Theme.ResourcesProvider resourcesProvider;
private boolean topAnimationAutoRepeat = true;
private boolean blurredBackground;
private boolean blurredNativeBackground;
private int backgroundColor;
float blurAlpha = 0.8f;
private boolean blurBehind;
private int additioanalHorizontalPadding;
public void setBlurParams(float blurAlpha, boolean blurBehind, boolean blurBackground) {
this.blurAlpha = blurAlpha;
this.blurBehind = blurBehind;
this.blurredBackground = blurBackground;
}
private boolean supportsNativeBlur() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && LaunchActivity.systemBlurEnabled;
}
public void redPositive() {
TextView button = (TextView) getButton(DialogInterface.BUTTON_POSITIVE);
if (button != null) {
button.setTextColor(getThemedColor(Theme.key_dialogTextRed2));
}
}
public static class AlertDialogCell extends FrameLayout {
@ -220,18 +269,36 @@ public class AlertDialog extends Dialog implements Drawable.Callback, Notificati
public AlertDialog(Context context, int progressStyle, Theme.ResourcesProvider resourcesProvider) {
super(context, R.style.TransparentDialog);
blurredNativeBackground = supportsNativeBlur() && progressViewStyle == ALERT_TYPE_MESSAGE;
blurredBackground = blurredNativeBackground || !supportsNativeBlur() && SharedConfig.getDevicePerformanceClass() >= SharedConfig.PERFORMANCE_CLASS_HIGH;
this.resourcesProvider = resourcesProvider;
backgroundPaddings = new Rect();
if (progressStyle != 3) {
if (progressStyle != ALERT_TYPE_SPINNER || blurredBackground) {
shadowDrawable = context.getResources().getDrawable(R.drawable.popup_fixed_alert3).mutate();
shadowDrawable.setColorFilter(new PorterDuffColorFilter(getThemedColor(Theme.key_dialogBackground), PorterDuff.Mode.MULTIPLY));
backgroundColor = getThemedColor(Theme.key_dialogBackground);
blurOpacity = progressStyle == ALERT_TYPE_SPINNER ? 0.55f : (AndroidUtilities.computePerceivedBrightness(backgroundColor) < 0.721f ? 0.80f : 0.92f);
shadowDrawable.setColorFilter(new PorterDuffColorFilter(backgroundColor, PorterDuff.Mode.MULTIPLY));
shadowDrawable.getPadding(backgroundPaddings);
}
progressViewStyle = progressStyle;
}
@Override
public void show() {
super.show();
if (progressViewContainer != null && progressViewStyle == ALERT_TYPE_SPINNER) {
progressViewContainer.setScaleX(0);
progressViewContainer.setScaleY(0);
progressViewContainer.animate()
.scaleX(1f).scaleY(1f)
.setInterpolator(new OvershootInterpolator(1.3f))
.setDuration(190)
.start();
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -242,7 +309,7 @@ public class AlertDialog extends Dialog implements Drawable.Callback, Notificati
@Override
public boolean onTouchEvent(MotionEvent event) {
if (progressViewStyle == 3) {
if (progressViewStyle == ALERT_TYPE_SPINNER) {
showCancelAlert();
return false;
}
@ -251,7 +318,7 @@ public class AlertDialog extends Dialog implements Drawable.Callback, Notificati
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (progressViewStyle == 3) {
if (progressViewStyle == ALERT_TYPE_SPINNER) {
showCancelAlert();
return false;
}
@ -260,7 +327,7 @@ public class AlertDialog extends Dialog implements Drawable.Callback, Notificati
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (progressViewStyle == 3) {
if (progressViewStyle == ALERT_TYPE_SPINNER) {
progressViewContainer.measure(MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(86), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(86), MeasureSpec.EXACTLY));
setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.getSize(heightMeasureSpec));
} else {
@ -309,8 +376,8 @@ public class AlertDialog extends Dialog implements Drawable.Callback, Notificati
availableHeight -= subtitleTextView.getMeasuredHeight() + layoutParams.bottomMargin + layoutParams.topMargin;
}
if (topImageView != null) {
topImageView.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(topHeight), MeasureSpec.EXACTLY));
availableHeight -= topImageView.getMeasuredHeight() - AndroidUtilities.dp(8);
topImageView.measure(MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(topHeight), MeasureSpec.EXACTLY));
availableHeight -= topImageView.getMeasuredHeight();
}
if (topView != null) {
int w = width - AndroidUtilities.dp(16);
@ -325,7 +392,7 @@ public class AlertDialog extends Dialog implements Drawable.Callback, Notificati
topView.getLayoutParams().height = h;
availableHeight -= topView.getMeasuredHeight();
}
if (progressViewStyle == 0) {
if (progressViewStyle == ALERT_TYPE_MESSAGE) {
layoutParams = (LayoutParams) contentScrollView.getLayoutParams();
if (customView != null) {
@ -400,7 +467,7 @@ public class AlertDialog extends Dialog implements Drawable.Callback, Notificati
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
if (progressViewStyle == 3) {
if (progressViewStyle == ALERT_TYPE_SPINNER) {
int x = (r - l - progressViewContainer.getMeasuredWidth()) / 2;
int y = (b - t - progressViewContainer.getMeasuredHeight()) / 2;
progressViewContainer.layout(x, y, x + progressViewContainer.getMeasuredWidth(), y + progressViewContainer.getMeasuredHeight());
@ -415,6 +482,14 @@ public class AlertDialog extends Dialog implements Drawable.Callback, Notificati
}
onScrollChangedListener.onScrollChanged();
}
getLocationOnScreen(containerViewLocation);
if (blurMatrix != null && blurShader != null) {
blurMatrix.reset();
blurMatrix.postScale(8f, 8f);
blurMatrix.postTranslate(-containerViewLocation[0], -containerViewLocation[1]);
blurShader.setLocalMatrix(blurMatrix);
}
}
@Override
@ -430,9 +505,53 @@ public class AlertDialog extends Dialog implements Drawable.Callback, Notificati
return false;
}
private AnimatedFloat blurPaintAlpha = new AnimatedFloat(0, this);
private Paint backgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
@Override
public void draw(Canvas canvas) {
if (blurredBackground && !blurredNativeBackground) {
float r;
if (progressViewStyle == ALERT_TYPE_SPINNER && progressViewContainer != null) {
r = AndroidUtilities.dp(18);
float w = progressViewContainer.getWidth() * progressViewContainer.getScaleX();
float h = progressViewContainer.getHeight() * progressViewContainer.getScaleY();
AndroidUtilities.rectTmp.set(
(getWidth() - w) / 2f,
(getHeight() - h) / 2f,
(getWidth() + w) / 2f,
(getHeight() + h) / 2f
);
} else {
r = AndroidUtilities.dp(10);
AndroidUtilities.rectTmp.set(getPaddingLeft(), getPaddingTop(), getMeasuredWidth() - getPaddingRight(), getMeasuredHeight() - getPaddingBottom());
}
// draw blur of background
float blurAlpha = blurPaintAlpha.set(blurPaint != null ? 1f : 0f);
if (blurPaint != null) {
blurPaint.setAlpha((int) (0xFF * blurAlpha));
canvas.drawRoundRect(AndroidUtilities.rectTmp, r, r, blurPaint);
}
// draw dim above blur
if (dimBlurPaint == null) {
dimBlurPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
dimBlurPaint.setColor(ColorUtils.setAlphaComponent(0xff000000, (int) (0xFF * dimAlpha)));
}
canvas.drawRoundRect(AndroidUtilities.rectTmp, r, r, dimBlurPaint);
// draw background
backgroundPaint.setColor(backgroundColor);
backgroundPaint.setAlpha((int) (backgroundPaint.getAlpha() * (blurAlpha * (blurOpacity - 1f) + 1f)));
canvas.drawRoundRect(AndroidUtilities.rectTmp, r, r, backgroundPaint);
}
super.draw(canvas);
}
@Override
protected void dispatchDraw(Canvas canvas) {
if (drawBackground) {
if (drawBackground && !blurredBackground) {
shadowDrawable.setBounds(0, 0, getMeasuredWidth(), getMeasuredHeight());
if (topView != null && notDrawBackgroundOnTopView) {
int clipTop = topView.getBottom();
@ -448,9 +567,12 @@ public class AlertDialog extends Dialog implements Drawable.Callback, Notificati
}
};
containerView.setOrientation(LinearLayout.VERTICAL);
if (progressViewStyle == 3) {
if (blurredBackground || progressViewStyle == ALERT_TYPE_SPINNER) {
containerView.setBackgroundDrawable(null);
containerView.setPadding(0, 0, 0, 0);
if (blurredBackground && !blurredNativeBackground) {
containerView.setWillNotDraw(false);
}
drawBackground = false;
} else {
if (notDrawBackgroundOnTopView) {
@ -518,8 +640,7 @@ public class AlertDialog extends Dialog implements Drawable.Callback, Notificati
});
topHeight = 92;
} else {
topImageView.setBackgroundDrawable(getContext().getResources().getDrawable(R.drawable.popup_fixed_top));
topImageView.getBackground().setColorFilter(new PorterDuffColorFilter(topBackgroundColor, PorterDuff.Mode.MULTIPLY));
topImageView.setBackground(Theme.createRoundRectDrawable(AndroidUtilities.dp(10), 0, topBackgroundColor));
}
if (topAnimationIsNew) {
topImageView.setTranslationY(AndroidUtilities.dp(16));
@ -527,7 +648,7 @@ public class AlertDialog extends Dialog implements Drawable.Callback, Notificati
topImageView.setTranslationY(0);
}
topImageView.setPadding(0, 0, 0, 0);
containerView.addView(topImageView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, topHeight, Gravity.LEFT | Gravity.TOP, -8, -8, 0, 0));
containerView.addView(topImageView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, topHeight, Gravity.LEFT | Gravity.TOP, 0, 0, 0, 0));
} else if (topView != null) {
topView.setPadding(0, 0, 0, 0);
containerView.addView(topView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, topHeight, Gravity.LEFT | Gravity.TOP, 0, 0, 0, 0));
@ -564,7 +685,7 @@ public class AlertDialog extends Dialog implements Drawable.Callback, Notificati
containerView.addView(subtitleTextView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, 24, 0, 24, items != null ? 14 : 10));
}
if (progressViewStyle == 0) {
if (progressViewStyle == ALERT_TYPE_MESSAGE) {
shadow[0] = (BitmapDrawable) getContext().getResources().getDrawable(R.drawable.header_shadow).mutate();
shadow[1] = (BitmapDrawable) getContext().getResources().getDrawable(R.drawable.header_shadow_reverse).mutate();
shadow[0].setAlpha(0);
@ -613,7 +734,7 @@ public class AlertDialog extends Dialog implements Drawable.Callback, Notificati
messageTextView.setEnabled(false);
}
messageTextView.setGravity((topAnimationIsNew ? Gravity.CENTER_HORIZONTAL : LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP);
if (progressViewStyle == 1) {
if (progressViewStyle == ALERT_TYPE_SPINNER_DETAIL) {
progressViewContainer = new FrameLayout(getContext());
containerView.addView(progressViewContainer, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 44, Gravity.LEFT | Gravity.TOP, 23, title == null ? 24 : 0, 23, 24));
@ -624,7 +745,7 @@ public class AlertDialog extends Dialog implements Drawable.Callback, Notificati
messageTextView.setLines(1);
messageTextView.setEllipsize(TextUtils.TruncateAt.END);
progressViewContainer.addView(messageTextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.CENTER_VERTICAL, (LocaleController.isRTL ? 0 : 62), 0, (LocaleController.isRTL ? 62 : 0), 0));
} else if (progressViewStyle == 2) {
} else if (progressViewStyle == ALERT_TYPE_LOADING) {
containerView.addView(messageTextView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, 24, title == null ? 19 : 0, 24, 20));
lineProgressView = new LineProgressView(getContext());
@ -640,30 +761,36 @@ public class AlertDialog extends Dialog implements Drawable.Callback, Notificati
lineProgressViewPercent.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
containerView.addView(lineProgressViewPercent, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, 23, 4, 23, 24));
updateLineProgressTextView();
} else if (progressViewStyle == 3) {
} else if (progressViewStyle == ALERT_TYPE_SPINNER) {
setCanceledOnTouchOutside(false);
setCancelable(false);
progressViewContainer = new FrameLayout(getContext());
progressViewContainer.setBackgroundDrawable(Theme.createRoundRectDrawable(AndroidUtilities.dp(18), getThemedColor(Theme.key_dialog_inlineProgressBackground)));
backgroundColor = getThemedColor(Theme.key_dialog_inlineProgressBackground);
if (!(blurredBackground && !blurredNativeBackground)) {
progressViewContainer.setBackgroundDrawable(Theme.createRoundRectDrawable(AndroidUtilities.dp(18), backgroundColor));
}
containerView.addView(progressViewContainer, LayoutHelper.createLinear(86, 86, Gravity.CENTER));
RadialProgressView progressView = new RadialProgressView(getContext(), resourcesProvider);
progressView.setSize(AndroidUtilities.dp(32));
progressView.setProgressColor(getThemedColor(Theme.key_dialog_inlineProgress));
progressViewContainer.addView(progressView, LayoutHelper.createLinear(86, 86));
progressViewContainer.addView(progressView, LayoutHelper.createFrame(86, 86, Gravity.CENTER));
} else {
scrollContainer.addView(messageTextView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, (topAnimationIsNew ? Gravity.CENTER_HORIZONTAL : LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, 24, 0, 24, customView != null || items != null ? customViewOffset : 0));
}
if (!TextUtils.isEmpty(message)) {
messageTextView.setText(message);
if (customView != null) {
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) messageTextView.getLayoutParams();
params.topMargin = AndroidUtilities.dp(16);
}
messageTextView.setVisibility(View.VISIBLE);
} else {
messageTextView.setVisibility(View.GONE);
}
if (items != null) {
FrameLayout rowLayout = null;
int lastRowLayoutNum = 0;
for (int a = 0; a < items.length; a++) {
if (items[a] == null) {
continue;
@ -928,7 +1055,7 @@ public class AlertDialog extends Dialog implements Drawable.Callback, Notificati
Window window = getWindow();
WindowManager.LayoutParams params = new WindowManager.LayoutParams();
params.copyFrom(window.getAttributes());
if (progressViewStyle == 3) {
if (progressViewStyle == ALERT_TYPE_SPINNER) {
params.width = WindowManager.LayoutParams.MATCH_PARENT;
} else {
if (dimEnabled && !dimCustom) {
@ -940,7 +1067,7 @@ public class AlertDialog extends Dialog implements Drawable.Callback, Notificati
}
lastScreenWidth = AndroidUtilities.displaySize.x;
final int calculatedWidth = AndroidUtilities.displaySize.x - AndroidUtilities.dp(48);
final int calculatedWidth = AndroidUtilities.displaySize.x - AndroidUtilities.dp(48) - additioanalHorizontalPadding * 2;
int maxWidth;
if (AndroidUtilities.isTablet()) {
if (AndroidUtilities.isSmallTablet()) {
@ -963,6 +1090,40 @@ public class AlertDialog extends Dialog implements Drawable.Callback, Notificati
params.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT;
}
if (blurredBackground) {
if (supportsNativeBlur()) {
if (progressViewStyle == ALERT_TYPE_MESSAGE) {
blurredNativeBackground = true;
window.setBackgroundBlurRadius(50);
float rad = AndroidUtilities.dp(12);
ShapeDrawable shapeDrawable = new ShapeDrawable(new RoundRectShape(new float[]{rad, rad, rad, rad, rad, rad, rad, rad}, null, null));
shapeDrawable.getPaint().setColor(ColorUtils.setAlphaComponent(backgroundColor, (int) (blurAlpha * 255)));
window.setBackgroundDrawable(shapeDrawable);
if (blurBehind) {
params.flags |= WindowManager.LayoutParams.FLAG_BLUR_BEHIND;
params.setBlurBehindRadius(20);
}
}
} else {
AndroidUtilities.makeGlobalBlurBitmap(bitmap -> {
if (bitmap == null) {
return;
}
if (blurPaint == null) {
blurPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
}
blurBitmap = bitmap;
blurShader = new BitmapShader(blurBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
blurPaint.setShader(blurShader);
blurMatrix = new Matrix();
blurMatrix.postScale(8f, 8f);
blurMatrix.postTranslate(-containerViewLocation[0], -containerViewLocation[1]);
blurShader.setLocalMatrix(blurMatrix);
containerView.invalidate();
}, 8);
}
}
window.setAttributes(params);
NotificationCenter.getGlobalInstance().addObserver(this, NotificationCenter.emojiLoaded);
@ -994,7 +1155,10 @@ public class AlertDialog extends Dialog implements Drawable.Callback, Notificati
}
public void setBackgroundColor(int color) {
shadowDrawable.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.MULTIPLY));
backgroundColor = color;
if (shadowDrawable != null) {
shadowDrawable.setColorFilter(new PorterDuffColorFilter(backgroundColor, PorterDuff.Mode.MULTIPLY));
}
}
public void setTextColor(int color) {
@ -1011,7 +1175,7 @@ public class AlertDialog extends Dialog implements Drawable.Callback, Notificati
return;
}
Builder builder = new Builder(getContext());
builder.setTitle(LocaleController.getString("AppName", R.string.AppName));
builder.setTitle(LocaleController.getString("StopLoadingTitle", R.string.StopLoadingTitle));
builder.setMessage(LocaleController.getString("StopLoading", R.string.StopLoading));
builder.setPositiveButton(LocaleController.getString("WaitMore", R.string.WaitMore), null);
builder.setNegativeButton(LocaleController.getString("Stop", R.string.Stop), (dialogInterface, i) -> {
@ -1130,6 +1294,13 @@ public class AlertDialog extends Dialog implements Drawable.Callback, Notificati
}
AndroidUtilities.cancelRunOnUIThread(showRunnable);
if (blurShader != null && blurBitmap != null) {
blurBitmap.recycle();
blurShader = null;
blurPaint = null;
blurBitmap = null;
}
}
@Override
@ -1475,6 +1646,7 @@ public class AlertDialog extends Dialog implements Drawable.Callback, Notificati
public void notDrawBackgroundOnTopView(boolean b) {
alertDialog.notDrawBackgroundOnTopView = b;
alertDialog.blurredBackground = false;
}
public void setButtonsVertical(boolean vertical) {
@ -1485,5 +1657,15 @@ public class AlertDialog extends Dialog implements Drawable.Callback, Notificati
alertDialog.onDismissListener = onDismissListener;
return this;
}
public Builder setBlurredBackground(boolean b) {
alertDialog.blurredBackground = b;
return this;
}
public Builder setAdditionalHorizontalPadding(int padding) {
alertDialog.additioanalHorizontalPadding = padding;
return this;
}
}
}

View file

@ -298,6 +298,10 @@ public abstract class BaseFragment {
}
}
public void setFinishing(boolean finishing) {
this.finishing = finishing;
}
public void finishFragment(boolean animated) {
if (isFinished || parentLayout == null) {
return;
@ -864,6 +868,15 @@ public abstract class BaseFragment {
this.previewDelegate = previewDelegate;
}
public void resetFragment() {
if (isFinished) {
clearViews();
isFinished = false;
finishing = false;
}
}
public interface PreviewDelegate {
void finishFragment();
}

View file

@ -180,7 +180,7 @@ public class BottomSheet extends Dialog {
public boolean useBackgroundTopPadding = true;
protected int customViewGravity = Gravity.LEFT | Gravity.TOP;
protected class ContainerView extends FrameLayout implements NestedScrollingParent {
public class ContainerView extends FrameLayout implements NestedScrollingParent {
private VelocityTracker velocityTracker = null;
private int startedTrackingX;
@ -1386,7 +1386,7 @@ public class BottomSheet extends Dialog {
delegate = bottomSheetDelegate;
}
public FrameLayout getContainer() {
public ContainerView getContainer() {
return container;
}

View file

@ -1849,6 +1849,44 @@ public class Theme {
);
}
public static int adaptHue(int color, int hueFromColor) {
float hue, sat;
float[] tempHSV = getTempHsv(5);
Color.colorToHSV(hueFromColor, tempHSV);
hue = tempHSV[0];
sat = tempHSV[1];
Color.colorToHSV(color, tempHSV);
tempHSV[0] = hue;
tempHSV[1] = AndroidUtilities.lerp(tempHSV[1], sat, .25f);
return Color.HSVToColor(Color.alpha(color), tempHSV);
}
public static int adaptHSV(int color, float sat, float val) {
float[] tempHSV = getTempHsv(5);
Color.colorToHSV(color, tempHSV);
tempHSV[1] = MathUtils.clamp(tempHSV[1] + sat, 0, 1);
tempHSV[2] = MathUtils.clamp(tempHSV[2] + val, 0, 1);
return Color.HSVToColor(Color.alpha(color), tempHSV);
}
public static int percentSV(int color1, int color2, float satT, float valT) {
float[] tempHSV = getTempHsv(5);
Color.colorToHSV(color2, tempHSV);
float sat2 = tempHSV[1];
float val2 = tempHSV[2];
Color.colorToHSV(color1, tempHSV);
tempHSV[1] = MathUtils.clamp(AndroidUtilities.lerp(tempHSV[1], sat2, satT), 0, 1);
tempHSV[2] = MathUtils.clamp(AndroidUtilities.lerp(tempHSV[2], val2, valT), 0, 1);
return Color.HSVToColor(
AndroidUtilities.lerp(Color.alpha(color1), Color.alpha(color2), .85f),
tempHSV
);
}
public static int multAlpha(int color, float multiply) {
return ColorUtils.setAlphaComponent(color, MathUtils.clamp((int) (Color.alpha(color) * multiply), 0, 0xFF));
}
public static int reverseBlendOver(float ax, int y, int z) {
float ay = Color.alpha(y) / 255f,
az = Color.alpha(z) / 255f;
@ -3489,6 +3527,7 @@ public class Theme {
public static final String key_chat_serviceIcon = "chat_serviceIcon";
public static final String key_chat_serviceBackground = "chat_serviceBackground";
public static final String key_chat_serviceBackgroundSelected = "chat_serviceBackgroundSelected";
public static final String key_chat_serviceBackgroundSelector = "chat_serviceBackgroundSelector";
public static final String key_chat_muteIcon = "chat_muteIcon";
public static final String key_chat_lockIcon = "chat_lockIcon";
public static final String key_chat_outSentCheck = "chat_outSentCheck";
@ -3964,6 +4003,8 @@ public class Theme {
public final static String key_statisticChartLine_lightgreen = "statisticChartLine_lightgreen";
public final static String key_statisticChartLine_orange = "statisticChartLine_orange";
public final static String key_statisticChartLine_indigo = "statisticChartLine_indigo";
public final static String key_statisticChartLine_purple = "statisticChartLine_purple";
public final static String key_statisticChartLine_cyan = "statisticChartLine_cyan";
public final static String key_statisticChartLineEmpty = "statisticChartLineEmpty";
public static final String key_chat_outReactionButtonBackground = "chat_outReactionButtonBackground";
@ -4106,7 +4147,7 @@ public class Theme {
defaultColors.put(key_dialogCheckboxSquareDisabled, 0xffb0b0b0);
defaultColors.put(key_dialogRadioBackground, 0xffb3b3b3);
defaultColors.put(key_dialogRadioBackgroundChecked, 0xff37a9f0);
defaultColors.put(key_dialogProgressCircle, 0xff289deb);
defaultColors.put(key_dialogProgressCircle, 0xff0A0D0F);
defaultColors.put(key_dialogLineProgress, 0xff527da3);
defaultColors.put(key_dialogLineProgressBackground, 0xffdbdbdb);
defaultColors.put(key_dialogButton, 0xff4991cc);
@ -4626,6 +4667,7 @@ public class Theme {
defaultColors.put(key_chat_mediaLoaderPhotoIconSelected, 0xffd9d9d9);
defaultColors.put(key_chat_secretTimerBackground, 0xcc3e648e);
defaultColors.put(key_chat_secretTimerText, 0xffffffff);
defaultColors.put(key_chat_serviceBackgroundSelector, 0x20ffffff);
defaultColors.put(key_profile_creatorIcon, 0xff3a95d5);
defaultColors.put(key_profile_actionIcon, 0xff81868a);
@ -4796,11 +4838,13 @@ public class Theme {
defaultColors.put(key_statisticChartLine_blue, 0xff327FE5);
defaultColors.put(key_statisticChartLine_green, 0xff61C752);
defaultColors.put(key_statisticChartLine_red, 0xffE05356);
defaultColors.put(key_statisticChartLine_golden, 0xffDEBA08);
defaultColors.put(key_statisticChartLine_golden, 0xffEBA52D);
defaultColors.put(key_statisticChartLine_lightblue, 0xff58A8ED);
defaultColors.put(key_statisticChartLine_lightgreen, 0xff8FCF39);
defaultColors.put(key_statisticChartLine_orange, 0xffE3B727);
defaultColors.put(key_statisticChartLine_orange, 0xffF28C39);
defaultColors.put(key_statisticChartLine_indigo, 0xff7F79F3);
defaultColors.put(key_statisticChartLine_purple, 0xff9F79E8);
defaultColors.put(key_statisticChartLine_cyan, 0xff40D0CA);
defaultColors.put(key_statisticChartLineEmpty, 0xFFEEEEEE);
defaultColors.put(key_actionBarTipBackground, 0xFF446F94);
@ -5849,13 +5893,13 @@ public class Theme {
if (monthOfYear == 0 && dayOfMonth == 1 && hour <= 23) {
canStartHolidayAnimation = true;
} else {
canStartHolidayAnimation = false;
canStartHolidayAnimation = BuildVars.DEBUG_VERSION;//false;
}
if (dialogs_holidayDrawable == null) {
if (monthOfYear == 11 && dayOfMonth >= (BuildVars.DEBUG_PRIVATE_VERSION ? 29 : 31) && dayOfMonth <= 31 || monthOfYear == 0 && dayOfMonth == 1) {
dialogs_holidayDrawable = ApplicationLoader.applicationContext.getResources().getDrawable(R.drawable.newyear);
dialogs_holidayDrawableOffsetX = -AndroidUtilities.dp(3);
dialogs_holidayDrawableOffsetY = -AndroidUtilities.dp(1);
dialogs_holidayDrawableOffsetY = -AndroidUtilities.dp(-7);
}
}
}
@ -6680,7 +6724,7 @@ public class Theme {
}
}
public static void setMaskDrawableRad(Drawable rippleDrawable, int topLeftRad, int topRightRad, int bottomRightRad, int bottomLeftRad) {
public static void setMaskDrawableRad(Drawable rippleDrawable, float topLeftRad, float topRightRad, float bottomRightRad, float bottomLeftRad) {
if (Build.VERSION.SDK_INT < 21) {
return;
}
@ -9821,7 +9865,7 @@ public class Theme {
}
Drawable drawable = wallpaperOverride != null ? wallpaperOverride : currentWallpaper;
boolean drawServiceGradient = drawable instanceof MotionBackgroundDrawable && SharedConfig.getDevicePerformanceClass() != SharedConfig.PERFORMANCE_CLASS_LOW;
boolean drawServiceGradient = drawable instanceof MotionBackgroundDrawable && SharedConfig.getDevicePerformanceClass() != SharedConfig.PERFORMANCE_CLASS_LOW && !SharedConfig.getLiteMode().enabled();
if (drawServiceGradient) {
Bitmap newBitmap = ((MotionBackgroundDrawable) drawable).getBitmap();
if (serviceBitmap != newBitmap) {

View file

@ -232,7 +232,12 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
super(viewType, true);
this.dialog = dialog;
if (dialog != null) {
pinned = dialog.pinned;
if (dialogsType == 7 || dialogsType == 8) {
MessagesController.DialogFilter filter = MessagesController.getInstance(currentAccount).selectedDialogFilter[dialogsType == 8 ? 1 : 0];
pinned = filter != null && filter.pinnedDialogs.indexOfKey(dialog.id) >= 0;
} else {
pinned = dialog.pinned;
}
isFolder = dialog.isFolder;
isForumCell = MessagesController.getInstance(currentAccount).isForum(dialog.id);
}
@ -366,12 +371,12 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
hasHints = folderId == 0 && dialogsType == 0 && !isOnlySelect && !MessagesController.getInstance(currentAccount).hintDialogs.isEmpty();
}
public void updateList(RecyclerListView recyclerListView, boolean hasHiddenArchive) {
public void updateList(RecyclerListView recyclerListView, boolean hasHiddenArchive, float tabsTranslation) {
oldItems.clear();
oldItems.addAll(itemInternals);
updateItemList();
if (recyclerListView != null && recyclerListView.getChildCount() > 0 && recyclerListView.getLayoutManager() != null) {
if (recyclerListView != null && recyclerListView.getScrollState() == RecyclerView.SCROLL_STATE_IDLE && recyclerListView.getChildCount() > 0 && recyclerListView.getLayoutManager() != null) {
LinearLayoutManager layoutManager = ((LinearLayoutManager) recyclerListView.getLayoutManager());
View view = null;
int position = -1;
@ -379,19 +384,19 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
for (int i = 0; i < recyclerListView.getChildCount(); i++) {
int childPosition = recyclerListView.getChildAdapterPosition(recyclerListView.getChildAt(i));
View child = recyclerListView.getChildAt(i);
if (childPosition != RecyclerListView.NO_POSITION && child.getTop() < top) {
if (childPosition != RecyclerListView.NO_POSITION && child != null && child.getTop() < top) {
view = child;
position = childPosition;
top = child.getTop();
}
}
if (view != null) {
int offset = view.getTop() - recyclerListView.getPaddingTop();
if (hasHiddenArchive && position == 0 && view.getTop() - recyclerListView.getPaddingTop() < AndroidUtilities.dp(SharedConfig.useThreeLinesLayout ? 78 : 72)) {
float offset = view.getTop() - recyclerListView.getPaddingTop() + tabsTranslation;
if (hasHiddenArchive && position == 0 && view.getTop() - recyclerListView.getPaddingTop() + tabsTranslation < AndroidUtilities.dp(SharedConfig.useThreeLinesLayout ? 78 : 72)) {
position = 1;
offset = 0;
offset = tabsTranslation;
}
layoutManager.scrollToPositionWithOffset(position, offset);
layoutManager.scrollToPositionWithOffset(position, (int) offset);
}
}
@ -825,7 +830,7 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
toDialog.pinnedNum = oldNum;
}
Collections.swap(dialogs, fromIndex, toIndex);
updateList(recyclerView, false);
updateList(recyclerView, false, 0);
}
@Override
public void notifyItemMoved(int fromPosition, int toPosition) {

View file

@ -70,11 +70,12 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
private final int VIEW_TYPE_HASHTAG_CELL = 5;
private final int VIEW_TYPE_CATEGORY_LIST = 6;
private final int VIEW_TYPE_ADD_BY_PHONE = 7;
private final int VIEW_TYPE_INVITE_CONTACT_CELL = 8;
private Context mContext;
private Runnable searchRunnable;
private Runnable searchRunnable2;
private ArrayList<Object> searchResult = new ArrayList<>();
private ArrayList<ContactsController.Contact> searchContacts = new ArrayList<>();
private ArrayList<TLRPC.TL_forumTopic> searchTopics = new ArrayList<>();
private ArrayList<CharSequence> searchResultNames = new ArrayList<>();
private ArrayList<MessageObject> searchForumResultMessages = new ArrayList<>();
@ -121,6 +122,7 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
private FilteredSearchView.Delegate filtersDelegate;
private int currentItemCount;
private int folderId;
private ArrayList<ContactEntry> allContacts;
public boolean isSearching() {
return waitingResponseCount > 0;
@ -212,7 +214,7 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
}
}
public DialogsSearchAdapter(Context context, int messagesSearch, int type, DefaultItemAnimator itemAnimator) {
public DialogsSearchAdapter(Context context, int messagesSearch, int type, DefaultItemAnimator itemAnimator, boolean allowGlobalSearch) {
this.itemAnimator = itemAnimator;
searchAdapterHelper = new SearchAdapterHelper(false);
searchAdapterHelper.setDelegate(new SearchAdapterHelper.SearchAdapterHelperDelegate() {
@ -252,6 +254,7 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
return searchId == lastSearchId;
}
});
searchAdapterHelper.setAllowGlobalResults(allowGlobalSearch);
mContext = context;
needMessagesSearch = messagesSearch;
dialogsType = type;
@ -540,7 +543,11 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
}
public boolean hasRecentSearch() {
return dialogsType != 2 && dialogsType != 4 && dialogsType != 5 && dialogsType != 6 && dialogsType != 11 && getRecentItemsCount() > 0;
return resentSearchAvailable() && getRecentItemsCount() > 0;
}
private boolean resentSearchAvailable() {
return dialogsType != 2 && dialogsType != 4 && dialogsType != 5 && dialogsType != 6 && dialogsType != 11;
}
public boolean isSearchWas() {
@ -777,15 +784,31 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
String q = query.trim().toLowerCase();
if (q.length() == 0) {
lastSearchId = 0;
updateSearchResults(new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), lastSearchId);
updateSearchResults(new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), lastSearchId);
return;
}
MessagesStorage.getInstance(currentAccount).getStorageQueue().postRunnable(() -> {
ArrayList<Object> resultArray = new ArrayList<>();
ArrayList<CharSequence> resultArrayNames = new ArrayList<>();
ArrayList<TLRPC.User> encUsers = new ArrayList<>();
ArrayList<ContactsController.Contact> contacts = new ArrayList<>();
MessagesStorage.getInstance(currentAccount).localSearch(dialogsType, q, resultArray, resultArrayNames, encUsers, -1);
updateSearchResults(resultArray, resultArrayNames, encUsers, searchId);
// if (allContacts == null) {
// allContacts = new ArrayList<>();
// for (ContactsController.Contact contact : ContactsController.getInstance(currentAccount).phoneBookContacts) {
// ContactEntry contactEntry = new ContactEntry();
// contactEntry.contact = contact;
// contactEntry.q1 = (contact.first_name + " " + contact.last_name).toLowerCase();
// contactEntry.q2 = (contact.last_name + " " + contact.first_name).toLowerCase();
// allContacts.add(contactEntry);
// }
// }
// for (int i = 0; i < allContacts.size(); i++) {
// if (allContacts.get(i).q1.toLowerCase().contains(q) || allContacts.get(i).q1.toLowerCase().contains(q)) {
// contacts.add(allContacts.get(i).contact);
// }
// }
updateSearchResults(resultArray, resultArrayNames, encUsers, contacts, searchId);
FiltersView.fillTipDates(q, localTipDates);
localTipArchive = false;
if (q.length() >= 3 && (LocaleController.getString("ArchiveSearchFilter", R.string.ArchiveSearchFilter).toLowerCase().startsWith(q) || "archive".startsWith(query))) {
@ -800,7 +823,7 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
}
private void updateSearchResults(final ArrayList<Object> result, final ArrayList<CharSequence> names, final ArrayList<TLRPC.User> encUsers, final int searchId) {
private void updateSearchResults(final ArrayList<Object> result, final ArrayList<CharSequence> names, final ArrayList<TLRPC.User> encUsers, final ArrayList<ContactsController.Contact> contacts, final int searchId) {
AndroidUtilities.runOnUIThread(() -> {
waitingResponseCount--;
if (searchId != lastSearchId) {
@ -853,25 +876,28 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
}
}
boolean foundInRecent = false;
if (delegate != null && delegate.getSearchForumDialogId() == dialogId) {
foundInRecent = true;
}
for (int j = 0; !foundInRecent && j < recentCount; ++j) {
RecentSearchObject o = filtered2RecentSearchObjects.get(j);
if (o != null && o.did == dialogId) {
if (resentSearchAvailable()) {
boolean foundInRecent = false;
if (delegate != null && delegate.getSearchForumDialogId() == dialogId) {
foundInRecent = true;
}
}
if (foundInRecent) {
result.remove(a);
names.remove(a);
a--;
for (int j = 0; !foundInRecent && j < recentCount; ++j) {
RecentSearchObject o = filtered2RecentSearchObjects.get(j);
if (o != null && o.did == dialogId) {
foundInRecent = true;
}
}
if (foundInRecent) {
result.remove(a);
names.remove(a);
a--;
}
}
}
MessagesController.getInstance(currentAccount).putUsers(encUsers, true);
searchResult = result;
searchResultNames = names;
// searchContacts = contacts;
searchAdapterHelper.mergeResults(searchResult, filtered2RecentSearchObjects);
notifyDataSetChanged();
if (delegate != null) {
@ -1024,8 +1050,13 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
}
if (!searchTopics.isEmpty()) {
count++;
count += searchTopics.size();
}
count += searchTopics.size();
if (!searchContacts.isEmpty()) {
int contactsCount = searchContacts.size();
count += contactsCount + 1;
}
int resultsCount = searchResult.size();
count += resultsCount;
int localServerCount = searchAdapterHelper.getLocalServerSearch().size();
@ -1102,6 +1133,12 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
}
i -= 1 + searchTopics.size();
}
if (!searchContacts.isEmpty()) {
if (i > 0 && i <= searchContacts.size()) {
return searchContacts.get(i - 1);
}
i -= 1 + searchContacts.size();
}
ArrayList<TLObject> globalSearch = searchAdapterHelper.getGlobalSearch();
ArrayList<TLObject> localServerSearch = searchAdapterHelper.getLocalServerSearch();
ArrayList<Object> phoneSearch = searchAdapterHelper.getPhoneSearch();
@ -1178,7 +1215,11 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
if (globalCount > 4 && globalSearchCollapsed) {
globalCount = 4;
}
int contactsCount = searchContacts.size();
if (i >= 0 && i < contactsCount) {
return false;
}
i -= contactsCount + 1;
if (i >= 0 && i < localCount) {
return false;
}
@ -1286,6 +1327,9 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
view = horizontalListView;
innerListView = horizontalListView;
break;
case VIEW_TYPE_INVITE_CONTACT_CELL:
view = new ProfileSearchCell(mContext);
break;
case VIEW_TYPE_ADD_BY_PHONE:
default:
view = new TextCell(mContext, 16, false);
@ -1449,7 +1493,7 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
});
} else {
int rawPosition = position;
if (isRecentSearchDisplayed() || !searchTopics.isEmpty()) {
if (isRecentSearchDisplayed() || !searchTopics.isEmpty() || !searchContacts.isEmpty()) {
int offset = (!searchWas && !MediaDataController.getInstance(currentAccount).hints.isEmpty() ? 1 : 0);
if (position < offset) {
cell.setText(LocaleController.getString("ChatHints", R.string.ChatHints));
@ -1469,7 +1513,7 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
});
}
return;
} else if (position == getRecentItemsCount() + (searchTopics.isEmpty() ? 0 : searchTopics.size() + 1)) {
} else if (position == getRecentItemsCount() + (searchTopics.isEmpty() ? 0 : searchTopics.size() + 1) + (searchContacts.isEmpty() ? 0 : searchContacts.size() + 1)) {
cell.setText(LocaleController.getString("SearchAllChatsShort", R.string.SearchAllChatsShort));
return;
} else {
@ -1498,6 +1542,12 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
}
position -= 1 + searchTopics.size();
}
if (!searchContacts.isEmpty()) {
if (position == 0) {
title = LocaleController.getString("InviteToTelegramShort", R.string.InviteToTelegramShort);
}
position -= 1 + searchContacts.size();
}
if (title == null) {
position -= localCount + localServerCount;
if (position >= 0 && position < phoneCount) {
@ -1630,6 +1680,12 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
cell.setText(LocaleController.formatString("AddContactByPhone", R.string.AddContactByPhone, PhoneFormat.getInstance().format("+" + str)), false);
break;
}
case VIEW_TYPE_INVITE_CONTACT_CELL: {
ProfileSearchCell profileSearchCell = (ProfileSearchCell) holder.itemView;
ContactsController.Contact contact = (ContactsController.Contact) getItem(position);
profileSearchCell.setData(contact, null, ContactsController.formatName(contact.first_name, contact.last_name), PhoneFormat.getInstance().format("+" + contact.shortPhones.get(0)), false, false);
break;
}
}
}
@ -1662,6 +1718,15 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
}
i -= 1 + searchTopics.size();
}
if (!searchContacts.isEmpty()) {
if (i == 0) {
return VIEW_TYPE_GRAY_SECTION;
} else if (i <= searchContacts.size()) {
return VIEW_TYPE_INVITE_CONTACT_CELL;
}
i -= 1 + searchContacts.size();
}
ArrayList<TLObject> globalSearch = searchAdapterHelper.getGlobalSearch();
int localCount = searchResult.size();
int localServerCount = searchAdapterHelper.getLocalServerSearch().size();
@ -1809,4 +1874,10 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
public interface OnRecentSearchLoaded {
void setRecentSearch(ArrayList<RecentSearchObject> arrayList, LongSparseArray<RecentSearchObject> hashMap);
}
private static class ContactEntry {
String q1;
String q2;
ContactsController.Contact contact;
}
}

View file

@ -63,6 +63,8 @@ public class SearchAdapter extends RecyclerListView.SelectionAdapter {
private boolean searchInProgress;
private int searchReqId;
private int searchPointer;
private ArrayList<ContactEntry> allUnregistredContacts;
private ArrayList<ContactsController.Contact> unregistredContacts = new ArrayList<>();
public SearchAdapter(Context context, LongSparseArray<TLRPC.User> arg1, boolean usernameSearch, boolean mutual, boolean chats, boolean bots, boolean self, boolean phones, int searchChannelId) {
@ -109,6 +111,7 @@ public class SearchAdapter extends RecyclerListView.SelectionAdapter {
FileLog.e(e);
}
searchResult.clear();
unregistredContacts.clear();
searchResultNames.clear();
if (allowUsernameSearch) {
searchAdapterHelper.queryServerSearch(null, true, allowChats, allowBots, allowSelf, false, channelId, allowPhoneNumbers, 0, 0);
@ -144,7 +147,7 @@ public class SearchAdapter extends RecyclerListView.SelectionAdapter {
Utilities.searchQueue.postRunnable(() -> {
String search1 = query.trim().toLowerCase();
if (search1.length() == 0) {
updateSearchResults(searchReqIdFinal, new ArrayList<>(), new ArrayList<>());
updateSearchResults(searchReqIdFinal, new ArrayList<>(), new ArrayList<>(), unregistredContacts);
return;
}
String search2 = LocaleController.getInstance().getTranslitString(search1);
@ -159,6 +162,7 @@ public class SearchAdapter extends RecyclerListView.SelectionAdapter {
ArrayList<Object> resultArray = new ArrayList<>();
ArrayList<CharSequence> resultArrayNames = new ArrayList<>();
ArrayList<ContactsController.Contact> unregistredContacts = new ArrayList<>();
for (int a = 0; a < contactsCopy.size(); a++) {
TLRPC.TL_contact contact = contactsCopy.get(a);
@ -203,16 +207,35 @@ public class SearchAdapter extends RecyclerListView.SelectionAdapter {
}
}
}
updateSearchResults(searchReqIdFinal, resultArray, resultArrayNames);
if (allUnregistredContacts == null) {
allUnregistredContacts = new ArrayList<>();
for (ContactsController.Contact contact : ContactsController.getInstance(currentAccount).phoneBookContacts) {
ContactEntry contactEntry = new ContactEntry();
contactEntry.contact = contact;
contactEntry.q1 = (contact.first_name + " " + contact.last_name).toLowerCase();
contactEntry.q2 = (contact.last_name + " " + contact.first_name).toLowerCase();
allUnregistredContacts.add(contactEntry);
}
}
for (int i = 0; i < allUnregistredContacts.size(); i++) {
ContactEntry contact = allUnregistredContacts.get(i);
if ((search2 != null && (contact.q1.toLowerCase().contains(search2) || contact.q1.toLowerCase().contains(search2))) || contact.q1.toLowerCase().contains(search1) || contact.q1.toLowerCase().contains(search1)) {
unregistredContacts.add(contact.contact);
}
}
updateSearchResults(searchReqIdFinal, resultArray, resultArrayNames, unregistredContacts);
});
});
}
private void updateSearchResults(int searchReqIdFinal, final ArrayList<Object> users, final ArrayList<CharSequence> names) {
private void updateSearchResults(int searchReqIdFinal, final ArrayList<Object> users, final ArrayList<CharSequence> names, ArrayList<ContactsController.Contact> unregistredContacts) {
AndroidUtilities.runOnUIThread(() -> {
if (searchReqIdFinal == searchReqId) {
searchResult = users;
searchResultNames = names;
this.unregistredContacts = unregistredContacts;
searchAdapterHelper.mergeResults(users);
searchInProgress = false;
notifyDataSetChanged();
@ -232,12 +255,19 @@ public class SearchAdapter extends RecyclerListView.SelectionAdapter {
@Override
public boolean isEnabled(RecyclerView.ViewHolder holder) {
int type = holder.getItemViewType();
return type == 0 || type == 2;
return type == 0 || type == 2 || type == 3;
}
int unregistredContactsHeaderRow;
@Override
public int getItemCount() {
unregistredContactsHeaderRow = -1;
int count = searchResult.size();
unregistredContactsHeaderRow = count;
if (!unregistredContacts.isEmpty()) {
count += unregistredContacts.size() + 1;
}
int globalCount = searchAdapterHelper.getGlobalSearch().size();
if (globalCount != 0) {
count += globalCount + 1;
@ -251,13 +281,16 @@ public class SearchAdapter extends RecyclerListView.SelectionAdapter {
public boolean isGlobalSearch(int i) {
int localCount = searchResult.size();
int unregistredCount = unregistredContacts.size();
int globalCount = searchAdapterHelper.getGlobalSearch().size();
int phoneCount = searchAdapterHelper.getPhoneSearch().size();
if (i >= 0 && i < localCount) {
return false;
} else if (i > localCount && i < localCount + phoneCount) {
} else if (i > localCount && i < localCount + unregistredCount + 1) {
return false;
} else if (i > localCount + phoneCount && i <= globalCount + phoneCount + localCount) {
} else if (i > localCount + unregistredCount + 1 && i < localCount + phoneCount + unregistredCount + 1) {
return false;
} else if (i > localCount + phoneCount + unregistredCount + 1 && i <= globalCount + phoneCount + localCount + unregistredCount + 1) {
return true;
}
return false;
@ -265,12 +298,23 @@ public class SearchAdapter extends RecyclerListView.SelectionAdapter {
public Object getItem(int i) {
int localCount = searchResult.size();
int unregistredCount = unregistredContacts.size();
int globalCount = searchAdapterHelper.getGlobalSearch().size();
int phoneCount = searchAdapterHelper.getPhoneSearch().size();
if (i >= 0 && i < localCount) {
return searchResult.get(i);
} else {
i -= localCount;
if (unregistredCount > 0) {
if (i == 0) {
return null;
}
if (i > 0 && i <= unregistredCount) {
return unregistredContacts.get(i - 1);
} else {
i -= unregistredCount + 1;
}
}
if (i >= 0 && i < phoneCount) {
return searchAdapterHelper.getPhoneSearch().get(i);
} else {
@ -304,6 +348,9 @@ public class SearchAdapter extends RecyclerListView.SelectionAdapter {
default:
view = new TextCell(mContext, 16, false);
break;
case 3:
view = new ProfileSearchCell(mContext);
break;
}
return new RecyclerListView.Holder(view);
}
@ -388,7 +435,9 @@ public class SearchAdapter extends RecyclerListView.SelectionAdapter {
}
case 1: {
GraySectionCell cell = (GraySectionCell) holder.itemView;
if (getItem(position) == null) {
if (position == unregistredContactsHeaderRow) {
cell.setText(LocaleController.getString("InviteToTelegramShort", R.string.InviteToTelegramShort));
} else if (getItem(position) == null) {
cell.setText(LocaleController.getString("GlobalSearch", R.string.GlobalSearch));
} else {
cell.setText(LocaleController.getString("PhoneNumberSearch", R.string.PhoneNumberSearch));
@ -402,6 +451,13 @@ public class SearchAdapter extends RecyclerListView.SelectionAdapter {
cell.setText(LocaleController.formatString("AddContactByPhone", R.string.AddContactByPhone, PhoneFormat.getInstance().format("+" + str)), false);
break;
}
case 3: {
ProfileSearchCell profileSearchCell = (ProfileSearchCell) holder.itemView;
ContactsController.Contact contact = (ContactsController.Contact) getItem(position);
profileSearchCell.useSeparator = getItem(position + 1) instanceof ContactsController.Contact ;
profileSearchCell.setData(contact, null, ContactsController.formatName(contact.first_name, contact.last_name), PhoneFormat.getInstance().format("+" + contact.shortPhones.get(0)), false, false);
break;
}
}
}
@ -417,7 +473,15 @@ public class SearchAdapter extends RecyclerListView.SelectionAdapter {
} else {
return 2;
}
} else if (item instanceof ContactsController.Contact) {
return 3;
}
return 0;
}
private static class ContactEntry {
String q1;
String q2;
ContactsController.Contact contact;
}
}

View file

@ -3687,7 +3687,7 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg
textSelectionHelper.setParentView(listView[0]);
if (MessagesController.getGlobalMainSettings().getBoolean("translate_button", false)) {
textSelectionHelper.setOnTranslate((text, fromLang, toLang, onAlertDismiss) -> {
TranslateAlert.showAlert(parentActivity, parentFragment, fromLang, toLang, text, false, null, onAlertDismiss);
TranslateAlert.showAlert(parentActivity, parentFragment, currentAccount, fromLang, toLang, text, false, null, onAlertDismiss);
});
}
textSelectionHelper.layoutManager = layoutManager[0];

View file

@ -0,0 +1,327 @@
package org.telegram.ui;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.CacheByChatsController;
import org.telegram.messenger.ContactsController;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.R;
import org.telegram.tgnet.TLObject;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.ActionBar;
import org.telegram.ui.ActionBar.ActionBarPopupWindow;
import org.telegram.ui.ActionBar.AlertDialog;
import org.telegram.ui.ActionBar.BackDrawable;
import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Cells.ShadowSectionCell;
import org.telegram.ui.Cells.TextCell;
import org.telegram.ui.Cells.UserCell;
import org.telegram.ui.Components.AlertsCreator;
import org.telegram.ui.Components.ListView.AdapterWithDiffUtils;
import org.telegram.ui.Components.RecyclerListView;
import java.util.ArrayList;
public class CacheChatsExceptionsFragment extends BaseFragment {
private final int VIEW_TYPE_ADD_EXCEPTION = 1;
private final int VIEW_TYPE_CHAT= 2;
private final int VIEW_TYPE_DIVIDER = 3;
private final int VIEW_TYPE_DELETE_ALL = 4;
Adapter adapter;
RecyclerListView recyclerListView;
ArrayList<Item> items = new ArrayList<>();
ArrayList<CacheByChatsController.KeepMediaException> exceptionsDialogs = new ArrayList<>();
int currentType;
public CacheChatsExceptionsFragment(Bundle bundle) {
super(bundle);
}
@Override
public View createView(Context context) {
FrameLayout frameLayout = new FrameLayout(context);
fragmentView = frameLayout;
actionBar.setBackButtonDrawable(new BackDrawable(false));
actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() {
@Override
public void onItemClick(int id) {
if (id == -1) {
finishFragment();
return;
}
}
});
actionBar.setTitle(LocaleController.getString(R.string.NotificationsExceptions));
recyclerListView = new RecyclerListView(context);
DefaultItemAnimator defaultItemAnimator = new DefaultItemAnimator();
defaultItemAnimator.setDelayAnimations(false);
defaultItemAnimator.setSupportsChangeAnimations(false);
recyclerListView.setItemAnimator(defaultItemAnimator);
recyclerListView.setLayoutManager(new LinearLayoutManager(context));
recyclerListView.setAdapter(adapter = new Adapter());
recyclerListView.setOnItemClickListener((view, position, x, y) -> {
if (items.get(position).viewType == VIEW_TYPE_ADD_EXCEPTION) {
Bundle args = new Bundle();
args.putBoolean("onlySelect", true);
args.putBoolean("checkCanWrite", false);
if (currentType == CacheControlActivity.KEEP_MEDIA_TYPE_GROUP) {
args.putInt("dialogsType", 6);
} else if (currentType == CacheControlActivity.KEEP_MEDIA_TYPE_CHANNEL) {
args.putInt("dialogsType", 5);
} else {
args.putInt("dialogsType", 4);
}
args.putBoolean("allowGlobalSearch", false);
DialogsActivity activity = new DialogsActivity(args);
activity.setDelegate((fragment, dids, message, param) -> {
activity.finishFragment();
CacheByChatsController.KeepMediaException newException = null;
for (int i = 0; i < dids.size(); i++) {
boolean contains = false;
for (int k = 0; k < exceptionsDialogs.size(); k++) {
if (exceptionsDialogs.get(k).dialogId == dids.get(i).dialogId) {
newException = exceptionsDialogs.get(k);
contains = true;
break;
}
}
if (!contains) {
int startFrom = CacheByChatsController.KEEP_MEDIA_FOREVER;
if (getMessagesController().getCacheByChatsController().getKeepMedia(currentType) == CacheByChatsController.KEEP_MEDIA_FOREVER) {
startFrom = CacheByChatsController.KEEP_MEDIA_ONE_DAY;
}
exceptionsDialogs.add(newException = new CacheByChatsController.KeepMediaException(dids.get(i).dialogId, startFrom));
}
}
getMessagesController().getCacheByChatsController().saveKeepMediaExceptions(currentType, exceptionsDialogs);
updateRows();
if (newException != null) {
int p = 0;
for (int i = 0; i < items.size(); i++) {
if (items.get(i).exception != null && items.get(i).exception.dialogId == newException.dialogId) {
p = i;
break;
}
}
recyclerListView.scrollToPosition(p);
int finalP = p;
showPopupFor(newException);
}
});
presentFragment(activity);
} else if (items.get(position).viewType == VIEW_TYPE_CHAT) {
CacheByChatsController.KeepMediaException keepMediaException = items.get(position).exception;
KeepMediaPopupView windowLayout = new KeepMediaPopupView(CacheChatsExceptionsFragment.this, view.getContext());
windowLayout.updateForDialog(false);
ActionBarPopupWindow popupWindow = AlertsCreator.createSimplePopup(CacheChatsExceptionsFragment.this, windowLayout, view, x, y);
windowLayout.setParentWindow(popupWindow);
windowLayout.setCallback((type, keepMedia) -> {
if (keepMedia == CacheByChatsController.KEEP_MEDIA_DELETE) {
exceptionsDialogs.remove(keepMediaException);
updateRows();
} else {
keepMediaException.keepMedia = keepMedia;
AndroidUtilities.updateVisibleRows(recyclerListView);
}
getMessagesController().getCacheByChatsController().saveKeepMediaExceptions(currentType, exceptionsDialogs);
});
} else if (items.get(position).viewType == VIEW_TYPE_DELETE_ALL) {
AlertDialog alertDialog = AlertsCreator.createSimpleAlert(getContext(),
LocaleController.getString("NotificationsDeleteAllExceptionTitle", R.string.NotificationsDeleteAllExceptionTitle),
LocaleController.getString("NotificationsDeleteAllExceptionAlert", R.string.NotificationsDeleteAllExceptionAlert),
LocaleController.getString("Delete", R.string.Delete),
() -> {
exceptionsDialogs.clear();
getMessagesController().getCacheByChatsController().saveKeepMediaExceptions(currentType, exceptionsDialogs);
updateRows();
finishFragment();
}, null).create();
alertDialog.show();
alertDialog.redPositive();
}
});
frameLayout.addView(recyclerListView);
frameLayout.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundGray));
updateRows();
return fragmentView;
}
public void showPopupFor(CacheByChatsController.KeepMediaException newException) {
AndroidUtilities.runOnUIThread(() -> {
int p = 0;
for (int i = 0; i < items.size(); i++) {
if (items.get(i).exception != null && items.get(i).exception.dialogId == newException.dialogId) {
p = i;
break;
}
}
RecyclerView.ViewHolder viewHolder = recyclerListView.findViewHolderForAdapterPosition(p);
if (viewHolder != null) {
KeepMediaPopupView windowLayout = new KeepMediaPopupView(CacheChatsExceptionsFragment.this, getContext());
windowLayout.updateForDialog(true);
ActionBarPopupWindow popupWindow = AlertsCreator.createSimplePopup(CacheChatsExceptionsFragment.this, windowLayout, viewHolder.itemView, viewHolder.itemView.getMeasuredWidth() / 2f, viewHolder.itemView.getMeasuredHeight() / 2f);
windowLayout.setParentWindow(popupWindow);
windowLayout.setCallback((type, keepMedia) -> {
newException.keepMedia = keepMedia;
getMessagesController().getCacheByChatsController().saveKeepMediaExceptions(currentType, exceptionsDialogs);
AndroidUtilities.updateVisibleRows(recyclerListView);
});
}
}, 150);
}
@Override
public boolean onFragmentCreate() {
currentType = getArguments().getInt("type");
updateRows();
return super.onFragmentCreate();
}
private void updateRows() {
boolean animated = !isPaused && adapter != null;
ArrayList<Item> oldItems = null;
if (animated) {
oldItems = new ArrayList();
oldItems.addAll(items);
}
items.clear();
items.add(new Item(VIEW_TYPE_ADD_EXCEPTION, null));
boolean added = false;
for (CacheByChatsController.KeepMediaException exception : exceptionsDialogs) {
items.add(new Item(VIEW_TYPE_CHAT, exception));
added = true;
}
if (added) {
items.add(new Item(VIEW_TYPE_DIVIDER, null));
items.add(new Item(VIEW_TYPE_DELETE_ALL, null));
}
items.add(new Item(VIEW_TYPE_DIVIDER, null));
if (adapter != null) {
if (oldItems != null) {
adapter.setItems(oldItems, items);
} else {
adapter.notifyDataSetChanged();
}
}
}
public void setExceptions(ArrayList<CacheByChatsController.KeepMediaException> notificationsExceptionTopics) {
exceptionsDialogs = notificationsExceptionTopics;
updateRows();
}
private class Adapter extends AdapterWithDiffUtils {
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = null;
switch (viewType) {
case VIEW_TYPE_CHAT:
view = new UserCell(parent.getContext(), 4, 0, false, false);
view.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite));
break;
case VIEW_TYPE_ADD_EXCEPTION:
TextCell textCell = new TextCell(parent.getContext());
textCell.setTextAndIcon(LocaleController.getString("NotificationsAddAnException", R.string.NotificationsAddAnException), R.drawable.msg_contact_add, true);
textCell.setColors(Theme.key_windowBackgroundWhiteBlueIcon, Theme.key_windowBackgroundWhiteBlueButton);
view = textCell;
view.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite));
break;
case VIEW_TYPE_DIVIDER:
view = new ShadowSectionCell(parent.getContext());
break;
case VIEW_TYPE_DELETE_ALL:
textCell = new TextCell(parent.getContext());
textCell.setText(LocaleController.getString("NotificationsDeleteAllException", R.string.NotificationsDeleteAllException), false);
textCell.setColors(null, Theme.key_windowBackgroundWhiteRedText5);
view = textCell;
view.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite));
break;
}
view.setLayoutParams(new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
return new RecyclerListView.Holder(view);
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
if (items.get(position).viewType == VIEW_TYPE_CHAT) {
UserCell cell = (UserCell) holder.itemView;
CacheByChatsController.KeepMediaException exception = items.get(position).exception;
TLObject object = getMessagesController().getUserOrChat(exception.dialogId);
String title = null;
if (object instanceof TLRPC.User) {
TLRPC.User user = (TLRPC.User) object;
if (user.self) {
title = LocaleController.getString("SavedMessages", R.string.SavedMessages);
} else {
title = ContactsController.formatName(user.first_name, user.last_name);
}
} else if (object instanceof TLRPC.Chat) {
TLRPC.Chat chat = (TLRPC.Chat) object;
title = chat.title;
}
cell.setSelfAsSavedMessages(true);
cell.setData(object, title, CacheByChatsController.getKeepMediaString(exception.keepMedia), 0, !(position != items.size() - 1 && items.get(position + 1).viewType != VIEW_TYPE_CHAT));
}
}
@Override
public int getItemCount() {
return items.size();
}
@Override
public int getItemViewType(int position) {
return items.get(position).viewType;
}
@Override
public boolean isEnabled(RecyclerView.ViewHolder holder) {
return holder.getItemViewType() == VIEW_TYPE_ADD_EXCEPTION || holder.getItemViewType() == VIEW_TYPE_CHAT || holder.getItemViewType() == VIEW_TYPE_DELETE_ALL;
}
}
private class Item extends AdapterWithDiffUtils.Item {
final CacheByChatsController.KeepMediaException exception;
private Item(int viewType, CacheByChatsController.KeepMediaException exception) {
super(viewType, false);
this.exception = exception;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Item item = (Item) o;
if (viewType != item.viewType) {
return false;
}
if (exception != null && item.exception != null) {
return exception.dialogId == item.exception.dialogId;
}
return true;
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -35,7 +35,6 @@ import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.style.ClickableSpan;
import android.util.Log;
import android.util.SparseArray;
import android.util.TypedValue;
import android.view.Gravity;
@ -142,6 +141,7 @@ public class CameraScanActivity extends BaseFragment {
public static final int TYPE_MRZ = 0;
public static final int TYPE_QR = 1;
public static final int TYPE_QR_LOGIN = 2;
public static final int TYPE_QR_WEB_BOT = 3;
public interface CameraScanActivityDelegate {
default void didFindMrzInfo(MrzRecognizer.Result result) {
@ -155,20 +155,31 @@ public class CameraScanActivity extends BaseFragment {
default boolean processQr(String text, Runnable onLoadEnd) {
return false;
}
}
public static INavigationLayout[] showAsSheet(BaseFragment parentFragment, boolean gallery, int type, CameraScanActivityDelegate cameraDelegate) {
if (parentFragment == null || parentFragment.getParentActivity() == null) {
default String getSubtitleText() {
return null;
}
INavigationLayout[] actionBarLayout = new INavigationLayout[]{INavigationLayout.newLayout(parentFragment.getParentActivity())};
BottomSheet bottomSheet = new BottomSheet(parentFragment.getParentActivity(), false) {
default void onDismiss() {}
}
public static BottomSheet showAsSheet(BaseFragment parentFragment, boolean gallery, int type, CameraScanActivityDelegate cameraDelegate) {
return showAsSheet(parentFragment.getParentActivity(), gallery, type, cameraDelegate);
}
public static BottomSheet showAsSheet(Activity parentActivity, boolean gallery, int type, CameraScanActivityDelegate cameraDelegate) {
if (parentActivity == null) {
return null;
}
INavigationLayout[] actionBarLayout = new INavigationLayout[]{INavigationLayout.newLayout(parentActivity)};
BottomSheet bottomSheet = new BottomSheet(parentActivity, false) {
CameraScanActivity fragment;
{
actionBarLayout[0].setFragmentStack(new ArrayList<>());
fragment = new CameraScanActivity(type) {
@Override
public void finishFragment() {
setFinishing(true);
dismiss();
}
@ -183,6 +194,9 @@ public class CameraScanActivity extends BaseFragment {
actionBarLayout[0].showLastFragment();
actionBarLayout[0].getView().setPadding(backgroundPaddingLeft, 0, backgroundPaddingLeft, 0);
fragment.setDelegate(cameraDelegate);
if (cameraDelegate.getSubtitleText() != null) {
fragment.descriptionText.setText(cameraDelegate.getSubtitleText());
}
containerView = actionBarLayout[0].getView();
setApplyBottomPadding(false);
setApplyBottomPadding(false);
@ -207,6 +221,7 @@ public class CameraScanActivity extends BaseFragment {
public void dismiss() {
super.dismiss();
actionBarLayout[0] = null;
cameraDelegate.onDismiss();
}
};
bottomSheet.setUseLightStatusBar(false);
@ -215,7 +230,7 @@ public class CameraScanActivity extends BaseFragment {
bottomSheet.setUseLightStatusBar(false);
bottomSheet.getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
bottomSheet.show();
return actionBarLayout;
return bottomSheet;
}
public CameraScanActivity(int type) {
@ -304,7 +319,11 @@ public class CameraScanActivity extends BaseFragment {
flashButton.measure(MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(60), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(60), MeasureSpec.EXACTLY));
}
titleTextView.measure(MeasureSpec.makeMeasureSpec(width - AndroidUtilities.dp(72), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(height, MeasureSpec.UNSPECIFIED));
descriptionText.measure(MeasureSpec.makeMeasureSpec((int) (width * 0.9f), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(height, MeasureSpec.UNSPECIFIED));
if (currentType == TYPE_QR_WEB_BOT) {
descriptionText.measure(MeasureSpec.makeMeasureSpec(width - AndroidUtilities.dp(72), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(height, MeasureSpec.UNSPECIFIED));
} else {
descriptionText.measure(MeasureSpec.makeMeasureSpec((int) (width * 0.9f), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(height, MeasureSpec.UNSPECIFIED));
}
setMeasuredDimension(width, height);
}
@ -335,6 +354,10 @@ public class CameraScanActivity extends BaseFragment {
y = (height - size) / 2 - titleTextView.getMeasuredHeight() - AndroidUtilities.dp(64);
}
titleTextView.layout(AndroidUtilities.dp(36), y, AndroidUtilities.dp(36) + titleTextView.getMeasuredWidth(), y + titleTextView.getMeasuredHeight());
if (currentType == TYPE_QR_WEB_BOT) {
y += titleTextView.getMeasuredHeight() + AndroidUtilities.dp(8);
descriptionText.layout(AndroidUtilities.dp(36), y, AndroidUtilities.dp(36) + descriptionText.getMeasuredWidth(), y + descriptionText.getMeasuredHeight());
}
recognizedMrzView.layout(0, getMeasuredHeight() - recognizedMrzView.getMeasuredHeight(), getMeasuredWidth(), getMeasuredHeight());
int x;
@ -352,9 +375,11 @@ public class CameraScanActivity extends BaseFragment {
}
}
y = (int) (height * 0.74f);
int x = (int) (width * 0.05f);
descriptionText.layout(x, y, x + descriptionText.getMeasuredWidth(), y + descriptionText.getMeasuredHeight());
if (currentType != TYPE_QR_WEB_BOT) {
y = (int) (height * 0.74f);
int x = (int) (width * 0.05f);
descriptionText.layout(x, y, x + descriptionText.getMeasuredWidth(), y + descriptionText.getMeasuredHeight());
}
updateNormalBounds();
}
@ -433,7 +458,7 @@ public class CameraScanActivity extends BaseFragment {
viewGroup.setOnTouchListener((v, event) -> true);
fragmentView = viewGroup;
if (currentType == TYPE_QR || currentType == TYPE_QR_LOGIN) {
if (isQr()) {
fragmentView.postDelayed(this::initCameraView, 450);
} else {
initCameraView();
@ -452,7 +477,7 @@ public class CameraScanActivity extends BaseFragment {
viewGroup.addView(actionBar);
}
if (currentType == TYPE_QR_LOGIN) {
if (currentType == TYPE_QR_LOGIN || currentType == TYPE_QR_WEB_BOT) {
actionBar.setTitle(LocaleController.getString("AuthAnotherClientScan", R.string.AuthAnotherClientScan));
}
@ -564,7 +589,7 @@ public class CameraScanActivity extends BaseFragment {
if (needGalleryButton) {
//titleTextView.setText(LocaleController.getString("WalletScanCode", R.string.WalletScanCode));
} else {
if (currentType == TYPE_QR) {
if (currentType == TYPE_QR || currentType == TYPE_QR_WEB_BOT) {
titleTextView.setText(LocaleController.getString("AuthAnotherClientScan", R.string.AuthAnotherClientScan));
} else {
String text = LocaleController.getString("AuthAnotherClientInfo5", R.string.AuthAnotherClientInfo5);
@ -601,6 +626,9 @@ public class CameraScanActivity extends BaseFragment {
}
}
titleTextView.setTextColor(0xffffffff);
if (currentType == TYPE_QR_WEB_BOT) {
descriptionText.setTextColor(0x99ffffff);
}
recognizedMrzView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
recognizedMrzView.setPadding(AndroidUtilities.dp(10), 0, AndroidUtilities.dp(10), AndroidUtilities.dp(10));
if (needGalleryButton) {
@ -717,17 +745,27 @@ public class CameraScanActivity extends BaseFragment {
private ValueAnimator recognizedAnimator;
private float recognizedT = 0;
private float newRecognizedT = 0;
private SpringAnimation useRecognizedBoundsAnimator;
private float useRecognizedBounds = 0;
private void updateRecognized() {
if (recognizedAnimator != null) {
recognizedAnimator.cancel();
float wasNewRecognizedT = recognizedT;
newRecognizedT = recognized ? 1f : 0f;
if (wasNewRecognizedT != newRecognizedT) {
if (recognizedAnimator != null) {
recognizedAnimator.cancel();
}
} else {
return;
}
float newRecognizedT = recognized ? 1f : 0f;
recognizedAnimator = ValueAnimator.ofFloat(recognizedT, newRecognizedT);
recognizedAnimator.addUpdateListener(a -> {
recognizedT = (float) a.getAnimatedValue();
titleTextView.setAlpha(1f - recognizedT);
if (currentType == TYPE_QR_WEB_BOT) {
descriptionText.setAlpha(1f - recognizedT);
}
flashButton.setAlpha(1f - recognizedT);
backShadowAlpha = .5f + recognizedT * .25f;
fragmentView.invalidate();
@ -988,15 +1026,32 @@ public class CameraScanActivity extends BaseFragment {
(recognizeIndex == 0 && res != null && res.bounds == null && !qrLoading) || // first recognition doesn't have bounds
(SystemClock.elapsedRealtime() - recognizedStart > 1000 && !qrLoading) // got more than 1 second and nothing is loading
) && recognizedText != null) {
if (cameraView != null && cameraView.getCameraSession() != null) {
if (cameraView != null && cameraView.getCameraSession() != null && currentType != TYPE_QR_WEB_BOT) {
CameraController.getInstance().stopPreview(cameraView.getCameraSession());
}
String text = recognizedText;
AndroidUtilities.runOnUIThread(() -> {
if (delegate != null) {
delegate.didFindQr(recognizedText);
delegate.didFindQr(text);
}
if (currentType != TYPE_QR_WEB_BOT) {
finishFragment();
}
finishFragment();
});
if (currentType == TYPE_QR_WEB_BOT) {
AndroidUtilities.runOnUIThread(()->{
if (isFinishing()) {
return;
}
recognizedText = null;
recognized = false;
requestShot.run();
if (!recognized) {
AndroidUtilities.runOnUIThread(this::updateRecognized, 500);
}
});
}
} else if (recognized) {
long delay = Math.max(16, 1000 / sps - (long) averageProcessTime);
handler.postDelayed(() -> {
@ -1206,14 +1261,10 @@ public class CameraScanActivity extends BaseFragment {
return null;
}
if (needGalleryButton) {
if (!text.startsWith("ton://transfer/")) {
//onNoWalletFound(bitmap != null);
return null;
}
Uri uri = Uri.parse(text);
String path = uri.getPath().replace("/", "");
} else {
if (!text.startsWith("tg://login?token=")) {
if (!text.startsWith("tg://login?token=") && currentType != TYPE_QR_WEB_BOT) {
onNoQrFound();
return null;
}
@ -1239,7 +1290,7 @@ public class CameraScanActivity extends BaseFragment {
private boolean isQr() {
return currentType == TYPE_QR || currentType == TYPE_QR_LOGIN;
return currentType == TYPE_QR || currentType == TYPE_QR_LOGIN || currentType == TYPE_QR_WEB_BOT;
}
@Override

View file

@ -19,6 +19,7 @@ import android.graphics.Point;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.text.Layout;
import android.text.Spannable;
@ -27,7 +28,6 @@ import android.text.StaticLayout;
import android.text.TextUtils;
import android.text.style.ClickableSpan;
import android.text.style.URLSpan;
import android.text.util.Linkify;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.HapticFeedbackConstants;
@ -39,7 +39,6 @@ import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.FrameLayout;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.core.view.GestureDetectorCompat;
import androidx.recyclerview.widget.RecyclerView;
@ -58,6 +57,7 @@ import org.telegram.ui.Components.BulletinFactory;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.LinkPath;
import org.telegram.ui.Components.LinkSpanDrawable;
import org.telegram.ui.Components.LoadingDrawable;
import org.telegram.ui.Components.StaticLayoutEx;
import org.telegram.ui.Components.URLSpanNoUnderline;
@ -77,9 +77,13 @@ public class AboutLinkCell extends FrameLayout {
private Drawable showMoreBackgroundDrawable;
private LinkSpanDrawable pressedLink;
private float pressedLinkYOffset;
private Layout pressedLinkLayout;
private LinkSpanDrawable.LinkCollector links;
private Point urlPathOffset = new Point();
private LinkPath urlPath = new LinkPath(true);
private Browser.Progress currentProgress;
private LoadingDrawable currentLoading;
private BaseFragment parentFragment;
private Theme.ResourcesProvider resourcesProvider;
@ -204,12 +208,13 @@ public class AboutLinkCell extends FrameLayout {
LinkSpanDrawable link = hitLink(x, y);
if (link != null) {
result = true;
pressedLinkLayout = textLayout;
links.addLink(pressedLink = link);
AndroidUtilities.runOnUIThread(longPressedRunnable, ViewConfiguration.getLongPressTimeout());
}
} else if (pressedLink != null) {
try {
onLinkClick((ClickableSpan) pressedLink.getSpan());
onLinkClick((ClickableSpan) pressedLink.getSpan(), textLayout, pressedLinkYOffset);
} catch (Exception e) {
FileLog.e(e);
}
@ -318,7 +323,7 @@ public class AboutLinkCell extends FrameLayout {
canvas.restore();
}
protected void didPressUrl(String url) {
protected void didPressUrl(String url, Browser.Progress progress) {
}
protected void didResizeStart() {
@ -387,12 +392,15 @@ public class AboutLinkCell extends FrameLayout {
performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
} catch (Exception ignore) {}
final Layout layout = pressedLinkLayout;
final float yOffset = pressedLinkYOffset;
ClickableSpan pressedLinkFinal = (ClickableSpan) pressedLink.getSpan();
BottomSheet.Builder builder = new BottomSheet.Builder(parentFragment.getParentActivity());
builder.setTitle(url);
builder.setItems(new CharSequence[]{LocaleController.getString("Open", R.string.Open), LocaleController.getString("Copy", R.string.Copy)}, (dialog, which) -> {
if (which == 0) {
onLinkClick(pressedLinkFinal);
onLinkClick(pressedLinkFinal, layout, yOffset);
} else if (which == 1) {
AndroidUtilities.addToClipboard(url);
if (AndroidUtilities.shouldShowClipboardToast()) {
@ -457,7 +465,7 @@ public class AboutLinkCell extends FrameLayout {
int start = buffer.getSpanStart(link[0]);
int end = buffer.getSpanEnd(link[0]);
LinkPath path = linkDrawable.obtainNewPath();
path.setCurrentLayout(textLayout, start, textY);
path.setCurrentLayout(textLayout, start, pressedLinkYOffset = textY);
textLayout.getSelectionPath(start, end, path);
return linkDrawable;
}
@ -468,19 +476,49 @@ public class AboutLinkCell extends FrameLayout {
return null;
}
private void onLinkClick(ClickableSpan pressedLink) {
private void onLinkClick(ClickableSpan pressedLink, Layout layout, float yOffset) {
if (currentProgress != null) {
currentProgress.cancel();
currentProgress = null;
}
currentProgress = layout != null && pressedLink != null ? new Browser.Progress() {
LoadingDrawable thisLoading;
@Override
public void init() {
if (currentLoading != null) {
links.removeLoading(currentLoading, true);
}
currentLoading = thisLoading = LinkSpanDrawable.LinkCollector.makeLoading(layout, pressedLink, yOffset);
thisLoading.setColors(
Theme.multAlpha(Theme.getColor(Theme.key_chat_linkSelectBackground, resourcesProvider), .8f),
Theme.multAlpha(Theme.getColor(Theme.key_chat_linkSelectBackground, resourcesProvider), 1.3f),
Theme.multAlpha(Theme.getColor(Theme.key_chat_linkSelectBackground, resourcesProvider), 1f),
Theme.multAlpha(Theme.getColor(Theme.key_chat_linkSelectBackground, resourcesProvider), 4f)
);
thisLoading.strokePaint.setStrokeWidth(AndroidUtilities.dpf2(1.25f));
links.addLoading(thisLoading);
}
@Override
public void end(boolean replacing) {
if (thisLoading != null) {
links.removeLoading(thisLoading, true);
}
}
} : null;
if (pressedLink instanceof URLSpanNoUnderline) {
String url = ((URLSpanNoUnderline) pressedLink).getURL();
if (url.startsWith("@") || url.startsWith("#") || url.startsWith("/")) {
didPressUrl(url);
didPressUrl(url, currentProgress);
}
} else {
if (pressedLink instanceof URLSpan) {
String url = ((URLSpan) pressedLink).getURL();
if (AndroidUtilities.shouldShowUrlInAlert(url)) {
AlertsCreator.showOpenUrlAlert(parentFragment, url, true, true);
AlertsCreator.showOpenUrlAlert(parentFragment, url, true, true, true, currentProgress, null);
} else {
Browser.openUrl(getContext(), url);
Browser.openUrl(getContext(), Uri.parse(url), true, true, currentProgress);
}
} else {
pressedLink.onClick(this);

View file

@ -53,6 +53,7 @@ import org.telegram.messenger.R;
import org.telegram.messenger.SharedConfig;
import org.telegram.messenger.SvgHelper;
import org.telegram.messenger.UserConfig;
import org.telegram.messenger.Utilities;
import org.telegram.messenger.browser.Browser;
import org.telegram.tgnet.TLObject;
import org.telegram.tgnet.TLRPC;
@ -63,8 +64,12 @@ import org.telegram.ui.Components.AnimatedEmojiDrawable;
import org.telegram.ui.Components.AnimatedEmojiSpan;
import org.telegram.ui.Components.AvatarDrawable;
import org.telegram.ui.Components.Forum.ForumUtilities;
import org.telegram.ui.Components.ImageUpdater;
import org.telegram.ui.Components.MediaActionDrawable;
import org.telegram.ui.Components.Premium.StarParticlesView;
import org.telegram.ui.Components.RLottieDrawable;
import org.telegram.ui.Components.RadialProgress2;
import org.telegram.ui.Components.RadialProgressView;
import org.telegram.ui.Components.TypefaceSpan;
import org.telegram.ui.Components.URLSpanNoUnderline;
import org.telegram.ui.Components.spoilers.SpoilerEffect;
@ -81,7 +86,7 @@ import java.util.Stack;
public class ChatActionCell extends BaseCell implements DownloadController.FileDownloadProgressListener, NotificationCenter.NotificationCenterDelegate {
private final static boolean USE_PREMIUM_GIFT_LOCAL_STICKER = false;
private final static boolean USE_PREMIUM_GIFT_MONTHS_AS_EMOJI_NUMBERS = false;
private static Map<Integer, String> monthsToEmoticon = new HashMap<>();
static {
@ -155,7 +160,7 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
return 0;
}
default int getTopicId() {
default int getTopicId() {
return 0;
}
@ -184,6 +189,8 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
private int previousWidth;
private boolean imagePressed;
private boolean giftButtonPressed;
RadialProgressView progressView;
float progressToProgress;
private RectF giftButtonRect = new RectF();
@ -237,9 +244,10 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
private TLRPC.Document giftSticker;
private TLRPC.VideoSize giftEffectAnimation;
private RadialProgress2 radialProgress = new RadialProgress2(this);
private int giftPremiumAdditionalHeight;
private boolean forceWasUnread;
private RectF backroundRect;
private ImageReceiver.ImageReceiverDelegate giftStickerDelegate = (imageReceiver1, set, thumb, memCache) -> {
if (set) {
RLottieDrawable drawable = imageReceiver.getLottieAnimation();
@ -377,18 +385,61 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
}
public void setMessageObject(MessageObject messageObject, boolean force) {
if (currentMessageObject == messageObject && (textLayout == null || TextUtils.equals(textLayout.getText(), messageObject.messageText)) && (hasReplyMessage || messageObject.replyMessageObject == null) && !force) {
if (currentMessageObject == messageObject && (textLayout == null || TextUtils.equals(textLayout.getText(), messageObject.messageText)) && (hasReplyMessage || messageObject.replyMessageObject == null) && !force && messageObject.type != MessageObject.TYPE_SUGGEST_PHOTO) {
return;
}
if (BuildVars.DEBUG_PRIVATE_VERSION && Thread.currentThread() != ApplicationLoader.applicationHandler.getLooper().getThread()) {
FileLog.e(new IllegalStateException("Wrong thread!!!"));
}
accessibilityText = null;
boolean messageIdChanged = currentMessageObject == null || currentMessageObject.stableId != messageObject.stableId;
currentMessageObject = messageObject;
hasReplyMessage = messageObject.replyMessageObject != null;
DownloadController.getInstance(currentAccount).removeLoadingFileObserver(this);
previousWidth = 0;
if (messageObject.type == MessageObject.TYPE_GIFT_PREMIUM) {
if (messageObject.type == MessageObject.TYPE_SUGGEST_PHOTO) {
imageReceiver.setRoundRadius((int) (stickerSize / 2f));
imageReceiver.setAllowStartLottieAnimation(true);
imageReceiver.setDelegate(null);
TLRPC.TL_messageActionSuggestProfilePhoto action = (TLRPC.TL_messageActionSuggestProfilePhoto) messageObject.messageOwner.action;
ImageLocation videoLocation;
if (action.photo.video_sizes != null && !action.photo.video_sizes.isEmpty()) {
videoLocation = ImageLocation.getForPhoto(action.photo.video_sizes.get(0), action.photo);
} else {
videoLocation = null;
}
TLRPC.Photo photo = messageObject.messageOwner.action.photo;
TLRPC.VideoSize videoSize = null;
TLRPC.PhotoSize strippedPhotoSize = null;
for (int a = 0, N = messageObject.photoThumbs.size(); a < N; a++) {
TLRPC.PhotoSize photoSize = messageObject.photoThumbs.get(a);
if (photoSize instanceof TLRPC.TL_photoStrippedSize) {
strippedPhotoSize = photoSize;
break;
}
}
TLRPC.PhotoSize photoSize = FileLoader.getClosestPhotoSizeWithSize(messageObject.photoThumbs, 1000);
if (photoSize != null) {
if (!photo.video_sizes.isEmpty()) {
videoSize = photo.video_sizes.get(0);
}
if (videoSize != null) {
imageReceiver.setImage(videoLocation, ImageLoader.AUTOPLAY_FILTER, ImageLocation.getForPhoto(photoSize, photo), "150_150", ImageLocation.getForObject(strippedPhotoSize, messageObject.photoThumbsObject), "50_50_b", null, 0, null, messageObject, 0);
} else {
imageReceiver.setImage(ImageLocation.getForPhoto(photoSize, photo), "150_150", ImageLocation.getForObject(strippedPhotoSize, messageObject.photoThumbsObject), "50_50_b", null, 0, null, messageObject, 0);
}
}
imageReceiver.setAllowStartLottieAnimation(false);
ImageUpdater imageUpdater = MessagesController.getInstance(currentAccount).photoSuggestion.get(messageObject.messageOwner.local_id);
if (imageUpdater == null || imageUpdater.getCurrentImageProgress() == 1f) {
radialProgress.setProgress(1f, !messageIdChanged);
radialProgress.setIcon(MediaActionDrawable.ICON_NONE, !messageIdChanged, !messageIdChanged);
} else {
radialProgress.setIcon(MediaActionDrawable.ICON_CANCEL, !messageIdChanged, !messageIdChanged);
}
} else if (messageObject.type == MessageObject.TYPE_GIFT_PREMIUM) {
imageReceiver.setRoundRadius(0);
if (USE_PREMIUM_GIFT_LOCAL_STICKER) {
@ -517,7 +568,7 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
imageReceiver.setDelegate(null);
imageReceiver.setImageBitmap((Bitmap) null);
}
rippleView.setVisibility(messageObject.type == MessageObject.TYPE_GIFT_PREMIUM ? VISIBLE : GONE);
rippleView.setVisibility(isButtonLayout(messageObject) ? VISIBLE : GONE);
ForumUtilities.applyTopicToMessage(messageObject);
requestLayout();
}
@ -571,6 +622,10 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
animatedEmojiStack = AnimatedEmojiSpan.update(AnimatedEmojiDrawable.CACHE_TYPE_MESSAGES, this, canDrawInParent && (delegate != null && !delegate.canDrawOutboundsContent()), animatedEmojiStack, textLayout);
NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.didUpdatePremiumGiftStickers);
NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.diceStickersDidLoad);
if (currentMessageObject != null && currentMessageObject.type == MessageObject.TYPE_SUGGEST_PHOTO) {
setMessageObject(currentMessageObject, true);
}
}
private void setStarsPaused(boolean paused) {
@ -601,11 +656,15 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
boolean result = false;
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (delegate != null) {
if ((messageObject.type == MessageObject.TYPE_ACTION_PHOTO || messageObject.type == MessageObject.TYPE_GIFT_PREMIUM) && imageReceiver.isInsideImage(x, y)) {
if ((messageObject.type == MessageObject.TYPE_ACTION_PHOTO || isButtonLayout(messageObject)) && imageReceiver.isInsideImage(x, y)) {
imagePressed = true;
result = true;
}
if (messageObject.type == MessageObject.TYPE_GIFT_PREMIUM && giftButtonRect.contains(x, y)) {
if (messageObject.type == MessageObject.TYPE_SUGGEST_PHOTO && backroundRect.contains(x, y)) {
imagePressed = true;
result = true;
}
if (isButtonLayout(messageObject) && giftButtonRect.contains(x, y)) {
rippleView.setPressed(giftButtonPressed = true);
result = true;
}
@ -624,16 +683,27 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
if (messageObject.type == MessageObject.TYPE_GIFT_PREMIUM) {
openPremiumGiftPreview();
} else if (delegate != null) {
delegate.didClickImage(this);
playSoundEffect(SoundEffectConstants.CLICK);
ImageUpdater imageUpdater = MessagesController.getInstance(currentAccount).photoSuggestion.get(messageObject.messageOwner.local_id);
if (imageUpdater != null) {
imageUpdater.cancel();
} else {
delegate.didClickImage(this);
playSoundEffect(SoundEffectConstants.CLICK);
}
}
break;
case MotionEvent.ACTION_CANCEL:
imagePressed = false;
break;
case MotionEvent.ACTION_MOVE:
if (!imageReceiver.isInsideImage(x, y)) {
imagePressed = false;
if (messageObject.type == MessageObject.TYPE_SUGGEST_PHOTO) {
if (!backroundRect.contains(x, y)) {
imagePressed = false;
}
} else {
if (!imageReceiver.isInsideImage(x, y)) {
imagePressed = false;
}
}
break;
}
@ -642,8 +712,15 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
case MotionEvent.ACTION_UP:
rippleView.setPressed(giftButtonPressed = false);
if (delegate != null) {
playSoundEffect(SoundEffectConstants.CLICK);
openPremiumGiftPreview();
if (messageObject.type == MessageObject.TYPE_GIFT_PREMIUM) {
playSoundEffect(SoundEffectConstants.CLICK);
openPremiumGiftPreview();
} else {
ImageUpdater imageUpdater = MessagesController.getInstance(currentAccount).photoSuggestion.get(messageObject.messageOwner.local_id);
if (imageUpdater == null) {
delegate.didClickImage(this);
}
}
}
break;
case MotionEvent.ACTION_CANCEL:
@ -810,9 +887,14 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), textHeight + AndroidUtilities.dp(14));
return;
}
if (messageObject != null && messageObject.type == MessageObject.TYPE_GIFT_PREMIUM) {
if (isButtonLayout(messageObject)) {
giftRectSize = Math.min((int) (AndroidUtilities.isTablet() ? AndroidUtilities.getMinTabletSide() * 0.6f : AndroidUtilities.displaySize.x * 0.6f), AndroidUtilities.displaySize.y - ActionBar.getCurrentActionBarHeight() - AndroidUtilities.statusBarHeight - AndroidUtilities.dp(64));
stickerSize = giftRectSize - AndroidUtilities.dp(106);
if (messageObject.type == MessageObject.TYPE_SUGGEST_PHOTO) {
imageReceiver.setRoundRadius(stickerSize / 2);
} else {
imageReceiver.setRoundRadius(0);
}
}
int width = Math.max(AndroidUtilities.dp(30), MeasureSpec.getSize(widthMeasureSpec));
if (previousWidth != width) {
@ -824,15 +906,36 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
if (messageObject != null) {
if (messageObject.type == MessageObject.TYPE_ACTION_PHOTO) {
additionalHeight = AndroidUtilities.roundMessageSize + AndroidUtilities.dp(10);
} else if (messageObject.type == MessageObject.TYPE_GIFT_PREMIUM) {
} else if (isButtonLayout(messageObject)) {
additionalHeight = giftRectSize + AndroidUtilities.dp(12);
}
}
setMeasuredDimension(width, textHeight + additionalHeight + AndroidUtilities.dp(14));
if (messageObject != null && messageObject.type == MessageObject.TYPE_GIFT_PREMIUM) {
float y = textY + textHeight + giftRectSize * 0.075f + stickerSize + AndroidUtilities.dp(4) + giftPremiumTitleLayout.getHeight() + AndroidUtilities.dp(4) + giftPremiumSubtitleLayout.getHeight();
y += (getMeasuredHeight() - y - giftPremiumButtonLayout.getHeight() - AndroidUtilities.dp(8)) / 2f;
if (isButtonLayout(messageObject)) {
int imageSize = stickerSize;
if (messageObject.type == MessageObject.TYPE_SUGGEST_PHOTO) {
imageSize = (int) (stickerSize * 0.7f);
}
float y = textY + textHeight + giftRectSize * 0.075f + imageSize + AndroidUtilities.dp(4) + AndroidUtilities.dp(4) + giftPremiumSubtitleLayout.getHeight();
giftPremiumAdditionalHeight = 0;
if (giftPremiumTitleLayout != null) {
y += giftPremiumTitleLayout.getHeight();
} else {
y -= AndroidUtilities.dp(12);
giftPremiumAdditionalHeight -= AndroidUtilities.dp(30);
}
if (messageObject.type == MessageObject.TYPE_SUGGEST_PHOTO) {
y += AndroidUtilities.dp(16);
}
if (giftPremiumSubtitleLayout.getLineCount() > 2) {
giftPremiumAdditionalHeight += (giftPremiumSubtitleLayout.getLineBottom(0) - giftPremiumSubtitleLayout.getLineTop(0)) * giftPremiumSubtitleLayout.getLineCount() - 2;
}
additionalHeight += giftPremiumAdditionalHeight;
int h = textHeight + additionalHeight + AndroidUtilities.dp(14);
y += (h - y - giftPremiumButtonLayout.getHeight() - AndroidUtilities.dp(8)) / 2f;
float rectX = (previousWidth - giftPremiumButtonWidth) / 2f;
giftButtonRect.set(rectX - AndroidUtilities.dp(18), y - AndroidUtilities.dp(8), rectX + giftPremiumButtonWidth + AndroidUtilities.dp(18), y + giftPremiumButtonLayout.getHeight() + AndroidUtilities.dp(8));
@ -843,7 +946,12 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
starsSize = sizeInternal;
starParticlesDrawable.resetPositions();
}
}
setMeasuredDimension(width, textHeight + additionalHeight + AndroidUtilities.dp(14));
}
private void buildLayout() {
@ -876,14 +984,53 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
imageReceiver.setImageCoords((previousWidth - AndroidUtilities.roundMessageSize) / 2f, textHeight + AndroidUtilities.dp(19), AndroidUtilities.roundMessageSize, AndroidUtilities.roundMessageSize);
} else if (messageObject.type == MessageObject.TYPE_GIFT_PREMIUM) {
createGiftPremiumLayouts(LocaleController.getString(R.string.ActionGiftPremiumTitle), LocaleController.formatString(R.string.ActionGiftPremiumSubtitle, LocaleController.formatPluralString("Months", messageObject.messageOwner.action.months)), LocaleController.getString(R.string.ActionGiftPremiumView), giftRectSize);
} else if (messageObject.type == MessageObject.TYPE_SUGGEST_PHOTO) {
TLRPC.TL_messageActionSuggestProfilePhoto actionSuggestProfilePhoto = (TLRPC.TL_messageActionSuggestProfilePhoto) messageObject.messageOwner.action;
String description;
TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(messageObject.isOutOwner() ? 0 : messageObject.getDialogId());
boolean isVideo = actionSuggestProfilePhoto.video || (actionSuggestProfilePhoto.photo != null && actionSuggestProfilePhoto.photo.video_sizes != null && !actionSuggestProfilePhoto.photo.video_sizes.isEmpty());
if (user.id == UserConfig.getInstance(currentAccount).clientUserId) {
TLRPC.User user2 = MessagesController.getInstance(currentAccount).getUser(messageObject.getDialogId());
if (isVideo) {
description = LocaleController.formatString("ActionSuggestVideoFromYouDescription", R.string.ActionSuggestVideoFromYouDescription, user2.first_name);
} else {
description = LocaleController.formatString("ActionSuggestPhotoFromYouDescription", R.string.ActionSuggestPhotoFromYouDescription, user2.first_name);
}
} else {
if (isVideo) {
description = LocaleController.formatString("ActionSuggestVideoToYouDescription", R.string.ActionSuggestVideoToYouDescription, user.first_name);
} else {
description = LocaleController.formatString("ActionSuggestPhotoToYouDescription", R.string.ActionSuggestPhotoToYouDescription, user.first_name);
}
}
String action;
if (actionSuggestProfilePhoto.video || (actionSuggestProfilePhoto.photo.video_sizes != null && !actionSuggestProfilePhoto.photo.video_sizes.isEmpty())) {
action = LocaleController.getString("ViewVideoAction", R.string.ViewVideoAction);
} else {
action = LocaleController.getString("ViewPhotoAction", R.string.ViewPhotoAction);
}
createGiftPremiumLayouts(null, description, action, giftRectSize);
textLayout = null;
textHeight = 0;
textY = 0;
}
}
}
private void createGiftPremiumLayouts(CharSequence title, CharSequence subtitle, CharSequence button, int width) {
SpannableStringBuilder titleBuilder = SpannableStringBuilder.valueOf(title);
titleBuilder.setSpan(new TypefaceSpan(AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_ROBOTO_MEDIUM)), 0, titleBuilder.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
giftPremiumTitleLayout = new StaticLayout(titleBuilder, giftTitlePaint, width, Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false);
width -= AndroidUtilities.dp(16);
if (title != null) {
SpannableStringBuilder titleBuilder = SpannableStringBuilder.valueOf(title);
titleBuilder.setSpan(new TypefaceSpan(AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_ROBOTO_MEDIUM)), 0, titleBuilder.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
giftPremiumTitleLayout = new StaticLayout(titleBuilder, giftTitlePaint, width, Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false);
} else {
giftPremiumTitleLayout = null;
}
if (currentMessageObject != null && currentMessageObject.type == MessageObject.TYPE_SUGGEST_PHOTO) {
giftSubtitlePaint.setTextSize(AndroidUtilities.dp(13));
} else {
giftSubtitlePaint.setTextSize(AndroidUtilities.dp(15));
}
giftPremiumSubtitleLayout = new StaticLayout(subtitle, giftSubtitlePaint, width, Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false);
SpannableStringBuilder buttonBuilder = SpannableStringBuilder.valueOf(button);
buttonBuilder.setSpan(new TypefaceSpan(AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_ROBOTO_MEDIUM)), 0, buttonBuilder.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
@ -909,10 +1056,15 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
@Override
protected void onDraw(Canvas canvas) {
MessageObject messageObject = currentMessageObject;
if (messageObject != null && messageObject.type == MessageObject.TYPE_GIFT_PREMIUM) {
int imageSize = stickerSize;
if (isButtonLayout(messageObject)) {
stickerSize = giftRectSize - AndroidUtilities.dp(106);
imageReceiver.setImageCoords((previousWidth - stickerSize) / 2f, textY + textHeight + giftRectSize * 0.075f, stickerSize, stickerSize);
if (messageObject.type == MessageObject.TYPE_ACTION_PHOTO) {
imageReceiver.setImageCoords((previousWidth - stickerSize) / 2f, textY + textHeight + giftRectSize * 0.075f, stickerSize, stickerSize);
} else {
imageSize = (int) (stickerSize * 0.7f);
imageReceiver.setImageCoords((previousWidth - imageSize) / 2f, textY + textHeight + giftRectSize * 0.075f + AndroidUtilities.dp(8), imageSize, imageSize);
}
if (textPaint != null && giftTitlePaint != null && giftSubtitlePaint != null) {
if (giftTitlePaint.getColor() != textPaint.getColor()) {
giftTitlePaint.setColor(textPaint.getColor());
@ -922,17 +1074,35 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
}
}
}
if (messageObject != null && (messageObject.type == MessageObject.TYPE_ACTION_PHOTO || messageObject.type == MessageObject.TYPE_GIFT_PREMIUM)) {
imageReceiver.draw(canvas);
}
if (textLayout == null) {
return;
}
drawBackground(canvas, false);
if (textPaint != null) {
if (isButtonLayout(messageObject) || (messageObject != null && messageObject.type == MessageObject.TYPE_ACTION_PHOTO)) {
imageReceiver.draw(canvas);
radialProgress.setProgressRect(
imageReceiver.getImageX(),
imageReceiver.getImageY(),
imageReceiver.getImageX() + imageReceiver.getImageWidth(),
imageReceiver.getImageY() + imageReceiver.getImageHeight()
);
if (messageObject.type == MessageObject.TYPE_SUGGEST_PHOTO) {
ImageUpdater imageUpdater = MessagesController.getInstance(currentAccount).photoSuggestion.get(messageObject.messageOwner.local_id);
if (imageUpdater != null) {
radialProgress.setProgress(imageUpdater.getCurrentImageProgress(), true);
radialProgress.setCircleRadius((int) (imageReceiver.getImageWidth() * 0.5f) + 1);
radialProgress.setMaxIconSize(AndroidUtilities.dp(24));
radialProgress.setColors(Theme.key_chat_mediaLoaderPhoto, Theme.key_chat_mediaLoaderPhotoSelected, Theme.key_chat_mediaLoaderPhotoIcon, Theme.key_chat_mediaLoaderPhotoIconSelected);
if (imageUpdater.getCurrentImageProgress() == 1f) {
radialProgress.setIcon(MediaActionDrawable.ICON_NONE, true, true);
} else {
radialProgress.setIcon(MediaActionDrawable.ICON_CANCEL, true, true);
}
}
radialProgress.draw(canvas);
}
}
if (textPaint != null && textLayout != null) {
canvas.save();
canvas.translate(textXLeft, textY);
if (textLayout.getPaint() != textPaint) {
@ -954,23 +1124,39 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
canvas.restore();
}
if (messageObject != null && messageObject.type == MessageObject.TYPE_GIFT_PREMIUM) {
if (isButtonLayout(messageObject)) {
canvas.save();
float x = (previousWidth - giftRectSize) / 2f, y = textY + textHeight + giftRectSize * 0.075f + stickerSize + AndroidUtilities.dp(4);
float x = (previousWidth - giftRectSize) / 2f + AndroidUtilities.dp(8), y = textY + textHeight + giftRectSize * 0.075f + imageSize + AndroidUtilities.dp(4);
if (messageObject.type == MessageObject.TYPE_SUGGEST_PHOTO) {
y += +AndroidUtilities.dp(16);
}
canvas.translate(x, y);
giftPremiumTitleLayout.draw(canvas);
if (giftPremiumTitleLayout != null) {
giftPremiumTitleLayout.draw(canvas);
y += giftPremiumTitleLayout.getHeight();
} else {
y -= AndroidUtilities.dp(4);
}
canvas.restore();
y += giftPremiumTitleLayout.getHeight();
y += AndroidUtilities.dp(4);
canvas.save();
canvas.translate(x, y);
giftPremiumSubtitleLayout.draw(canvas);
canvas.restore();
if (giftPremiumTitleLayout == null) {
y -= AndroidUtilities.dp(8);
}
y += giftPremiumSubtitleLayout.getHeight();
y += (getHeight() - y - giftPremiumButtonLayout.getHeight() - AndroidUtilities.dp(8)) / 2f;
if (themeDelegate != null) {
themeDelegate.applyServiceShaderMatrix(getMeasuredWidth(), backgroundHeight, 0, viewTop + AndroidUtilities.dp(4));
} else {
Theme.applyServiceShaderMatrix(getMeasuredWidth(), backgroundHeight, 0, viewTop + AndroidUtilities.dp(4));
}
Paint backgroundPaint = getThemedPaint(Theme.key_paint_chatActionBackground);
canvas.drawRoundRect(giftButtonRect, AndroidUtilities.dp(16), AndroidUtilities.dp(16), backgroundPaint);
@ -982,16 +1168,43 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
starsPath.addRoundRect(giftButtonRect, AndroidUtilities.dp(16), AndroidUtilities.dp(16), Path.Direction.CW);
canvas.save();
canvas.clipPath(starsPath);
starParticlesDrawable.onDraw(canvas);
if (!starParticlesDrawable.paused) {
if (getMessageObject().type != MessageObject.TYPE_SUGGEST_PHOTO) {
starParticlesDrawable.onDraw(canvas);
if (!starParticlesDrawable.paused) {
invalidate();
}
} else {
//TODO optimize
invalidate();
}
canvas.restore();
canvas.save();
canvas.translate(x, y);
giftPremiumButtonLayout.draw(canvas);
canvas.restore();
if (messageObject.settingAvatar && progressToProgress != 1f) {
progressToProgress += 16 / 150f;
} else if (!messageObject.settingAvatar && progressToProgress != 0) {
progressToProgress -= 16 / 150f;
}
progressToProgress = Utilities.clamp(progressToProgress, 1f, 0f);
if (progressToProgress != 0) {
if (progressView == null) {
progressView = new RadialProgressView(getContext());
}
int rad = AndroidUtilities.dp(16);
canvas.save();
canvas.scale(progressToProgress, progressToProgress, giftButtonRect.centerX(), giftButtonRect.centerY());
progressView.setSize(rad);
progressView.setProgressColor(Theme.getColor(Theme.key_chat_serviceText));
progressView.draw(canvas, giftButtonRect.centerX(), giftButtonRect.centerY());
canvas.restore();
}
if (progressToProgress != 1f){
canvas.save();
float s = 1f - progressToProgress;
canvas.scale(s, s, giftButtonRect.centerX(), giftButtonRect.centerY());
canvas.translate(x, y);
giftPremiumButtonLayout.draw(canvas);
canvas.restore();
}
}
}
@ -1022,7 +1235,7 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
if (invalidatePath) {
invalidatePath = false;
lineWidths.clear();
final int count = textLayout.getLineCount();
final int count = textLayout == null ? 0 : textLayout.getLineCount();
final int corner = AndroidUtilities.dp(11);
final int cornerIn = AndroidUtilities.dp(8);
@ -1171,13 +1384,17 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
}
MessageObject messageObject = currentMessageObject;
if (messageObject != null && messageObject.type == MessageObject.TYPE_GIFT_PREMIUM) {
if (isButtonLayout(messageObject)) {
float x = (getWidth() - giftRectSize) / 2f, y = textY + textHeight + AndroidUtilities.dp(12);
AndroidUtilities.rectTmp.set(x, y, x + giftRectSize, y + giftRectSize);
canvas.drawRoundRect(AndroidUtilities.rectTmp, AndroidUtilities.dp(16), AndroidUtilities.dp(16), backgroundPaint);
AndroidUtilities.rectTmp.set(x, y, x + giftRectSize, y + giftRectSize + giftPremiumAdditionalHeight);
if (backroundRect == null) {
backroundRect = new RectF();
}
backroundRect.set(AndroidUtilities.rectTmp);
canvas.drawRoundRect(backroundRect, AndroidUtilities.dp(16), AndroidUtilities.dp(16), backgroundPaint);
if (hasGradientService()) {
canvas.drawRoundRect(AndroidUtilities.rectTmp, AndroidUtilities.dp(16), AndroidUtilities.dp(16), Theme.chat_actionBackgroundGradientDarkenPaint);
canvas.drawRoundRect(backroundRect, AndroidUtilities.dp(16), AndroidUtilities.dp(16), Theme.chat_actionBackgroundGradientDarkenPaint);
}
}
@ -1290,4 +1507,8 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
AnimatedEmojiSpan.drawAnimatedEmojis(canvas, textLayout, animatedEmojiStack, 0, spoilers, 0, 0, 0, 1f);
canvas.restore();
}
private boolean isButtonLayout(MessageObject messageObject) {
return messageObject != null && (messageObject.type == MessageObject.TYPE_GIFT_PREMIUM || messageObject.type == MessageObject.TYPE_SUGGEST_PHOTO);
}
}

View file

@ -10,19 +10,27 @@ package org.telegram.ui.Cells;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.TextView;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.Emoji;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.CheckBox2;
import org.telegram.ui.Components.CheckBoxSquare;
import org.telegram.ui.Components.CubicBezierInterpolator;
import org.telegram.ui.Components.LayoutHelper;
public class CheckBoxCell extends FrameLayout {
@ -40,6 +48,12 @@ public class CheckBoxCell extends FrameLayout {
private int currentType;
private int checkBoxSize = 18;
private LinearLayout contentView;
private Boolean collapsed;
private View collapsedArrow;
private boolean collapseArrowSet;
public CheckBoxCell(Context context, int type) {
this(context, type, 17, null);
}
@ -54,7 +68,20 @@ public class CheckBoxCell extends FrameLayout {
currentType = type;
textView = new TextView(context);
textView = new TextView(context) {
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
updateCollapseArrowTranslation();
}
@Override
public void setText(CharSequence text, BufferType type) {
text = Emoji.replaceEmoji(text, getPaint().getFontMetricsInt(), false);
super.setText(text, type);
}
};
NotificationCenter.listenEmojiLoading(textView);
textView.setTag(getThemedColor(type == 1 || type == 5 ? Theme.key_dialogTextBlack : Theme.key_windowBackgroundWhiteBlackText));
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
textView.setLines(1);
@ -71,7 +98,7 @@ public class CheckBoxCell extends FrameLayout {
addView(textView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, (LocaleController.isRTL ? 8 : 29), 0, (LocaleController.isRTL ? 29 : 8), 0));
} else {
int offset = type == 4 ? 56 : 46;
addView(textView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, (LocaleController.isRTL ? padding : offset + (padding - 17)), 0, (LocaleController.isRTL ? offset + (padding - 17) : padding), 0));
addView(textView, LayoutHelper.createFrame(type == 4 ? LayoutHelper.WRAP_CONTENT : LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, (LocaleController.isRTL ? padding : offset + (padding - 17)), 0, (LocaleController.isRTL ? offset + (padding - 17) : padding), 0));
}
}
@ -114,11 +141,82 @@ public class CheckBoxCell extends FrameLayout {
valueTextView.setTextColor(getThemedColor(currentType == 1 || currentType == 5 ? Theme.key_dialogTextBlue : Theme.key_windowBackgroundWhiteValueText));
}
private View click1Container, click2Container;
public void setOnSectionsClickListener(OnClickListener onTextClick, OnClickListener onCheckboxClick) {
if (onTextClick == null) {
if (click1Container != null) {
removeView(click1Container);
click1Container = null;
}
} else {
if (click1Container == null) {
click1Container = new View(getContext());
click1Container.setBackground(Theme.createSelectorDrawable(getThemedColor(Theme.key_listSelector), Theme.RIPPLE_MASK_ALL));
addView(click1Container, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.FILL));
}
click1Container.setOnClickListener(onTextClick);
}
if (onCheckboxClick == null) {
if (click2Container != null) {
removeView(click2Container);
click2Container = null;
}
} else {
if (click2Container == null) {
click2Container = new View(getContext());
addView(click2Container, LayoutHelper.createFrame(56, LayoutHelper.MATCH_PARENT, LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT));
}
click2Container.setOnClickListener(onCheckboxClick);
}
}
public void setCollapsed(Boolean collapsed) {
if (collapsed == null) {
if (collapsedArrow != null) {
removeView(collapsedArrow);
collapsedArrow = null;
}
} else {
if (collapsedArrow == null) {
collapsedArrow = new View(getContext());
Drawable drawable = getContext().getResources().getDrawable(R.drawable.arrow_more).mutate();
drawable.setColorFilter(new PorterDuffColorFilter(getThemedColor(Theme.key_windowBackgroundWhiteBlackText), PorterDuff.Mode.MULTIPLY));
collapsedArrow.setBackground(drawable);
addView(collapsedArrow, LayoutHelper.createFrame(16, 16, Gravity.CENTER_VERTICAL));
}
updateCollapseArrowTranslation();
collapsedArrow.animate().cancel();
collapsedArrow.animate().rotation(collapsed ? 0 : 180).setDuration(340).setInterpolator(CubicBezierInterpolator.EASE_OUT_QUINT).start();
}
this.collapsed = collapsed;
}
private void updateCollapseArrowTranslation() {
if (collapsedArrow == null) {
return;
}
float textWidth = 0;
try {
textWidth = textView.getMeasuredWidth();
} catch (Exception e) {}
float translateX;
if (LocaleController.isRTL) {
translateX = textView.getRight() - textWidth - AndroidUtilities.dp(20);
} else {
translateX = textView.getLeft() + textWidth + AndroidUtilities.dp(4);
}
collapsedArrow.setTranslationX(translateX);
collapseArrowSet = true;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = MeasureSpec.getSize(widthMeasureSpec);
if (currentType == 3) {
int width = MeasureSpec.getSize(widthMeasureSpec);
valueTextView.measure(MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(10), MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(50), MeasureSpec.EXACTLY));
textView.measure(MeasureSpec.makeMeasureSpec(width - AndroidUtilities.dp(34), MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(50), MeasureSpec.EXACTLY));
checkBox.measure(MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(checkBoxSize), MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(checkBoxSize), MeasureSpec.EXACTLY));
@ -129,12 +227,29 @@ public class CheckBoxCell extends FrameLayout {
} else {
setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), AndroidUtilities.dp(50) + (needDivider ? 1 : 0));
int availableWidth = getMeasuredWidth() - getPaddingLeft() - getPaddingRight() - AndroidUtilities.dp(34);
int availableWidth = getMeasuredWidth() - getPaddingLeft() - getPaddingRight() - AndroidUtilities.dp(currentType == TYPE_CHECK_BOX_ROUND ? 60 : 34);
if (valueTextView.getLayoutParams() instanceof MarginLayoutParams) {
availableWidth -= ((MarginLayoutParams) valueTextView.getLayoutParams()).rightMargin;
}
valueTextView.measure(MeasureSpec.makeMeasureSpec(availableWidth / 2, MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.EXACTLY));
textView.measure(MeasureSpec.makeMeasureSpec(availableWidth - valueTextView.getMeasuredWidth() - AndroidUtilities.dp(8), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.EXACTLY));
textView.measure(MeasureSpec.makeMeasureSpec(availableWidth - (int) Math.abs(textView.getTranslationX()) - valueTextView.getMeasuredWidth() - AndroidUtilities.dp(8), MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.EXACTLY));
checkBox.measure(MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(checkBoxSize), MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(checkBoxSize), MeasureSpec.EXACTLY));
}
if (click1Container != null) {
MarginLayoutParams margin = (MarginLayoutParams) click1Container.getLayoutParams();
click1Container.measure(MeasureSpec.makeMeasureSpec(width - margin.leftMargin - margin.rightMargin, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(50), MeasureSpec.EXACTLY));
}
if (click2Container != null) {
click2Container.measure(MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(56), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(50), MeasureSpec.EXACTLY));
}
if (collapsedArrow != null) {
collapsedArrow.measure(
MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(16), MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(16), MeasureSpec.EXACTLY)
);
}
}
public void setTextColor(int color) {
@ -151,6 +266,21 @@ public class CheckBoxCell extends FrameLayout {
valueTextView.setText(value);
needDivider = divider;
setWillNotDraw(!divider);
collapseArrowSet = false;
}
public void setPad(int pad) {
int offset = AndroidUtilities.dp(pad * 40 * (LocaleController.isRTL ? -1 : 1));
if (checkBox != null) {
checkBox.setTranslationX(offset);
}
textView.setTranslationX(offset);
if (click1Container != null) {
click1Container.setTranslationX(offset);
}
if (click2Container != null) {
click2Container.setTranslationX(offset);
}
}
public void setNeedDivider(boolean needDivider){
@ -238,8 +368,8 @@ public class CheckBoxCell extends FrameLayout {
@Override
protected void onDraw(Canvas canvas) {
if (needDivider) {
int offset = currentType == TYPE_CHECK_BOX_ROUND ? 60 : 20;
canvas.drawLine(LocaleController.isRTL ? 0 : AndroidUtilities.dp(offset), getMeasuredHeight() - 1, getMeasuredWidth() - (LocaleController.isRTL ? AndroidUtilities.dp(offset) : 0), getMeasuredHeight() - 1, Theme.dividerPaint);
int offset = AndroidUtilities.dp(currentType == TYPE_CHECK_BOX_ROUND ? 60 : 20) + (int) Math.abs(textView.getTranslationX());
canvas.drawLine(LocaleController.isRTL ? 0 : offset, getMeasuredHeight() - 1, getMeasuredWidth() - (LocaleController.isRTL ? offset : 0), getMeasuredHeight() - 1, Theme.dividerPaint);
}
}

View file

@ -17,6 +17,7 @@ import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
@ -76,6 +77,7 @@ import org.telegram.ui.Adapters.DialogsAdapter;
import org.telegram.ui.Components.AnimatedEmojiDrawable;
import org.telegram.ui.Components.AnimatedEmojiSpan;
import org.telegram.ui.Components.AvatarDrawable;
import org.telegram.ui.Components.BubbleCounterPath;
import org.telegram.ui.Components.CanvasButton;
import org.telegram.ui.Components.CheckBox2;
import org.telegram.ui.Components.ColoredImageSpan;
@ -153,6 +155,9 @@ public class DialogCell extends BaseCell {
private Paint timerPaint;
private Paint timerPaint2;
private Path thumbPath = new Path();
private SpoilerEffect thumbSpoiler = new SpoilerEffect();
public void setMoving(boolean moving) {
this.moving = moving;
}
@ -323,6 +328,7 @@ public class DialogCell extends BaseCell {
private Paint thumbBackgroundPaint;
private ImageReceiver[] thumbImage = new ImageReceiver[3];
private boolean[] drawPlay = new boolean[3];
private boolean[] drawSpoiler = new boolean[3];
public ImageReceiver avatarImage = new ImageReceiver(this);
private AvatarDrawable avatarDrawable = new AvatarDrawable();
@ -450,6 +456,8 @@ public class DialogCell extends BaseCell {
private RectF rect = new RectF();
private DialogsAdapter.DialogsPreloader preloader;
private Path counterPath;
private RectF counterPathRect;
private int animateToStatusDrawableParams;
private int animateFromStatusDrawableParams;
@ -469,7 +477,6 @@ public class DialogCell extends BaseCell {
private final DialogUpdateHelper updateHelper = new DialogUpdateHelper();
public static class BounceInterpolator implements Interpolator {
public float getInterpolation(float t) {
if (t < 0.33f) {
return 0.1f * (t / 0.33f);
@ -591,7 +598,7 @@ public class DialogCell extends BaseCell {
}
private void checkTtl() {
showTtl = ttlPeriod > 0 && !hasCall && !isOnline();
showTtl = ttlPeriod > 0 && !hasCall && !isOnline() && !(checkBox != null && checkBox.isChecked());
ttlProgress = showTtl ? 1.0f : 0.0f;
}
@ -847,7 +854,8 @@ public class DialogCell extends BaseCell {
return;
}
if (isDialogCell) {
if (!updateHelper.update()) {
boolean needUpdate = updateHelper.update();
if (!needUpdate && currentDialogFolderId == 0) {
return;
}
}
@ -1187,7 +1195,7 @@ public class DialogCell extends BaseCell {
mess = mess.substring(0, 150);
}
Spannable messSpan = new SpannableStringBuilder(mess);
MediaDataController.addTextStyleRuns(draftMessage, messSpan, TextStyleSpan.FLAG_STYLE_SPOILER);
MediaDataController.addTextStyleRuns(draftMessage, messSpan, TextStyleSpan.FLAG_STYLE_SPOILER | TextStyleSpan.FLAG_STYLE_STRIKE);
if (draftMessage != null && draftMessage.entities != null) {
MediaDataController.addAnimatedEmojiSpans(draftMessage.entities, messSpan, currentMessagePaint == null ? null : currentMessagePaint.getFontMetricsInt());
}
@ -1307,6 +1315,10 @@ public class DialogCell extends BaseCell {
messageString = msgText;
}
currentMessagePaint = Theme.dialogs_messagePrintingPaint[paintIndex];
if (message.type == MessageObject.TYPE_SUGGEST_PHOTO) {
updateMessageThumbs();
messageString = applyThumbs(messageString);
}
} else {
needEmoji = true;
updateMessageThumbs();
@ -1411,7 +1423,7 @@ public class DialogCell extends BaseCell {
} else {
SpannableStringBuilder msgBuilder = new SpannableStringBuilder(message.caption);
if (message != null && message.messageOwner != null) {
MediaDataController.addTextStyleRuns(message.messageOwner.entities, message.caption, msgBuilder, TextStyleSpan.FLAG_STYLE_SPOILER);
MediaDataController.addTextStyleRuns(message.messageOwner.entities, message.caption, msgBuilder, TextStyleSpan.FLAG_STYLE_SPOILER | TextStyleSpan.FLAG_STYLE_STRIKE);
MediaDataController.addAnimatedEmojiSpans(message.messageOwner.entities, msgBuilder, currentMessagePaint == null ? null : currentMessagePaint.getFontMetricsInt());
}
messageString = new SpannableStringBuilder(emoji).append(msgBuilder);
@ -1443,7 +1455,7 @@ public class DialogCell extends BaseCell {
messageString = AndroidUtilities.ellipsizeCenterEnd(messageString, message.highlightedWords.get(0), w, currentMessagePaint, 130).toString();
} else {
SpannableStringBuilder stringBuilder = new SpannableStringBuilder(msgText);
MediaDataController.addTextStyleRuns(message, stringBuilder, TextStyleSpan.FLAG_STYLE_SPOILER);
MediaDataController.addTextStyleRuns(message, stringBuilder, TextStyleSpan.FLAG_STYLE_SPOILER | TextStyleSpan.FLAG_STYLE_STRIKE);
if (message != null && message.messageOwner != null) {
MediaDataController.addAnimatedEmojiSpans(message.messageOwner.entities, stringBuilder, currentMessagePaint == null ? null : currentMessagePaint.getFontMetricsInt());
}
@ -2457,6 +2469,7 @@ public class DialogCell extends BaseCell {
addView(checkBox);
}
checkBox.setChecked(checked, animated);
checkTtl();
}
private MessageObject findFolderTopMessage() {
@ -3630,6 +3643,21 @@ public class DialogCell extends BaseCell {
thumbBackgroundPaint
);
thumbImage[i].draw(canvas);
if (drawSpoiler[i]) {
thumbPath.rewind();
thumbPath.addRoundRect(AndroidUtilities.rectTmp, thumbImage[i].getRoundRadius()[0], thumbImage[i].getRoundRadius()[1], Path.Direction.CW);
canvas.save();
canvas.clipPath(thumbPath);
int sColor = Color.WHITE;
thumbSpoiler.setColor(ColorUtils.setAlphaComponent(sColor, (int) (Color.alpha(sColor) * 0.325f)));
thumbSpoiler.setBounds((int) thumbImage[i].getImageX(), (int) thumbImage[i].getImageY(), (int) thumbImage[i].getImageX2(), (int) thumbImage[i].getImageY2());
thumbSpoiler.draw(canvas);
invalidate();
canvas.restore();
}
if (drawPlay[i]) {
int x = (int) (thumbImage[i].getCenterX() - Theme.dialogs_playDrawable.getIntrinsicWidth() / 2);
int y = (int) (thumbImage[i].getCenterY() - Theme.dialogs_playDrawable.getIntrinsicHeight() / 2);
@ -3699,6 +3727,9 @@ public class DialogCell extends BaseCell {
}
canvas.save();
float s = ttlProgress * (1f - rightFragmentOpenedProgress);
if (checkBox != null) {
s *= 1f - checkBox.getProgress();
}
canvas.scale(s, s, left, top);
canvas.drawCircle(left, top, AndroidUtilities.dpf2(11f), timerPaint);
canvas.drawCircle(left, top, AndroidUtilities.dpf2(11f), timerPaint2);
@ -3766,6 +3797,9 @@ public class DialogCell extends BaseCell {
float size1;
float size2;
if (SharedConfig.getLiteMode().enabled()) {
innerProgress = 0.65f;
}
if (progressStage == 0) {
size1 = AndroidUtilities.dp(1) + AndroidUtilities.dp(4) * innerProgress;
size2 = AndroidUtilities.dp(3) - AndroidUtilities.dp(2) * innerProgress;
@ -3808,15 +3842,17 @@ public class DialogCell extends BaseCell {
canvas.restore();
}
innerProgress += 16f / 400.0f;
if (innerProgress >= 1.0f) {
innerProgress = 0.0f;
progressStage++;
if (progressStage >= 8) {
progressStage = 0;
if (!SharedConfig.getLiteMode().enabled()) {
innerProgress += 16f / 400.0f;
if (innerProgress >= 1.0f) {
innerProgress = 0.0f;
progressStage++;
if (progressStage >= 8) {
progressStage = 0;
}
}
needInvalidate = true;
}
needInvalidate = true;
if (hasCall) {
if (chatCallProgress < 1.0f) {
@ -4004,6 +4040,7 @@ public class DialogCell extends BaseCell {
}
private void drawCounter(Canvas canvas, boolean drawCounterMuted, int countTop, int countLeftLocal, int countLeftOld, float globalScale, boolean outline) {
final boolean drawBubble = isForumCell() || isFolderCell();
if (drawCount && drawCount2 || countChangeProgress != 1f) {
final float progressFinal = (unreadCount == 0 && !markUnread) ? 1f - countChangeProgress : countChangeProgress;
Paint paint;
@ -4014,6 +4051,8 @@ public class DialogCell extends BaseCell {
counterPaintOutline = new Paint();
counterPaintOutline.setStyle(Paint.Style.STROKE);
counterPaintOutline.setStrokeWidth(AndroidUtilities.dp(2));
counterPaintOutline.setStrokeJoin(Paint.Join.ROUND);
counterPaintOutline.setStrokeCap(Paint.Cap.ROUND);
}
int color = Theme.getColor(Theme.key_chats_pinnedOverlay);
counterPaintOutline.setColor(ColorUtils.blendARGB(
@ -4060,9 +4099,27 @@ public class DialogCell extends BaseCell {
canvas.scale(progressFinal, progressFinal, rect.centerX(), rect.centerY());
}
canvas.drawRoundRect(rect, 11.5f * AndroidUtilities.density, 11.5f * AndroidUtilities.density, paint);
if (outline) {
canvas.drawRoundRect(rect, 11.5f * AndroidUtilities.density, 11.5f * AndroidUtilities.density, counterPaintOutline);
if (drawBubble) {
if (counterPath == null || counterPathRect == null || !counterPathRect.equals(rect)) {
if (counterPathRect == null) {
counterPathRect = new RectF(rect);
} else {
counterPathRect.set(rect);
}
if (counterPath == null) {
counterPath = new Path();
}
BubbleCounterPath.addBubbleRect(counterPath, counterPathRect, AndroidUtilities.dp(11.5f));
}
canvas.drawPath(counterPath, paint);
if (outline) {
canvas.drawPath(counterPath, counterPaintOutline);
}
} else {
canvas.drawRoundRect(rect, AndroidUtilities.dp(11.5f), AndroidUtilities.dp(11.5f), paint);
if (outline) {
canvas.drawRoundRect(rect, AndroidUtilities.dp(11.5f), AndroidUtilities.dp(11.5f), counterPaintOutline);
}
}
if (drawLayout != null) {
canvas.save();
@ -4092,12 +4149,29 @@ public class DialogCell extends BaseCell {
scale += 0.1f * CubicBezierInterpolator.EASE_IN.getInterpolation((1f - (progressFinal - 0.5f) * 2));
}
canvas.save();
canvas.scale(scale * globalScale, scale * globalScale, rect.centerX(), rect.centerY());
canvas.drawRoundRect(rect, 11.5f * AndroidUtilities.density, 11.5f * AndroidUtilities.density, paint);
if (outline) {
canvas.drawRoundRect(rect, 11.5f * AndroidUtilities.density, 11.5f * AndroidUtilities.density, counterPaintOutline);
if (drawBubble) {
if (counterPath == null || counterPathRect == null || !counterPathRect.equals(rect)) {
if (counterPathRect == null) {
counterPathRect = new RectF(rect);
} else {
counterPathRect.set(rect);
}
if (counterPath == null) {
counterPath = new Path();
}
BubbleCounterPath.addBubbleRect(counterPath, counterPathRect, AndroidUtilities.dp(11.5f));
}
canvas.drawPath(counterPath, paint);
if (outline) {
canvas.drawPath(counterPath, counterPaintOutline);
}
} else {
canvas.drawRoundRect(rect, AndroidUtilities.dp(11.5f), AndroidUtilities.dp(11.5f), paint);
if (outline) {
canvas.drawRoundRect(rect, AndroidUtilities.dp(11.5f), AndroidUtilities.dp(11.5f), counterPaintOutline);
}
}
if (countAnimationStableLayout != null) {
canvas.save();
@ -4424,9 +4498,11 @@ public class DialogCell extends BaseCell {
hasVideoThumb = hasVideoThumb || (message.isVideo() || message.isRoundVideo());
if (thumbsCount < 3) {
thumbsCount++;
drawPlay[index] = message.isVideo() || message.isRoundVideo();
drawPlay[index] = (message.isVideo() || message.isRoundVideo()) && !message.hasMediaSpoilers();
drawSpoiler[index] = message.hasMediaSpoilers();
int size = message.type == MessageObject.TYPE_PHOTO && selectedThumb != null ? selectedThumb.size : 0;
thumbImage[index].setImage(ImageLocation.getForObject(selectedThumb, message.photoThumbsObject), "20_20", ImageLocation.getForObject(smallThumb, message.photoThumbsObject), "20_20", size, null, message, 0);
String filter = message.hasMediaSpoilers() ? "5_5_b" : "20_20";
thumbImage[index].setImage(ImageLocation.getForObject(selectedThumb, message.photoThumbsObject), filter, ImageLocation.getForObject(smallThumb, message.photoThumbsObject), filter, size, null, message, 0);
thumbImage[index].setRoundRadius(message.isRoundVideo() ? AndroidUtilities.dp(18) : AndroidUtilities.dp(2));
needEmoji = false;
}
@ -4534,7 +4610,7 @@ public class DialogCell extends BaseCell {
mess = mess.subSequence(0, 150);
}
SpannableStringBuilder msgBuilder = new SpannableStringBuilder(mess);
MediaDataController.addTextStyleRuns(message.messageOwner.entities, mess, msgBuilder, TextStyleSpan.FLAG_STYLE_SPOILER);
MediaDataController.addTextStyleRuns(message.messageOwner.entities, mess, msgBuilder, TextStyleSpan.FLAG_STYLE_SPOILER | TextStyleSpan.FLAG_STYLE_STRIKE);
if (message != null && message.messageOwner != null) {
MediaDataController.addAnimatedEmojiSpans(message.messageOwner.entities, msgBuilder, currentMessagePaint == null ? null : currentMessagePaint.getFontMetricsInt());
}
@ -4616,7 +4692,7 @@ public class DialogCell extends BaseCell {
mess = AndroidUtilities.replaceNewLines(mess);
}
mess = new SpannableStringBuilder(mess);
MediaDataController.addTextStyleRuns(message, (Spannable) mess, TextStyleSpan.FLAG_STYLE_SPOILER);
MediaDataController.addTextStyleRuns(message, (Spannable) mess, TextStyleSpan.FLAG_STYLE_SPOILER | TextStyleSpan.FLAG_STYLE_STRIKE);
if (message != null && message.messageOwner != null) {
MediaDataController.addAnimatedEmojiSpans(message.messageOwner.entities, mess, currentMessagePaint == null ? null : currentMessagePaint.getFontMetricsInt());
}

View file

@ -10,9 +10,9 @@ package org.telegram.ui.Cells;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Path;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.os.SystemClock;
import android.view.Gravity;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.FrameLayout;

View file

@ -33,6 +33,7 @@ import org.telegram.messenger.ImageLocation;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MessageObject;
import org.telegram.messenger.R;
import org.telegram.messenger.SharedConfig;
import org.telegram.messenger.UserObject;
import org.telegram.messenger.Utilities;
import org.telegram.messenger.voip.VoIPService;
@ -983,6 +984,9 @@ public class GroupCallUserCell extends FrameLayout {
}
public void draw(Canvas canvas, float cx, float cy, View parentView) {
if (SharedConfig.getLiteMode().enabled()) {
return;
}
float scaleBlob = 0.8f + 0.4f * amplitude;
if (showWaves || wavesEnter != 0) {
canvas.save();

View file

@ -21,6 +21,7 @@ import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ChatObject;
import org.telegram.messenger.Emoji;
import org.telegram.messenger.MediaDataController;
import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.UserConfig;
import org.telegram.messenger.UserObject;
import org.telegram.tgnet.TLRPC;
@ -47,13 +48,20 @@ public class MentionCell extends LinearLayout {
setOrientation(HORIZONTAL);
avatarDrawable = new AvatarDrawable();
avatarDrawable.setTextSize(AndroidUtilities.dp(12));
avatarDrawable.setTextSize(AndroidUtilities.dp(18));
imageView = new BackupImageView(context);
imageView.setRoundRadius(AndroidUtilities.dp(14));
addView(imageView, LayoutHelper.createLinear(28, 28, 12, 4, 0, 0));
nameTextView = new TextView(context);
nameTextView = new TextView(context) {
@Override
public void setText(CharSequence text, BufferType type) {
text = Emoji.replaceEmoji(text, getPaint().getFontMetricsInt(), false);
super.setText(text, type);
}
};
NotificationCenter.listenEmojiLoading(nameTextView);
nameTextView.setTextColor(getThemedColor(Theme.key_windowBackgroundWhiteBlackText));
nameTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
nameTextView.setSingleLine(true);

View file

@ -12,11 +12,16 @@ import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Region;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
@ -34,9 +39,13 @@ import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.core.graphics.ColorUtils;
import androidx.core.math.MathUtils;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.FileLoader;
import org.telegram.messenger.ImageLocation;
import org.telegram.messenger.ImageReceiver;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MediaController;
import org.telegram.messenger.MessageObject;
@ -45,7 +54,9 @@ import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.BackupImageView;
import org.telegram.ui.Components.CheckBox2;
import org.telegram.ui.Components.CubicBezierInterpolator;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.spoilers.SpoilerEffect;
import org.telegram.ui.PhotoViewer;
public class PhotoAttachPhotoCell extends FrameLayout {
@ -74,6 +85,19 @@ public class PhotoAttachPhotoCell extends FrameLayout {
private AnimatorSet animator;
private final Theme.ResourcesProvider resourcesProvider;
private SpoilerEffect spoilerEffect = new SpoilerEffect();
private boolean hasSpoiler;
private Path path = new Path();
private float spoilerRevealX;
private float spoilerRevealY;
private float spoilerMaxRadius;
private float spoilerRevealProgress;
private Bitmap imageViewCrossfadeSnapshot;
private Float crossfadeDuration;
private float imageViewCrossfadeProgress = 1f;
public interface PhotoAttachPhotoCellDelegate {
void onCheckClick(PhotoAttachPhotoCell v);
}
@ -87,7 +111,62 @@ public class PhotoAttachPhotoCell extends FrameLayout {
container = new FrameLayout(context);
addView(container, LayoutHelper.createFrame(80, 80));
imageView = new BackupImageView(context);
int sColor = Color.WHITE;
spoilerEffect.setColor(ColorUtils.setAlphaComponent(sColor, (int) (Color.alpha(sColor) * 0.325f)));
imageView = new BackupImageView(context) {
private Paint crossfadePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private long lastUpdate;
@Override
protected void onDraw(Canvas canvas) {
ImageReceiver imageReceiver = animatedEmojiDrawable != null ? animatedEmojiDrawable.getImageReceiver() : this.imageReceiver;
if (imageReceiver == null) {
return;
}
if (width != -1 && height != -1) {
imageReceiver.setImageCoords((getWidth() - width) / 2, (getHeight() - height) / 2, width, height);
blurImageReceiver.setImageCoords((getWidth() - width) / 2, (getHeight() - height) / 2, width, height);
} else {
imageReceiver.setImageCoords(0, 0, getWidth(), getHeight());
blurImageReceiver.setImageCoords(0, 0, getWidth(), getHeight());
}
imageReceiver.draw(canvas);
if (hasSpoiler && spoilerRevealProgress != 1f && (photoEntry == null || !photoEntry.isAttachSpoilerRevealed)) {
if (spoilerRevealProgress != 0f) {
canvas.save();
path.rewind();
path.addCircle(spoilerRevealX, spoilerRevealY, spoilerMaxRadius * spoilerRevealProgress, Path.Direction.CW);
canvas.clipPath(path, Region.Op.DIFFERENCE);
}
blurImageReceiver.draw(canvas);
spoilerEffect.setBounds(0, 0, getWidth(), getHeight());
spoilerEffect.draw(canvas);
invalidate();
if (spoilerRevealProgress != 0f) {
canvas.restore();
}
}
if (imageViewCrossfadeProgress != 1f && imageViewCrossfadeSnapshot != null) {
crossfadePaint.setAlpha((int) (CubicBezierInterpolator.DEFAULT.getInterpolation(1f - imageViewCrossfadeProgress) * 0xFF));
canvas.drawBitmap(imageViewCrossfadeSnapshot, 0, 0, crossfadePaint);
long dt = Math.min(16, System.currentTimeMillis() - lastUpdate);
float duration = crossfadeDuration == null ? 250f : crossfadeDuration;
imageViewCrossfadeProgress = Math.min(1f, imageViewCrossfadeProgress + dt / duration);
lastUpdate = System.currentTimeMillis();
invalidate();
} else if (imageViewCrossfadeProgress == 1f && imageViewCrossfadeSnapshot != null) {
imageViewCrossfadeSnapshot.recycle();
imageViewCrossfadeSnapshot = null;
crossfadeDuration = null;
invalidate();
}
}
};
imageView.setBlurAllowed(true);
container.addView(imageView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
videoInfoContainer = new FrameLayout(context) {
@ -110,7 +189,7 @@ public class PhotoAttachPhotoCell extends FrameLayout {
videoTextView = new TextView(context);
videoTextView.setTextColor(0xffffffff);
videoTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
videoTextView.setTypeface(AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_ROBOTO_MEDIUM));
videoTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 12);
videoTextView.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO);
videoInfoContainer.addView(videoTextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.CENTER_VERTICAL, 13, -0.7f, 0, 0));
@ -128,6 +207,60 @@ public class PhotoAttachPhotoCell extends FrameLayout {
itemSize = AndroidUtilities.dp(80);
}
public boolean canRevealSpoiler() {
return hasSpoiler && spoilerRevealProgress == 0f && (photoEntry == null || !photoEntry.isAttachSpoilerRevealed);
}
public void startRevealMedia(float x, float y) {
spoilerRevealX = x;
spoilerRevealY = y;
spoilerMaxRadius = (float) Math.sqrt(Math.pow(getWidth(), 2) + Math.pow(getHeight(), 2));
ValueAnimator animator = ValueAnimator.ofFloat(0, 1).setDuration((long) MathUtils.clamp(spoilerMaxRadius * 0.3f, 250, 550));
animator.setInterpolator(CubicBezierInterpolator.EASE_BOTH);
animator.addUpdateListener(animation -> {
spoilerRevealProgress = (float) animation.getAnimatedValue();
invalidate();
});
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
photoEntry.isAttachSpoilerRevealed = true;
invalidate();
}
});
animator.start();
}
public void setHasSpoiler(boolean hasSpoiler) {
setHasSpoiler(hasSpoiler, null);
}
public void setHasSpoiler(boolean hasSpoiler, Float crossfadeDuration) {
if (this.hasSpoiler != hasSpoiler) {
spoilerRevealProgress = 0f;
if (isLaidOut()) {
Bitmap prevSnapshot = imageViewCrossfadeSnapshot;
imageViewCrossfadeSnapshot = AndroidUtilities.snapshotView(imageView);
if (prevSnapshot != null) {
prevSnapshot.recycle();
}
imageViewCrossfadeProgress = 0f;
} else {
if (imageViewCrossfadeSnapshot != null) {
imageViewCrossfadeSnapshot.recycle();
imageViewCrossfadeSnapshot = null;
}
imageViewCrossfadeProgress = 1f;
}
this.hasSpoiler = hasSpoiler;
this.crossfadeDuration = crossfadeDuration;
imageView.setHasBlur(hasSpoiler);
imageView.invalidate();
}
}
public void setIsVertical(boolean value) {
isVertical = value;
}
@ -216,6 +349,7 @@ public class PhotoAttachPhotoCell extends FrameLayout {
checkBox.setAlpha(showing ? 0.0f : 1.0f);
videoInfoContainer.setAlpha(showing ? 0.0f : 1.0f);
requestLayout();
setHasSpoiler(entry.hasSpoiler);
}
public void setPhotoEntry(MediaController.SearchImage searchImage, boolean needCheckShow, boolean last) {
@ -254,6 +388,7 @@ public class PhotoAttachPhotoCell extends FrameLayout {
checkBox.setAlpha(showing ? 0.0f : 1.0f);
videoInfoContainer.setAlpha(showing ? 0.0f : 1.0f);
requestLayout();
setHasSpoiler(false);
}
public boolean isChecked() {

View file

@ -16,11 +16,13 @@ import android.text.Layout;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.text.TextUtils;
import android.view.MotionEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import org.telegram.PhoneFormat.PhoneFormat;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ChatObject;
import org.telegram.messenger.ContactsController;
import org.telegram.messenger.DialogObject;
import org.telegram.messenger.Emoji;
import org.telegram.messenger.ImageLocation;
@ -32,14 +34,15 @@ import org.telegram.messenger.R;
import org.telegram.messenger.UserConfig;
import org.telegram.messenger.UserObject;
import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.TLObject;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.AnimatedEmojiDrawable;
import org.telegram.ui.Components.AvatarDrawable;
import org.telegram.ui.Components.CanvasButton;
import org.telegram.ui.Components.CheckBox2;
import org.telegram.ui.Components.CombinedDrawable;
import org.telegram.ui.Components.Premium.PremiumGradient;
import org.telegram.ui.Components.RecyclerListView;
import org.telegram.ui.NotificationsSettingsActivity;
import java.util.Locale;
@ -55,6 +58,7 @@ public class ProfileSearchCell extends BaseCell implements NotificationCenter.No
private TLRPC.User user;
private TLRPC.Chat chat;
private TLRPC.EncryptedChat encryptedChat;
private ContactsController.Contact contact;
private long dialog_id;
private String lastName;
@ -74,6 +78,9 @@ public class ProfileSearchCell extends BaseCell implements NotificationCenter.No
private int nameLockLeft;
private int nameLockTop;
private int nameWidth;
CanvasButton actionButton;
private StaticLayout actionLayout;
private int actionLeft;
private int sublabelOffsetX;
private int sublabelOffsetY;
@ -84,6 +91,7 @@ public class ProfileSearchCell extends BaseCell implements NotificationCenter.No
private int countLeft;
private int countWidth;
private StaticLayout countLayout;
private boolean[] isOnline;
private boolean drawCheck;
@ -118,14 +126,20 @@ public class ProfileSearchCell extends BaseCell implements NotificationCenter.No
statusDrawable = new AnimatedEmojiDrawable.SwapAnimatedEmojiDrawable(this, AndroidUtilities.dp(20));
}
public void setData(TLObject object, TLRPC.EncryptedChat ec, CharSequence n, CharSequence s, boolean needCount, boolean saved) {
public void setData(Object object, TLRPC.EncryptedChat ec, CharSequence n, CharSequence s, boolean needCount, boolean saved) {
currentName = n;
if (object instanceof TLRPC.User) {
user = (TLRPC.User) object;
chat = null;
contact = null;
} else if (object instanceof TLRPC.Chat) {
chat = (TLRPC.Chat) object;
user = null;
contact = null;
} else if (object instanceof ContactsController.Contact) {
contact = (ContactsController.Contact) object;
chat = null;
user = null;
}
encryptedChat = ec;
subLabel = s;
@ -229,7 +243,7 @@ public class ProfileSearchCell extends BaseCell implements NotificationCenter.No
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
if (user == null && chat == null && encryptedChat == null) {
if (user == null && chat == null && encryptedChat == null && contact == null) {
return;
}
if (checkBox != null) {
@ -296,6 +310,23 @@ public class ProfileSearchCell extends BaseCell implements NotificationCenter.No
drawCheck = user.verified;
drawPremium = !user.self && MessagesController.getInstance(currentAccount).isPremiumUser(user);
updateStatus(drawCheck, user, false);
} else if (contact != null) {
if (!LocaleController.isRTL) {
nameLeft = AndroidUtilities.dp(AndroidUtilities.leftBaseline);
} else {
nameLeft = AndroidUtilities.dp(11);
}
if (actionButton == null) {
actionButton = new CanvasButton(this);
actionButton.setDelegate(() -> {
if (getParent() instanceof RecyclerListView) {
RecyclerListView parent = (RecyclerListView) getParent();
parent.getOnItemClickListener().onItemClick(this, parent.getChildAdapterPosition(this));
} else {
callOnClick();
}
});
}
}
}
@ -332,6 +363,18 @@ public class ProfileSearchCell extends BaseCell implements NotificationCenter.No
if (drawNameLock) {
nameWidth -= AndroidUtilities.dp(6) + Theme.dialogs_lockDrawable.getIntrinsicWidth();
}
if (contact != null) {
int w = (int) (Theme.dialogs_countTextPaint.measureText(LocaleController.getString(R.string.Invite)) + 1);
actionLayout = new StaticLayout(LocaleController.getString(R.string.Invite), Theme.dialogs_countTextPaint, w, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
if (!LocaleController.isRTL) {
actionLeft = getMeasuredWidth() - w - AndroidUtilities.dp(19) - AndroidUtilities.dp(16);
} else {
actionLeft = AndroidUtilities.dp(19) + AndroidUtilities.dp(16);
nameLeft += w;
}
nameWidth -= AndroidUtilities.dp(32) + w;
}
nameWidth -= getPaddingLeft() + getPaddingRight();
statusWidth -= getPaddingLeft() + getPaddingRight();
@ -550,6 +593,9 @@ public class ProfileSearchCell extends BaseCell implements NotificationCenter.No
}
avatarDrawable.setInfo(chat);
avatarImage.setImage(ImageLocation.getForUserOrChat(chat, ImageLocation.TYPE_SMALL), "50_50", ImageLocation.getForUserOrChat(chat, ImageLocation.TYPE_STRIPPED), "50_50", thumb, chat, 0);
} else if (contact != null) {
avatarDrawable.setInfo(0, contact.first_name, contact.last_name);
avatarImage.setImage(null, null, avatarDrawable, null, null, 0);
} else {
avatarDrawable.setInfo(0, null, null);
avatarImage.setImage(null, null, avatarDrawable, null, null, 0);
@ -621,7 +667,7 @@ public class ProfileSearchCell extends BaseCell implements NotificationCenter.No
@Override
protected void onDraw(Canvas canvas) {
if (user == null && chat == null && encryptedChat == null) {
if (user == null && chat == null && encryptedChat == null && contact == null) {
return;
}
@ -676,6 +722,19 @@ public class ProfileSearchCell extends BaseCell implements NotificationCenter.No
canvas.restore();
}
if (actionLayout != null) {
actionButton.setColor(Theme.getColor(Theme.key_chats_unreadCounter), Theme.getColor(Theme.key_chats_unreadCounterText));
AndroidUtilities.rectTmp.set(actionLeft, countTop, actionLeft + actionLayout.getWidth(), countTop + AndroidUtilities.dp(23));
AndroidUtilities.rectTmp.inset(-AndroidUtilities.dp(16), -AndroidUtilities.dp(4));
actionButton.setRect(AndroidUtilities.rectTmp);
actionButton.setRounded(true);
actionButton.draw(canvas);
canvas.save();
canvas.translate(actionLeft, countTop + AndroidUtilities.dp(4));
actionLayout.draw(canvas);
canvas.restore();
}
avatarImage.draw(canvas);
}
@ -713,4 +772,17 @@ public class ProfileSearchCell extends BaseCell implements NotificationCenter.No
}
checkBox.setChecked(checked, animated);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return onTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (actionButton != null && actionButton.checkTouchEvent(event)) {
return true;
}
return super.onTouchEvent(event);
}
}

View file

@ -94,7 +94,7 @@ public class SessionCell extends FrameLayout {
imageView.setRoundRadius(AndroidUtilities.dp(10));
addView(imageView, LayoutHelper.createFrame(42, 42, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, (LocaleController.isRTL ? 0 : 16), 9, (LocaleController.isRTL ? 16 : 0), 0));
addView(linearLayout, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 30, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, (LocaleController.isRTL ? 15 : 72), 7.333f, (LocaleController.isRTL ? 72 : 15), 0));
addView(linearLayout, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 30, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, (LocaleController.isRTL ? 15 : 72), 6.333f, (LocaleController.isRTL ? 72 : 15), 0));
}
@ -432,7 +432,7 @@ public class SessionCell extends FrameLayout {
}
}
if (needDivider) {
int margin = currentType == 1 ? 49 : 21;
int margin = currentType == 1 ? 49 : 72;
canvas.drawLine(LocaleController.isRTL ? 0 : AndroidUtilities.dp(margin), getMeasuredHeight() - 1, getMeasuredWidth() - (LocaleController.isRTL ? AndroidUtilities.dp(margin) : 0), getMeasuredHeight() - 1, Theme.dividerPaint);
}
}

View file

@ -66,6 +66,9 @@ public class ShareTopicCell extends FrameLayout {
}
public void setTopic(TLRPC.Dialog dialog, TLRPC.TL_forumTopic topic, boolean checked, CharSequence name) {
if (dialog == null) {
return;
}
TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(-dialog.id);
if (name != null) {
nameTextView.setText(name);

View file

@ -90,6 +90,8 @@ public class SharedAudioCell extends FrameLayout implements DownloadController.F
boolean showReorderIcon;
float showReorderIconProgress;
boolean showName = true;
float showNameProgress = 0;
public SharedAudioCell(Context context) {
this(context, VIEW_TYPE_DEFAULT, null);
@ -285,6 +287,11 @@ public class SharedAudioCell extends FrameLayout implements DownloadController.F
radialProgress.initMiniIcons();
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return onTouchEvent(ev);
}
private boolean checkAudioMotionEvent(MotionEvent event) {
int x = (int) event.getX();
int y = (int) event.getY();
@ -302,6 +309,7 @@ public class SharedAudioCell extends FrameLayout implements DownloadController.F
invalidate();
result = true;
} else if (checkForButtonPress && radialProgress.getProgressRect().contains(x, y)) {
requestDisallowInterceptTouchEvent(true);
buttonPressed = true;
radialProgress.setPressed(buttonPressed, false);
invalidate();
@ -319,7 +327,9 @@ public class SharedAudioCell extends FrameLayout implements DownloadController.F
didPressedButton();
invalidate();
}
requestDisallowInterceptTouchEvent(false);
} else if (event.getAction() == MotionEvent.ACTION_CANCEL) {
requestDisallowInterceptTouchEvent(false);
miniButtonPressed = false;
buttonPressed = false;
invalidate();
@ -330,7 +340,7 @@ public class SharedAudioCell extends FrameLayout implements DownloadController.F
}
}
radialProgress.setPressed(miniButtonPressed, true);
return result;
return result || buttonPressed;
}
@Override
@ -575,6 +585,14 @@ public class SharedAudioCell extends FrameLayout implements DownloadController.F
@Override
protected void dispatchDraw(Canvas canvas) {
if (showName && showNameProgress != 1f) {
showNameProgress += 16 / 150f;
invalidate();
} else if (!showName && showNameProgress != 0) {
showNameProgress -= 16 / 150f;
invalidate();
}
showNameProgress = Utilities.clamp(showNameProgress, 1f, 0);
if (enterAlpha != 1f && globalGradientView != null) {
canvas.saveLayerAlpha(0, 0, getMeasuredWidth(), getMeasuredHeight(), (int) ((1f - enterAlpha) * 255), Canvas.ALL_SAVE_FLAG);
globalGradientView.setViewType(FlickerLoadingView.AUDIO_TYPE);
@ -630,11 +648,18 @@ public class SharedAudioCell extends FrameLayout implements DownloadController.F
}
if (titleLayout != null) {
int oldAlpha = Theme.chat_contextResult_titleTextPaint.getAlpha();
if (showNameProgress != 1f) {
Theme.chat_contextResult_titleTextPaint.setAlpha((int) (oldAlpha * showNameProgress));
}
canvas.save();
canvas.translate(AndroidUtilities.dp(LocaleController.isRTL ? 8 : AndroidUtilities.leftBaseline) + (LocaleController.isRTL && dateLayout != null ? dateLayout.getWidth() + AndroidUtilities.dp(4) : 0), titleY);
titleLayout.draw(canvas);
AnimatedEmojiSpan.drawAnimatedEmojis(canvas, titleLayout, titleLayoutEmojis, 0, null, 0, 0, 0, 1f);
canvas.restore();
if (showNameProgress != 1f) {
Theme.chat_contextResult_titleTextPaint.setAlpha(oldAlpha);
}
}
if (captionLayout != null) {
@ -647,14 +672,22 @@ public class SharedAudioCell extends FrameLayout implements DownloadController.F
if (descriptionLayout != null) {
Theme.chat_contextResult_descriptionTextPaint.setColor(getThemedColor(Theme.key_windowBackgroundWhiteGrayText2));
int oldAlpha = Theme.chat_contextResult_descriptionTextPaint.getAlpha();
if (showNameProgress != 1f) {
Theme.chat_contextResult_descriptionTextPaint.setAlpha((int) (oldAlpha * showNameProgress));
}
canvas.save();
canvas.translate(AndroidUtilities.dp(LocaleController.isRTL ? 8 : AndroidUtilities.leftBaseline), descriptionY);
descriptionLayout.draw(canvas);
AnimatedEmojiSpan.drawAnimatedEmojis(canvas, descriptionLayout, descriptionLayoutEmojis, 0, null, 0, 0, 0, 1f);
canvas.restore();
if (showNameProgress != 1f) {
Theme.chat_contextResult_descriptionTextPaint.setAlpha(oldAlpha);
}
}
radialProgress.setProgressColor(getThemedColor(buttonPressed ? Theme.key_chat_inAudioSelectedProgress : Theme.key_chat_inAudioProgress));
radialProgress.setOverlayImageAlpha(showNameProgress);
radialProgress.draw(canvas);
if (needDivider) {
@ -680,5 +713,16 @@ public class SharedAudioCell extends FrameLayout implements DownloadController.F
}
invalidate();
}
public void showName(boolean show, boolean animated) {
if (!animated) {
showNameProgress = show ? 1f : 0f;
}
if (showName == show) {
return;
}
showName = show;
invalidate();
}
}

View file

@ -87,6 +87,7 @@ public class SharedDocumentCell extends FrameLayout implements DownloadControlle
public final static int VIEW_TYPE_DEFAULT = 0;
public final static int VIEW_TYPE_PICKER = 1;
public final static int VIEW_TYPE_GLOBAL_SEARCH = 2;
public final static int VIEW_TYPE_CACHE = 3;
private SpannableStringBuilder dotSpan;
private CharSequence caption;
@ -270,7 +271,9 @@ public class SharedDocumentCell extends FrameLayout implements DownloadControlle
}
if (thumb != null || resId != 0) {
if (thumb != null) {
thumbImageView.setImage(thumb, "42_42", null);
if (viewType != VIEW_TYPE_CACHE) {
thumbImageView.setImage(thumb, "42_42", null);
}
} else {
Drawable drawable = Theme.createCircleDrawableWithIcon(AndroidUtilities.dp(42), resId);
String iconKey;
@ -299,8 +302,10 @@ public class SharedDocumentCell extends FrameLayout implements DownloadControlle
} else {
extTextView.setAlpha(1.0f);
placeholderImageView.setAlpha(1.0f);
thumbImageView.setImageBitmap(null);
thumbImageView.setVisibility(INVISIBLE);
if (viewType != VIEW_TYPE_CACHE) {
thumbImageView.setImageBitmap(null);
thumbImageView.setVisibility(INVISIBLE);
}
}
setWillNotDraw(!needDivider);
}
@ -723,10 +728,10 @@ public class SharedDocumentCell extends FrameLayout implements DownloadControlle
if (showReorderIcon || showReorderIconProgress != 0) {
if (showReorderIcon && showReorderIconProgress != 1f) {
showReorderIconProgress += 16 /150f;
showReorderIconProgress += 16 / 150f;
invalidate();
} else if (!showReorderIcon && showReorderIconProgress != 0) {
showReorderIconProgress -= 16 /150f;
showReorderIconProgress -= 16 / 150f;
invalidate();
}
showReorderIconProgress = Utilities.clamp(showReorderIconProgress, 1f, 0);
@ -765,4 +770,16 @@ public class SharedDocumentCell extends FrameLayout implements DownloadControlle
}
invalidate();
}
public void setPhoto(String path) {
if (path.endsWith("mp4")) {
thumbImageView.setImage("vthumb://0:" + path, null, null);
thumbImageView.setVisibility(View.VISIBLE);
} else if (path.endsWith(".jpg") || path.endsWith(".jpeg") || path.endsWith(".png") || path.endsWith(".gif")) {
thumbImageView.setImage("thumb://0:" + path, null, null);
thumbImageView.setVisibility(View.VISIBLE);
} else {
thumbImageView.setVisibility(View.GONE);
}
}
}

View file

@ -4,19 +4,24 @@ import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Region;
import android.graphics.drawable.Drawable;
import android.text.Layout;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.text.TextUtils;
import android.util.SparseArray;
import android.view.MotionEvent;
import android.view.View;
import androidx.core.content.ContextCompat;
import androidx.core.graphics.ColorUtils;
import androidx.core.math.MathUtils;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.DownloadController;
@ -26,16 +31,21 @@ import org.telegram.messenger.ImageReceiver;
import org.telegram.messenger.MessageObject;
import org.telegram.messenger.MessagesController;
import org.telegram.messenger.R;
import org.telegram.messenger.Utilities;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.CanvasButton;
import org.telegram.ui.Components.CheckBoxBase;
import org.telegram.ui.Components.CubicBezierInterpolator;
import org.telegram.ui.Components.FlickerLoadingView;
import org.telegram.ui.Components.spoilers.SpoilerEffect;
import org.telegram.ui.PhotoViewer;
public class SharedPhotoVideoCell2 extends View {
public ImageReceiver imageReceiver = new ImageReceiver();
public ImageReceiver blurImageReceiver = new ImageReceiver();
int currentAccount;
MessageObject currentMessageObject;
int currentParentColumnsCount;
@ -45,6 +55,7 @@ public class SharedPhotoVideoCell2 extends View {
float imageScale = 1f;
boolean showVideoLayout;
StaticLayout videoInfoLayot;
boolean drawVideoIcon = true;
String videoText;
CheckBoxBase checkBoxBase;
SharedResources sharedResources;
@ -56,6 +67,19 @@ public class SharedPhotoVideoCell2 extends View {
static long lastUpdateDownloadSettingsTime;
static boolean lastAutoDownload;
private Path path = new Path();
private SpoilerEffect mediaSpoilerEffect = new SpoilerEffect();
private float spoilerRevealProgress;
private float spoilerRevealX;
private float spoilerRevealY;
private float spoilerMaxRadius;
public final static int STYLE_SHARED_MEDIA = 0;
public final static int STYLE_CACHE = 1;
private int style = STYLE_SHARED_MEDIA;
CanvasButton canvasButton;
public SharedPhotoVideoCell2(Context context, SharedResources sharedResources, int currentAccount) {
super(context);
this.sharedResources = sharedResources;
@ -63,6 +87,41 @@ public class SharedPhotoVideoCell2 extends View {
setChecked(false, false);
imageReceiver.setParentView(this);
blurImageReceiver.setParentView(this);
imageReceiver.setDelegate((imageReceiver1, set, thumb, memCache) -> {
if (set && !thumb && currentMessageObject != null && currentMessageObject.hasMediaSpoilers() && imageReceiver.getBitmap() != null) {
if (blurImageReceiver.getBitmap() != null) {
blurImageReceiver.getBitmap().recycle();
}
blurImageReceiver.setImageBitmap(Utilities.stackBlurBitmapMax(imageReceiver.getBitmap()));
}
});
}
public void setStyle(int style) {
if (this.style == style) {
return;
}
this.style = style;
if (style == STYLE_CACHE) {
checkBoxBase = new CheckBoxBase(this, 21, null);
checkBoxBase.setColor(null, Theme.key_sharedMedia_photoPlaceholder, Theme.key_checkboxCheck);
checkBoxBase.setDrawUnchecked(true);
checkBoxBase.setBackgroundType(0);
checkBoxBase.setBounds(0, 0, AndroidUtilities.dp(24), AndroidUtilities.dp(24));
if (attached) {
checkBoxBase.onAttachedToWindow();
}
canvasButton = new CanvasButton(this);
canvasButton.setDelegate(() -> {
onCheckBoxPressed();
});
}
}
public void onCheckBoxPressed() {
}
@ -78,6 +137,7 @@ public class SharedPhotoVideoCell2 extends View {
currentMessageObject = messageObject;
if (messageObject == null) {
imageReceiver.onDetachedFromWindow();
blurImageReceiver.onDetachedFromWindow();
videoText = null;
videoInfoLayot = null;
showVideoLayout = false;
@ -85,6 +145,7 @@ public class SharedPhotoVideoCell2 extends View {
} else {
if (attached) {
imageReceiver.onAttachedToWindow();
blurImageReceiver.onAttachedToWindow();
}
}
String restrictionReason = MessagesController.getRestrictionReason(messageObject.messageOwner.restriction_reason);
@ -170,6 +231,15 @@ public class SharedPhotoVideoCell2 extends View {
if (showImageStub) {
imageReceiver.setImageBitmap(ContextCompat.getDrawable(getContext(), R.drawable.photo_placeholder_in));
}
if (blurImageReceiver.getBitmap() != null) {
blurImageReceiver.getBitmap().recycle();
blurImageReceiver.setImageBitmap((Bitmap) null);
}
if (imageReceiver.getBitmap() != null && currentMessageObject.hasMediaSpoilers() && !currentMessageObject.isMediaSpoilersRevealed) {
blurImageReceiver.setImageBitmap(Utilities.stackBlurBitmapMax(imageReceiver.getBitmap()));
}
invalidate();
}
@ -182,6 +252,11 @@ public class SharedPhotoVideoCell2 extends View {
return lastAutoDownload;
}
public void setVideoText(String videoText, boolean drawVideoIcon) {
this.videoText = videoText;
showVideoLayout = videoText != null;
this.drawVideoIcon = drawVideoIcon;
}
@Override
protected void onDraw(Canvas canvas) {
@ -207,7 +282,7 @@ public class SharedPhotoVideoCell2 extends View {
}
if (currentMessageObject == null || !imageReceiver.hasBitmapImage() || imageReceiver.getCurrentAlpha() != 1.0f || imageAlpha != 1f) {
if (SharedPhotoVideoCell2.this.getParent() != null) {
if (SharedPhotoVideoCell2.this.getParent() != null && globalGradientView != null) {
globalGradientView.setParentSize(((View) SharedPhotoVideoCell2.this.getParent()).getMeasuredWidth(), SharedPhotoVideoCell2.this.getMeasuredHeight(), -getX());
globalGradientView.updateColors();
globalGradientView.updateGradient();
@ -219,12 +294,9 @@ public class SharedPhotoVideoCell2 extends View {
}
invalidate();
}
if (currentMessageObject == null) {
return;
}
if (imageAlpha != 1f) {
canvas.saveLayerAlpha(0,0, padding * 2 + imageWidth, padding * 2 + imageHeight, (int) (255 * imageAlpha), Canvas.ALL_SAVE_FLAG);
canvas.saveLayerAlpha(0, 0, padding * 2 + imageWidth, padding * 2 + imageHeight, (int) (255 * imageAlpha), Canvas.ALL_SAVE_FLAG);
} else {
canvas.save();
}
@ -232,25 +304,48 @@ public class SharedPhotoVideoCell2 extends View {
if ((checkBoxBase != null && checkBoxBase.isChecked()) || PhotoViewer.isShowingImage(currentMessageObject)) {
canvas.drawRect(padding, padding, imageWidth, imageHeight, sharedResources.backgroundPaint);
}
if (currentMessageObject != null) {
if (checkBoxProgress > 0) {
float offset = AndroidUtilities.dp(10) * checkBoxProgress;
imageReceiver.setImageCoords(padding + offset, padding + offset, imageWidth - offset * 2, imageHeight - offset * 2);
} else {
float localPadding = padding;
if (crossfadeProgress > 0.5f && crossfadeToColumnsCount != 9 && currentParentColumnsCount != 9) {
localPadding += 1;
}
imageReceiver.setImageCoords(localPadding, localPadding, imageWidth, imageHeight);
if (checkBoxProgress > 0) {
float offset = AndroidUtilities.dp(10) * checkBoxProgress;
imageReceiver.setImageCoords(padding + offset, padding + offset, imageWidth - offset * 2, imageHeight - offset * 2);
blurImageReceiver.setImageCoords(padding + offset, padding + offset, imageWidth - offset * 2, imageHeight - offset * 2);
} else {
float localPadding = padding;
if (crossfadeProgress > 0.5f && crossfadeToColumnsCount != 9 && currentParentColumnsCount != 9) {
localPadding += 1;
}
if (!PhotoViewer.isShowingImage(currentMessageObject)) {
imageReceiver.draw(canvas);
if (highlightProgress > 0) {
sharedResources.highlightPaint.setColor(ColorUtils.setAlphaComponent(Color.BLACK, (int) (0.5f * highlightProgress * 255)));
canvas.drawRect(imageReceiver.getDrawRegion(), sharedResources.highlightPaint);
imageReceiver.setImageCoords(localPadding, localPadding, imageWidth, imageHeight);
blurImageReceiver.setImageCoords(localPadding, localPadding, imageWidth, imageHeight);
}
if (!PhotoViewer.isShowingImage(currentMessageObject)) {
imageReceiver.draw(canvas);
if (currentMessageObject != null && currentMessageObject.hasMediaSpoilers() && !currentMessageObject.isMediaSpoilersRevealedInSharedMedia) {
canvas.save();
canvas.clipRect(padding, padding, padding + imageWidth, padding + imageHeight);
if (spoilerRevealProgress != 0f) {
path.rewind();
path.addCircle(spoilerRevealX, spoilerRevealY, spoilerMaxRadius * spoilerRevealProgress, Path.Direction.CW);
canvas.clipPath(path, Region.Op.DIFFERENCE);
}
blurImageReceiver.draw(canvas);
int sColor = Color.WHITE;
mediaSpoilerEffect.setColor(ColorUtils.setAlphaComponent(sColor, (int) (Color.alpha(sColor) * 0.325f)));
mediaSpoilerEffect.setBounds((int) imageReceiver.getImageX(), (int) imageReceiver.getImageY(), (int) imageReceiver.getImageX2(), (int) imageReceiver.getImageY2());
mediaSpoilerEffect.draw(canvas);
canvas.restore();
invalidate();
}
if (highlightProgress > 0) {
sharedResources.highlightPaint.setColor(ColorUtils.setAlphaComponent(Color.BLACK, (int) (0.5f * highlightProgress * 255)));
canvas.drawRect(imageReceiver.getDrawRegion(), sharedResources.highlightPaint);
}
}
if (showVideoLayout) {
canvas.save();
canvas.clipRect(padding, padding, padding + imageWidth, padding + imageHeight);
@ -262,32 +357,75 @@ public class SharedPhotoVideoCell2 extends View {
if (videoInfoLayot == null) {
width = AndroidUtilities.dp(17);
} else {
width = AndroidUtilities.dp(14) + videoInfoLayot.getWidth() + AndroidUtilities.dp(4);
width = AndroidUtilities.dp(4) + videoInfoLayot.getWidth() + AndroidUtilities.dp(4);
}
if (drawVideoIcon) {
width += AndroidUtilities.dp(10);
}
canvas.translate(AndroidUtilities.dp(5), AndroidUtilities.dp(1) + imageHeight - AndroidUtilities.dp(17) - AndroidUtilities.dp(4));
AndroidUtilities.rectTmp.set(0, 0, width, AndroidUtilities.dp(17));
canvas.drawRoundRect(AndroidUtilities.rectTmp, AndroidUtilities.dp(4), AndroidUtilities.dp(4), Theme.chat_timeBackgroundPaint);
canvas.save();
canvas.translate(videoInfoLayot == null ? AndroidUtilities.dp(5) : AndroidUtilities.dp(4), (AndroidUtilities.dp(17) - sharedResources.playDrawable.getIntrinsicHeight()) / 2f);
sharedResources.playDrawable.setAlpha((int) (255 * imageAlpha));
sharedResources.playDrawable.draw(canvas);
canvas.restore();
if (drawVideoIcon) {
canvas.save();
canvas.translate(videoInfoLayot == null ? AndroidUtilities.dp(5) : AndroidUtilities.dp(4), (AndroidUtilities.dp(17) - sharedResources.playDrawable.getIntrinsicHeight()) / 2f);
sharedResources.playDrawable.setAlpha((int) (255 * imageAlpha));
sharedResources.playDrawable.draw(canvas);
canvas.restore();
}
if (videoInfoLayot != null) {
canvas.translate(AndroidUtilities.dp(14), (AndroidUtilities.dp(17) - videoInfoLayot.getHeight()) / 2f);
canvas.translate(AndroidUtilities.dp(4 + (drawVideoIcon ? 10 : 0)), (AndroidUtilities.dp(17) - videoInfoLayot.getHeight()) / 2f);
videoInfoLayot.draw(canvas);
}
canvas.restore();
}
if (checkBoxBase != null && checkBoxBase.getProgress() != 0) {
if (checkBoxBase != null && (style == STYLE_CACHE || checkBoxBase.getProgress() != 0)) {
canvas.save();
canvas.translate(imageWidth + AndroidUtilities.dp(2) - AndroidUtilities.dp(25), 0);
float x, y;
if (style == STYLE_CACHE) {
x = imageWidth + AndroidUtilities.dp(2) - AndroidUtilities.dp(25) - AndroidUtilities.dp(4);
y = AndroidUtilities.dp(4);
} else {
x = imageWidth + AndroidUtilities.dp(2) - AndroidUtilities.dp(25);
y = 0;
}
canvas.translate(x, y);
checkBoxBase.draw(canvas);
if (canvasButton != null) {
AndroidUtilities.rectTmp.set(x, y, x + checkBoxBase.bounds.width(), y + checkBoxBase.bounds.height());
canvasButton.setRect(AndroidUtilities.rectTmp);
}
canvas.restore();
}
canvas.restore();
}
public boolean canRevealSpoiler() {
return currentMessageObject != null && currentMessageObject.hasMediaSpoilers() && spoilerRevealProgress == 0f && !currentMessageObject.isMediaSpoilersRevealedInSharedMedia;
}
public void startRevealMedia(float x, float y) {
spoilerRevealX = x;
spoilerRevealY = y;
spoilerMaxRadius = (float) Math.sqrt(Math.pow(getWidth(), 2) + Math.pow(getHeight(), 2));
ValueAnimator animator = ValueAnimator.ofFloat(0, 1).setDuration((long) MathUtils.clamp(spoilerMaxRadius * 0.3f, 250, 550));
animator.setInterpolator(CubicBezierInterpolator.EASE_BOTH);
animator.addUpdateListener(animation -> {
spoilerRevealProgress = (float) animation.getAnimatedValue();
invalidate();
});
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
currentMessageObject.isMediaSpoilersRevealedInSharedMedia = true;
invalidate();
}
});
animator.start();
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
@ -297,6 +435,7 @@ public class SharedPhotoVideoCell2 extends View {
}
if (currentMessageObject != null) {
imageReceiver.onAttachedToWindow();
blurImageReceiver.onAttachedToWindow();
}
}
@ -309,6 +448,7 @@ public class SharedPhotoVideoCell2 extends View {
}
if (currentMessageObject != null) {
imageReceiver.onDetachedFromWindow();
blurImageReceiver.onDetachedFromWindow();
}
}
@ -377,7 +517,7 @@ public class SharedPhotoVideoCell2 extends View {
return;
}
if (checkBoxBase == null) {
checkBoxBase = new CheckBoxBase(this,21, null);
checkBoxBase = new CheckBoxBase(this, 21, null);
checkBoxBase.setColor(null, Theme.key_sharedMedia_photoPlaceholder, Theme.key_checkboxCheck);
checkBoxBase.setDrawUnchecked(false);
checkBoxBase.setBackgroundType(1);
@ -452,10 +592,20 @@ public class SharedPhotoVideoCell2 extends View {
public String getFilterString(int width) {
String str = imageFilters.get(width);
if (str == null) {
str = width + "_" + width + "_isc";
str = width + "_" + width + "_isc";
imageFilters.put(width, str);
}
return str;
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (canvasButton != null) {
if (canvasButton.checkTouchEvent(event)) {
return true;
}
}
return super.onTouchEvent(event);
}
}

View file

@ -32,6 +32,7 @@ import org.telegram.messenger.MessageObject;
import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R;
import org.telegram.messenger.SendMessagesHelper;
import org.telegram.messenger.SharedConfig;
import org.telegram.messenger.SvgHelper;
import org.telegram.messenger.UserConfig;
import org.telegram.tgnet.TLRPC;

View file

@ -10,12 +10,14 @@ package org.telegram.ui.Cells;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.view.Gravity;
import android.view.View;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.FrameLayout;
import android.widget.ImageView;
@ -33,6 +35,7 @@ import org.telegram.ui.Components.Switch;
public class TextCell extends FrameLayout {
public final SimpleTextView textView;
private final SimpleTextView subtitleView;
public final AnimatedTextView valueTextView;
public final RLottieImageView imageView;
private Switch checkBox;
@ -78,6 +81,13 @@ public class TextCell extends FrameLayout {
textView.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO);
addView(textView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.MATCH_PARENT));
subtitleView = new SimpleTextView(context);
subtitleView.setTextColor(Theme.getColor(dialog ? Theme.key_dialogTextGray : Theme.key_windowBackgroundWhiteGrayText, resourcesProvider));
subtitleView.setTextSize(13);
subtitleView.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT);
subtitleView.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO);
addView(subtitleView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.MATCH_PARENT));
valueTextView = new AnimatedTextView(context);
valueTextView.setTextColor(Theme.getColor(dialog ? Theme.key_dialogTextBlue2 : Theme.key_windowBackgroundWhiteValueText, resourcesProvider));
valueTextView.setPadding(0, AndroidUtilities.dp(18), 0, AndroidUtilities.dp(18));
@ -144,10 +154,12 @@ public class TextCell extends FrameLayout {
if (prioritizeTitleOverValue) {
textView.measure(MeasureSpec.makeMeasureSpec(width - AndroidUtilities.dp(71 + leftPadding), MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(20), MeasureSpec.EXACTLY));
subtitleView.measure(MeasureSpec.makeMeasureSpec(width - AndroidUtilities.dp(71 + leftPadding), MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(20), MeasureSpec.EXACTLY));
valueTextView.measure(MeasureSpec.makeMeasureSpec(width - AndroidUtilities.dp(103 + leftPadding) - textView.getTextWidth(), LocaleController.isRTL ? MeasureSpec.AT_MOST : MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(20), MeasureSpec.EXACTLY));
} else {
valueTextView.measure(MeasureSpec.makeMeasureSpec(width - AndroidUtilities.dp(leftPadding), LocaleController.isRTL ? MeasureSpec.AT_MOST : MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(20), MeasureSpec.EXACTLY));
textView.measure(MeasureSpec.makeMeasureSpec(width - AndroidUtilities.dp(71 + leftPadding) - valueTextView.width(), MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(20), MeasureSpec.EXACTLY));
subtitleView.measure(MeasureSpec.makeMeasureSpec(width - AndroidUtilities.dp(71 + leftPadding) - valueTextView.width(), MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(20), MeasureSpec.EXACTLY));
}
if (imageView.getVisibility() == VISIBLE) {
imageView.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST));
@ -181,14 +193,21 @@ public class TextCell extends FrameLayout {
}
valueTextView.layout(viewLeft, viewTop, viewLeft + valueTextView.getMeasuredWidth(), viewTop + valueTextView.getMeasuredHeight());
viewTop = (height - textView.getTextHeight()) / 2;
if (LocaleController.isRTL) {
viewLeft = getMeasuredWidth() - textView.getMeasuredWidth() - AndroidUtilities.dp(imageView.getVisibility() == VISIBLE ? offsetFromImage : leftPadding);
} else {
viewLeft = AndroidUtilities.dp(imageView.getVisibility() == VISIBLE ? offsetFromImage : leftPadding);
}
textView.layout(viewLeft, viewTop, viewLeft + textView.getMeasuredWidth(), viewTop + textView.getMeasuredHeight());
if (subtitleView.getVisibility() == View.VISIBLE) {
viewTop = (height - textView.getTextHeight() - subtitleView.getTextHeight() - AndroidUtilities.dp(2)) / 2;
textView.layout(viewLeft, viewTop, viewLeft + textView.getMeasuredWidth(), viewTop + textView.getMeasuredHeight());
viewTop = viewTop + textView.getTextHeight() + AndroidUtilities.dp(2);
subtitleView.layout(viewLeft, viewTop, viewLeft + subtitleView.getMeasuredWidth(), viewTop + subtitleView.getMeasuredHeight());
} else {
viewTop = (height - textView.getTextHeight()) / 2;
textView.layout(viewLeft, viewTop, viewLeft + textView.getMeasuredWidth(), viewTop + textView.getMeasuredHeight());
}
if (imageView.getVisibility() == VISIBLE) {
viewTop = AndroidUtilities.dp(5);
viewLeft = !LocaleController.isRTL ? AndroidUtilities.dp(imageLeft) : width - imageView.getMeasuredWidth() - AndroidUtilities.dp(imageLeft);
@ -303,6 +322,8 @@ public class TextCell extends FrameLayout {
valueTextView.setVisibility(VISIBLE);
valueImageView.setVisibility(GONE);
imageView.setVisibility(VISIBLE);
imageView.setTranslationX(0);
imageView.setTranslationY(0);
imageView.setPadding(0, AndroidUtilities.dp(7), 0, 0);
imageView.setImageResource(resId);
needDivider = divider;
@ -312,6 +333,17 @@ public class TextCell extends FrameLayout {
}
}
public void setColorfulIcon(int color, int resId) {
offsetFromImage = 65;
imageView.setVisibility(VISIBLE);
imageView.setPadding(AndroidUtilities.dp(2), AndroidUtilities.dp(2), AndroidUtilities.dp(2), AndroidUtilities.dp(2));
imageView.setTranslationX(AndroidUtilities.dp(-3));
imageView.setTranslationY(AndroidUtilities.dp(6));
imageView.setImageResource(resId);
imageView.setColorFilter(new PorterDuffColorFilter(Color.WHITE, PorterDuff.Mode.SRC_IN));
imageView.setBackground(Theme.createRoundRectDrawable(AndroidUtilities.dp(8), color));
}
public void setTextAndCheck(String text, boolean checked, boolean divider) {
imageLeft = 21;
offsetFromImage = 71;
@ -521,4 +553,13 @@ public class TextCell extends FrameLayout {
valueTextView.setAlpha(1f - drawLoadingProgress);
super.dispatchDraw(canvas);
}
public void setSubtitle(CharSequence charSequence) {
if (!TextUtils.isEmpty(charSequence)) {
subtitleView.setVisibility(View.VISIBLE);
subtitleView.setText(charSequence);
} else {
subtitleView.setVisibility(View.GONE);
}
}
}

View file

@ -315,7 +315,8 @@ public class TextSettingsCell extends FrameLayout {
super.dispatchDraw(canvas);
if (needDivider) {
canvas.drawLine(LocaleController.isRTL ? 0 : AndroidUtilities.dp(20), getMeasuredHeight() - 1, getMeasuredWidth() - (LocaleController.isRTL ? AndroidUtilities.dp(20) : 0), getMeasuredHeight() - 1, Theme.dividerPaint);
int offset = AndroidUtilities.dp(imageView.getVisibility() == View.VISIBLE ? 71 : 20);
canvas.drawLine(LocaleController.isRTL ? 0 : offset, getMeasuredHeight() - 1, getMeasuredWidth() - (LocaleController.isRTL ? offset : 0), getMeasuredHeight() - 1, Theme.dividerPaint);
}
}

View file

@ -208,7 +208,7 @@ public class ChangeBioActivity extends BaseFragment {
return;
}
final AlertDialog progressDialog = new AlertDialog(getParentActivity(), 3);
final AlertDialog progressDialog = new AlertDialog(getParentActivity(), AlertDialog.ALERT_TYPE_SPINNER);
final TLRPC.TL_account_updateProfile req = new TLRPC.TL_account_updateProfile();
req.about = newName;

View file

@ -1288,7 +1288,7 @@ public class ChangeUsernameActivity extends BaseFragment {
return;
}
final AlertDialog progressDialog = new AlertDialog(getParentActivity(), 3);
final AlertDialog progressDialog = new AlertDialog(getParentActivity(), AlertDialog.ALERT_TYPE_SPINNER);
final TLRPC.TL_account_updateUsername req = new TLRPC.TL_account_updateUsername();
req.username = username;

View file

@ -2710,7 +2710,7 @@ public class ChannelAdminLogActivity extends BaseFragment implements Notificatio
linviteLoading = true;
boolean[] canceled = new boolean[1];
final AlertDialog progressDialog = new AlertDialog(getParentActivity(), 3);
final AlertDialog progressDialog = new AlertDialog(getParentActivity(), AlertDialog.ALERT_TYPE_SPINNER);
progressDialog.setOnCancelListener(dialogInterface -> {
linviteLoading = false;
canceled[0] = true;

View file

@ -265,7 +265,7 @@ public class ChannelCreateActivity extends BaseFragment implements NotificationC
return;
}
AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity());
builder.setTitle(LocaleController.getString("AppName", R.string.AppName));
builder.setTitle(LocaleController.getString("StopLoadingTitle", R.string.StopLoadingTitle));
builder.setMessage(LocaleController.getString("StopLoading", R.string.StopLoading));
builder.setPositiveButton(LocaleController.getString("WaitMore", R.string.WaitMore), null);
builder.setNegativeButton(LocaleController.getString("Stop", R.string.Stop), (dialogInterface, i) -> {
@ -571,7 +571,7 @@ public class ChannelCreateActivity extends BaseFragment implements NotificationC
} else {
cameraDrawable.setCurrentFrame(0, false);
}
});
}, 0);
cameraDrawable.setCurrentFrame(0);
cameraDrawable.setCustomEndFrame(43);
avatarEditor.playAnimation();
@ -954,7 +954,7 @@ public class ChannelCreateActivity extends BaseFragment implements NotificationC
}
@Override
public void didUploadPhoto(final TLRPC.InputFile photo, final TLRPC.InputFile video, double videoStartTimestamp, String videoPath, final TLRPC.PhotoSize bigSize, final TLRPC.PhotoSize smallSize) {
public void didUploadPhoto(final TLRPC.InputFile photo, final TLRPC.InputFile video, double videoStartTimestamp, String videoPath, final TLRPC.PhotoSize bigSize, final TLRPC.PhotoSize smallSize, boolean isVideo) {
AndroidUtilities.runOnUIThread(() -> {
if (photo != null || video != null) {
inputPhoto = photo;

File diff suppressed because it is too large Load diff

View file

@ -618,7 +618,7 @@ public class ChatEditActivity extends BaseFragment implements ImageUpdater.Image
cameraDrawable.setCurrentFrame(0, false);
}
});
}, 0);
cameraDrawable.setCurrentFrame(0);
cameraDrawable.setCustomEndFrame(43);
setAvatarCell.imageView.playAnimation();
@ -1110,7 +1110,7 @@ public class ChatEditActivity extends BaseFragment implements ImageUpdater.Image
}
@Override
public void didUploadPhoto(final TLRPC.InputFile photo, final TLRPC.InputFile video, double videoStartTimestamp, String videoPath, final TLRPC.PhotoSize bigSize, final TLRPC.PhotoSize smallSize) {
public void didUploadPhoto(final TLRPC.InputFile photo, final TLRPC.InputFile video, double videoStartTimestamp, String videoPath, final TLRPC.PhotoSize bigSize, final TLRPC.PhotoSize smallSize, boolean isVideo) {
AndroidUtilities.runOnUIThread(() -> {
avatar = smallSize.location;
if (photo != null || video != null) {
@ -1226,7 +1226,7 @@ public class ChatEditActivity extends BaseFragment implements ImageUpdater.Image
if (imageUpdater.isUploadingImage()) {
createAfterUpload = true;
progressDialog = new AlertDialog(getParentActivity(), 3);
progressDialog = new AlertDialog(getParentActivity(), AlertDialog.ALERT_TYPE_SPINNER);
progressDialog.setOnCancelListener(dialog -> {
createAfterUpload = false;
progressDialog = null;

View file

@ -428,7 +428,7 @@ public class ChatLinkActivity extends BaseFragment implements NotificationCenter
builder.setMessage(AndroidUtilities.replaceTags(message));
builder.setPositiveButton(LocaleController.getString("DiscussionUnlink", R.string.DiscussionUnlink), (dialogInterface, i) -> {
if (!isChannel || info.linked_chat_id != 0) {
final AlertDialog[] progressDialog = new AlertDialog[]{new AlertDialog(getParentActivity(), 3)};
final AlertDialog[] progressDialog = new AlertDialog[]{new AlertDialog(getParentActivity(), AlertDialog.ALERT_TYPE_SPINNER)};
TLRPC.TL_channels_setDiscussionGroup req = new TLRPC.TL_channels_setDiscussionGroup();
if (isChannel) {
req.broadcast = MessagesController.getInputChannel(currentChat);
@ -481,7 +481,7 @@ public class ChatLinkActivity extends BaseFragment implements NotificationCenter
if (query) {
getMessagesController().loadFullChat(chat.id, 0, true);
waitingForFullChat = chat;
waitingForFullChatProgressAlert = new AlertDialog(getParentActivity(), 3);
waitingForFullChatProgressAlert = new AlertDialog(getParentActivity(), AlertDialog.ALERT_TYPE_SPINNER);
AndroidUtilities.runOnUIThread(() -> {
if (waitingForFullChatProgressAlert == null) {
return;
@ -561,7 +561,7 @@ public class ChatLinkActivity extends BaseFragment implements NotificationCenter
});
return;
}
final AlertDialog[] progressDialog = new AlertDialog[]{createFragment != null ? null : new AlertDialog(getParentActivity(), 3)};
final AlertDialog[] progressDialog = new AlertDialog[]{createFragment != null ? null : new AlertDialog(getParentActivity(), AlertDialog.ALERT_TYPE_SPINNER)};
TLRPC.TL_channels_setDiscussionGroup req = new TLRPC.TL_channels_setDiscussionGroup();
req.broadcast = MessagesController.getInputChannel(currentChat);
req.group = MessagesController.getInputChannel(chat);

View file

@ -19,6 +19,7 @@ import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.style.ForegroundColorSpan;
import android.util.Log;
import android.util.SparseIntArray;
import android.view.Gravity;
import android.view.View;
@ -137,6 +138,9 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
private int participantsEndRow;
private int participantsDividerRow;
private int participantsDivider2Row;
private boolean hideMembersToggleLoading;
private int hideMembersRow;
private int hideMembersInfoRow;
private int slowmodeRow;
private int slowmodeSelectRow;
@ -241,6 +245,8 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
antiSpamInfoRow = -1;
addNewRow = -1;
addNew2Row = -1;
hideMembersRow = -1;
hideMembersInfoRow = -1;
addNewSectionRow = -1;
restricted1SectionRow = -1;
participantsStartRow = -1;
@ -392,6 +398,10 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
loadingUserCellRow = rowCount++;
}
} else if (type == TYPE_USERS) {
if (!ChatObject.isChannelAndNotMegaGroup(currentChat) && !needOpenSearch) {
hideMembersRow = rowCount++;
hideMembersInfoRow = rowCount++;
}
if (selectType == SELECT_TYPE_MEMBERS && ChatObject.canAddUsers(currentChat)) {
addNewRow = rowCount++;
}
@ -866,7 +876,7 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
getMessagesController().processUpdates((TLRPC.Updates) res, false);
getMessagesController().putChatFull(info);
}
if (err != null && !"".equals(err.text)) {
if (err != null && !"CHAT_NOT_MODIFIED".equals(err.text)) {
AndroidUtilities.runOnUIThread(() -> {
if (getParentActivity() == null) {
return;
@ -880,6 +890,36 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
});
}
return;
} else if (position == hideMembersRow) {
final TextCell textCell = (TextCell) view;
if (info != null && !info.participants_hidden && info.participants_count < getMessagesController().hiddenMembersGroupSizeMin) {
BulletinFactory.of(this).createSimpleBulletin(R.raw.contacts_sync_off, AndroidUtilities.replaceTags(LocaleController.formatPluralString("ChannelHiddenMembersForbidden", getMessagesController().hiddenMembersGroupSizeMin))).show();
} else if (info != null && ChatObject.canUserDoAdminAction(currentChat, ChatObject.ACTION_BLOCK_USERS) && !hideMembersToggleLoading) {
hideMembersToggleLoading = true;
boolean wasParticipantsHidden = info.participants_hidden;
TLRPC.TL_channels_toggleParticipantsHidden req = new TLRPC.TL_channels_toggleParticipantsHidden();
req.channel = getMessagesController().getInputChannel(chatId);
textCell.setChecked(req.enabled = (info.participants_hidden = !info.participants_hidden));
textCell.getCheckBox().setIcon(ChatObject.canUserDoAdminAction(currentChat, ChatObject.ACTION_BLOCK_USERS) && (info == null || info.participants_hidden || info.participants_count >= getMessagesController().hiddenMembersGroupSizeMin) ? 0 : R.drawable.permission_locked);
getConnectionsManager().sendRequest(req, (res, err) -> {
if (res != null) {
getMessagesController().processUpdates((TLRPC.Updates) res, false);
getMessagesController().putChatFull(info);
}
if (err != null && !"CHAT_NOT_MODIFIED".equals(err.text)) {
AndroidUtilities.runOnUIThread(() -> {
if (getParentActivity() == null) {
return;
}
textCell.setChecked(info.participants_hidden = wasParticipantsHidden);
textCell.getCheckBox().setIcon(ChatObject.canUserDoAdminAction(currentChat, ChatObject.ACTION_BLOCK_USERS) && (info == null || !info.participants_hidden || info.participants_count >= getMessagesController().hiddenMembersGroupSizeMin) ? 0 : R.drawable.permission_locked);
BulletinFactory.of(ChatUsersActivity.this).createSimpleBulletin(R.raw.error, LocaleController.getString("UnknownError", R.string.UnknownError)).show();
});
}
hideMembersToggleLoading = false;
});
}
return;
} else if (position == removedUsersRow) {
Bundle args = new Bundle();
args.putLong("chat_id", chatId);
@ -2910,7 +2950,18 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
}
return true;
}
return viewType == 0 || viewType == 2 || viewType == 6 || viewType == 12 && ChatObject.canUserDoAdminAction(currentChat, ChatObject.ACTION_DELETE_MESSAGES);
int position = holder.getAdapterPosition();
if (viewType == 0 || viewType == 2 || viewType == 6) {
return true;
}
if (viewType == 12) {
if (position == antiSpamRow) {
return ChatObject.canUserDoAdminAction(currentChat, ChatObject.ACTION_DELETE_MESSAGES);
} else if (position == hideMembersRow) {
return ChatObject.canUserDoAdminAction(currentChat, ChatObject.ACTION_BLOCK_USERS);
}
}
return false;
}
@Override
@ -3153,6 +3204,9 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
} else {
privacyCell.setText(LocaleController.formatString("SlowmodeInfoSelected", R.string.SlowmodeInfoSelected, formatSeconds(seconds)));
}
} else if (position == hideMembersInfoRow) {
privacyCell.setBackgroundDrawable(Theme.getThemedDrawable(mContext, R.drawable.greydivider, Theme.key_windowBackgroundGrayShadow));
privacyCell.setText(LocaleController.getString("ChannelHideMembersInfo", R.string.ChannelHideMembersInfo));
} else if (position == gigaInfoRow) {
privacyCell.setText(LocaleController.getString("BroadcastGroupConvertInfo", R.string.BroadcastGroupConvertInfo));
}
@ -3296,6 +3350,9 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
if (position == antiSpamRow) {
textCell.getCheckBox().setIcon(ChatObject.canUserDoAdminAction(currentChat, ChatObject.ACTION_DELETE_MESSAGES) && (info == null || info.antispam || info.participants_count >= getMessagesController().telegramAntispamGroupSizeMin) ? 0 : R.drawable.permission_locked);
textCell.setTextAndCheckAndIcon(LocaleController.getString("ChannelAntiSpam", R.string.ChannelAntiSpam), info != null && info.antispam, R.drawable.msg_policy, false);
} else if (position == hideMembersRow) {
textCell.getCheckBox().setIcon(ChatObject.canUserDoAdminAction(currentChat, ChatObject.ACTION_BLOCK_USERS) && (info == null || info.participants_hidden || info.participants_count >= getMessagesController().hiddenMembersGroupSizeMin) ? 0 : R.drawable.permission_locked);
textCell.setTextAndCheck(LocaleController.getString("ChannelHideMembers", R.string.ChannelHideMembers), info != null && info.participants_hidden, false);
}
break;
}
@ -3320,7 +3377,7 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
return 3;
} else if (position == restricted1SectionRow || position == permissionsSectionRow || position == slowmodeRow || position == gigaHeaderRow) {
return 5;
} else if (position == participantsInfoRow || position == slowmodeInfoRow || position == gigaInfoRow || position == antiSpamInfoRow) {
} else if (position == participantsInfoRow || position == slowmodeInfoRow || position == gigaInfoRow || position == antiSpamInfoRow || position == hideMembersInfoRow) {
return 1;
} else if (position == blockedEmptyRow) {
return 4;
@ -3337,7 +3394,7 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
return 10;
} else if (position == loadingUserCellRow) {
return 11;
} else if (position == antiSpamRow) {
} else if (position == antiSpamRow || position == hideMembersRow) {
return 12;
}
return 0;

View file

@ -250,7 +250,11 @@ public class CodeNumberField extends EditTextBoldCursor {
if (clipboard == null || clipboard.getPrimaryClipDescription() == null) {
return false;
}
clipboard.getPrimaryClipDescription().hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN);
ClipDescription description = clipboard.getPrimaryClipDescription();
if (description == null) {
return false;
}
description.hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN);
ClipData.Item item = clipboard.getPrimaryClip().getItemAt(0);
int i = -1;
String text = item == null || item.getText() == null ? "" : item.getText().toString();

View file

@ -70,6 +70,7 @@ import org.telegram.messenger.BuildVars;
import org.telegram.messenger.ChatObject;
import org.telegram.messenger.ContactsController;
import org.telegram.messenger.DialogObject;
import org.telegram.messenger.Emoji;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MessageObject;
@ -661,13 +662,27 @@ public class AlertsCreator {
}
public static AlertDialog.Builder createSimpleAlert(Context context, final String title, final String text, Theme.ResourcesProvider resourcesProvider) {
return createSimpleAlert(context, title, text, null, null, resourcesProvider);
}
public static AlertDialog.Builder createSimpleAlert(Context context, final String title, final String text, String positiveButton, Runnable positive, Theme.ResourcesProvider resourcesProvider) {
if (context == null || text == null) {
return null;
}
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(title == null ? LocaleController.getString("AppName", R.string.AppName) : title);
builder.setMessage(text);
builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), null);
if (positiveButton == null) {
builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), null);
} else {
builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null);
builder.setPositiveButton(positiveButton, (dialog, which) -> {
dialog.dismiss();
if (positive != null) {
positive.run();
}
});
}
return builder;
}
@ -1081,20 +1096,20 @@ public class AlertsCreator {
}
public static void showOpenUrlAlert(BaseFragment fragment, String url, boolean punycode, boolean ask) {
showOpenUrlAlert(fragment, url, punycode, true, ask, null);
showOpenUrlAlert(fragment, url, punycode, true, ask, null, null);
}
public static void showOpenUrlAlert(BaseFragment fragment, String url, boolean punycode, boolean ask, Theme.ResourcesProvider resourcesProvider) {
showOpenUrlAlert(fragment, url, punycode, true, ask, resourcesProvider);
showOpenUrlAlert(fragment, url, punycode, true, ask, null, resourcesProvider);
}
public static void showOpenUrlAlert(BaseFragment fragment, String url, boolean punycode, boolean tryTelegraph, boolean ask, Theme.ResourcesProvider resourcesProvider) {
public static void showOpenUrlAlert(BaseFragment fragment, String url, boolean punycode, boolean tryTelegraph, boolean ask, Browser.Progress progress, Theme.ResourcesProvider resourcesProvider) {
if (fragment == null || fragment.getParentActivity() == null) {
return;
}
long inlineReturn = (fragment instanceof ChatActivity) ? ((ChatActivity) fragment).getInlineReturn() : 0;
if (Browser.isInternalUrl(url, null) || !ask) {
Browser.openUrl(fragment.getParentActivity(), url, inlineReturn == 0, tryTelegraph);
Browser.openUrl(fragment.getParentActivity(), Uri.parse(url), inlineReturn == 0, tryTelegraph, progress);
} else {
String urlFinal;
if (punycode) {
@ -1119,7 +1134,7 @@ public class AlertsCreator {
}
builder.setMessage(stringBuilder);
builder.setMessageTextViewClickable(false);
builder.setPositiveButton(LocaleController.getString("Open", R.string.Open), (dialogInterface, i) -> Browser.openUrl(fragment.getParentActivity(), url, inlineReturn == 0, tryTelegraph));
builder.setPositiveButton(LocaleController.getString("Open", R.string.Open), (dialogInterface, i) -> Browser.openUrl(fragment.getParentActivity(), Uri.parse(url), inlineReturn == 0, tryTelegraph, progress));
builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null);
fragment.showDialog(builder.create());
}
@ -1190,7 +1205,7 @@ public class AlertsCreator {
}
}
if (supportUser == null) {
final AlertDialog progressDialog = new AlertDialog(fragment.getParentActivity(), 3);
final AlertDialog progressDialog = new AlertDialog(fragment.getParentActivity(), AlertDialog.ALERT_TYPE_SPINNER);
progressDialog.setCanCancel(false);
progressDialog.show();
TLRPC.TL_help_getSupport req = new TLRPC.TL_help_getSupport();
@ -1343,7 +1358,14 @@ public class AlertsCreator {
CheckBoxCell[] cell = new CheckBoxCell[1];
TextView messageTextView = new TextView(context);
TextView messageTextView = new TextView(context) {
@Override
public void setText(CharSequence text, BufferType type) {
text = Emoji.replaceEmoji(text, getPaint().getFontMetricsInt(), false);
super.setText(text, type);
}
};
NotificationCenter.listenEmojiLoading(messageTextView);
messageTextView.setTextColor(Theme.getColor(Theme.key_dialogTextBlack));
messageTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
messageTextView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP);
@ -1362,7 +1384,7 @@ public class AlertsCreator {
builder.setView(frameLayout);
AvatarDrawable avatarDrawable = new AvatarDrawable();
avatarDrawable.setTextSize(AndroidUtilities.dp(12));
avatarDrawable.setTextSize(AndroidUtilities.dp(18));
BackupImageView imageView = new BackupImageView(context);
imageView.setRoundRadius(AndroidUtilities.dp(20));
@ -1619,7 +1641,14 @@ public class AlertsCreator {
CheckBoxCell[] cell = new CheckBoxCell[1];
TextView messageTextView = new TextView(context);
TextView messageTextView = new TextView(context) {
@Override
public void setText(CharSequence text, BufferType type) {
text = Emoji.replaceEmoji(text, getPaint().getFontMetricsInt(), false);
super.setText(text, type);
}
};
NotificationCenter.listenEmojiLoading(messageTextView);
messageTextView.setTextColor(Theme.getColor(Theme.key_dialogTextBlack));
messageTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
messageTextView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP);
@ -1730,7 +1759,14 @@ public class AlertsCreator {
message = LocaleController.formatString("CallAlert", R.string.CallAlert, UserObject.getUserName(user));
}
TextView messageTextView = new TextView(context);
TextView messageTextView = new TextView(context) {
@Override
public void setText(CharSequence text, BufferType type) {
text = Emoji.replaceEmoji(text, getPaint().getFontMetricsInt(), false);
super.setText(text, type);
}
};
NotificationCenter.listenEmojiLoading(messageTextView);
messageTextView.setTextColor(Theme.getColor(Theme.key_dialogTextBlack));
messageTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
messageTextView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP);
@ -2115,6 +2151,52 @@ public class AlertsCreator {
baseFragment.showDialog(builder.create());
}
public static void createContactInviteDialog(BaseFragment parentFragment, String fisrtName, String lastName, String phone) {
AlertDialog.Builder builder = new AlertDialog.Builder(parentFragment.getParentActivity());
builder.setTitle(LocaleController.getString("ContactNotRegisteredTitle", R.string.ContactNotRegisteredTitle));
builder.setMessage(LocaleController.formatString("ContactNotRegistered", R.string.ContactNotRegistered, ContactsController.formatName(fisrtName, lastName)));
builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null);
builder.setPositiveButton(LocaleController.getString("Invite", R.string.Invite), (dialog, which) -> {
try {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.fromParts("sms", phone, null));
intent.putExtra("sms_body", ContactsController.getInstance(parentFragment.getCurrentAccount()).getInviteText(1));
parentFragment.getParentActivity().startActivityForResult(intent, 500);
} catch (Exception e) {
FileLog.e(e);
}
});
parentFragment.showDialog(builder.create());
}
public static ActionBarPopupWindow createSimplePopup(BaseFragment fragment, View popupView, View anhcorView, float x, float y) {
if (fragment == null || anhcorView == null || popupView == null) {
return null;
}
ActionBarPopupWindow popupWindow = new ActionBarPopupWindow(popupView, LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT);
popupWindow.setPauseNotifications(true);
popupWindow.setDismissAnimationDuration(220);
popupWindow.setOutsideTouchable(true);
popupWindow.setClippingEnabled(true);
popupWindow.setAnimationStyle(R.style.PopupContextAnimation);
popupWindow.setFocusable(true);
popupView.measure(View.MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(1000), View.MeasureSpec.AT_MOST), View.MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(1000), View.MeasureSpec.AT_MOST));
popupWindow.setInputMethodMode(ActionBarPopupWindow.INPUT_METHOD_NOT_NEEDED);
popupWindow.getContentView().setFocusableInTouchMode(true);
float viewX = 0, viewY = 0;
View child = anhcorView;
while (child != anhcorView.getRootView()) {
viewX += child.getX();
viewY += child.getY();
child = (View) child.getParent();
if (child == null) {
break;
}
}
popupWindow.showAtLocation(anhcorView.getRootView(), 0, (int) (viewX + x - popupView.getMeasuredWidth() / 2f), (int) (viewY + y - popupView.getMeasuredHeight() / 2f));
popupWindow.dimBehind();
return popupWindow;
}
public interface BlockDialogCallback {
void run(boolean report, boolean delete);
}
@ -2459,6 +2541,8 @@ public class AlertsCreator {
return LocaleController.formatPluralString("Hours", value);
}
};
hourPicker.setWrapSelectorWheel(true);
hourPicker.setAllItemsCount(24);
hourPicker.setItemCount(5);
hourPicker.setTextColor(datePickerColors.textColor);
hourPicker.setTextOffset(-AndroidUtilities.dp(10));
@ -2468,6 +2552,8 @@ public class AlertsCreator {
return LocaleController.formatPluralString("Minutes", value);
}
};
minutePicker.setWrapSelectorWheel(true);
minutePicker.setAllItemsCount(60);
minutePicker.setItemCount(5);
minutePicker.setTextColor(datePickerColors.textColor);
minutePicker.setTextOffset(-AndroidUtilities.dp(34));
@ -3737,6 +3823,44 @@ public class AlertsCreator {
return builder.create();
}
public static BottomSheet createMuteAlert(BaseFragment fragment, ArrayList<Long> dialog_ids, int topicId, Theme.ResourcesProvider resourcesProvider) {
if (fragment == null || fragment.getParentActivity() == null) {
return null;
}
BottomSheet.Builder builder = new BottomSheet.Builder(fragment.getParentActivity(), false, resourcesProvider);
builder.setTitle(LocaleController.getString("Notifications", R.string.Notifications), true);
CharSequence[] items = new CharSequence[]{
LocaleController.formatString("MuteFor", R.string.MuteFor, LocaleController.formatPluralString("Hours", 1)),
LocaleController.formatString("MuteFor", R.string.MuteFor, LocaleController.formatPluralString("Hours", 8)),
LocaleController.formatString("MuteFor", R.string.MuteFor, LocaleController.formatPluralString("Days", 2)),
LocaleController.getString("MuteDisable", R.string.MuteDisable)
};
builder.setItems(items, (dialogInterface, i) -> {
int setting;
if (i == 0) {
setting = NotificationsController.SETTING_MUTE_HOUR;
} else if (i == 1) {
setting = NotificationsController.SETTING_MUTE_8_HOURS;
} else if (i == 2) {
setting = NotificationsController.SETTING_MUTE_2_DAYS;
} else {
setting = NotificationsController.SETTING_MUTE_FOREVER;
}
if (dialog_ids != null) {
for (int j = 0; j < dialog_ids.size(); ++j) {
long dialog_id = dialog_ids.get(j);
NotificationsController.getInstance(UserConfig.selectedAccount).setDialogNotificationsSettings(dialog_id, topicId, setting);
}
}
if (BulletinFactory.canShowBulletin(fragment)) {
BulletinFactory.createMuteBulletin(fragment, setting, 0, resourcesProvider).show();
}
}
);
return builder.create();
}
public static void sendReport(TLRPC.InputPeer peer, int type, String message, ArrayList<Integer> messages) {
TLRPC.TL_messages_report request = new TLRPC.TL_messages_report();
request.peer = peer;
@ -4572,69 +4696,11 @@ public class AlertsCreator {
}
public static Dialog createFreeSpaceDialog(final LaunchActivity parentActivity) {
final int[] selected = new int[1];
if (SharedConfig.keepMedia == 2) {
selected[0] = 3;
} else if (SharedConfig.keepMedia == 0) {
selected[0] = 1;
} else if (SharedConfig.keepMedia == 1) {
selected[0] = 2;
} else if (SharedConfig.keepMedia == 3) {
selected[0] = 0;
}
String[] descriptions = new String[]{
LocaleController.formatPluralString("Days", 3),
LocaleController.formatPluralString("Weeks", 1),
LocaleController.formatPluralString("Months", 1),
LocaleController.getString("LowDiskSpaceNeverRemove", R.string.LowDiskSpaceNeverRemove)
};
final LinearLayout linearLayout = new LinearLayout(parentActivity);
linearLayout.setOrientation(LinearLayout.VERTICAL);
TextView titleTextView = new TextView(parentActivity);
titleTextView.setText(LocaleController.getString("LowDiskSpaceTitle2", R.string.LowDiskSpaceTitle2));
titleTextView.setTextColor(Theme.getColor(Theme.key_dialogTextBlack));
titleTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
titleTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
titleTextView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP);
linearLayout.addView(titleTextView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, 24, 0, 24, 8));
for (int a = 0; a < descriptions.length; a++) {
RadioColorCell cell = new RadioColorCell(parentActivity);
cell.setPadding(AndroidUtilities.dp(4), 0, AndroidUtilities.dp(4), 0);
cell.setTag(a);
cell.setCheckColor(Theme.getColor(Theme.key_radioBackground), Theme.getColor(Theme.key_dialogRadioBackgroundChecked));
cell.setTextAndValue(descriptions[a], selected[0] == a);
linearLayout.addView(cell);
cell.setOnClickListener(v -> {
int num = (Integer) v.getTag();
if (num == 0) {
selected[0] = 3;
} else if (num == 1) {
selected[0] = 0;
} else if (num == 2) {
selected[0] = 1;
} else if (num == 3) {
selected[0] = 2;
}
int count = linearLayout.getChildCount();
for (int a1 = 0; a1 < count; a1++) {
View child = linearLayout.getChildAt(a1);
if (child instanceof RadioColorCell) {
((RadioColorCell) child).setChecked(child == v, true);
}
}
});
}
AlertDialog.Builder builder = new AlertDialog.Builder(parentActivity);
builder.setTitle(LocaleController.getString("LowDiskSpaceTitle", R.string.LowDiskSpaceTitle));
builder.setMessage(LocaleController.getString("LowDiskSpaceMessage", R.string.LowDiskSpaceMessage));
builder.setView(linearLayout);
builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), (dialog, which) -> SharedConfig.setKeepMedia(selected[0]));
builder.setNeutralButton(LocaleController.getString("ClearMediaCache", R.string.ClearMediaCache), (dialog, which) -> parentActivity.presentFragment(new CacheControlActivity()));
builder.setMessage(LocaleController.getString("LowDiskSpaceMessage2", R.string.LowDiskSpaceMessage2));
builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null);
builder.setPositiveButton(LocaleController.getString("LowDiskSpaceButton", R.string.LowDiskSpaceButton), (dialog, which) -> parentActivity.presentFragment(new CacheControlActivity()));
return builder.create();
}
@ -5059,7 +5125,7 @@ public class AlertsCreator {
}
if ((actionUser != null && actionUser.id != UserConfig.getInstance(currentAccount).getClientUserId()) || (actionChat != null && !ChatObject.hasAdminRights(actionChat))) {
if (loadParticipant == 1 && !chat.creator && actionUser != null) {
final AlertDialog[] progressDialog = new AlertDialog[]{new AlertDialog(activity, 3)};
final AlertDialog[] progressDialog = new AlertDialog[]{new AlertDialog(activity, AlertDialog.ALERT_TYPE_SPINNER)};
TLRPC.TL_channels_getParticipant req = new TLRPC.TL_channels_getParticipant();
req.channel = MessagesController.getInputChannel(chat);

View file

@ -11,7 +11,6 @@ import android.graphics.drawable.Drawable;
import android.os.Looper;
import android.text.TextUtils;
import android.view.View;
import android.view.animation.LinearInterpolator;
import android.view.animation.OvershootInterpolator;
import androidx.annotation.NonNull;
@ -40,6 +39,7 @@ import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.Premium.PremiumLockIconView;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
@ -60,10 +60,19 @@ public class AnimatedEmojiDrawable extends Drawable {
public static final int CACHE_TYPE_ALERT_EMOJI_STATUS = 9;
public static final int CACHE_TYPE_FORUM_TOPIC = 10;
public static final int CACHE_TYPE_FORUM_TOPIC_LARGE = 11;
public static final int CACHE_TYPE_RENDERING_VIDEO = 12;
public int rawDrawIndex;
private static HashMap<Integer, HashMap<Long, AnimatedEmojiDrawable>> globalEmojiCache;
@NonNull
public static AnimatedEmojiDrawable make(int account, int cacheType, long documentId) {
return make(account, cacheType, documentId, null);
}
@NonNull
public static AnimatedEmojiDrawable make(int account, int cacheType, long documentId, String absolutePath) {
if (globalEmojiCache == null) {
globalEmojiCache = new HashMap<>();
}
@ -74,7 +83,7 @@ public class AnimatedEmojiDrawable extends Drawable {
}
AnimatedEmojiDrawable drawable = cache.get(documentId);
if (drawable == null) {
cache.put(documentId, drawable = new AnimatedEmojiDrawable(cacheType, account, documentId));
cache.put(documentId, drawable = new AnimatedEmojiDrawable(cacheType, account, documentId, absolutePath));
}
return drawable;
}
@ -150,14 +159,18 @@ public class AnimatedEmojiDrawable extends Drawable {
}
public void fetchDocument(long id, ReceivedDocument onDone) {
checkThread();
if (emojiDocumentsCache != null) {
TLRPC.Document cacheDocument = emojiDocumentsCache.get(id);
if (cacheDocument != null) {
onDone.run(cacheDocument);
return;
synchronized (this) {
if (emojiDocumentsCache != null) {
TLRPC.Document cacheDocument = emojiDocumentsCache.get(id);
if (cacheDocument != null) {
onDone.run(cacheDocument);
return;
}
}
}
if (!checkThread()) {
return;
}
if (onDone != null) {
if (loadingDocuments == null) {
loadingDocuments = new HashMap<>();
@ -186,10 +199,14 @@ public class AnimatedEmojiDrawable extends Drawable {
});
}
private void checkThread() {
if (BuildVars.DEBUG_VERSION && Thread.currentThread() != Looper.getMainLooper().getThread()) {
throw new IllegalStateException("Wrong thread");
private boolean checkThread() {
if (Thread.currentThread() != Looper.getMainLooper().getThread()) {
if (BuildVars.DEBUG_VERSION) {
FileLog.e("EmojiDocumentFetcher", new IllegalStateException("Wrong thread"));
}
return false;
}
return true;
}
private void loadFromDatabase(ArrayList<Long> emojiToLoad) {
@ -284,14 +301,13 @@ public class AnimatedEmojiDrawable extends Drawable {
}
public void processDocuments(ArrayList<?> documents) {
checkThread();
if (!checkThread()) {
return;
}
for (int i = 0; i < documents.size(); ++i) {
if (documents.get(i) instanceof TLRPC.Document) {
TLRPC.Document document = (TLRPC.Document) documents.get(i);
if (emojiDocumentsCache == null) {
emojiDocumentsCache = new HashMap<>();
}
emojiDocumentsCache.put(document.id, document);
putDocument(document);
if (loadingDocuments != null) {
ArrayList<ReceivedDocument> loadingCallbacks = loadingDocuments.remove(document.id);
if (loadingCallbacks != null) {
@ -305,15 +321,29 @@ public class AnimatedEmojiDrawable extends Drawable {
}
}
public TLRPC.InputStickerSet findStickerSet(long documentId) {
if (emojiDocumentsCache == null) {
return null;
}
TLRPC.Document document = emojiDocumentsCache.get(documentId);
public void putDocument(TLRPC.Document document) {
if (document == null) {
return null;
return;
}
synchronized (this) {
if (emojiDocumentsCache == null) {
emojiDocumentsCache = new HashMap<>();
}
emojiDocumentsCache.put(document.id, document);
}
}
public TLRPC.InputStickerSet findStickerSet(long documentId) {
synchronized (this) {
if (emojiDocumentsCache == null) {
return null;
}
TLRPC.Document document = emojiDocumentsCache.get(documentId);
if (document == null) {
return null;
}
return MessageObject.getInputStickerSet(document);
}
return MessageObject.getInputStickerSet(document);
}
}
@ -340,6 +370,7 @@ public class AnimatedEmojiDrawable extends Drawable {
private long documentId;
private int cacheType;
private int currentAccount;
private String absolutePath;
private ImageReceiver imageReceiver;
private float alpha = 1f;
@ -351,7 +382,19 @@ public class AnimatedEmojiDrawable extends Drawable {
this.documentId = documentId;
getDocumentFetcher(currentAccount).fetchDocument(documentId, document -> {
this.document = document;
this.initDocument();
this.initDocument(false);
});
}
public AnimatedEmojiDrawable(int cacheType, int currentAccount, long documentId, String absolutePath) {
this.currentAccount = currentAccount;
this.cacheType = cacheType;
updateSize();
this.documentId = documentId;
this.absolutePath = absolutePath;
getDocumentFetcher(currentAccount).fetchDocument(documentId, document -> {
this.document = document;
this.initDocument(false);
});
}
@ -360,7 +403,7 @@ public class AnimatedEmojiDrawable extends Drawable {
this.currentAccount = currentAccount;
this.document = document;
updateSize();
this.initDocument();
this.initDocument(false);
}
private void updateSize() {
@ -382,34 +425,46 @@ public class AnimatedEmojiDrawable extends Drawable {
return this.document;
}
private void initDocument() {
if (document == null || imageReceiver != null) {
private void initDocument(boolean force) {
if (document == null || (imageReceiver != null && !force)) {
return;
}
imageReceiver = new ImageReceiver() {
@Override
public void invalidate() {
AnimatedEmojiDrawable.this.invalidate();
super.invalidate();
}
if (imageReceiver == null) {
imageReceiver = new ImageReceiver() {
@Override
public void invalidate() {
AnimatedEmojiDrawable.this.invalidate();
super.invalidate();
}
@Override
protected boolean setImageBitmapByKey(Drawable drawable, String key, int type, boolean memCache, int guid) {
AnimatedEmojiDrawable.this.invalidate();
return super.setImageBitmapByKey(drawable, key, type, memCache, guid);
}
@Override
protected boolean setImageBitmapByKey(Drawable drawable, String key, int type, boolean memCache, int guid) {
AnimatedEmojiDrawable.this.invalidate();
return super.setImageBitmapByKey(drawable, key, type, memCache, guid);
}
};
};
if (cacheType == CACHE_TYPE_RENDERING_VIDEO) {
imageReceiver.ignoreNotifications = true;
}
if (colorFilterToSet != null && canOverrideColor()) {
imageReceiver.setColorFilter(colorFilterToSet);
}
if (cacheType != 0) {
int cacheType = this.cacheType;
if (cacheType == CACHE_TYPE_RENDERING_VIDEO) {
cacheType = CACHE_TYPE_KEYBOARD;
}
imageReceiver.setUniqKeyPrefix(cacheType + "_");
}
imageReceiver.setVideoThumbIsSame(true);
boolean onlyStaticPreview = SharedConfig.getDevicePerformanceClass() == SharedConfig.PERFORMANCE_CLASS_LOW && (cacheType == CACHE_TYPE_KEYBOARD || cacheType == CACHE_TYPE_ALERT_PREVIEW || cacheType == CACHE_TYPE_ALERT_PREVIEW_TAB_STRIP);
String filter = sizedp + "_" + sizedp;
if (cacheType != STANDARD_LOTTIE_FRAME && (cacheType != CACHE_TYPE_MESSAGES_LARGE || SharedConfig.getDevicePerformanceClass() < SharedConfig.PERFORMANCE_CLASS_HIGH)) {
if (cacheType == CACHE_TYPE_RENDERING_VIDEO) {
filter += "_d_nostream";
}
if (cacheType != STANDARD_LOTTIE_FRAME && (cacheType != CACHE_TYPE_MESSAGES_LARGE || SharedConfig.getDevicePerformanceClass() < SharedConfig.PERFORMANCE_CLASS_HIGH) && cacheType != CACHE_TYPE_RENDERING_VIDEO) {
filter += "_pcache";
}
if (cacheType != CACHE_TYPE_MESSAGES && cacheType != CACHE_TYPE_MESSAGES_LARGE) {
@ -451,12 +506,24 @@ public class AnimatedEmojiDrawable extends Drawable {
if (onlyStaticPreview) {
mediaLocation = null;
}
if (cacheType == STANDARD_LOTTIE_FRAME) {
if (absolutePath != null) {
imageReceiver.setImageBitmap(new AnimatedFileDrawable(new File(absolutePath), true, 0, null, null, null, 0, currentAccount, true, 512, 512, null));
} else if (cacheType == STANDARD_LOTTIE_FRAME) {
imageReceiver.setImage(null, null, mediaLocation, mediaFilter, null, null, thumbDrawable, document.size, null, document, 1);
} else {
imageReceiver.setImage(mediaLocation, mediaFilter, ImageLocation.getForDocument(thumb, document), sizedp + "_" + sizedp, null, null, thumbDrawable, document.size, null, document, 1);
if (SharedConfig.getLiteMode().enabled()) {
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 {
imageReceiver.setImage(mediaLocation, mediaFilter + "_firstframe", ImageLocation.getForDocument(thumb, document), sizedp + "_" + sizedp, null, null, thumbDrawable, document.size, null, document, 1);
}
} else {
imageReceiver.setImage(mediaLocation, mediaFilter, ImageLocation.getForDocument(thumb, document), sizedp + "_" + sizedp, null, null, thumbDrawable, document.size, null, document, 1);
}
}
if (cacheType == CACHE_TYPE_EMOJI_STATUS || cacheType == CACHE_TYPE_ALERT_EMOJI_STATUS || cacheType == CACHE_TYPE_FORUM_TOPIC) {
imageReceiver.setAutoRepeatCount(2);
} else if (cacheType == CACHE_TYPE_FORUM_TOPIC_LARGE) {
@ -470,14 +537,14 @@ public class AnimatedEmojiDrawable extends Drawable {
imageReceiver.setLayerNum(6656);
}
imageReceiver.setAspectFit(true);
if (cacheType != STANDARD_LOTTIE_FRAME) {
imageReceiver.setAllowStartLottieAnimation(true);
imageReceiver.setAllowStartAnimation(true);
imageReceiver.setAutoRepeat(1);
} else {
if (cacheType == CACHE_TYPE_RENDERING_VIDEO || cacheType == STANDARD_LOTTIE_FRAME) {
imageReceiver.setAllowStartAnimation(false);
imageReceiver.setAllowStartLottieAnimation(false);
imageReceiver.setAutoRepeat(0);
} else {
imageReceiver.setAllowStartLottieAnimation(true);
imageReceiver.setAllowStartAnimation(true);
imageReceiver.setAutoRepeat(1);
}
imageReceiver.setAllowDecodeSingleFrame(true);
int roundRadius = 0;
@ -522,66 +589,51 @@ public class AnimatedEmojiDrawable extends Drawable {
@Override
public void draw(@NonNull Canvas canvas) {
draw(canvas, true);
if (imageReceiver == null) {
return;
}
imageReceiver.setImageCoords(getBounds());
imageReceiver.setAlpha(alpha);
imageReceiver.draw(canvas);
}
public void draw(@NonNull Canvas canvas, boolean canTranslate) {
if (imageReceiver != null) {
public void drawRaw(Canvas canvas, boolean nextFrame, int fps) {
if (imageReceiver == null) {
return;
}
if (imageReceiver.getLottieAnimation() != null) {
RLottieDrawable rlottie = imageReceiver.getLottieAnimation();
if (nextFrame) {
int inc = (int) Math.round((float) rlottie.getFramesCount() / (rlottie.getDuration() / 1000f) / 30f);
rlottie.currentFrame = (rlottie.currentFrame + inc) % rlottie.getFramesCount();
}
rlottie.setBounds(getBounds());
rlottie.drawFrame(canvas, rlottie.currentFrame);
} else if (imageReceiver.getAnimation() != null) {
AnimatedFileDrawable webp = imageReceiver.getAnimation();
webp.drawFrame(canvas, nextFrame ? fps / 30 : 0);
} else {
imageReceiver.setImageCoords(getBounds());
imageReceiver.setAlpha(alpha);
imageReceiver.draw(canvas);
} else {
shouldDrawPlaceholder = true;
}
drawPlaceholder(canvas, getBounds().centerX(), getBounds().centerY(), getBounds().width() / 2f);
}
public void draw(Canvas canvas, Rect drawableBounds, float alpha) {
if (imageReceiver != null) {
imageReceiver.setImageCoords(drawableBounds);
imageReceiver.setAlpha(alpha);
imageReceiver.draw(canvas);
} else {
shouldDrawPlaceholder = true;
}
if (drawableBounds != null) {
drawPlaceholder(canvas, drawableBounds.centerX(), drawableBounds.centerY(), drawableBounds.width() / 2f);
if (imageReceiver == null) {
return;
}
imageReceiver.setImageCoords(drawableBounds);
imageReceiver.setAlpha(alpha);
imageReceiver.draw(canvas);
}
public void draw(Canvas canvas, ImageReceiver.BackgroundThreadDrawHolder backgroundThreadDrawHolder, boolean canTranslate) {
if (imageReceiver != null) {
imageReceiver.setAlpha(alpha);
imageReceiver.draw(canvas, backgroundThreadDrawHolder);
} else {
shouldDrawPlaceholder = true;
if (imageReceiver == null) {
return;
}
if (backgroundThreadDrawHolder != null) {
drawPlaceholder(canvas, backgroundThreadDrawHolder.imageX + backgroundThreadDrawHolder.imageW / 2, backgroundThreadDrawHolder.imageY + backgroundThreadDrawHolder.imageH / 2, backgroundThreadDrawHolder.imageW / 2);
}
}
private AnimatedFloat placeholderAlpha = new AnimatedFloat(1f, this::invalidate, 0, 150, new LinearInterpolator());
private boolean shouldDrawPlaceholder = false;
private void drawPlaceholder(Canvas canvas, float cx, float cy, float r) {
// if (!shouldDrawPlaceholder) {
// return;
// }
// float alpha = placeholderAlpha.set(imageReceiver == null ? 1f : 0f);
// if (alpha < 0) {
// if (imageReceiver != null) {
// shouldDrawPlaceholder = false;
// }
// return;
// }
// if (placeholderPaint == null) {
// placeholderPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
// placeholderPaint.setColor(Theme.isCurrentThemeDark() ? 0x0fffffff : 0x0f000000);
// }
// int wasAlpha = placeholderPaint.getAlpha();
// placeholderPaint.setAlpha((int) (wasAlpha * alpha));
// canvas.drawCircle(cx, cy, r, placeholderPaint);
// placeholderPaint.setAlpha(wasAlpha);
imageReceiver.setAlpha(alpha);
imageReceiver.draw(canvas, backgroundThreadDrawHolder);
}
public void addView(View callback) {
@ -1095,4 +1147,18 @@ public class AnimatedEmojiDrawable extends Drawable {
}
}
}
public static void lightModeChanged() {
for (HashMap<Long, AnimatedEmojiDrawable> map :globalEmojiCache.values()) {
ArrayList<Long> set = new ArrayList(map.keySet());
for (Long documentId : set) {
AnimatedEmojiDrawable animatedEmojiDrawable = map.get(documentId);
if (animatedEmojiDrawable.attached) {
animatedEmojiDrawable.initDocument(true);
} else {
map.remove(documentId);
}
}
}
}
}

View file

@ -21,6 +21,7 @@ import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.Emoji;
import org.telegram.messenger.ImageReceiver;
import org.telegram.messenger.MessageObject;
import org.telegram.messenger.SharedConfig;
import org.telegram.messenger.UserConfig;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.Theme;
@ -42,6 +43,7 @@ public class AnimatedEmojiSpan extends ReplacementSpan {
private Paint.FontMetricsInt fontMetrics;
private float size = AndroidUtilities.dp(20);
public int cacheType = -1;
public String documentAbsolutePath;
int measuredSize;
boolean spanDrawn;
@ -87,6 +89,16 @@ public class AnimatedEmojiSpan extends ReplacementSpan {
return document != null ? document.id : documentId;
}
public void replaceFontMetrics(Paint.FontMetricsInt newMetrics) {
this.fontMetrics = newMetrics;
if (fontMetrics != null) {
size = Math.abs(fontMetrics.descent) + Math.abs(fontMetrics.ascent);
if (size == 0) {
size = AndroidUtilities.dp(20);
}
}
}
public void replaceFontMetrics(Paint.FontMetricsInt newMetrics, int newSize, int cacheType) {
fontMetrics = newMetrics;
size = newSize;
@ -203,6 +215,40 @@ public class AnimatedEmojiSpan extends ReplacementSpan {
}
}
public static void drawRawAnimatedEmojis(Canvas canvas, Layout layout, EmojiGroupedSpans stack, float offset, List<SpoilerEffect> spoilers, float boundTop, float boundBottom, float drawingYOffset, float alpha, int fps) {
if (canvas == null || layout == null || stack == null) {
return;
}
boolean needRestore = false;
if (Emoji.emojiDrawingYOffset != 0 || offset != 0) {
needRestore = true;
canvas.save();
canvas.translate(0, Emoji.emojiDrawingYOffset + AndroidUtilities.dp(20 * offset));
}
stack.rawIndex++;
for (int k = 0; k < stack.holders.size(); ++k) {
AnimatedEmojiHolder holder = stack.holders.get(k);
float halfSide = holder.span.measuredSize / 2f;
float cx, cy;
cx = holder.span.lastDrawnCx;
cy = holder.span.lastDrawnCy;
holder.drawableBounds.set((int) (cx - halfSide), (int) (cy - halfSide), (int) (cx + halfSide), (int) (cy + halfSide));
holder.drawable.setBounds(holder.drawableBounds);
boolean nextFrame = false;
if (holder.drawable.rawDrawIndex < stack.rawIndex) {
holder.drawable.rawDrawIndex = stack.rawIndex;
nextFrame = true;
}
holder.drawable.drawRaw(canvas, nextFrame, fps);
}
if (needRestore) {
canvas.restore();
}
}
private static boolean isInsideSpoiler(Layout layout, int start, int end) {
if (layout == null || !(layout.getText() instanceof Spanned)) {
return false;
@ -233,6 +279,7 @@ public class AnimatedEmojiSpan extends ReplacementSpan {
public float alpha;
public SpansChunk spansChunk;
public boolean insideSpoiler;
private int rawIndex;
private ImageReceiver.BackgroundThreadDrawHolder[] backgroundDrawHolder = new ImageReceiver.BackgroundThreadDrawHolder[DrawingInBackgroundThreadDrawable.THREAD_COUNT];
@ -370,7 +417,9 @@ public class AnimatedEmojiSpan extends ReplacementSpan {
holder = new AnimatedEmojiHolder(view, invalidateParent);
holder.layout = textLayout;
int localCacheType = span.standard ? AnimatedEmojiDrawable.STANDARD_LOTTIE_FRAME : (span.cacheType < 0 ? cacheType : span.cacheType);
if (span.document != null) {
if (span.documentAbsolutePath != null) {
holder.drawable = AnimatedEmojiDrawable.make(UserConfig.selectedAccount, localCacheType, span.getDocumentId(), span.documentAbsolutePath);
} else if (span.document != null) {
holder.drawable = AnimatedEmojiDrawable.make(UserConfig.selectedAccount, localCacheType, span.document);
} else {
holder.drawable = AnimatedEmojiDrawable.make(UserConfig.selectedAccount, localCacheType, span.documentId);
@ -561,6 +610,7 @@ public class AnimatedEmojiSpan extends ReplacementSpan {
public ArrayList<AnimatedEmojiHolder> holders = new ArrayList<>();
HashMap<Layout, SpansChunk> groupedByLayout = new HashMap<>();
ArrayList<SpansChunk> backgroundDrawingArray = new ArrayList<>();
private int rawIndex;
public boolean isEmpty() {
return holders.isEmpty();
@ -625,6 +675,14 @@ public class AnimatedEmojiSpan extends ReplacementSpan {
}
}
public void incrementFrames(int inc) {
for (int i = 0; i < holders.size(); i++) {
if (holders.get(i).drawable != null && holders.get(i).drawable.getImageReceiver() != null) {
holders.get(i).drawable.getImageReceiver().incrementFrames(inc);
}
}
}
public void recordPositions(boolean record) {
for (int i = 0; i < holders.size(); i++) {
holders.get(i).span.recordPositions = record;
@ -672,13 +730,13 @@ public class AnimatedEmojiSpan extends ReplacementSpan {
}
private void checkBackgroundRendering() {
if (allowBackgroundRendering && holders.size() >= 10 && backgroundThreadDrawable == null) {
if (allowBackgroundRendering && holders.size() >= 10 && backgroundThreadDrawable == null && !SharedConfig.getLiteMode().enabled()) {
backgroundThreadDrawable = new DrawingInBackgroundThreadDrawable() {
private final ArrayList<AnimatedEmojiHolder> backgroundHolders = new ArrayList<>();
@Override
public void drawInBackground(Canvas canvas) {
public void drawInBackground(Canvas canvas) {
for (int i = 0; i < backgroundHolders.size(); i++) {
AnimatedEmojiHolder holder = backgroundHolders.get(i);
if (holder != null && holder.backgroundDrawHolder[threadIndex] != null) {

View file

@ -481,9 +481,7 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable,
if (!precise) {
seekToMs(nativePtr, ms, precise);
}
if (backgroundBitmap == null) {
backgroundBitmap = Bitmap.createBitmap((int) (metaData[0] * scaleFactor), (int) (metaData[1] * scaleFactor), Bitmap.Config.ARGB_8888);
}
Bitmap backgroundBitmap = Bitmap.createBitmap((int) (metaData[0] * scaleFactor), (int) (metaData[1] * scaleFactor), Bitmap.Config.ARGB_8888);
int result;
if (precise) {
result = getFrameAtTime(nativePtr, ms, backgroundBitmap, metaData, backgroundBitmap.getRowBytes());
@ -616,13 +614,12 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable,
ArrayList<Bitmap> bitmapToRecycle = new ArrayList<>();
bitmapToRecycle.add(renderingBitmap);
bitmapToRecycle.add(nextRenderingBitmap);
bitmapToRecycle.add(backgroundBitmap);
renderingBitmap = null;
nextRenderingBitmap = null;
backgroundBitmap = null;
if (renderingBitmap != null) {
renderingBitmap = null;
}
if (nextRenderingBitmap != null) {
nextRenderingBitmap = null;
}
if (decodeQueue != null) {
decodeQueue.recycle();
decodeQueue = null;
@ -1096,6 +1093,21 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable,
return bitmap;
}
public void drawFrame(Canvas canvas, int incFrame) {
if (nativePtr == 0) {
return;
}
for (int i = 0; i < incFrame; ++i) {
getNextFrame();
}
Bitmap bitmap = getBackgroundBitmap();
if (bitmap == null) {
bitmap = getNextFrame();
}
AndroidUtilities.rectTmp2.set(0, 0, bitmap.getWidth(), bitmap.getHeight());
canvas.drawBitmap(getBackgroundBitmap(), AndroidUtilities.rectTmp2, getBounds(), getPaint());
}
public boolean canLoadFrames() {
if (precache) {
return bitmapsCache != null;

View file

@ -3,7 +3,6 @@ package org.telegram.ui.Components;
import android.animation.TimeInterpolator;
import android.os.SystemClock;
import android.util.Log;
import android.view.View;
import androidx.core.math.MathUtils;
@ -120,7 +119,6 @@ public class AnimatedFloat {
}
public float set(float mustBe, boolean force) {
final long now = SystemClock.elapsedRealtime();
if (force || transitionDuration <= 0 || firstSet) {
value = targetValue = mustBe;
transition = false;
@ -129,9 +127,10 @@ public class AnimatedFloat {
transition = true;
targetValue = mustBe;
startValue = value;
transitionStart = now;
transitionStart = SystemClock.elapsedRealtime();
}
if (transition) {
final long now = SystemClock.elapsedRealtime();
final float t = MathUtils.clamp((now - transitionStart - transitionDelay) / (float) transitionDuration, 0, 1);
if (now - transitionStart >= transitionDelay) {
if (transitionInterpolator == null) {
@ -154,6 +153,10 @@ public class AnimatedFloat {
return value;
}
public boolean isInProgress() {
return transition;
}
public float getTransitionProgress() {
if (!transition) {
return 0;

View file

@ -71,6 +71,7 @@ public class AnimatedTextView extends View {
private Runnable onAnimationFinishListener;
private boolean allowCancel;
public boolean ignoreRTL;
public AnimatedTextDrawable() {
this(false, false, false);
@ -113,7 +114,7 @@ public class AnimatedTextView extends View {
}
canvas.save();
int lwidth = j >= 0 ? width : currentWidth;
if (isRTL) {
if (isRTL && !ignoreRTL) {
x = -x + 2 * lwidth - currentLayout[i].getWidth() - fullWidth;
}
if ((gravity | ~Gravity.LEFT) != ~0) {
@ -121,11 +122,11 @@ public class AnimatedTextView extends View {
x += fullWidth - lwidth;
} else if ((gravity | ~Gravity.CENTER_HORIZONTAL) == ~0) {
x += (fullWidth - lwidth) / 2f;
} else if (isRTL) {
} else if (isRTL && !ignoreRTL) {
x += fullWidth - lwidth;
}
}
canvas.translate(Math.round(x), Math.round(y));
canvas.translate(x, y);
currentLayout[i].draw(canvas);
canvas.restore();
}
@ -138,7 +139,7 @@ public class AnimatedTextView extends View {
float y = textPaint.getTextSize() * moveAmplitude * t * (moveDown ? 1f : -1f);
textPaint.setAlpha((int) (alpha * (1f - t)));
canvas.save();
if (isRTL) {
if (isRTL && !ignoreRTL) {
x = -x + 2 * oldWidth - oldLayout[i].getWidth() - fullWidth;
}
if ((gravity | ~Gravity.LEFT) != ~0) {
@ -146,11 +147,11 @@ public class AnimatedTextView extends View {
x += fullWidth - oldWidth;
} else if ((gravity | ~Gravity.CENTER_HORIZONTAL) == ~0) {
x += (fullWidth - oldWidth) / 2f;
} else if (isRTL) {
} else if (isRTL && !ignoreRTL) {
x += fullWidth - oldWidth;
}
}
canvas.translate(Math.round(x), Math.round(y));
canvas.translate(x, y);
oldLayout[i].draw(canvas);
canvas.restore();
}
@ -161,7 +162,7 @@ public class AnimatedTextView extends View {
textPaint.setAlpha(alpha);
canvas.save();
float x = currentLayoutOffsets[i];
if (isRTL) {
if (isRTL && !ignoreRTL) {
x = -x + 2 * currentWidth - currentLayout[i].getWidth() - fullWidth;
}
if ((gravity | ~Gravity.LEFT) != ~0) {
@ -169,11 +170,11 @@ public class AnimatedTextView extends View {
x += fullWidth - currentWidth;
} else if ((gravity | ~Gravity.CENTER_HORIZONTAL) == ~0) {
x += (fullWidth - currentWidth) / 2f;
} else if (isRTL) {
} else if (isRTL && !ignoreRTL) {
x += fullWidth - currentWidth;
}
}
canvas.translate(Math.round(x), 0);
canvas.translate(x, 0);
currentLayout[i].draw(canvas);
canvas.restore();
}
@ -391,6 +392,10 @@ public class AnimatedTextView extends View {
return currentWidth;
}
public int getHeight() {
return currentHeight;
}
private StaticLayout makeLayout(CharSequence textPart, int width) {
if (width <= 0) {
width = Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y);
@ -706,6 +711,12 @@ public class AnimatedTextView extends View {
super.setBounds(left, top, right, bottom);
this.bounds.set(left, top, right, bottom);
}
@NonNull
@Override
public Rect getDirtyBounds() {
return this.bounds;
}
}
private AnimatedTextDrawable drawable;
@ -736,7 +747,7 @@ public class AnimatedTextView extends View {
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
if (lastMaxWidth != width) {
if (lastMaxWidth != width && getLayoutParams().width != 0) {
drawable.setBounds(getPaddingLeft(), getPaddingTop(), width - getPaddingRight(), height - getPaddingBottom());
setText(drawable.getText(), false);
}
@ -769,6 +780,10 @@ public class AnimatedTextView extends View {
return drawable.isAnimating();
}
private void setIgnoreRTL(boolean value) {
drawable.ignoreRTL = value;
}
private boolean first = true;
public void setText(CharSequence text, boolean animated, boolean moveDown) {
animated = !first && animated;

View file

@ -620,6 +620,7 @@ public class AudioPlayerAlert extends BottomSheet implements NotificationCenter.
return super.onTouch(ev);
}
};
seekBarView.setLineWidth(4);
seekBarView.setDelegate(new SeekBarView.SeekBarViewDelegate() {
@Override
public void onSeekBarDrag(boolean stop, float progress) {
@ -645,7 +646,7 @@ public class AudioPlayerAlert extends BottomSheet implements NotificationCenter.
}
});
seekBarView.setReportChanges(true);
playerLayout.addView(seekBarView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 38, Gravity.TOP | Gravity.LEFT, 5, 70, 5, 0));
playerLayout.addView(seekBarView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 38 + 6, Gravity.TOP | Gravity.LEFT, 5, 67, 5, 0));
seekBarBufferSpring = new SpringAnimation(new FloatValueHolder(0))
.setSpring(new SpringForce()
@ -1880,6 +1881,7 @@ public class AudioPlayerAlert extends BottomSheet implements NotificationCenter.
lastTime = newTime;
timeTextView.setText(AndroidUtilities.formatShortDuration(newTime));
}
seekBarView.updateTimestamps(messageObject, null);
}
}

View file

@ -5,8 +5,8 @@ import android.graphics.Paint;
import android.view.View;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.SharedConfig;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Cells.ChatMessageCell;
import java.util.Random;
@ -52,6 +52,9 @@ public class AudioVisualizerDrawable {
public void setWaveform(boolean playing, boolean animate, float[] waveform) {
if (SharedConfig.getLiteMode().enabled()) {
return;
}
if (!playing && !animate) {
for (int i = 0; i < 8; i++) {
animateTo[i] = current[i] = 0;
@ -111,6 +114,9 @@ public class AudioVisualizerDrawable {
float rotation;
public void draw(Canvas canvas, float cx, float cy, boolean outOwner, float alpha, Theme.ResourcesProvider resourcesProvider) {
if (SharedConfig.getLiteMode().enabled()) {
return;
}
if (outOwner) {
p1.setColor(Theme.getColor(Theme.key_chat_outLoader, resourcesProvider));
p1.setAlpha((int) (ALPHA * alpha));
@ -122,6 +128,9 @@ public class AudioVisualizerDrawable {
}
public void draw(Canvas canvas, float cx, float cy, boolean outOwner, Theme.ResourcesProvider resourcesProvider) {
if (SharedConfig.getLiteMode().enabled()) {
return;
}
if (outOwner) {
p1.setColor(Theme.getColor(Theme.key_chat_outLoader, resourcesProvider));
p1.setAlpha(ALPHA);
@ -133,6 +142,9 @@ public class AudioVisualizerDrawable {
}
public void draw(Canvas canvas, float cx, float cy) {
if (SharedConfig.getLiteMode().enabled()) {
return;
}
for (int i = 0; i < 8; i++) {
if (animateTo[i] != current[i]) {
current[i] += dt[i] * 16;

View file

@ -34,6 +34,7 @@ public class AvatarsDrawable {
public final static int STYLE_GROUP_CALL_TOOLTIP = 10;
public final static int STYLE_MESSAGE_SEEN = 11;
private boolean showSavedMessages;
DrawingState[] currentStates = new DrawingState[3];
DrawingState[] animatingStates = new DrawingState[3];
@ -316,15 +317,28 @@ public class AvatarsDrawable {
animatingStates[index].id = id;
} else if (object instanceof TLRPC.User) {
currentUser = (TLRPC.User) object;
animatingStates[index].avatarDrawable.setInfo(currentUser);
if (currentUser.self && showSavedMessages) {
animatingStates[index].avatarDrawable.setAvatarType(AvatarDrawable.AVATAR_TYPE_SAVED);
animatingStates[index].avatarDrawable.setScaleSize(0.6f);
} else {
animatingStates[index].avatarDrawable.setAvatarType(AvatarDrawable.AVATAR_TYPE_NORMAL);
animatingStates[index].avatarDrawable.setScaleSize(1f);
animatingStates[index].avatarDrawable.setInfo(currentUser);
}
animatingStates[index].id = currentUser.id;
} else {
currentChat = (TLRPC.Chat) object;
animatingStates[index].avatarDrawable.setAvatarType(AvatarDrawable.AVATAR_TYPE_NORMAL);
animatingStates[index].avatarDrawable.setScaleSize(1f);
animatingStates[index].avatarDrawable.setInfo(currentChat);
animatingStates[index].id = -currentChat.id;
}
if (currentUser != null) {
animatingStates[index].imageReceiver.setForUserOrChat(currentUser, animatingStates[index].avatarDrawable);
if (currentUser.self && showSavedMessages) {
animatingStates[index].imageReceiver.setImageBitmap(animatingStates[index].avatarDrawable);
} else {
animatingStates[index].imageReceiver.setForUserOrChat(currentUser, animatingStates[index].avatarDrawable);
}
} else {
animatingStates[index].imageReceiver.setForUserOrChat(currentChat, animatingStates[index].avatarDrawable);
}
@ -569,4 +583,8 @@ public class AvatarsDrawable {
setObject(0, 0, null);
}
}
public void setShowSavedMessages(boolean showSavedMessages) {
this.showSavedMessages = showSavedMessages;
}
}

View file

@ -22,20 +22,75 @@ import android.view.View;
import org.telegram.messenger.ImageLocation;
import org.telegram.messenger.ImageReceiver;
import org.telegram.messenger.SecureDocument;
import org.telegram.messenger.Utilities;
import org.telegram.tgnet.TLObject;
public class BackupImageView extends View {
protected ImageReceiver imageReceiver;
protected ImageReceiver blurImageReceiver;
protected int width = -1;
protected int height = -1;
public AnimatedEmojiDrawable animatedEmojiDrawable;
private AvatarDrawable avatarDrawable;
boolean attached;
protected boolean hasBlur;
protected boolean blurAllowed;
public BackupImageView(Context context) {
super(context);
imageReceiver = new ImageReceiver(this);
imageReceiver.setDelegate((imageReceiver1, set, thumb, memCache) -> {
if (set && !thumb) {
checkCreateBlurredImage();
}
});
}
public void setBlurAllowed(boolean blurAllowed) {
if (attached) {
throw new IllegalStateException("You should call setBlurAllowed(...) only when detached!");
}
this.blurAllowed = blurAllowed;
if (blurAllowed) {
blurImageReceiver = new ImageReceiver();
}
}
public void setHasBlur(boolean hasBlur) {
if (hasBlur && !blurAllowed) {
throw new IllegalStateException("You should call setBlurAllowed(...) before calling setHasBlur(true)!");
}
this.hasBlur = hasBlur;
if (!hasBlur) {
if (blurImageReceiver.getBitmap() != null && !blurImageReceiver.getBitmap().isRecycled()) {
blurImageReceiver.getBitmap().recycle();
}
blurImageReceiver.setImageBitmap((Bitmap) null);
}
checkCreateBlurredImage();
}
private void onNewImageSet() {
if (hasBlur) {
if (blurImageReceiver.getBitmap() != null && !blurImageReceiver.getBitmap().isRecycled()) {
blurImageReceiver.getBitmap().recycle();
}
blurImageReceiver.setImageBitmap((Bitmap) null);
checkCreateBlurredImage();
}
}
private void checkCreateBlurredImage() {
if (hasBlur && blurImageReceiver.getBitmap() == null && imageReceiver.getBitmap() != null) {
Bitmap bitmap = imageReceiver.getBitmap();
if (bitmap != null && !bitmap.isRecycled()) {
blurImageReceiver.setImageBitmap(Utilities.stackBlurBitmapMax(bitmap));
invalidate();
}
}
}
public void setOrientation(int angle, boolean center) {
@ -56,6 +111,7 @@ public class BackupImageView extends View {
public void setImage(ImageLocation mediaLocation, String mediaFilter, ImageLocation imageLocation, String imageFilter, Drawable thumb, Object parentObject) {
imageReceiver.setImage(mediaLocation, mediaFilter, imageLocation, imageFilter, null, null, thumb, 0, null, parentObject, 1);
onNewImageSet();
}
public void setImage(ImageLocation imageLocation, String imageFilter, Bitmap thumb, Object parentObject) {
@ -72,14 +128,17 @@ public class BackupImageView extends View {
thumb = new BitmapDrawable(null, thumbBitmap);
}
imageReceiver.setImage(imageLocation, imageFilter, null, null, thumb, size, null, parentObject, cacheType);
onNewImageSet();
}
public void setForUserOrChat(TLObject object, AvatarDrawable avatarDrawable) {
imageReceiver.setForUserOrChat(object, avatarDrawable);
onNewImageSet();
}
public void setForUserOrChat(TLObject object, AvatarDrawable avatarDrawable, Object parent) {
imageReceiver.setForUserOrChat(object, avatarDrawable, parent);
onNewImageSet();
}
public void setImageMedia(ImageLocation mediaLocation, String mediaFilter, ImageLocation imageLocation, String imageFilter, Bitmap thumbBitmap, int size, int cacheType, Object parentObject) {
@ -88,6 +147,7 @@ public class BackupImageView extends View {
thumb = new BitmapDrawable(null, thumbBitmap);
}
imageReceiver.setImage(mediaLocation, mediaFilter, imageLocation, imageFilter, null, null, thumb, size, null, parentObject, cacheType);
onNewImageSet();
}
public void setImage(ImageLocation imageLocation, String imageFilter, ImageLocation thumbLocation, String thumbFilter, int size, Object parentObject) {
@ -107,24 +167,29 @@ public class BackupImageView extends View {
thumb = new BitmapDrawable(null, thumbBitmap);
}
imageReceiver.setImage(imageLocation, imageFilter, thumbLocation, thumbFilter, thumb, size, ext, parentObject, 0);
onNewImageSet();
}
public void setImage(ImageLocation imageLocation, String imageFilter, ImageLocation thumbLocation, String thumbFilter, String ext, long size, int cacheType, Object parentObject) {
imageReceiver.setImage(imageLocation, imageFilter, thumbLocation, thumbFilter, null, size, ext, parentObject, cacheType);
onNewImageSet();
}
public void setImageMedia(ImageLocation mediaLocation, String mediaFilter, ImageLocation imageLocation, String imageFilter, ImageLocation thumbLocation, String thumbFilter, String ext, int size, int cacheType, Object parentObject) {
imageReceiver.setImage(mediaLocation, mediaFilter, imageLocation, imageFilter, thumbLocation, thumbFilter, null, size, ext, parentObject, cacheType);
onNewImageSet();
}
public void setImageBitmap(Bitmap bitmap) {
imageReceiver.setImageBitmap(bitmap);
onNewImageSet();
}
public void setImageResource(int resId) {
Drawable drawable = getResources().getDrawable(resId);
imageReceiver.setImageBitmap(drawable);
invalidate();
onNewImageSet();
}
public void setImageResource(int resId, int color) {
@ -134,10 +199,12 @@ public class BackupImageView extends View {
}
imageReceiver.setImageBitmap(drawable);
invalidate();
onNewImageSet();
}
public void setImageDrawable(Drawable drawable) {
imageReceiver.setImageBitmap(drawable);
onNewImageSet();
}
public void setLayerNum(int value) {
@ -146,11 +213,17 @@ public class BackupImageView extends View {
public void setRoundRadius(int value) {
imageReceiver.setRoundRadius(value);
if (blurAllowed) {
blurImageReceiver.setRoundRadius(value);
}
invalidate();
}
public void setRoundRadius(int tl, int tr, int bl, int br) {
imageReceiver.setRoundRadius(tl, tr, bl ,br);
if (blurAllowed) {
blurImageReceiver.setRoundRadius(tl, tr, bl, br);
}
invalidate();
}
@ -184,6 +257,9 @@ public class BackupImageView extends View {
super.onDetachedFromWindow();
attached = false;
imageReceiver.onDetachedFromWindow();
if (blurAllowed) {
blurImageReceiver.onDetachedFromWindow();
}
if (animatedEmojiDrawable != null) {
animatedEmojiDrawable.removeView(this);
}
@ -194,6 +270,9 @@ public class BackupImageView extends View {
super.onAttachedToWindow();
attached = true;
imageReceiver.onAttachedToWindow();
if (blurAllowed) {
blurImageReceiver.onAttachedToWindow();
}
if (animatedEmojiDrawable != null) {
animatedEmojiDrawable.addView(this);
}
@ -207,10 +286,19 @@ public class BackupImageView extends View {
}
if (width != -1 && height != -1) {
imageReceiver.setImageCoords((getWidth() - width) / 2, (getHeight() - height) / 2, width, height);
if (blurAllowed) {
blurImageReceiver.setImageCoords((getWidth() - width) / 2, (getHeight() - height) / 2, width, height);
}
} else {
imageReceiver.setImageCoords(0, 0, getWidth(), getHeight());
if (blurAllowed) {
blurImageReceiver.setImageCoords(0, 0, getWidth(), getHeight());
}
}
imageReceiver.draw(canvas);
if (blurAllowed) {
blurImageReceiver.draw(canvas);
}
}
public void setColorFilter(ColorFilter colorFilter) {

Some files were not shown because too many files have changed in this diff Show more