update to 9.2.0

This commit is contained in:
xaxtix 2022-12-06 23:13:44 +04:00
parent 0e17caa7a6
commit b73fc8de38
242 changed files with 14252 additions and 5037 deletions

View File

@ -30,16 +30,16 @@ dependencies {
implementation 'com.google.firebase:firebase-config:21.0.1'
implementation 'com.google.firebase:firebase-datatransport:18.1.0'
implementation 'com.google.firebase:firebase-appindexing:20.0.0'
implementation 'com.google.android.gms:play-services-maps:17.0.1'
implementation 'com.google.android.gms:play-services-auth:19.2.0'
implementation 'com.google.android.gms:play-services-maps:18.1.0'
implementation 'com.google.android.gms:play-services-auth:20.4.0'
implementation 'com.google.android.gms:play-services-vision:20.1.3'
implementation 'com.google.android.gms:play-services-wearable:17.1.0'
implementation 'com.google.android.gms:play-services-location:18.0.0'
implementation 'com.google.android.gms:play-services-wallet:18.1.3'
implementation 'com.google.android.gms:play-services-wearable:18.0.0'
implementation 'com.google.android.gms:play-services-location:21.0.1'
implementation 'com.google.android.gms:play-services-wallet:19.1.0'
implementation 'com.googlecode.mp4parser:isoparser:1.0.6'
implementation 'com.stripe:stripe-android:2.0.2'
implementation 'com.google.mlkit:language-id:16.1.1'
implementation 'com.android.billingclient:billing:5.0.0'
implementation 'com.android.billingclient:billing:5.1.0'
implementation 'com.google.code.gson:gson:2.10'
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'

View File

@ -219,9 +219,9 @@ int64_t listdir(const char *fileName, int32_t mode, int32_t docType, int64_t tim
value += listdir(buff, mode, docType, time, subdirs);
}
} else {
stat(buff, &attrib);
int rc = stat(buff, &attrib);
if (mode == 0) {
value += 512 * attrib.st_blocks;
value += rc == 0 ? attrib.st_size : 0;
} else if (mode == 1) {
if (attrib.st_atim.tv_sec != 0) {
if (attrib.st_atim.tv_sec < time) {

View File

@ -19,6 +19,7 @@
<uses-feature android:name="android.hardware.camera" android:required="false" />
<uses-feature android:name="android.hardware.camera2" android:required="false" />
<uses-permission android:name="android.permission.READ_CLIPBOARD"/>
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
@ -75,6 +76,10 @@
<queries>
<package android:name="com.google.android.apps.maps"/>
<intent>
<action android:name="android.intent.action.VIEW"/>
<data android:scheme="ton"/>
</intent>
</queries>
<application

View File

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

View File

@ -42,6 +42,7 @@
962;JO;Jordan;X XXXX XXXX
961;LB;Lebanon
960;MV;Maldives;XXX XXXX
888;FT;Anonymous Numbers;XXXX XXXX
886;TW;Taiwan;XXX XXX XXX
883;GO;International Networks
882;GO;International Networks

View File

@ -49,6 +49,9 @@
player.setSize(window.innerWidth, window.innerHeight);
});
function onError(event) {
if (window.YoutubeProxy !== undefined) {
YoutubeProxy.onPlayerError(event.data);
}
if (!posted) {
if (window.YoutubeProxy !== undefined) {
YoutubeProxy.onPlayerLoaded();

View File

@ -885,16 +885,12 @@ public class ChatListItemAnimator extends DefaultItemAnimator {
animators.put(holder, animatorSet);
}
boolean reset;
@Override
public void resetAnimation(RecyclerView.ViewHolder holder) {
if (BuildVars.LOGS_ENABLED) {
FileLog.d("reset animation");
}
reset = true;
super.resetAnimation(holder);
reset = false;
}
@Override

View File

@ -21,7 +21,6 @@ import android.animation.TimeInterpolator;
import android.animation.ValueAnimator;
import android.os.Build;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewPropertyAnimator;
import android.view.animation.Interpolator;
@ -229,7 +228,7 @@ public class DefaultItemAnimator extends SimpleItemAnimator {
mRemoveAnimations.add(holder);
if (getRemoveDelay() > 0) {
// wanted to achieve an effect of next items covering current
((ViewGroup) view.getParent()).bringChildToFront(view);
view.bringToFront();
}
animation
.setDuration(getRemoveDuration())
@ -337,6 +336,14 @@ public class DefaultItemAnimator extends SimpleItemAnimator {
}
protected void beforeAnimateMoveImpl(final RecyclerView.ViewHolder holder) {
}
protected void afterAnimateMoveImpl(final RecyclerView.ViewHolder holder) {
}
protected void animateMoveImpl(final RecyclerView.ViewHolder holder, MoveInfo moveInfo) {
int fromX = moveInfo.fromX;
int fromY = moveInfo.fromY;
@ -362,6 +369,7 @@ public class DefaultItemAnimator extends SimpleItemAnimator {
if (translationInterpolator != null) {
animation.setInterpolator(translationInterpolator);
}
beforeAnimateMoveImpl(holder);
animation
.setDuration(getMoveDuration())
.setStartDelay(getMoveDelay())
@ -388,6 +396,8 @@ public class DefaultItemAnimator extends SimpleItemAnimator {
dispatchMoveFinished(holder);
mMoveAnimations.remove(holder);
dispatchFinishedWhenDone();
afterAnimateMoveImpl(holder);
}
})
.start();

View File

@ -32,8 +32,6 @@ import android.view.ViewConfiguration;
import android.view.ViewParent;
import android.view.animation.Interpolator;
import org.telegram.messenger.AndroidUtilities;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.view.GestureDetectorCompat;
@ -41,6 +39,8 @@ import androidx.core.view.ViewCompat;
import androidx.recyclerview.widget.RecyclerView.OnItemTouchListener;
import androidx.recyclerview.widget.RecyclerView.ViewHolder;
import org.telegram.messenger.AndroidUtilities;
import java.util.ArrayList;
import java.util.List;
@ -506,6 +506,10 @@ public class ItemTouchHelper extends RecyclerView.ItemDecoration
stopGestureDetection();
}
public void clearRecoverAnimations() {
mRecoverAnimations.clear();
}
private void startGestureDetection() {
mItemTouchHelperGestureListener = new ItemTouchHelperGestureListener();
mGestureDetector = new GestureDetectorCompat(mRecyclerView.getContext(),
@ -561,6 +565,10 @@ public class ItemTouchHelper extends RecyclerView.ItemDecoration
mRecoverAnimations, mActionState, dx, dy);
}
protected boolean shouldSwipeBack() {
return false;
}
/**
* Starts dragging or swiping the given View. Call with null if you want to clear it.
*
@ -596,28 +604,33 @@ public class ItemTouchHelper extends RecyclerView.ItemDecoration
if (mSelected != null) {
final ViewHolder prevSelected = mSelected;
if (prevSelected.itemView.getParent() != null) {
final boolean swipeBack = shouldSwipeBack();
final int swipeDir = prevActionState == ACTION_STATE_DRAG ? 0
: swipeIfNecessary(prevSelected);
releaseVelocityTracker();
// find where we should animate to
final float targetTranslateX, targetTranslateY;
int animationType;
switch (swipeDir) {
case LEFT:
case RIGHT:
case START:
case END:
targetTranslateY = 0;
targetTranslateX = Math.signum(mDx) * mRecyclerView.getWidth();
break;
case UP:
case DOWN:
targetTranslateX = 0;
targetTranslateY = Math.signum(mDy) * mRecyclerView.getHeight();
break;
default:
targetTranslateX = 0;
targetTranslateY = 0;
if (swipeBack) {
targetTranslateX = targetTranslateY = 0;
} else {
switch (swipeDir) {
case LEFT:
case RIGHT:
case START:
case END:
targetTranslateY = 0;
targetTranslateX = Math.signum(mDx) * mRecyclerView.getWidth();
break;
case UP:
case DOWN:
targetTranslateX = 0;
targetTranslateY = Math.signum(mDy) * mRecyclerView.getHeight();
break;
default:
targetTranslateX = 0;
targetTranslateY = 0;
}
}
if (prevActionState == ACTION_STATE_DRAG) {
animationType = ANIMATION_TYPE_DRAG;

View File

@ -158,6 +158,7 @@ public class LinearLayoutManager extends RecyclerView.LayoutManager implements
private int[] mReusableIntPair = new int[2];
private boolean needFixGap = true;
private boolean needFixEndGap = true;
/**
* Creates a vertical LinearLayoutManager
@ -958,7 +959,7 @@ public class LinearLayoutManager extends RecyclerView.LayoutManager implements
*/
private int fixLayoutEndGap(int endOffset, RecyclerView.Recycler recycler,
RecyclerView.State state, boolean canOffsetChildren) {
if (!needFixGap) {
if (!needFixGap || !needFixEndGap) {
return 0;
}
int gap = mOrientationHelper.getEndAfterPadding() - endOffset;
@ -981,7 +982,7 @@ public class LinearLayoutManager extends RecyclerView.LayoutManager implements
return fixOffset;
}
public int getStarForFixGap() {
public int getStartForFixGap() {
return mOrientationHelper.getStartAfterPadding();
}
@ -993,7 +994,7 @@ public class LinearLayoutManager extends RecyclerView.LayoutManager implements
if (!needFixGap) {
return 0;
}
int gap = startOffset - getStarForFixGap();
int gap = startOffset - getStartForFixGap();
int fixOffset = 0;
if (gap > 0) {
// check if we should fix this gap.
@ -2601,4 +2602,8 @@ public class LinearLayoutManager extends RecyclerView.LayoutManager implements
public void setNeedFixGap(boolean needFixGap) {
this.needFixGap = needFixGap;
}
public void setNeedFixEndGap(boolean needFixEndGap) {
this.needFixEndGap = needFixEndGap;
}
}

View File

@ -32,6 +32,7 @@ import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.google.zxing.qrcode.encoder.Encoder;
import com.google.zxing.qrcode.encoder.QRCode;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.R;
import org.telegram.messenger.SvgHelper;
import org.telegram.ui.Components.RLottieDrawable;
@ -51,6 +52,7 @@ public final class QRCodeWriter {
private float[] radii = new float[8];
private int imageBloks;
private int imageBlockX;
public boolean includeSideQuads = true;
private int sideQuadSize;
private int imageSize;
@ -126,57 +128,11 @@ public final class QRCodeWriter {
imageBlockX = (inputWidth - imageBloks) / 2;
imageSize = imageBloks * multiple - 24;
int imageX = (size - imageSize) / 2;
boolean isTransparentBackground = Color.alpha(backgroundColor) == 0;
Path clipPath = new Path();
RectF rectF = new RectF();
for (int a = 0; a < 3; a++) {
int x, y;
if (a == 0) {
x = padding;
y = padding;
} else if (a == 1) {
x = size - sideQuadSize * multiple - padding;
y = padding;
} else {
x = padding;
y = size - sideQuadSize * multiple - padding;
}
float r;
if (isTransparentBackground) {
rectF.set(x + multiple, y + multiple, x + (sideQuadSize - 1) * multiple, y + (sideQuadSize - 1) * multiple);
r = (sideQuadSize * multiple) / 4.0f * radiusFactor;
clipPath.reset();
clipPath.addRoundRect(rectF, r, r, Path.Direction.CW);
clipPath.close();
canvas.save();
canvas.clipPath(clipPath, Region.Op.DIFFERENCE);
}
r = (sideQuadSize * multiple) / 3.0f * radiusFactor;
Arrays.fill(radii, r);
rect.setColor(color);
rect.setBounds(x, y, x + sideQuadSize * multiple, y + sideQuadSize * multiple);
rect.draw(canvas);
canvas.drawRect(x + multiple, y + multiple, x + (sideQuadSize - 1) * multiple, y + (sideQuadSize - 1) * multiple, blackPaint);
if (isTransparentBackground) {
canvas.restore();
}
if (!isTransparentBackground) {
r = (sideQuadSize * multiple) / 4.0f * radiusFactor;
Arrays.fill(radii, r);
rect.setColor(backgroundColor);
rect.setBounds(x + multiple, y + multiple, x + (sideQuadSize - 1) * multiple, y + (sideQuadSize - 1) * multiple);
rect.draw(canvas);
}
r = ((sideQuadSize - 2) * multiple) / 4.0f * radiusFactor;
Arrays.fill(radii, r);
rect.setColor(color);
rect.setBounds(x + multiple * 2, y + multiple * 2, x + (sideQuadSize - 2) * multiple, y + (sideQuadSize - 2) * multiple);
rect.draw(canvas);
if (includeSideQuads) {
blackPaint.setColor(color);
drawSideQuadsGradient(canvas, blackPaint, rect, sideQuadSize, multiple, padding, size, radiusFactor, radii, backgroundColor, color);
}
boolean isTransparentBackground = Color.alpha(backgroundColor) == 0;
float r = multiple / 2.0f * radiusFactor;
for (int y = 0, outputY = padding; y < inputHeight; y++, outputY += multiple) {
@ -241,6 +197,102 @@ public final class QRCodeWriter {
return bitmap;
}
public static void drawSideQuadsGradient(Canvas canvas, Paint blackPaint, GradientDrawable rect, float sideQuadSize, float multiple, int padding, float size, float radiusFactor, float[] radii, int backgroundColor, int color) {
boolean isTransparentBackground = Color.alpha(backgroundColor) == 0;
rect.setShape(GradientDrawable.RECTANGLE);
rect.setCornerRadii(radii);
Path clipPath = new Path();
RectF rectF = new RectF();
for (int a = 0; a < 3; a++) {
float x, y;
if (a == 0) {
x = padding;
y = padding;
} else if (a == 1) {
x = size - sideQuadSize * multiple - padding;
y = padding;
} else {
x = padding;
y = size - sideQuadSize * multiple - padding;
}
float r;
if (isTransparentBackground) {
rectF.set(x + multiple, y + multiple, x + (sideQuadSize - 1) * multiple, y + (sideQuadSize - 1) * multiple);
r = (sideQuadSize * multiple) / 4.0f * radiusFactor;
clipPath.reset();
clipPath.addRoundRect(rectF, r, r, Path.Direction.CW);
clipPath.close();
canvas.save();
canvas.clipPath(clipPath, Region.Op.DIFFERENCE);
}
r = (sideQuadSize * multiple) / 3.0f * radiusFactor;
Arrays.fill(radii, r);
rect.setColor(color);
rect.setBounds((int) x, (int) y, (int) (x + sideQuadSize * multiple), (int) (y + sideQuadSize * multiple));
rect.draw(canvas);
canvas.drawRect(x + multiple, y + multiple, x + (sideQuadSize - 1) * multiple, y + (sideQuadSize - 1) * multiple, blackPaint);
if (isTransparentBackground) {
canvas.restore();
}
if (!isTransparentBackground) {
r = (sideQuadSize * multiple) / 4.0f * radiusFactor;
Arrays.fill(radii, r);
rect.setColor(backgroundColor);
rect.setBounds((int) (x + multiple), (int) (y + multiple), (int) (x + (sideQuadSize - 1) * multiple), (int) (y + (sideQuadSize - 1) * multiple));
rect.draw(canvas);
}
r = ((sideQuadSize - 2) * multiple) / 4.0f * radiusFactor;
Arrays.fill(radii, r);
rect.setColor(color);
rect.setBounds((int) (x + multiple * 2), (int) (y + multiple * 2), (int) (x + (sideQuadSize - 2) * multiple), (int) (y + (sideQuadSize - 2) * multiple));
rect.draw(canvas);
}
}
public static void drawSideQuads(Canvas canvas, float xOffset, float yOffset, Paint blackPaint, float sideQuadSize, float multiple, int padding, float size, float radiusFactor, float[] radii, boolean isTransparentBackground) {
Path clipPath = new Path();
for (int a = 0; a < 3; a++) {
float x, y;
if (a == 0) {
x = padding;
y = padding;
} else if (a == 1) {
x = size - sideQuadSize * multiple - padding;
y = padding;
} else {
x = padding;
y = size - sideQuadSize * multiple - padding;
}
x += xOffset;
y += yOffset;
float r;
if (isTransparentBackground) {
AndroidUtilities.rectTmp.set(x + multiple, y + multiple, x + (sideQuadSize - 1) * multiple, y + (sideQuadSize - 1) * multiple);
r = (sideQuadSize * multiple) / 4.0f * radiusFactor;
clipPath.reset();
clipPath.addRoundRect(AndroidUtilities.rectTmp, r, r, Path.Direction.CW);
clipPath.close();
canvas.save();
canvas.clipPath(clipPath, Region.Op.DIFFERENCE);
}
r = (sideQuadSize * multiple) / 3.0f * radiusFactor;
AndroidUtilities.rectTmp.set(x, y, x + sideQuadSize * multiple, y + sideQuadSize * multiple);
canvas.drawRoundRect(AndroidUtilities.rectTmp, r, r, blackPaint);
if (isTransparentBackground) {
canvas.restore();
}
r = ((sideQuadSize - 2) * multiple) / 4.0f * radiusFactor;
AndroidUtilities.rectTmp.set(x + multiple * 2, y + multiple * 2, x + (sideQuadSize - 2) * multiple, y + (sideQuadSize - 2) * multiple);
canvas.drawRoundRect(AndroidUtilities.rectTmp, r, r, blackPaint);
}
}
private boolean has(int x, int y) {
if (x >= imageBlockX && x < imageBlockX + imageBloks && y >= imageBlockX && y < imageBlockX + imageBloks) {
return false;
@ -257,4 +309,8 @@ public final class QRCodeWriter {
public int getImageSize() {
return imageSize;
}
public int getSideSize() {
return sideQuadSize;
}
}

View File

@ -475,7 +475,7 @@ public class AndroidUtilities {
return spannableStringBuilder;
}
public static void recycleBitmaps(ArrayList<Bitmap> bitmapToRecycle) {
public static void recycleBitmaps(List<Bitmap> bitmapToRecycle) {
if (bitmapToRecycle != null && !bitmapToRecycle.isEmpty()) {
AndroidUtilities.runOnUIThread(() -> Utilities.globalQueue.postRunnable(() -> {
for (int i = 0; i < bitmapToRecycle.size(); i++) {
@ -526,6 +526,10 @@ public class AndroidUtilities {
});
}
public static void recycleBitmap(Bitmap image) {
recycleBitmaps(Collections.singletonList(image));
}
private static class LinkSpec {
String url;
int start;
@ -2636,7 +2640,7 @@ public class AndroidUtilities {
}
public static boolean shouldShowClipboardToast() {
return Build.VERSION.SDK_INT < Build.VERSION_CODES.S || !OneUIUtilities.hasBuiltInClipboardToasts();
return (Build.VERSION.SDK_INT < Build.VERSION_CODES.S || !OneUIUtilities.hasBuiltInClipboardToasts()) && Build.VERSION.SDK_INT < 32 /* TODO: Update to TIRAMISU when compileSdkVersion would be 32 */;
}
public static boolean addToClipboard(CharSequence str) {

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 = 2929;
public static String BUILD_VERSION_STRING = "9.1.6";
public static int BUILD_VERSION = 2956;
public static String BUILD_VERSION_STRING = "9.2.0";
public static int APP_ID = 4;
public static String APP_HASH = "014b35b6184100b085b0d0572f9b5103";

View File

@ -1700,9 +1700,17 @@ public class ChatObject {
}
public static boolean canDeleteTopic(int currentAccount, TLRPC.Chat chat, int topicId) {
if (topicId == 1) {
// general topic can't be deleted
return false;
}
return chat != null && canDeleteTopic(currentAccount, chat, MessagesController.getInstance(currentAccount).getTopicsController().findTopic(chat.id, topicId));
}
public static boolean canDeleteTopic(int currentAccount, TLRPC.Chat chat, TLRPC.TL_forumTopic topic) {
if (topic != null && topic.id == 1) {
// general topic can't be deleted
return false;
}
return canUserDoAction(chat, ACTION_DELETE_MESSAGES) || isMyTopic(currentAccount, topic) && topic.topMessage != null && topic.topicStartMessage != null && topic.topMessage.id - topic.topicStartMessage.id <= Math.max(1, topic.groupedMessages == null ? 0 : topic.groupedMessages.size()) && MessageObject.peersEqual(topic.from_id, topic.topMessage.from_id);
}

View File

@ -23,8 +23,6 @@ import android.widget.RemoteViewsService;
import androidx.collection.LongSparseArray;
import com.google.android.exoplayer2.util.Log;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.AvatarDrawable;
@ -352,8 +350,6 @@ class ChatsRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory {
fillInIntent.putExtras(extras);
rv.setOnClickFillInIntent(R.id.shortcut_widget_item, fillInIntent);
Log.d("kek", "kek " + name);
rv.setViewVisibility(R.id.shortcut_widget_item_divider, position == getCount() ? View.GONE : View.VISIBLE);
return rv;

View File

@ -203,8 +203,6 @@ class ContactsRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactor
}
extras.putInt("currentAccount", accountInstance.getCurrentAccount());
Log.d("kek", "kek " + name);
Intent fillInIntent = new Intent();
fillInIntent.putExtras(extras);
rv.setOnClickFillInIntent(a == 0 ? R.id.contacts_widget_item1 : R.id.contacts_widget_item2, fillInIntent);

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,10 @@
package org.telegram.messenger;
import org.telegram.tgnet.TLObject;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.Components.AvatarDrawable;
import org.telegram.ui.Components.BackupImageView;
public class DialogObject {
@ -98,4 +101,66 @@ public class DialogObject {
public static int getFolderId(long dialogId) {
return (int) dialogId;
}
public static String getDialogTitle(TLObject dialog) {
return setDialogPhotoTitle(null, null, dialog);
}
public static String setDialogPhotoTitle(ImageReceiver imageReceiver, AvatarDrawable avatarDrawable, TLObject dialog) {
String title = "";
if (dialog instanceof TLRPC.User) {
TLRPC.User user = (TLRPC.User) dialog;
if (UserObject.isReplyUser(user)) {
title = LocaleController.getString("RepliesTitle", R.string.RepliesTitle);
if (avatarDrawable != null) {
avatarDrawable.setAvatarType(AvatarDrawable.AVATAR_TYPE_REPLIES);
}
if (imageReceiver != null) {
imageReceiver.setForUserOrChat(null, avatarDrawable);
}
} else if (UserObject.isUserSelf(user)) {
title = LocaleController.getString("SavedMessages", R.string.SavedMessages);
if (avatarDrawable != null) {
avatarDrawable.setAvatarType(AvatarDrawable.AVATAR_TYPE_SAVED);
}
if (imageReceiver != null) {
imageReceiver.setForUserOrChat(null, avatarDrawable);
}
} else {
title = UserObject.getUserName(user);
if (avatarDrawable != null) {
avatarDrawable.setInfo(user);
}
if (imageReceiver != null) {
imageReceiver.setForUserOrChat(dialog, avatarDrawable);
}
}
} else if (dialog instanceof TLRPC.Chat) {
TLRPC.Chat chat = (TLRPC.Chat) dialog;
title = chat.title;
if (avatarDrawable != null) {
avatarDrawable.setInfo(chat);
}
if (imageReceiver != null) {
imageReceiver.setForUserOrChat(dialog, avatarDrawable);
}
}
return title;
}
public static String setDialogPhotoTitle(BackupImageView imageView, TLObject dialog) {
if (imageView != null) {
return setDialogPhotoTitle(imageView.getImageReceiver(), imageView.getAvatarDrawable(), dialog);
}
return setDialogPhotoTitle(null, null, dialog);
}
public static String getPublicUsername(TLObject dialog) {
if (dialog instanceof TLRPC.Chat) {
return ChatObject.getPublicUsername((TLRPC.Chat) dialog);
} else if (dialog instanceof TLRPC.User) {
return UserObject.getPublicUsername((TLRPC.User) dialog);
}
return null;
}
}

View File

@ -1108,14 +1108,26 @@ public class DownloadController extends BaseController implements NotificationCe
public void startDownloadFile(TLRPC.Document document, MessageObject parentObject) {
if (parentObject.getDocument() == null) {
if (parentObject == null) {
return;
}
TLRPC.Document parentDocument = parentObject.getDocument();
if (parentDocument == null) {
return;
}
AndroidUtilities.runOnUIThread(() -> {
if (parentDocument == null) {
return;
}
boolean contains = false;
for (int i = 0; i < recentDownloadingFiles.size(); i++) {
if (recentDownloadingFiles.get(i).getDocument() != null && recentDownloadingFiles.get(i).getDocument().id == parentObject.getDocument().id) {
MessageObject messageObject = recentDownloadingFiles.get(i);
if (messageObject == null) {
continue;
}
TLRPC.Document document1 = messageObject.getDocument();
if (document1 != null && document1.id == parentDocument.id) {
contains = true;
break;
}
@ -1123,7 +1135,12 @@ public class DownloadController extends BaseController implements NotificationCe
if (!contains) {
for (int i = 0; i < downloadingFiles.size(); i++) {
if (downloadingFiles.get(i).getDocument() != null && downloadingFiles.get(i).getDocument().id == parentObject.getDocument().id) {
MessageObject messageObject = downloadingFiles.get(i);
if (messageObject == null) {
continue;
}
TLRPC.Document document1 = messageObject.getDocument();
if (document1 != null && document1.id == parentDocument.id) {
contains = true;
break;
}

View File

@ -24,7 +24,6 @@ import android.text.TextPaint;
import android.text.TextUtils;
import android.text.style.DynamicDrawableSpan;
import android.text.style.ImageSpan;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
@ -330,9 +329,9 @@ public class Emoji {
this.end = end;
this.code = code;
}
int start;
int end;
CharSequence code;
public int start;
public int end;
public CharSequence code;
}
public static boolean fullyConsistsOfEmojis(CharSequence cs) {
@ -505,10 +504,14 @@ public class Emoji {
s = Spannable.Factory.getInstance().newSpannable(cs.toString());
}
ArrayList<EmojiSpanRange> emojis = parseEmojis(s, emojiOnly);
if (emojis.isEmpty()) {
return cs;
}
AnimatedEmojiSpan[] animatedEmojiSpans = s.getSpans(0, s.length(), AnimatedEmojiSpan.class);
EmojiSpan span;
Drawable drawable;
int limitCount = SharedConfig.getDevicePerformanceClass() >= SharedConfig.PERFORMANCE_CLASS_HIGH ? 100 : 50;
for (int i = 0; i < emojis.size(); ++i) {
try {
EmojiSpanRange emojiRange = emojis.get(i);
@ -534,7 +537,6 @@ public class Emoji {
} catch (Exception e) {
FileLog.e(e);
}
int limitCount = SharedConfig.getDevicePerformanceClass() >= SharedConfig.PERFORMANCE_CLASS_HIGH ? 100 : 50;
if ((Build.VERSION.SDK_INT < 23 || Build.VERSION.SDK_INT >= 29)/* && !BuildVars.DEBUG_PRIVATE_VERSION*/ && (i + 1) >= limitCount) {
break;
}

View File

@ -16,6 +16,7 @@ import org.telegram.ui.LaunchActivity;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
@ -186,6 +187,7 @@ public class FileLoadOperation {
private File tempPath;
private boolean isForceRequest;
private int priority;
private long fileDialogId;
private boolean ungzip;
@ -218,6 +220,7 @@ public class FileLoadOperation {
public FileLoadOperation(ImageLocation imageLocation, Object parent, String extension, long size) {
updateParams();
parentObject = parent;
fileDialogId = FileLoader.getDialogIdFromParent(currentAccount, parentObject);
isStream = imageLocation.imageType == FileLoader.IMAGE_TYPE_ANIMATION;
if (imageLocation.isEncrypted()) {
location = new TLRPC.TL_inputEncryptedFileLocation();
@ -324,6 +327,7 @@ public class FileLoadOperation {
updateParams();
try {
parentObject = parent;
fileDialogId = FileLoader.getDialogIdFromParent(currentAccount, parentObject);
if (documentLocation instanceof TLRPC.TL_documentEncrypted) {
location = new TLRPC.TL_inputEncryptedFileLocation();
location.id = documentLocation.id;
@ -827,6 +831,7 @@ public class FileLoadOperation {
finalFileExist = false;
}
if (!finalFileExist) {
cacheFileTemp = new File(tempPath, fileNameTemp);
if (ungzip) {
@ -964,6 +969,11 @@ public class FileLoadOperation {
}
}
if (fileDialogId != 0) {
FileLoader.getInstance(currentAccount).getFileDatabase().saveFileDialogId(cacheFileParts, fileDialogId);
FileLoader.getInstance(currentAccount).getFileDatabase().saveFileDialogId(cacheFileTemp, fileDialogId);
}
if (cacheFileTemp.exists()) {
if (newKeyGenerated) {
cacheFileTemp.delete();
@ -1281,6 +1291,14 @@ public class FileLoadOperation {
if (BuildVars.DEBUG_VERSION) {
FileLog.d("finished preloading file to " + cacheFileTemp + " loaded " + totalPreloadedBytes + " of " + totalBytesCount);
}
if (fileDialogId != 0) {
if (cacheFileTemp != null) {
FileLoader.getInstance(currentAccount).getFileDatabase().removeFiles(Collections.singletonList(cacheFileTemp));
}
if (cacheFileParts != null) {
FileLoader.getInstance(currentAccount).getFileDatabase().removeFiles(Collections.singletonList(cacheFileParts));
}
}
delegate.didFinishLoadingFile(FileLoadOperation.this, cacheFileFinal);
} else {
final File cacheIvTempFinal = cacheIvTemp;
@ -1310,7 +1328,7 @@ public class FileLoadOperation {
} catch (ZipException zipException) {
ungzip = false;
} catch (Throwable e) {
FileLog.e(e);
FileLog.e(e, !(e instanceof FileNotFoundException));
if (BuildVars.LOGS_ENABLED) {
FileLog.e("unable to ungzip temp = " + cacheFileTempFinal + " to final = " + cacheFileFinal);
}

View File

@ -19,11 +19,14 @@ import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class FileLoader extends BaseController {
@ -35,6 +38,30 @@ public class FileLoader extends BaseController {
private int priorityIncreasePointer;
private static Pattern sentPattern;
public static long getDialogIdFromParent(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]+)");
}
try {
Matcher matcher = sentPattern.matcher(str);
if (matcher.matches()) {
return Long.parseLong(matcher.group(1));
}
} catch (Exception e) {
FileLog.e(e);
}
}
} else if (parentObject instanceof MessageObject) {
return ((MessageObject) parentObject).getDialogId();
}
return 0;
}
private int getPriorityValue(int priorityType) {
if (priorityType == PRIORITY_STREAM) {
return Integer.MAX_VALUE;
@ -51,6 +78,10 @@ public class FileLoader extends BaseController {
}
}
public DispatchQueue getFileLoaderQueue() {
return fileLoaderQueue;
}
public interface FileLoaderDelegate {
void fileUploadProgressChanged(FileUploadOperation operation, String location, long uploadedSize, long totalSize, boolean isEncrypted);
@ -104,7 +135,6 @@ public class FileLoader extends BaseController {
private ConcurrentHashMap<String, FileLoadOperation> loadOperationPaths = new ConcurrentHashMap<>();
private ArrayList<FileLoadOperation> activeFileLoadOperation = new ArrayList<>();
private ConcurrentHashMap<String, LoadOperationUIObject> loadOperationPathsUI = new ConcurrentHashMap<>(10, 1, 2);
private HashMap<String, Long> uploadSizes = new HashMap<>();
@ -498,6 +528,30 @@ public class FileLoader extends BaseController {
}
}
public void cancelLoadAllFiles() {
for (String fileName : loadOperationPathsUI.keySet()) {
LoadOperationUIObject uiObject = loadOperationPathsUI.get(fileName);
Runnable runnable = uiObject != null ? uiObject.loadInternalRunnable : null;
boolean removed = uiObject != null;
if (runnable != null) {
fileLoaderQueue.cancelRunnable(runnable);
}
fileLoaderQueue.postRunnable(() -> {
FileLoadOperation operation = loadOperationPaths.remove(fileName);
if (operation != null) {
FileLoaderPriorityQueue queue = operation.getQueue();
queue.cancel(operation);
}
});
// if (removed && document != null) {
// AndroidUtilities.runOnUIThread(() -> {
// getNotificationCenter().postNotificationName(NotificationCenter.onDownloadingFilesChanged);
// });
// }
}
}
public boolean isLoadingFile(final String fileName) {
return fileName != null && loadOperationPathsUI.containsKey(fileName);
}
@ -713,8 +767,15 @@ public class FileLoader extends BaseController {
if (!operation.isPreloadVideoOperation() && operation.isPreloadFinished()) {
return;
}
if (document != null && parentObject instanceof MessageObject && ((MessageObject) parentObject).putInDownloadsStore) {
getDownloadController().onDownloadComplete((MessageObject) parentObject);
long dialogId = getDialogIdFromParent(currentAccount, parentObject);
if (dialogId != 0) {
getFileLoader().getFileDatabase().saveFileDialogId(finalFile, dialogId);
}
if (parentObject instanceof MessageObject) {
MessageObject messageObject = (MessageObject) parentObject;
if (document != null && messageObject.putInDownloadsStore) {
getDownloadController().onDownloadComplete(messageObject);
}
}
if (!operation.isPreloadVideoOperation()) {
@ -915,7 +976,7 @@ public class FileLoader extends BaseController {
}
}
} else if (MessageObject.getMedia(message) instanceof TLRPC.TL_messageMediaInvoice) {
TLRPC.WebDocument document = ((TLRPC.TL_messageMediaInvoice) MessageObject.getMedia(message)).photo;
TLRPC.WebDocument document = ((TLRPC.TL_messageMediaInvoice) MessageObject.getMedia(message)).webPhoto;
if (document != null) {
return Utilities.MD5(document.url) + "." + ImageLoader.getHttpUrlExtension(document.url, getMimeTypePart(document.mime_type));
}
@ -1087,7 +1148,7 @@ public class FileLoader extends BaseController {
return new File(dir, getAttachFileName(attach, ext));
}
private FilePathDatabase getFileDatabase() {
public FilePathDatabase getFileDatabase() {
return filePathDatabase;
}
@ -1498,4 +1559,19 @@ public class FileLoader extends BaseController {
private static class LoadOperationUIObject {
Runnable loadInternalRunnable;
}
public static byte[] longToBytes(long x) {
ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES);
buffer.putLong(x);
return buffer.array();
}
public static long bytesToLong(byte[] bytes) {
long l = 0;
for (int i = 0; i < 8; i++) {
l <<= 8;
l ^= bytes[i] & 0xFF;
}
return l;
}
}

View File

@ -37,6 +37,7 @@ public class FileLog {
private File networkFile = null;
private File tonlibFile = null;
private boolean initied;
public static boolean databaseIsMalformed = false;
private OutputStreamWriter tlStreamWriter = null;
private File tlRequestsFile = null;
@ -311,7 +312,7 @@ public class FileLog {
AndroidUtilities.appCenterLog(e);
}
if (BuildVars.DEBUG_VERSION && e instanceof SQLiteException && e.getMessage() != null && e.getMessage().contains("disk image is malformed")) {
databaseIsMalformed = true;
}
ensureInitied();
e.printStackTrace();

View File

@ -10,6 +10,7 @@ import org.telegram.SQLite.SQLitePreparedStatement;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
public class FilePathDatabase {
@ -21,7 +22,7 @@ public class FilePathDatabase {
private File cacheFile;
private File shmCacheFile;
private final static int LAST_DB_VERSION = 2;
private final static int LAST_DB_VERSION = 3;
private final static String DATABASE_NAME = "file_to_path";
private final static String DATABASE_BACKUP_NAME = "file_to_path_backup";
@ -56,6 +57,9 @@ public class FilePathDatabase {
if (createTable) {
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("PRAGMA user_version = " + LAST_DB_VERSION).stepThis().dispose();
} else {
int version = database.executeInt("PRAGMA user_version");
@ -95,6 +99,11 @@ public class FilePathDatabase {
database.executeFast("PRAGMA user_version = " + 2).stepThis().dispose();
version = 2;
}
if (version == 2) {
database.executeFast("CREATE TABLE paths_by_dialog_id(path TEXT PRIMARY KEY, dialog_id INTEGER);").stepThis().dispose();
database.executeFast("PRAGMA user_version = " + 3).stepThis().dispose();
version = 3;
}
}
private void createBackup() {
@ -271,6 +280,7 @@ public class FilePathDatabase {
dispatchQueue.postRunnable(() -> {
try {
database.executeFast("DELETE FROM paths WHERE 1").stepThis().dispose();
database.executeFast("DELETE FROM paths_by_dialog_id WHERE 1").stepThis().dispose();
} catch (Exception e) {
FileLog.e(e);
}
@ -300,6 +310,68 @@ public class FilePathDatabase {
return res[0];
}
public void saveFileDialogId(File file, long dialogId) {
if (file == null) {
return;
}
dispatchQueue.postRunnable(() -> {
SQLitePreparedStatement state = null;
try {
state = database.executeFast("REPLACE INTO paths_by_dialog_id VALUES(?, ?)");
state.requery();
state.bindString(1, file.getPath());
state.bindLong(2, dialogId);
state.step();
} catch (Exception e) {
FileLog.e(e);
} finally {
if (state != null) {
state.dispose();
}
}
});
}
public long getFileDialogId(File file) {
if (file == null) {
return 0;
}
long dialogId = 0;
SQLiteCursor cursor = null;
try {
cursor = database.queryFinalized("SELECT dialog_id FROM paths_by_dialog_id WHERE path = '" + file.getPath() + "'");
if (cursor.next()) {
dialogId = cursor.longValue(0);
}
} catch (Exception e) {
FileLog.e(e);
} finally {
if (cursor != null) {
cursor.dispose();
}
}
return dialogId;
}
public DispatchQueue getQueue() {
return dispatchQueue;
}
public void removeFiles(List<File> 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();
}
} catch (Exception e) {
FileLog.e(e);
} finally {
database.commitTransaction();
}
});
}
public static class PathData {
public final long id;
public final int dc;

View File

@ -458,7 +458,7 @@ public class FileRefController extends BaseController {
}
} else if (string.startsWith("sent_")) {
String[] params = string.split("_");
if (params.length == 3) {
if (params.length >= 3) {
long channelId = Utilities.parseLong(params[1]);
if (channelId != 0) {
TLRPC.TL_channels_getMessages req = new TLRPC.TL_channels_getMessages();

View File

@ -257,7 +257,7 @@ public class FileUploadOperation {
if (stream == null) {
File cacheFile = new File(uploadingFilePath);
if (AndroidUtilities.isInternalUri(Uri.fromFile(cacheFile))) {
throw new Exception("trying to upload internal file");
throw new FileLog.IgnoreSentException("trying to upload internal file");
}
stream = new RandomAccessFile(cacheFile, "r");
boolean isInternalFile = false;

View File

@ -29,7 +29,7 @@ public class GoogleLocationProvider implements ILocationServiceProvider {
@Override
public void init(Context context) {
locationProviderClient = LocationServices.getFusedLocationProviderClient(context);
settingsClient = new SettingsClient(context);
settingsClient = LocationServices.getSettingsClient(context);
}
@Override

View File

@ -28,7 +28,6 @@ import android.os.Environment;
import android.os.SystemClock;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.util.Log;
import android.util.SparseArray;
import androidx.exifinterface.media.ExifInterface;
@ -1354,7 +1353,7 @@ public class ImageLoader {
}
}
} catch (Throwable e) {
FileLog.e(e);
FileLog.e(e, !(e instanceof FileNotFoundException));
}
} else {
try {
@ -1399,7 +1398,8 @@ public class ImageLoader {
Utilities.loadWebpImage(image, buffer, buffer.limit(), null, !opts.inPurgeable);
file.close();
} else {
if (opts.inPurgeable || secureDocumentKey != null || Build.VERSION.SDK_INT <= 29) {
try {
RandomAccessFile f = new RandomAccessFile(cacheFileFinal, "r");
int len = (int) f.length();
int offset = 0;
@ -1426,7 +1426,11 @@ public class ImageLoader {
if (!error) {
image = BitmapFactory.decodeByteArray(data, offset, len, opts);
}
} else {
} catch (Throwable e) {
}
if (image == null) {
FileInputStream is;
if (inEncryptedFile) {
is = new EncryptedFileInputStream(cacheFileFinal, cacheImage.encryptionKeyPath);
@ -1623,7 +1627,7 @@ public class ImageLoader {
toSet = bitmapDrawable;
} else {
Bitmap image = bitmapDrawable.getBitmap();
image.recycle();
AndroidUtilities.recycleBitmap(image);
}
if (toSet != null && incrementUseCount) {
incrementUseCount(cacheImage.key);

View File

@ -44,6 +44,17 @@ import java.util.ArrayList;
public class ImageReceiver implements NotificationCenter.NotificationCenterDelegate {
public boolean updateThumbShaderMatrix() {
if (currentThumbDrawable != null && thumbShader != null) {
drawDrawable(null, currentThumbDrawable, 255, thumbShader, 0, 0, null);
return true;
} if (staticThumbDrawable != null && thumbShader != null) {
drawDrawable(null, staticThumbDrawable, 255, thumbShader, 0, 0, null);
return true;
}
return false;
}
public interface ImageReceiverDelegate {
void didSetImage(ImageReceiver imageReceiver, boolean set, boolean thumb, boolean memCache);
@ -208,7 +219,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
private String currentThumbKey;
private int thumbTag;
private Drawable currentThumbDrawable;
private BitmapShader thumbShader;
public BitmapShader thumbShader;
private int thumbOrientation;
private ImageLocation currentMediaLocation;
@ -378,13 +389,15 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
if (userFull == null) {
MessagesController.getInstance(currentAccount).loadFullUser(user, currentGuid, false);
} else {
if (userFull.profile_photo != null) {
TLRPC.Photo photo = userFull.profile_photo;
if (photo != null && photo.video_sizes != null && !photo.video_sizes.isEmpty()) {
TLRPC.VideoSize videoSize = photo.video_sizes.get(0);
for (int i = 0; i < photo.video_sizes.size(); i++) {
if ("p".equals(photo.video_sizes.get(i).type)) {
videoSize = photo.video_sizes.get(i);
TLRPC.Photo photo = userFull.profile_photo;
if (photo != null) {
ArrayList<TLRPC.VideoSize> videoSizes = photo.video_sizes;
if (videoSizes != null && !videoSizes.isEmpty()) {
TLRPC.VideoSize videoSize = videoSizes.get(0);
for (int i = 0; i < videoSizes.size(); i++) {
TLRPC.VideoSize videoSize1 = videoSizes.get(i);
if ("p".equals(videoSize1.type)) {
videoSize = videoSize1;
break;
}
}
@ -1170,10 +1183,12 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
if (isRoundRect) {
try {
if (roundRadius[0] == 0) {
canvas.drawRect(roundRect, roundPaint);
} else {
canvas.drawRoundRect(roundRect, roundRadius[0], roundRadius[0], roundPaint);
if (canvas != null) {
if (roundRadius[0] == 0) {
canvas.drawRect(roundRect, roundPaint);
} else {
canvas.drawRoundRect(roundRect, roundRadius[0], roundRadius[0], roundPaint);
}
}
} catch (Exception e) {
onBitmapException(bitmapDrawable);
@ -1187,7 +1202,9 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
roundPath.reset();
roundPath.addRoundRect(roundRect, radii, Path.Direction.CW);
roundPath.close();
canvas.drawPath(roundPath, roundPaint);
if (canvas != null) {
canvas.drawPath(roundPath, roundPaint);
}
}
}
} else {
@ -1273,16 +1290,18 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
if (isRoundRect) {
try {
if (roundRadius[0] == 0) {
if (reactionLastFrame) {
AndroidUtilities.rectTmp.set(roundRect);
AndroidUtilities.rectTmp.inset(-(drawRegion.width() * ReactionLastFrame.LAST_FRAME_SCALE - drawRegion.width()) / 2f, -(drawRegion.height() * ReactionLastFrame.LAST_FRAME_SCALE - drawRegion.height()) / 2f);
canvas.drawRect(AndroidUtilities.rectTmp, roundPaint);
if (canvas != null) {
if (roundRadius[0] == 0) {
if (reactionLastFrame) {
AndroidUtilities.rectTmp.set(roundRect);
AndroidUtilities.rectTmp.inset(-(drawRegion.width() * ReactionLastFrame.LAST_FRAME_SCALE - drawRegion.width()) / 2f, -(drawRegion.height() * ReactionLastFrame.LAST_FRAME_SCALE - drawRegion.height()) / 2f);
canvas.drawRect(AndroidUtilities.rectTmp, roundPaint);
} else {
canvas.drawRect(roundRect, roundPaint);
}
} else {
canvas.drawRect(roundRect, roundPaint);
canvas.drawRoundRect(roundRect, roundRadius[0], roundRadius[0], roundPaint);
}
} else {
canvas.drawRoundRect(roundRect, roundRadius[0], roundRadius[0], roundPaint);
}
} catch (Exception e) {
if (backgroundThreadDrawHolder == null) {
@ -1298,7 +1317,9 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
roundPath.reset();
roundPath.addRoundRect(roundRect, radii, Path.Direction.CW);
roundPath.close();
canvas.drawPath(roundPath, roundPaint);
if (canvas != null) {
canvas.drawPath(roundPath, roundPaint);
}
}
}
}
@ -1339,104 +1360,106 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
canvas.restore();
}
} else {
if (Math.abs(scaleW - scaleH) > 0.00001f) {
canvas.save();
if (clip) {
canvas.clipRect(imageX, imageY, imageX + imageW, imageY + imageH);
}
if (orientation % 360 != 0) {
if (centerRotation) {
canvas.rotate(orientation, imageW / 2, imageH / 2);
} else {
canvas.rotate(orientation, 0, 0);
if (canvas != null) {
if (Math.abs(scaleW - scaleH) > 0.00001f) {
canvas.save();
if (clip) {
canvas.clipRect(imageX, imageY, imageX + imageW, imageY + imageH);
}
}
if (bitmapW / scaleH > imageW) {
bitmapW /= scaleH;
drawRegion.set(imageX - (bitmapW - imageW) / 2.0f, imageY, imageX + (bitmapW + imageW) / 2.0f, imageY + imageH);
if (orientation % 360 != 0) {
if (centerRotation) {
canvas.rotate(orientation, imageW / 2, imageH / 2);
} else {
canvas.rotate(orientation, 0, 0);
}
}
if (bitmapW / scaleH > imageW) {
bitmapW /= scaleH;
drawRegion.set(imageX - (bitmapW - imageW) / 2.0f, imageY, imageX + (bitmapW + imageW) / 2.0f, imageY + imageH);
} else {
bitmapH /= scaleW;
drawRegion.set(imageX, imageY - (bitmapH - imageH) / 2.0f, imageX + imageW, imageY + (bitmapH + imageH) / 2.0f);
}
if (bitmapDrawable instanceof AnimatedFileDrawable) {
((AnimatedFileDrawable) bitmapDrawable).setActualDrawRect(imageX, imageY, imageW, imageH);
}
if (backgroundThreadDrawHolder == null) {
if (orientation % 360 == 90 || orientation % 360 == 270) {
float width = drawRegion.width() / 2;
float height = drawRegion.height() / 2;
float centerX = drawRegion.centerX();
float centerY = drawRegion.centerY();
bitmapDrawable.setBounds((int) (centerX - height), (int) (centerY - width), (int) (centerX + height), (int) (centerY + width));
} else {
bitmapDrawable.setBounds((int) drawRegion.left, (int) drawRegion.top, (int) drawRegion.right, (int) drawRegion.bottom);
}
}
if (isVisible) {
try {
if (Build.VERSION.SDK_INT >= 29) {
if (blendMode != null) {
bitmapDrawable.getPaint().setBlendMode((BlendMode) blendMode);
} else {
bitmapDrawable.getPaint().setBlendMode(null);
}
}
drawBitmapDrawable(canvas, bitmapDrawable, backgroundThreadDrawHolder, alpha);
} catch (Exception e) {
if (backgroundThreadDrawHolder == null) {
onBitmapException(bitmapDrawable);
}
FileLog.e(e);
}
}
canvas.restore();
} else {
bitmapH /= scaleW;
drawRegion.set(imageX, imageY - (bitmapH - imageH) / 2.0f, imageX + imageW, imageY + (bitmapH + imageH) / 2.0f);
}
if (bitmapDrawable instanceof AnimatedFileDrawable) {
((AnimatedFileDrawable) bitmapDrawable).setActualDrawRect(imageX, imageY, imageW, imageH);
}
if (backgroundThreadDrawHolder == null) {
if (orientation % 360 == 90 || orientation % 360 == 270) {
float width = drawRegion.width() / 2;
float height = drawRegion.height() / 2;
float centerX = drawRegion.centerX();
float centerY = drawRegion.centerY();
bitmapDrawable.setBounds((int) (centerX - height), (int) (centerY - width), (int) (centerX + height), (int) (centerY + width));
} else {
bitmapDrawable.setBounds((int) drawRegion.left, (int) drawRegion.top, (int) drawRegion.right, (int) drawRegion.bottom);
}
}
if (isVisible) {
try {
if (Build.VERSION.SDK_INT >= 29) {
if (blendMode != null) {
bitmapDrawable.getPaint().setBlendMode((BlendMode) blendMode);
} else {
bitmapDrawable.getPaint().setBlendMode(null);
}
canvas.save();
if (orientation % 360 != 0) {
if (centerRotation) {
canvas.rotate(orientation, imageW / 2, imageH / 2);
} else {
canvas.rotate(orientation, 0, 0);
}
drawBitmapDrawable(canvas, bitmapDrawable, backgroundThreadDrawHolder, alpha);
} catch (Exception e) {
if (backgroundThreadDrawHolder == null) {
}
drawRegion.set(imageX, imageY, imageX + imageW, imageY + imageH);
if (isRoundVideo) {
drawRegion.inset(-AndroidUtilities.roundMessageInset, -AndroidUtilities.roundMessageInset);
}
if (bitmapDrawable instanceof AnimatedFileDrawable) {
((AnimatedFileDrawable) bitmapDrawable).setActualDrawRect(imageX, imageY, imageW, imageH);
}
if (backgroundThreadDrawHolder == null) {
if (orientation % 360 == 90 || orientation % 360 == 270) {
float width = drawRegion.width() / 2;
float height = drawRegion.height() / 2;
float centerX = drawRegion.centerX();
float centerY = drawRegion.centerY();
bitmapDrawable.setBounds((int) (centerX - height), (int) (centerY - width), (int) (centerX + height), (int) (centerY + width));
} else {
bitmapDrawable.setBounds((int) drawRegion.left, (int) drawRegion.top, (int) drawRegion.right, (int) drawRegion.bottom);
}
}
if (isVisible) {
try {
if (Build.VERSION.SDK_INT >= 29) {
if (blendMode != null) {
bitmapDrawable.getPaint().setBlendMode((BlendMode) blendMode);
} else {
bitmapDrawable.getPaint().setBlendMode(null);
}
}
drawBitmapDrawable(canvas, bitmapDrawable, backgroundThreadDrawHolder, alpha);
} catch (Exception e) {
onBitmapException(bitmapDrawable);
FileLog.e(e);
}
FileLog.e(e);
}
canvas.restore();
}
canvas.restore();
} else {
canvas.save();
if (orientation % 360 != 0) {
if (centerRotation) {
canvas.rotate(orientation, imageW / 2, imageH / 2);
} else {
canvas.rotate(orientation, 0, 0);
}
}
drawRegion.set(imageX, imageY, imageX + imageW, imageY + imageH);
if (isRoundVideo) {
drawRegion.inset(-AndroidUtilities.roundMessageInset, -AndroidUtilities.roundMessageInset);
}
if (bitmapDrawable instanceof AnimatedFileDrawable) {
((AnimatedFileDrawable) bitmapDrawable).setActualDrawRect(imageX, imageY, imageW, imageH);
}
if (backgroundThreadDrawHolder == null) {
if (orientation % 360 == 90 || orientation % 360 == 270) {
float width = drawRegion.width() / 2;
float height = drawRegion.height() / 2;
float centerX = drawRegion.centerX();
float centerY = drawRegion.centerY();
bitmapDrawable.setBounds((int) (centerX - height), (int) (centerY - width), (int) (centerX + height), (int) (centerY + width));
} else {
bitmapDrawable.setBounds((int) drawRegion.left, (int) drawRegion.top, (int) drawRegion.right, (int) drawRegion.bottom);
}
}
if (isVisible) {
try {
if (Build.VERSION.SDK_INT >= 29) {
if (blendMode != null) {
bitmapDrawable.getPaint().setBlendMode((BlendMode) blendMode);
} else {
bitmapDrawable.getPaint().setBlendMode(null);
}
}
drawBitmapDrawable(canvas, bitmapDrawable, backgroundThreadDrawHolder, alpha);
} catch (Exception e) {
onBitmapException(bitmapDrawable);
FileLog.e(e);
}
}
canvas.restore();
}
}
}
@ -1464,7 +1487,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
}
drawable.setBounds((int) drawRegion.left, (int) drawRegion.top, (int) drawRegion.right, (int) drawRegion.bottom);
}
if (isVisible) {
if (isVisible && canvas != null) {
try {
drawable.setAlpha(alpha);
if (backgroundThreadDrawHolder != null) {
@ -1511,7 +1534,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
} else {
bitmapDrawable.setAlpha(alpha);
if (bitmapDrawable instanceof RLottieDrawable) {
((RLottieDrawable) bitmapDrawable).drawInternal(canvas, false, currentTime, 0);
((RLottieDrawable) bitmapDrawable).drawInternal(canvas, null, false, currentTime, 0);
} else if (bitmapDrawable instanceof AnimatedFileDrawable) {
((AnimatedFileDrawable) bitmapDrawable).drawInternal(canvas, false, currentTime, 0);
} else {

View File

@ -414,7 +414,9 @@ public class LocaleController {
public static String getLanguageFlag(String countryCode) {
if (countryCode.length() != 2 || countryCode.equals("YL")) return null;
if (countryCode.equals("XG")) {
if (countryCode.equals("FT")) {
return "\uD83C\uDFF4\u200D\u2620\uFE0F";
} else if (countryCode.equals("XG")) {
return "\uD83D\uDEF0";
} else if (countryCode.equals("XV")){
return "\uD83C\uDF0D";
@ -1056,10 +1058,11 @@ public class LocaleController {
String param = getInstance().stringForQuantity(getInstance().currentPluralRules.quantityForNumber(plural));
param = key + "_" + param;
int resourceId = ApplicationLoader.applicationContext.getResources().getIdentifier(param, "string", ApplicationLoader.applicationContext.getPackageName());
int fallbackResourceId = ApplicationLoader.applicationContext.getResources().getIdentifier(key + "_other", "string", ApplicationLoader.applicationContext.getPackageName());
Object[] argsWithPlural = new Object[args.length + 1];
argsWithPlural[0] = plural;
System.arraycopy(args, 0, argsWithPlural, 1, args.length);
return formatString(param, key + "_other", resourceId, argsWithPlural);
return formatString(param, key + "_other", resourceId, fallbackResourceId, argsWithPlural);
}
public static String formatPluralStringComma(String key, int plural) {
@ -1108,10 +1111,10 @@ public class LocaleController {
}
public static String formatString(String key, int res, Object... args) {
return formatString(key, null, res, args);
return formatString(key, null, res, 0, args);
}
public static String formatString(String key, String fallback, int res, Object... args) {
public static String formatString(String key, String fallback, int res, int fallbackRes, Object... args) {
try {
String value = BuildVars.USE_CLOUD_STRINGS ? getInstance().localeValues.get(key) : null;
if (value == null) {
@ -1119,7 +1122,15 @@ public class LocaleController {
value = getInstance().localeValues.get(fallback);
}
if (value == null) {
value = ApplicationLoader.applicationContext.getString(res);
try {
value = ApplicationLoader.applicationContext.getString(res);
} catch (Exception e) {
if (fallbackRes != 0) {
try {
value = ApplicationLoader.applicationContext.getString(fallbackRes);
} catch (Exception ignored) {}
}
}
}
}

View File

@ -128,25 +128,29 @@ public class LocationSharingService extends Service implements NotificationCente
if (getInfos().isEmpty()) {
stopSelf();
}
if (builder == null) {
Intent intent2 = new Intent(ApplicationLoader.applicationContext, LaunchActivity.class);
intent2.setAction("org.tmessages.openlocations");
intent2.addCategory(Intent.CATEGORY_LAUNCHER);
PendingIntent contentIntent = PendingIntent.getActivity(ApplicationLoader.applicationContext, 0, intent2, PendingIntent.FLAG_MUTABLE);
try {
if (builder == null) {
Intent intent2 = new Intent(ApplicationLoader.applicationContext, LaunchActivity.class);
intent2.setAction("org.tmessages.openlocations");
intent2.addCategory(Intent.CATEGORY_LAUNCHER);
PendingIntent contentIntent = PendingIntent.getActivity(ApplicationLoader.applicationContext, 0, intent2, PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_UPDATE_CURRENT);
builder = new NotificationCompat.Builder(ApplicationLoader.applicationContext);
builder.setWhen(System.currentTimeMillis());
builder.setSmallIcon(R.drawable.live_loc);
builder.setContentIntent(contentIntent);
NotificationsController.checkOtherNotificationsChannel();
builder.setChannelId(NotificationsController.OTHER_NOTIFICATIONS_CHANNEL);
builder.setContentTitle(LocaleController.getString("AppName", R.string.AppName));
Intent stopIntent = new Intent(ApplicationLoader.applicationContext, StopLiveLocationReceiver.class);
builder.addAction(0, LocaleController.getString("StopLiveLocation", R.string.StopLiveLocation), PendingIntent.getBroadcast(ApplicationLoader.applicationContext, 2, stopIntent, PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_UPDATE_CURRENT));
builder = new NotificationCompat.Builder(ApplicationLoader.applicationContext);
builder.setWhen(System.currentTimeMillis());
builder.setSmallIcon(R.drawable.live_loc);
builder.setContentIntent(contentIntent);
NotificationsController.checkOtherNotificationsChannel();
builder.setChannelId(NotificationsController.OTHER_NOTIFICATIONS_CHANNEL);
builder.setContentTitle(LocaleController.getString("AppName", R.string.AppName));
Intent stopIntent = new Intent(ApplicationLoader.applicationContext, StopLiveLocationReceiver.class);
builder.addAction(0, LocaleController.getString("StopLiveLocation", R.string.StopLiveLocation), PendingIntent.getBroadcast(ApplicationLoader.applicationContext, 2, stopIntent, PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_UPDATE_CURRENT));
}
updateNotification(false);
startForeground(6, builder.build());
} catch (Throwable e) {
FileLog.e(e);
}
updateNotification(false);
startForeground(6, builder.build());
return Service.START_NOT_STICKY;
}
}

View File

@ -1071,16 +1071,23 @@ public class MediaDataController extends BaseController {
return getStickerSet(inputStickerSet, cacheOnly, null);
}
public TLRPC.TL_messages_stickerSet getStickerSet(TLRPC.InputStickerSet inputStickerSet, boolean cacheOnly, Runnable onNotFound) {
public TLRPC.TL_messages_stickerSet getStickerSet(TLRPC.InputStickerSet inputStickerSet, boolean cacheOnly, Utilities.Callback<TLRPC.TL_messages_stickerSet> onResponse) {
if (inputStickerSet == null) {
return null;
}
TLRPC.TL_messages_stickerSet cacheSet = null;
if (inputStickerSet instanceof TLRPC.TL_inputStickerSetID && stickerSetsById.containsKey(inputStickerSet.id)) {
return stickerSetsById.get(inputStickerSet.id);
cacheSet = stickerSetsById.get(inputStickerSet.id);
} else if (inputStickerSet instanceof TLRPC.TL_inputStickerSetShortName && inputStickerSet.short_name != null && stickerSetsByName.containsKey(inputStickerSet.short_name.toLowerCase())) {
return stickerSetsByName.get(inputStickerSet.short_name.toLowerCase());
cacheSet = stickerSetsByName.get(inputStickerSet.short_name.toLowerCase());
} else if (inputStickerSet instanceof TLRPC.TL_inputStickerSetEmojiDefaultStatuses && stickerSetDefaultStatuses != null) {
return stickerSetDefaultStatuses;
cacheSet = stickerSetDefaultStatuses;
}
if (cacheSet != null) {
if (onResponse != null) {
onResponse.run(cacheSet);
}
return cacheSet;
}
if (cacheOnly) {
return null;
@ -1100,11 +1107,16 @@ public class MediaDataController extends BaseController {
stickerSetDefaultStatuses = set;
}
getNotificationCenter().postNotificationName(NotificationCenter.groupStickersDidLoad, set.set.id, set);
if (onResponse != null) {
onResponse.run(set);
}
});
} else {
if (onNotFound != null) {
onNotFound.run();
}
AndroidUtilities.runOnUIThread(() -> {
if (onResponse != null) {
onResponse.run(null);
}
});
}
});
return null;
@ -2713,27 +2725,31 @@ public class MediaDataController extends BaseController {
}
public void preloadStickerSetThumb(TLRPC.TL_messages_stickerSet stickerSet) {
TLRPC.PhotoSize thumb = FileLoader.getClosestPhotoSizeWithSize(stickerSet.set.thumbs, 90);
if (thumb != null) {
ArrayList<TLRPC.Document> documents = stickerSet.documents;
if (documents != null && !documents.isEmpty()) {
loadStickerSetThumbInternal(thumb, stickerSet, documents.get(0), stickerSet.set.thumb_version);
if (stickerSet != null && stickerSet.set != null) {
TLRPC.PhotoSize thumb = FileLoader.getClosestPhotoSizeWithSize(stickerSet.set.thumbs, 90);
if (thumb != null) {
ArrayList<TLRPC.Document> documents = stickerSet.documents;
if (documents != null && !documents.isEmpty()) {
loadStickerSetThumbInternal(thumb, stickerSet, documents.get(0), stickerSet.set.thumb_version);
}
}
}
}
public void preloadStickerSetThumb(TLRPC.StickerSetCovered stickerSet) {
TLRPC.PhotoSize thumb = FileLoader.getClosestPhotoSizeWithSize(stickerSet.set.thumbs, 90);
if (thumb != null) {
TLRPC.Document sticker;
if (stickerSet.cover != null) {
sticker = stickerSet.cover;
} else if (!stickerSet.covers.isEmpty()) {
sticker = stickerSet.covers.get(0);
} else {
return;
if (stickerSet != null && stickerSet.set != null) {
TLRPC.PhotoSize thumb = FileLoader.getClosestPhotoSizeWithSize(stickerSet.set.thumbs, 90);
if (thumb != null) {
TLRPC.Document sticker;
if (stickerSet.cover != null) {
sticker = stickerSet.cover;
} else if (!stickerSet.covers.isEmpty()) {
sticker = stickerSet.covers.get(0);
} else {
return;
}
loadStickerSetThumbInternal(thumb, stickerSet, sticker, stickerSet.set.thumb_version);
}
loadStickerSetThumbInternal(thumb, stickerSet, sticker, stickerSet.set.thumb_version);
}
}
@ -6923,14 +6939,14 @@ public class MediaDataController extends BaseController {
}
public void getEmojiSuggestions(String[] langCodes, String keyword, boolean fullMatch, KeywordResultCallback callback, boolean allowAnimated) {
getEmojiSuggestions(langCodes, keyword, fullMatch, callback, null, allowAnimated, null);
getEmojiSuggestions(langCodes, keyword, fullMatch, callback, null, allowAnimated, false, null);
}
public void getEmojiSuggestions(String[] langCodes, String keyword, boolean fullMatch, KeywordResultCallback callback, final CountDownLatch sync, boolean allowAnimated) {
getEmojiSuggestions(langCodes, keyword, fullMatch, callback, sync, allowAnimated, null);
getEmojiSuggestions(langCodes, keyword, fullMatch, callback, sync, allowAnimated, false, null);
}
public void getEmojiSuggestions(String[] langCodes, String keyword, boolean fullMatch, KeywordResultCallback callback, final CountDownLatch sync, boolean allowAnimated, Integer maxAnimatedPerEmoji) {
public void getEmojiSuggestions(String[] langCodes, String keyword, boolean fullMatch, KeywordResultCallback callback, final CountDownLatch sync, boolean allowAnimated, boolean allowTopicIcons, Integer maxAnimatedPerEmoji) {
if (callback == null) {
return;
}
@ -7042,7 +7058,7 @@ public class MediaDataController extends BaseController {
});
String aliasFinal = alias;
if (allowAnimated && SharedConfig.suggestAnimatedEmoji) {
fillWithAnimatedEmoji(result, maxAnimatedPerEmoji, () -> {
fillWithAnimatedEmoji(result, maxAnimatedPerEmoji, allowTopicIcons, () -> {
if (sync != null) {
callback.run(result, aliasFinal);
sync.countDown();
@ -7070,14 +7086,14 @@ public class MediaDataController extends BaseController {
private boolean triedLoadingEmojipacks = false;
public void fillWithAnimatedEmoji(ArrayList<KeywordResult> result, Integer maxAnimatedPerEmojiInput, Runnable onDone) {
public void fillWithAnimatedEmoji(ArrayList<KeywordResult> result, Integer maxAnimatedPerEmojiInput, boolean allowTopicIcons, Runnable onDone) {
if (result == null || result.isEmpty()) {
if (onDone != null) {
onDone.run();
}
return;
}
final ArrayList<TLRPC.TL_messages_stickerSet>[] emojiPacks = new ArrayList[2];
final ArrayList<TLRPC.TL_messages_stickerSet>[] emojiPacks = new ArrayList[1];
emojiPacks[0] = getStickerSets(TYPE_EMOJIPACKS);
final Runnable fillRunnable = () -> {
ArrayList<TLRPC.StickerSetCovered> featuredSets = getFeaturedEmojiSets();
@ -7085,13 +7101,29 @@ public class MediaDataController extends BaseController {
ArrayList<TLRPC.Document> animatedEmoji = new ArrayList<>();
final int maxAnimatedPerEmoji = maxAnimatedPerEmojiInput == null ? (result.size() > 5 ? 1 : (result.size() > 2 ? 2 : 3)) : maxAnimatedPerEmojiInput;
int len = maxAnimatedPerEmojiInput == null ? Math.min(15, result.size()) : result.size();
boolean isPremium = UserConfig.getInstance(currentAccount).isPremium();
String topicIconsName = null;
if (allowTopicIcons) {
topicIconsName = UserConfig.getInstance(currentAccount).defaultTopicIcons;
if (emojiPacks[0] != null) {
TLRPC.TL_messages_stickerSet set = null;
if (topicIconsName != null) {
set = MediaDataController.getInstance(currentAccount).getStickerSetByName(topicIconsName);
if (set == null) {
set = MediaDataController.getInstance(currentAccount).getStickerSetByEmojiOrName(topicIconsName);
}
}
if (set != null) {
emojiPacks[0].add(set);
}
}
}
for (int i = 0; i < len; ++i) {
String emoji = result.get(i).emoji;
if (emoji == null) {
continue;
}
animatedEmoji.clear();
boolean isPremium = UserConfig.getInstance(currentAccount).isPremium();
if (Emoji.recentEmoji != null) {
for (int j = 0; j < Emoji.recentEmoji.size(); ++j) {
if (Emoji.recentEmoji.get(j).startsWith("animated_")) {
@ -7099,8 +7131,9 @@ public class MediaDataController extends BaseController {
long documentId = Long.parseLong(Emoji.recentEmoji.get(j).substring(9));
TLRPC.Document document = AnimatedEmojiDrawable.findDocument(currentAccount, documentId);
if (document != null &&
(isPremium || MessageObject.isFreeEmoji(document)) &&
emoji.equals(MessageObject.findAnimatedEmojiEmoticon(document, null))) {
emoji.equals(MessageObject.findAnimatedEmojiEmoticon(document, null)) &&
(isPremium || MessageObject.isFreeEmoji(document))
) {
animatedEmoji.add(document);
}
} catch (Exception ignore) {
@ -7127,7 +7160,7 @@ public class MediaDataController extends BaseController {
}
}
if (attribute != null && emoji.equals(attribute.alt) && (isPremium || attribute.free)) {
if (attribute != null && emoji.equals(attribute.alt) && (isPremium || attribute.free || set.set != null && set.set.short_name != null && set.set.short_name.equals(topicIconsName))) {
boolean duplicate = false;
for (int l = 0; l < animatedEmoji.size(); ++l) {
if (animatedEmoji.get(l).id == document.id) {
@ -7172,7 +7205,7 @@ public class MediaDataController extends BaseController {
}
}
if (attribute != null && emoji.equals(attribute.alt) && (isPremium || attribute.free)) {
if (attribute != null && emoji.equals(attribute.alt) && (isPremium || attribute.free || set.set != null && set.set.short_name != null && set.set.short_name.equals(topicIconsName))) {
boolean duplicate = false;
for (int l = 0; l < animatedEmoji.size(); ++l) {
if (animatedEmoji.get(l).id == document.id) {

View File

@ -28,7 +28,6 @@ import android.text.style.URLSpan;
import android.text.util.Linkify;
import android.util.Base64;
import androidx.annotation.IntDef;
import androidx.collection.LongSparseArray;
import org.telegram.PhoneFormat.PhoneFormat;
@ -42,7 +41,6 @@ import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Cells.ChatMessageCell;
import org.telegram.ui.Components.AnimatedEmojiDrawable;
import org.telegram.ui.Components.AnimatedEmojiSpan;
import org.telegram.ui.Components.EmojiView;
import org.telegram.ui.Components.Forum.ForumBubbleDrawable;
import org.telegram.ui.Components.Forum.ForumUtilities;
import org.telegram.ui.Components.Reactions.ReactionsLayoutInBubble;
@ -62,8 +60,6 @@ import org.telegram.ui.Components.spoilers.SpoilerEffect;
import java.io.BufferedReader;
import java.io.File;
import java.io.StringReader;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.net.URLEncoder;
import java.util.AbstractMap;
import java.util.ArrayList;
@ -252,7 +248,7 @@ public class MessageObject {
// forwarding preview params
public boolean hideSendersName;
public TLRPC.Peer sendAsPeer;
public ForumBubbleDrawable[] topicIconDrawable = new ForumBubbleDrawable[1];
public Drawable[] topicIconDrawable = new Drawable[1];
static final String[] excludeWords = new String[]{
" vs. ",
@ -273,6 +269,7 @@ public class MessageObject {
public Drawable customAvatarDrawable;
private byte[] randomWaveform;
public boolean drawServiceWithDefaultTypeface;
public static boolean hasUnreadReactions(TLRPC.Message message) {
if (message == null) {
@ -305,12 +302,16 @@ public class MessageObject {
return false;
}
public static int getTopicId(TLRPC.Message message) {
private static int getTopicId(TLRPC.Message message) {
return getTopicId(message, false);
}
public static int getTopicId(TLRPC.Message message, boolean sureIsForum) {
if (message != null && message.action instanceof TLRPC.TL_messageActionTopicCreate) {
return message.id;
}
if (message == null || message.reply_to == null || !message.reply_to.forum_topic) {
return 0;
return sureIsForum ? 1 : 0; // 1 = general topic
}
if (message instanceof TLRPC.TL_messageService && !(message.action instanceof TLRPC.TL_messageActionPinMessage)) {
int topicId = message.reply_to.reply_to_msg_id;
@ -1334,12 +1335,9 @@ public class MessageObject {
boolean large = emojiOnlyCount == animatedEmojiCount;
int cacheType = -1;
TextPaint emojiPaint;
switch (emojiOnlyCount) {
switch (Math.max(emojiOnlyCount, animatedEmojiCount)) {
case 0:
case 1:
cacheType = AnimatedEmojiDrawable.CACHE_TYPE_MESSAGES_LARGE;
emojiPaint = large ? Theme.chat_msgTextPaintEmoji[0] : Theme.chat_msgTextPaintEmoji[2];
break;
case 2:
cacheType = AnimatedEmojiDrawable.CACHE_TYPE_MESSAGES_LARGE;
emojiPaint = large ? Theme.chat_msgTextPaintEmoji[0] : Theme.chat_msgTextPaintEmoji[2];
@ -1855,7 +1853,11 @@ public class MessageObject {
}
} else if (event.action instanceof TLRPC.TL_channelAdminLogEventActionDeleteMessage) {
message = ((TLRPC.TL_channelAdminLogEventActionDeleteMessage) event.action).message;
messageText = replaceWithLink(LocaleController.getString("EventLogDeletedMessages", R.string.EventLogDeletedMessages), "un1", fromUser);
if (fromUser != null && fromUser.id == MessagesController.getInstance(currentAccount).telegramAntispamUserId) {
messageText = LocaleController.getString("EventLogDeletedMessages", R.string.EventLogDeletedMessages).replace("un1", UserObject.getUserName(fromUser));
} else {
messageText = replaceWithLink(LocaleController.getString("EventLogDeletedMessages", R.string.EventLogDeletedMessages), "un1", fromUser);
}
} else if (event.action instanceof TLRPC.TL_channelAdminLogEventActionChangeLinkedChat) {
long newChatId = ((TLRPC.TL_channelAdminLogEventActionChangeLinkedChat) event.action).new_value;
long oldChatId = ((TLRPC.TL_channelAdminLogEventActionChangeLinkedChat) event.action).prev_value;
@ -2284,12 +2286,18 @@ public class MessageObject {
messageText = replaceWithLink(messageText, "un2", createTopic.topic);
} else if (event.action instanceof TLRPC.TL_channelAdminLogEventActionEditTopic) {
TLRPC.TL_channelAdminLogEventActionEditTopic editTopic = (TLRPC.TL_channelAdminLogEventActionEditTopic) event.action;
messageText = replaceWithLink(
LocaleController.formatString("EventLogEditTopic", R.string.EventLogEditTopic),
"un1", fromUser
);
messageText = replaceWithLink(messageText, "un2", editTopic.prev_topic);
messageText = replaceWithLink(messageText, "un3", editTopic.new_topic);
if (editTopic.prev_topic instanceof TLRPC.TL_forumTopic && editTopic.new_topic instanceof TLRPC.TL_forumTopic &&
((TLRPC.TL_forumTopic) editTopic.prev_topic).hidden != ((TLRPC.TL_forumTopic) editTopic.new_topic).hidden) {
String text = ((TLRPC.TL_forumTopic) editTopic.new_topic).hidden ? LocaleController.getString("TopicHidden2", R.string.TopicHidden2) : LocaleController.getString("TopicShown2", R.string.TopicShown2);
messageText = replaceWithLink(text, "%s", fromUser);
} else {
messageText = replaceWithLink(
LocaleController.getString("EventLogEditTopic", R.string.EventLogEditTopic),
"un1", fromUser
);
messageText = replaceWithLink(messageText, "un2", editTopic.prev_topic);
messageText = replaceWithLink(messageText, "un3", editTopic.new_topic);
}
} else if (event.action instanceof TLRPC.TL_channelAdminLogEventActionDeleteTopic) {
TLRPC.TL_channelAdminLogEventActionDeleteTopic deleteTopic = (TLRPC.TL_channelAdminLogEventActionDeleteTopic) event.action;
messageText = replaceWithLink(
@ -2337,11 +2345,13 @@ public class MessageObject {
if (message != null) {
message.out = false;
message.realId = message.id;
message.id = mid[0]++;
message.flags &= ~TLRPC.MESSAGE_FLAG_REPLY;
message.reply_to = null;
message.flags = message.flags & ~TLRPC.MESSAGE_FLAG_EDITED;
MessageObject messageObject = new MessageObject(currentAccount, message, null, null, true, true, eventId);
messageObject.currentEvent = event;
if (messageObject.contentType >= 0) {
if (mediaController.isPlayingMessage(messageObject)) {
MessageObject player = mediaController.getPlayingMessageObject();
@ -3081,6 +3091,7 @@ public class MessageObject {
fromChat = getChat(chats, sChats, messageOwner.from_id.channel_id);
}
TLObject fromObject = fromUser != null ? fromUser : fromChat;
drawServiceWithDefaultTypeface = false;
if (messageOwner instanceof TLRPC.TL_messageService) {
if (messageOwner.action != null) {
@ -3347,6 +3358,22 @@ public class MessageObject {
} else {
messageText = LocaleController.getString("ActionTTLChannelDisabled", R.string.ActionTTLChannelDisabled);
}
} else if (action.auto_setting_from != 0) {
drawServiceWithDefaultTypeface = true;
if (action.auto_setting_from == UserConfig.getInstance(currentAccount).clientUserId) {
messageText = AndroidUtilities.replaceTags(LocaleController.formatString("AutoDeleteGlobalActionFromYou", R.string.AutoDeleteGlobalActionFromYou, LocaleController.formatTTLString(action.period)));
} else {
TLObject object = null;
if (users != null) {
users.get(action.auto_setting_from);
}
if (object == null && chats != null) {
object = chats.get(action.auto_setting_from);
} else {
object = fromObject;
}
messageText = replaceWithLink(AndroidUtilities.replaceTags(LocaleController.formatString("AutoDeleteGlobalAction", R.string.AutoDeleteGlobalAction, LocaleController.formatTTLString(action.period))), "un1", object);
}
} else if (action.period != 0) {
if (isOut()) {
messageText = LocaleController.formatString("ActionTTLYouChanged", R.string.ActionTTLYouChanged, LocaleController.formatTTLString(action.period));
@ -3458,7 +3485,15 @@ public class MessageObject {
name = "DELETED";
}
if ((messageOwner.action.flags & 4) > 0) {
if ((messageOwner.action.flags & 8) > 0) {
if (((TLRPC.TL_messageActionTopicEdit) messageOwner.action).hidden) {
messageText = replaceWithLink(LocaleController.getString("TopicHidden2", R.string.TopicHidden2), "%s", object);
messageTextShort = LocaleController.getString("TopicHidden", R.string.TopicHidden);
} else {
messageText = replaceWithLink(LocaleController.getString("TopicShown2", R.string.TopicShown2), "%s", object);
messageTextShort = LocaleController.getString("TopicShown", R.string.TopicShown);
}
} else if ((messageOwner.action.flags & 4) > 0) {
if (((TLRPC.TL_messageActionTopicEdit) messageOwner.action).closed) {
messageText = replaceWithLink(LocaleController.getString("TopicClosed2", R.string.TopicClosed2), "%s", object);
messageTextShort = LocaleController.getString("TopicClosed", R.string.TopicClosed);
@ -3905,7 +3940,7 @@ public class MessageObject {
if (document != null) {
return document.mime_type;
} else if (getMedia(messageOwner) instanceof TLRPC.TL_messageMediaInvoice) {
TLRPC.WebDocument photo = ((TLRPC.TL_messageMediaInvoice) getMedia(messageOwner)).photo;
TLRPC.WebDocument photo = ((TLRPC.TL_messageMediaInvoice) getMedia(messageOwner)).webPhoto;
if (photo != null) {
return photo.mime_type;
}
@ -5448,23 +5483,27 @@ public class MessageObject {
return messageOwner.out;
}
Boolean isOutOwnerCached;
public boolean isOutOwner() {
if (preview) {
return true;
}
if (isOutOwnerCached != null) {
return isOutOwnerCached;
}
TLRPC.Chat chat = messageOwner.peer_id != null && messageOwner.peer_id.channel_id != 0 ? getChat(null, null, messageOwner.peer_id.channel_id) : null;
if (!messageOwner.out || !(messageOwner.from_id instanceof TLRPC.TL_peerUser) && (!(messageOwner.from_id instanceof TLRPC.TL_peerChannel) || ChatObject.isChannel(chat) && !chat.megagroup) || messageOwner.post) {
return false;
return isOutOwnerCached = false;
}
if (messageOwner.fwd_from == null) {
return true;
return isOutOwnerCached= true;
}
long selfUserId = UserConfig.getInstance(currentAccount).getClientUserId();
if (getDialogId() == selfUserId) {
return messageOwner.fwd_from.from_id instanceof TLRPC.TL_peerUser && messageOwner.fwd_from.from_id.user_id == selfUserId && (messageOwner.fwd_from.saved_from_peer == null || messageOwner.fwd_from.saved_from_peer.user_id == selfUserId)
return isOutOwnerCached = messageOwner.fwd_from.from_id instanceof TLRPC.TL_peerUser && messageOwner.fwd_from.from_id.user_id == selfUserId && (messageOwner.fwd_from.saved_from_peer == null || messageOwner.fwd_from.saved_from_peer.user_id == selfUserId)
|| messageOwner.fwd_from.saved_from_peer != null && messageOwner.fwd_from.saved_from_peer.user_id == selfUserId && (messageOwner.fwd_from.from_id == null || messageOwner.fwd_from.from_id.user_id == selfUserId);
}
return messageOwner.fwd_from.saved_from_peer == null || messageOwner.fwd_from.saved_from_peer.user_id == selfUserId;
return isOutOwnerCached = messageOwner.fwd_from.saved_from_peer == null || messageOwner.fwd_from.saved_from_peer.user_id == selfUserId;
}
public boolean needDrawAvatar() {
@ -5481,6 +5520,9 @@ public class MessageObject {
if (customAvatarDrawable != null) {
return true;
}
if (isSponsored() && (isFromChat() || sponsoredShowPeerPhoto)) {
return true;
}
return !isSponsored() && (isFromChat() && isFromUser() || isFromGroup() || eventId != 0 || messageOwner.fwd_from != null && messageOwner.fwd_from.saved_from_peer != null);
}
@ -5563,6 +5605,35 @@ public class MessageObject {
return 0;
}
public TLObject getFromPeerObject() {
if (messageOwner != null) {
if (messageOwner.from_id instanceof TLRPC.TL_peerChannel_layer131 ||
messageOwner.from_id instanceof TLRPC.TL_peerChannel) {
return MessagesController.getInstance(currentAccount).getChat(messageOwner.from_id.channel_id);
} else if (
messageOwner.from_id instanceof TLRPC.TL_peerUser_layer131 ||
messageOwner.from_id instanceof TLRPC.TL_peerUser
) {
return MessagesController.getInstance(currentAccount).getUser(messageOwner.from_id.user_id);
} else if (
messageOwner.from_id instanceof TLRPC.TL_peerChat_layer131 ||
messageOwner.from_id instanceof TLRPC.TL_peerChat
) {
return MessagesController.getInstance(currentAccount).getChat(messageOwner.from_id.chat_id);
}
}
return null;
}
public static String getPeerObjectName(TLObject object) {
if (object instanceof TLRPC.User) {
return UserObject.getUserName((TLRPC.User) object);
} else if (object instanceof TLRPC.Chat) {
return ((TLRPC.Chat) object).title;
}
return "DELETED";
}
public boolean isFromUser() {
return messageOwner.from_id instanceof TLRPC.TL_peerUser && !messageOwner.post;
}

View File

@ -371,6 +371,8 @@ public class MessagesController extends BaseController implements NotificationCe
public int reactionsInChatMax;
public int forumUpgradeParticipantsMin;
public int topicsPinnedLimit;
public long telegramAntispamUserId;
public int telegramAntispamGroupSizeMin;
public int uploadMaxFileParts;
public int uploadMaxFilePartsPremium;
@ -588,6 +590,14 @@ public class MessagesController extends BaseController implements NotificationCe
return chatLocal != null && chatLocal.forum;
}
public boolean isForum(MessageObject msg) {
return msg != null && isForum(msg.getDialogId());
}
public boolean isForum(TLRPC.Message msg) {
return msg != null && isForum(MessageObject.getDialogId(msg));
}
public void markAllTopicsAsRead(long did) {
getMessagesStorage().loadTopics(did, topics -> {
AndroidUtilities.runOnUIThread(() -> {
@ -1117,6 +1127,8 @@ public class MessagesController extends BaseController implements NotificationCe
transcribeButtonPressed = mainPreferences.getInt("transcribeButtonPressed", 0);
forumUpgradeParticipantsMin = mainPreferences.getInt("forumUpgradeParticipantsMin", 200);
topicsPinnedLimit = mainPreferences.getInt("topicsPinnedLimit", 3);
telegramAntispamUserId = mainPreferences.getLong("telegramAntispamUserId", -1);
telegramAntispamGroupSizeMin = mainPreferences.getInt("telegramAntispamGroupSizeMin", 100);
BuildVars.GOOGLE_AUTH_CLIENT_ID = mainPreferences.getString("googleAuthClientId", BuildVars.GOOGLE_AUTH_CLIENT_ID);
Set<String> currencySet = mainPreferences.getStringSet("directPaymentsCurrency", null);
@ -1335,7 +1347,6 @@ public class MessagesController extends BaseController implements NotificationCe
sendLoadPeersRequest(req3, requests, pinnedDialogs, pinnedRemoteDialogs, users, chats, filtersToSave, filtersToDelete, filtersOrder, filterDialogRemovals, filterUserRemovals, filtersUnreadCounterReset);
}
//no
TLRPC.TL_messages_getPeerDialogs req4 = null;
for (HashMap.Entry<Long, TLRPC.InputPeer> entry : dialogsToLoadMap.entrySet()) {
if (req4 == null) {
@ -2644,6 +2655,31 @@ public class MessagesController extends BaseController implements NotificationCe
}
}
}
case "telegram_antispam_user_id": {
if (value.value instanceof TLRPC.TL_jsonString) {
TLRPC.TL_jsonString string = (TLRPC.TL_jsonString) value.value;
try {
long number = Long.parseLong(string.value);
if (number != telegramAntispamUserId) {
telegramAntispamUserId = number;
editor.putLong("telegramAntispamUserId", telegramAntispamUserId);
changed = true;
}
} catch (Exception e) {
FileLog.e(e);
}
}
}
case "telegram_antispam_group_size_min": {
if (value.value instanceof TLRPC.TL_jsonNumber) {
TLRPC.TL_jsonNumber number = (TLRPC.TL_jsonNumber) value.value;
if (number.value != telegramAntispamGroupSizeMin) {
telegramAntispamGroupSizeMin = (int) number.value;
editor.putInt("telegramAntispamGroupSizeMin", telegramAntispamGroupSizeMin);
changed = true;
}
}
}
}
}
if (changed) {
@ -3029,7 +3065,6 @@ public class MessagesController extends BaseController implements NotificationCe
inputPeer.chat_id = -id;
}
} else {
TLRPC.User user = getUser(id);
inputPeer = new TLRPC.TL_peerUser();
inputPeer.user_id = id;
}
@ -3618,6 +3653,15 @@ public class MessagesController extends BaseController implements NotificationCe
return users.get(id);
}
public TLObject getUserOrChat(long dialogId) {
if (users.containsKey(dialogId)) {
return users.get(dialogId);
} else if (chats.containsKey(-dialogId)) {
return chats.get(-dialogId);
}
return null;
}
public TLObject getUserOrChat(String username) {
if (username == null || username.length() == 0) {
return null;
@ -3982,7 +4026,9 @@ public class MessagesController extends BaseController implements NotificationCe
addOrRemoveActiveVoiceChat(chat);
}
if (oldChat != null && oldChat.forum != chat.forum) {
getNotificationCenter().postNotificationName(NotificationCenter.chatSwithcedToForum, chat.id);
AndroidUtilities.runOnUIThread(() -> {
getNotificationCenter().postNotificationName(NotificationCenter.chatSwithcedToForum, chat.id);
});
}
}
@ -4133,7 +4179,6 @@ public class MessagesController extends BaseController implements NotificationCe
if (did == 0 && (dialogs == null || dialogs.isEmpty())) {
return;
}
//probably
TLRPC.TL_messages_getPeerDialogs req = new TLRPC.TL_messages_getPeerDialogs();
if (dialogs != null) {
for (int a = 0; a < dialogs.size(); a++) {
@ -4376,11 +4421,18 @@ public class MessagesController extends BaseController implements NotificationCe
getMediaDataController().getGroupStickerSetById(res.full_chat.stickerset);
}
getNotificationCenter().postNotificationName(NotificationCenter.chatInfoDidLoad, res.full_chat, classGuid, false, true);
if ((res.full_chat.flags & 2048) != 0) {
TLRPC.Dialog dialog = dialogs_dict.get(-chatId);
if (dialog != null && dialog.folder_id != res.full_chat.folder_id) {
dialog.folder_id = res.full_chat.folder_id;
sortDialogs(null);
TLRPC.Dialog dialog = dialogs_dict.get(-chatId);
if (dialog != null) {
if ((res.full_chat.flags & 2048) != 0) {
if (dialog.folder_id != res.full_chat.folder_id) {
dialog.folder_id = res.full_chat.folder_id;
sortDialogs(null);
getNotificationCenter().postNotificationName(NotificationCenter.dialogsNeedReload);
}
}
if (dialog.ttl_period != res.full_chat.ttl_period) {
dialog.ttl_period = res.full_chat.ttl_period;
getNotificationCenter().postNotificationName(NotificationCenter.dialogsNeedReload);
}
}
@ -4456,13 +4508,18 @@ public class MessagesController extends BaseController implements NotificationCe
getNotificationCenter().postNotificationName(NotificationCenter.botInfoDidLoad, userFull.bot_info, classGuid);
}
getNotificationCenter().postNotificationName(NotificationCenter.userInfoDidLoad, user.id, userFull);
if ((userFull.flags & 2048) != 0) {
TLRPC.Dialog dialog = dialogs_dict.get(user.id);
if (dialog != null && dialog.folder_id != userFull.folder_id) {
TLRPC.Dialog dialog = dialogs_dict.get(user.id);
if (dialog != null) {
if ((userFull.flags & 2048) != 0 && dialog.folder_id != userFull.folder_id) {
dialog.folder_id = userFull.folder_id;
sortDialogs(null);
getNotificationCenter().postNotificationName(NotificationCenter.dialogsNeedReload);
}
if ((userFull.flags & 16384) != 0 && dialog.ttl_period != userFull.ttl_period) {
dialog.ttl_period = userFull.ttl_period;
getNotificationCenter().postNotificationName(NotificationCenter.dialogsNeedReload);
}
}
});
} else {
@ -5892,28 +5949,31 @@ public class MessagesController extends BaseController implements NotificationCe
});
TLRPC.ChatFull chatFull = null;
TLRPC.UserFull userFull = null;
TLRPC.Dialog dialog = getMessagesController().dialogs_dict.get(did);
if (dialog != null) {
dialog.ttl_period = ttl;
}
getMessagesStorage().setDialogTtl(did, ttl);
if (did > 0) {
userFull = getUserFull(did);
if (userFull == null) {
return;
if (userFull != null) {
userFull.ttl_period = ttl;
userFull.flags |= 16384;
}
userFull.ttl_period = ttl;
userFull.flags |= 16384;
} else {
chatFull = getChatFull(-did);
if (chatFull == null) {
return;
}
chatFull.ttl_period = ttl;
if (chatFull instanceof TLRPC.TL_channelFull) {
chatFull.flags |= 16777216;
} else {
chatFull.flags |= 16384;
if (chatFull != null) {
chatFull.ttl_period = ttl;
if (chatFull instanceof TLRPC.TL_channelFull) {
chatFull.flags |= 16777216;
} else {
chatFull.flags |= 16384;
}
}
}
if (chatFull != null) {
getNotificationCenter().postNotificationName(NotificationCenter.chatInfoDidLoad, chatFull, 0, false, false);
} else {
} else if (userFull != null) {
getNotificationCenter().postNotificationName(NotificationCenter.userInfoDidLoad, did, userFull);
}
}
@ -6761,7 +6821,6 @@ public class MessagesController extends BaseController implements NotificationCe
chatsDict.put(c.id, c);
}
//no
TLRPC.TL_messages_getPeerDialogs req1 = new TLRPC.TL_messages_getPeerDialogs();
TLRPC.TL_inputDialogPeer peer = new TLRPC.TL_inputDialogPeer();
if (res.peer.user_id != 0) {
@ -7359,7 +7418,6 @@ public class MessagesController extends BaseController implements NotificationCe
getConnectionsManager().bindRequestToGuid(reqId, classGuid);
} else {
if (loadDialog && (load_type == 3 || load_type == 2) && last_message_id == 0) {
//probably--
TLRPC.TL_messages_getPeerDialogs req = new TLRPC.TL_messages_getPeerDialogs();
TLRPC.InputPeer inputPeer = getInputPeer(dialogId);
TLRPC.TL_inputDialogPeer inputDialogPeer = new TLRPC.TL_inputDialogPeer();
@ -8126,7 +8184,6 @@ public class MessagesController extends BaseController implements NotificationCe
FileLog.d("load unknown dialog " + dialogId);
}
//probably--
TLRPC.TL_messages_getPeerDialogs req = new TLRPC.TL_messages_getPeerDialogs();
TLRPC.TL_inputDialogPeer inputDialogPeer = new TLRPC.TL_inputDialogPeer();
inputDialogPeer.peer = peer;
@ -10162,10 +10219,14 @@ public class MessagesController extends BaseController implements NotificationCe
}
}
public int createChat(String title, ArrayList<Long> selectedContacts, String about, int type, boolean forImport, Location location, String locationAddress, BaseFragment fragment) {
public int createChat(String title, ArrayList<Long> selectedContacts, String about, int type, boolean forImport, Location location, String locationAddress, int ttlPeriod, BaseFragment fragment) {
if (type == ChatObject.CHAT_TYPE_CHAT && !forImport) {
TLRPC.TL_messages_createChat req = new TLRPC.TL_messages_createChat();
req.title = title;
if (ttlPeriod > 0) {
req.ttl_period = ttlPeriod;
req.flags |= 1;
}
for (int a = 0; a < selectedContacts.size(); a++) {
TLRPC.User user = getUser(selectedContacts.get(a));
if (user == null) {
@ -10690,6 +10751,78 @@ public class MessagesController extends BaseController implements NotificationCe
deleteParticipantFromChat(chatId, user, null, false, false);
}
public void deleteParticipantFromChat(long chatId, TLRPC.InputPeer peer) {
deleteParticipantFromChat(chatId, peer, false, false);
}
public void deleteParticipantFromChat(long chatId, TLRPC.InputPeer peer, boolean forceDelete, boolean revoke) {
if (peer == null) {
return;
}
TLObject request;
TLRPC.Chat ownerChat = getChat(chatId);
boolean self = peer instanceof TLRPC.TL_inputPeerUser && UserObject.isUserSelf(getMessagesController().getUser(peer.user_id));
boolean isChannel = ChatObject.isChannel(ownerChat);
if (isChannel) {
if (self) {
if (ownerChat.creator && forceDelete) {
TLRPC.TL_channels_deleteChannel req = new TLRPC.TL_channels_deleteChannel();
req.channel = getInputChannel(ownerChat);
request = req;
} else {
TLRPC.TL_channels_leaveChannel req = new TLRPC.TL_channels_leaveChannel();
req.channel = getInputChannel(ownerChat);
request = req;
}
} else {
TLRPC.TL_channels_editBanned req = new TLRPC.TL_channels_editBanned();
req.channel = getInputChannel(ownerChat);
req.participant = peer;
req.banned_rights = new TLRPC.TL_chatBannedRights();
req.banned_rights.view_messages = true;
req.banned_rights.send_media = true;
req.banned_rights.send_messages = true;
req.banned_rights.send_stickers = true;
req.banned_rights.send_gifs = true;
req.banned_rights.send_games = true;
req.banned_rights.send_inline = true;
req.banned_rights.embed_links = true;
req.banned_rights.pin_messages = true;
req.banned_rights.send_polls = true;
req.banned_rights.invite_users = true;
req.banned_rights.change_info = true;
request = req;
}
} else {
if (forceDelete) {
TLRPC.TL_messages_deleteChat req = new TLRPC.TL_messages_deleteChat();
req.chat_id = chatId;
getConnectionsManager().sendRequest(req, (response, error) -> {
});
return;
}
TLRPC.TL_messages_deleteChatUser req = new TLRPC.TL_messages_deleteChatUser();
req.chat_id = chatId;
req.user_id = (TLRPC.InputUser) getInputUser(peer);
req.revoke_history = true;
request = req;
}
if (self) {
deleteDialog(-chatId, 0, revoke);
}
getConnectionsManager().sendRequest(request, (response, error) -> {
if (error != null) {
return;
}
TLRPC.Updates updates = (TLRPC.Updates) response;
processUpdates(updates, false);
if (isChannel && !self) {
AndroidUtilities.runOnUIThread(() -> loadFullChat(chatId, 0, true), 1000);
}
}, ConnectionsManager.RequestFlagInvokeAfter);
}
public void deleteParticipantFromChat(long chatId, TLRPC.User user, TLRPC.Chat chat, boolean forceDelete, boolean revoke) {
if (user == null && chat == null) {
return;
@ -11272,7 +11405,6 @@ public class MessagesController extends BaseController implements NotificationCe
gettingUnknownChannels.put(channel.id, true);
//no
TLRPC.TL_messages_getPeerDialogs req = new TLRPC.TL_messages_getPeerDialogs();
TLRPC.TL_inputDialogPeer inputDialogPeer = new TLRPC.TL_inputDialogPeer();
inputDialogPeer.peer = inputPeer;
@ -15047,6 +15179,7 @@ public class MessagesController extends BaseController implements NotificationCe
long peerId = MessageObject.getPeerId(updatePeerHistoryTTL.peer);
TLRPC.ChatFull chatFull = null;
TLRPC.UserFull userFull = null;
if (peerId > 0) {
userFull = getUserFull(peerId);
if (userFull != null) {
@ -15083,6 +15216,12 @@ public class MessagesController extends BaseController implements NotificationCe
getNotificationCenter().postNotificationName(NotificationCenter.userInfoDidLoad, peerId, userFull);
getMessagesStorage().updateUserInfo(userFull, false);
}
getMessagesStorage().setDialogTtl(peerId, updatePeerHistoryTTL.ttl_period);
TLRPC.Dialog dialog = dialogs_dict.get(peerId);
if (dialog != null) {
dialog.ttl_period = updatePeerHistoryTTL.ttl_period;
getNotificationCenter().postNotificationName(NotificationCenter.updateInterfaces, 0);
}
} else if (baseUpdate instanceof TLRPC.TL_updatePendingJoinRequests) {
TLRPC.TL_updatePendingJoinRequests update = (TLRPC.TL_updatePendingJoinRequests) baseUpdate;
getMemberRequestsController().onPendingRequestsUpdated(update);
@ -15573,7 +15712,6 @@ public class MessagesController extends BaseController implements NotificationCe
}
if (needReload) {
if (topicId == 0) {
//no
TLRPC.TL_messages_getPeerDialogs req = new TLRPC.TL_messages_getPeerDialogs();
TLRPC.TL_inputDialogPeer inputDialogPeer = new TLRPC.TL_inputDialogPeer();
inputDialogPeer.peer = getInputPeer(dialogId);
@ -16744,7 +16882,7 @@ public class MessagesController extends BaseController implements NotificationCe
});
}
public void checkIsInChat(TLRPC.Chat chat, TLRPC.User user, IsInChatCheckedCallback callback) {
public void checkIsInChat(boolean tryCacheFirst, TLRPC.Chat chat, TLRPC.User user, IsInChatCheckedCallback callback) {
if (chat == null || user == null) {
if (callback != null) {
callback.run(false, null, null);
@ -16752,6 +16890,30 @@ public class MessagesController extends BaseController implements NotificationCe
return;
}
if (chat.megagroup || ChatObject.isChannel(chat)) {
if (tryCacheFirst) {
TLRPC.ChatFull chatFull = getChatFull(chat.id);
if (chatFull != null) {
TLRPC.ChatParticipant userParticipant = null;
if (chatFull.participants != null && chatFull.participants.participants != null) {
final int count = chatFull.participants.participants.size();
for (int i = 0; i < count; ++i) {
TLRPC.ChatParticipant participant = chatFull.participants.participants.get(i);
if (participant != null && participant.user_id == user.id) {
userParticipant = participant;
break;
}
}
}
if (callback != null && userParticipant != null) {
callback.run(
userParticipant != null,
chatFull.participants != null && chatFull.participants.admin_id == user.id ? ChatRightsEditActivity.emptyAdminRights(true) : null,
null
);
return;
}
}
}
TLRPC.TL_channels_getParticipant req = new TLRPC.TL_channels_getParticipant();
req.channel = getInputChannel(chat.id);
req.participant = getInputPeer(user);
@ -16781,9 +16943,9 @@ public class MessagesController extends BaseController implements NotificationCe
}
if (callback != null) {
callback.run(
userParticipant != null,
chatFull.participants != null && chatFull.participants.admin_id == user.id ? ChatRightsEditActivity.emptyAdminRights(true) : null,
null
userParticipant != null,
chatFull.participants != null && chatFull.participants.admin_id == user.id ? ChatRightsEditActivity.emptyAdminRights(true) : null,
null
);
}
} else {
@ -16874,4 +17036,38 @@ public class MessagesController extends BaseController implements NotificationCe
return unreadCount;
}
private boolean requestingContactToken;
private TLRPC.TL_exportedContactToken cachedContactToken;
public TLRPC.TL_exportedContactToken getCachedContactToken() {
if (cachedContactToken != null && cachedContactToken.expires > System.currentTimeMillis() / 1000) {
return cachedContactToken;
}
return null;
}
public void requestContactToken(Utilities.Callback<TLRPC.TL_exportedContactToken> callback) {
requestContactToken(0, callback);
}
public void requestContactToken(long minDuration, Utilities.Callback<TLRPC.TL_exportedContactToken> callback) {
if (callback == null || requestingContactToken) {
return;
}
if (cachedContactToken != null && cachedContactToken.expires > System.currentTimeMillis() / 1000) {
callback.run(cachedContactToken);
return;
}
requestingContactToken = true;
final long start = System.currentTimeMillis();
getConnectionsManager().sendRequest(new TLRPC.TL_contacts_exportContactToken(), (res, err) -> {
if (res instanceof TLRPC.TL_exportedContactToken) {
cachedContactToken = (TLRPC.TL_exportedContactToken) res;
AndroidUtilities.runOnUIThread(() -> {
callback.run(cachedContactToken);
requestingContactToken = false;
}, Math.max(0, minDuration - (System.currentTimeMillis() - start)));
} else {
requestingContactToken = false;
}
});
}
}

View File

@ -10,6 +10,7 @@ package org.telegram.messenger;
import android.os.SystemClock;
import android.util.SparseArray;
import android.view.View;
import androidx.annotation.UiThread;
@ -264,6 +265,7 @@ public class NotificationCenter {
public static final int permissionsGranted = totalEvents++;
public static int topicsDidLoaded = totalEvents++;
public static int chatSwithcedToForum = totalEvents++;
public static int didUpdateGlobalAutoDeleteTimer = totalEvents++;
private SparseArray<ArrayList<NotificationCenterDelegate>> observers = new SparseArray<>();
private SparseArray<ArrayList<NotificationCenterDelegate>> removeAfterBroadcast = new SparseArray<>();
@ -510,9 +512,6 @@ public class NotificationCenter {
if (!allowDuringAnimation && isAnimationInProgress()) {
DelayedPost delayedPost = new DelayedPost(id, args);
delayedPosts.add(delayedPost);
if (BuildVars.LOGS_ENABLED) {
FileLog.e("delay post notification " + id + " with args count = " + args.length);
}
return;
}
if (!postponeCallbackList.isEmpty()) {
@ -653,4 +652,29 @@ public class NotificationCenter {
time = SystemClock.elapsedRealtime();
}
}
public static void listenEmojiLoading(View view) {
if (view == null) {
return;
}
final NotificationCenterDelegate delegate = (id, account, args) -> {
if (id == NotificationCenter.emojiLoaded) {
if (view != null && view.isAttachedToWindow()) {
view.invalidate();
}
}
};
view.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
@Override
public void onViewAttachedToWindow(View view) {
NotificationCenter.getGlobalInstance().addObserver(delegate, NotificationCenter.emojiLoaded);
}
@Override
public void onViewDetachedFromWindow(View view) {
NotificationCenter.getGlobalInstance().removeObserver(delegate, NotificationCenter.emojiLoaded);
}
});
}
}

View File

@ -856,7 +856,7 @@ public class NotificationsController extends BaseController {
}
long originalDialogId = dialogId;
int topicId = MessageObject.getTopicId(messageObject.messageOwner);
int topicId = MessageObject.getTopicId(messageObject.messageOwner, getMessagesController().isForum(messageObject));
if (dialogId == openedDialogId && ApplicationLoader.isScreenOn) {
if (!isFcm) {
playInChatSound();
@ -919,7 +919,7 @@ public class NotificationsController extends BaseController {
if (messageObject.isReactionPush) {
SparseBooleanArray sparseBooleanArray = new SparseBooleanArray();
sparseBooleanArray.put(mid, true);
getMessagesController().checkUnreadReactions(dialogId, MessageObject.getTopicId(messageObject.messageOwner), sparseBooleanArray);
getMessagesController().checkUnreadReactions(dialogId, topicId, sparseBooleanArray);
}
}
@ -951,7 +951,7 @@ public class NotificationsController extends BaseController {
} else if (added) {
MessageObject messageObject = messageObjects.get(0);
long dialog_id = messageObject.getDialogId();
int topicId = MessageObject.getTopicId(messageObject.messageOwner);
int topicId = MessageObject.getTopicId(messageObject.messageOwner, getMessagesController().isForum(dialog_id));
Boolean isChannel;
if (messageObject.isFcmMessage()) {
isChannel = messageObject.localChannel;
@ -1182,7 +1182,7 @@ public class NotificationsController extends BaseController {
}
long dialog_id = messageObject.getDialogId();
long original_dialog_id = dialog_id;
int topicId = MessageObject.getTopicId(messageObject.messageOwner);
int topicId = MessageObject.getTopicId(messageObject.messageOwner, getMessagesController().isForum(messageObject));
if (messageObject.messageOwner.mentioned) {
dialog_id = messageObject.getFromChatId();
}
@ -1254,7 +1254,7 @@ public class NotificationsController extends BaseController {
}
long dialogId = messageObject.getDialogId();
long originalDialogId = dialogId;
int topicId = MessageObject.getTopicId(messageObject.messageOwner);
int topicId = MessageObject.getTopicId(messageObject.messageOwner, getMessagesController().isForum(messageObject));
long randomId = messageObject.messageOwner.random_id;
if (messageObject.messageOwner.mentioned) {
dialogId = messageObject.getFromChatId();
@ -3428,7 +3428,7 @@ public class NotificationsController extends BaseController {
}
long dialog_id = lastMessageObject.getDialogId();
int topicId = MessageObject.getTopicId(lastMessageObject.messageOwner);
int topicId = MessageObject.getTopicId(lastMessageObject.messageOwner, getMessagesController().isForum(lastMessageObject));
boolean isChannel = false;
long override_dialog_id = dialog_id;
@ -4016,7 +4016,7 @@ public class NotificationsController extends BaseController {
for (int a = 0; a < pushMessages.size(); a++) {
MessageObject messageObject = pushMessages.get(a);
long dialog_id = messageObject.getDialogId();
int topicId = MessageObject.getTopicId(messageObject.messageOwner);
int topicId = MessageObject.getTopicId(messageObject.messageOwner, getMessagesController().isForum(messageObject));
int dismissDate = preferences.getInt("dismissDate" + dialog_id, 0);
if (messageObject.messageOwner.date <= dismissDate) {
continue;
@ -4305,7 +4305,7 @@ public class NotificationsController extends BaseController {
int rowsMid = 0;
for (int a = messageObjects.size() - 1; a >= 0; a--) {
MessageObject messageObject = messageObjects.get(a);
int messageTopicId = MessageObject.getTopicId(messageObject.messageOwner);
int messageTopicId = MessageObject.getTopicId(messageObject.messageOwner, getMessagesController().isForum(messageObject));
if (topicId != messageTopicId) {
continue;
}

View File

@ -1451,7 +1451,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());
params.put("parentObject", "sent_" + messageObject.messageOwner.peer_id.channel_id + "_" + messageObject.getId() + "_" + messageObject.getDialogId());
}
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);
@ -2374,7 +2374,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
ArrayList<TLRPC.Message> arr = new ArrayList<>();
arr.add(newMsg);
getMessagesStorage().putMessages(arr, false, true, false, 0, messageObject.scheduled, MessageObject.getTopicId(newMsg));
getMessagesStorage().putMessages(arr, false, true, false, 0, messageObject.scheduled, MessageObject.getTopicId(newMsg, getMessagesController().isForum(newMsg)));
getMessagesController().getTopicsController().processEditedMessage(newMsg);
messageObject.type = -1;
@ -5570,7 +5570,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
LongSparseArray<SparseArray<TLRPC.MessageReplies>> channelReplies = null;
for (int a = 0; a < updatesArr.size(); a++) {
TLRPC.Update update = updatesArr.get(a);
if (update instanceof TLRPC.TL_updateNewMessage) {
if (update instanceof TLRPC.TL_updateNewMessage && ((TLRPC.TL_updateNewMessage) update).message.action == null) {
final TLRPC.TL_updateNewMessage newMessage = (TLRPC.TL_updateNewMessage) update;
sentMessages.add(message = newMessage.message);
Utilities.stageQueue.postRunnable(() -> getMessagesController().processNewDifferenceParams(-1, newMessage.pts, -1, newMessage.pts_count));
@ -5783,7 +5783,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);
getMessagesStorage().putSentFile(originalPath, sentMessage.media.photo, 0, "sent_" + sentMessage.peer_id.channel_id + "_" + sentMessage.id + "_" + DialogObject.getPeerDialogId(sentMessage.peer_id));
}
if (newMsg.media.photo.sizes.size() == 1 && newMsg.media.photo.sizes.get(0).location instanceof TLRPC.TL_fileLocationUnavailable) {
@ -5843,13 +5843,13 @@ 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);
getMessagesStorage().putSentFile(originalPath, sentMessage.media.document, 2, "sent_" + sentMessage.peer_id.channel_id + "_" + sentMessage.id + "_" + DialogObject.getPeerDialogId(sentMessage.peer_id));
}
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);
getMessagesStorage().putSentFile(originalPath, sentMessage.media.document, 1, "sent_" + sentMessage.peer_id.channel_id + "_" + sentMessage.id + "_" + DialogObject.getPeerDialogId(sentMessage.peer_id));
}
}
@ -7063,7 +7063,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
messageMediaInvoice.title = invoice.title;
messageMediaInvoice.description = invoice.description;
if (invoice.photo != null) {
messageMediaInvoice.photo = invoice.photo;
messageMediaInvoice.webPhoto = invoice.photo;
messageMediaInvoice.flags |= 1;
}
messageMediaInvoice.currency = invoice.currency;

View File

@ -164,7 +164,7 @@ public class SvgHelper {
}
float scale = getScale((int) w, (int) h);
if (placeholderGradient != null) {
if (placeholderGradient[threadIndex] != null && gradientWidth > 0) {
if (drawInBackground) {
long dt = time - lastUpdateTime;
if (dt > 64) {

View File

@ -1,6 +1,7 @@
package org.telegram.messenger;
import android.content.SharedPreferences;
import android.graphics.drawable.Drawable;
import android.text.TextPaint;
import android.text.TextUtils;
import android.util.SparseArray;
@ -21,7 +22,6 @@ import org.telegram.ui.Components.Forum.ForumUtilities;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@ -33,7 +33,8 @@ public class TopicsController extends BaseController {
public static final int TOPIC_FLAG_ICON = 2;
public static final int TOPIC_FLAG_PIN = 4;
public static final int TOPIC_FLAG_CLOSE = 8;
public static final int TOPIC_FLAG_TOTAL_MESSAGES_COUNT = 16;
public static final int TOPIC_FLAG_HIDE = 32;
private static final int MAX_PRELOAD_COUNT = 20;
@ -67,7 +68,7 @@ public class TopicsController extends BaseController {
return;
}
if (BuildVars.DEBUG_PRIVATE_VERSION) {
if (BuildVars.LOGS_ENABLED) {
FileLog.d("load topics " + chatId + " fromCache=" + fromCache + " loadType=" + loadType);
}
topicsIsLoading.put(chatId, 1);
@ -75,7 +76,7 @@ public class TopicsController extends BaseController {
if (fromCache) {
getMessagesStorage().loadTopics(-chatId, topics -> {
AndroidUtilities.runOnUIThread(() -> {
if (BuildVars.DEBUG_PRIVATE_VERSION) {
if (BuildVars.LOGS_ENABLED) {
FileLog.d("loaded from cache " + chatId + " topics_count=" + (topics == null ? 0 : topics.size()));
}
@ -98,7 +99,7 @@ public class TopicsController extends BaseController {
getForumTopics.offset_id = loadOffsets.lastMessageId;
getForumTopics.offset_topic = loadOffsets.lastTopicId;
if (BuildVars.DEBUG_PRIVATE_VERSION) {
if (BuildVars.LOGS_ENABLED) {
FileLog.d("offset_date=" + loadOffsets.lastMessageDate + " offset_id=" + loadOffsets.lastMessageId + " offset_topic=" + loadOffsets.lastTopicId);
}
}
@ -111,7 +112,7 @@ public class TopicsController extends BaseController {
messagesMap.put(topics.messages.get(i).id, topics.messages.get(i));
}
AndroidUtilities.runOnUIThread(() -> {
getMessagesStorage().putUsersAndChats(((TLRPC.TL_messages_forumTopics) response).users, ((TLRPC.TL_messages_forumTopics) response).chats, true, false);
getMessagesStorage().putUsersAndChats(((TLRPC.TL_messages_forumTopics) response).users, ((TLRPC.TL_messages_forumTopics) response).chats, true, true);
getMessagesController().putUsers(((TLRPC.TL_messages_forumTopics) response).users, false);
getMessagesController().putChats(((TLRPC.TL_messages_forumTopics) response).chats, false);
@ -141,6 +142,9 @@ public class TopicsController extends BaseController {
}
public void processTopics(long chatId, ArrayList<TLRPC.TL_forumTopic> newTopics, SparseArray<TLRPC.Message> messagesMap, boolean fromCache, int loadType, int totalCount) {
if (BuildVars.LOGS_ENABLED) {
FileLog.d("processTopics=" + "new_topics_size=" + (newTopics == null ? 0 : newTopics.size()) + " fromCache=" + fromCache + " load_type=" + loadType + " totalCount=" + totalCount);
}
ArrayList<TLRPC.TL_forumTopic> topics = topicsByChatId.get(chatId);
ArrayList<TLRPC.TL_forumTopic> topicsToReload = null;
LongSparseArray<TLRPC.TL_forumTopic> topicsMap = topicsMapByChatId.get(chatId);
@ -204,9 +208,10 @@ public class TopicsController extends BaseController {
if (topicsToReload != null && loadType != LOAD_TYPE_LOAD_UNKNOWN) {
reloadTopics(chatId, topicsToReload);
} else if (loadType == LOAD_TYPE_LOAD_NEXT && topics.size() >= totalCount && totalCount >= 0) {
} else if (((loadType == LOAD_TYPE_PRELOAD && !fromCache) || loadType == LOAD_TYPE_LOAD_NEXT) && topics.size() >= totalCount && totalCount >= 0) {
endIsReached.put(chatId, 1);
getUserConfig().getPreferences().edit().putBoolean("topics_end_reached_" + chatId, true).apply();
changed = true;
}
if (changed) {
@ -239,7 +244,19 @@ public class TopicsController extends BaseController {
ArrayList<TLRPC.TL_forumTopic> topics = topicsByChatId.get(chatId);
if (topics != null) {
if (openedTopicsBuChatId.get(chatId, 0) > 0) {
Collections.sort(topics, Comparator.comparingInt(o -> o.topMessage == null ? Integer.MAX_VALUE : -(o.pinned ? Integer.MAX_VALUE - o.pinnedOrder : o.topMessage.date)));
// Comparator.comparingInt(o -> o.topMessage == null ? Integer.MAX_VALUE : -(o.pinned ? Integer.MAX_VALUE - o.pinnedOrder : o.topMessage.date))
Collections.sort(topics, (a, b) -> {
if (a.hidden != b.hidden) {
return a.hidden ? -1 : 1;
}
if (a.pinned != b.pinned) {
return a.pinned ? -1 : 1;
}
if (a.pinned && b.pinned) {
return a.pinnedOrder - b.pinnedOrder;
}
return (b.topMessage != null ? b.topMessage.date : 0) - (a.topMessage != null ? a.topMessage.date : 0);
});
}
if (notify) {
getNotificationCenter().postNotificationName(NotificationCenter.topicsDidLoaded, chatId, true);
@ -405,6 +422,10 @@ public class TopicsController extends BaseController {
}
public CharSequence getTopicIconName(TLRPC.Chat chat, MessageObject message, TextPaint paint) {
return getTopicIconName(chat, message, paint, null);
}
public CharSequence getTopicIconName(TLRPC.Chat chat, MessageObject message, TextPaint paint, Drawable[] drawableToSet) {
if (message.messageOwner.reply_to == null) {
return null;
}
@ -415,7 +436,7 @@ public class TopicsController extends BaseController {
if (topicId != 0) {
TLRPC.TL_forumTopic topic = findTopic(chat.id, topicId);
if (topic != null) {
return ForumUtilities.getTopicSpannedName(topic, paint);
return ForumUtilities.getTopicSpannedName(topic, paint, drawableToSet);
}
}
return null;
@ -464,7 +485,7 @@ public class TopicsController extends BaseController {
}
public void onTopicEdited(long dialogId, TLRPC.TL_forumTopic forumTopic) {
getMessagesStorage().updateTopicData(dialogId, forumTopic, TOPIC_FLAG_ICON + TOPIC_FLAG_TITLE);
getMessagesStorage().updateTopicData(dialogId, forumTopic, TOPIC_FLAG_ICON + TOPIC_FLAG_TITLE + TOPIC_FLAG_HIDE);
sortTopics(-dialogId);
}
@ -590,6 +611,37 @@ public class TopicsController extends BaseController {
}
}
public void toggleShowTopic(long chatId, int topicId, boolean show) {
TLRPC.TL_channels_editForumTopic req = new TLRPC.TL_channels_editForumTopic();
req.channel = getMessagesController().getInputChannel(chatId);
req.topic_id = topicId;
req.flags = 8;
boolean wasHidden = show;
req.hidden = !show;
TLRPC.TL_forumTopic topic = findTopic(chatId, topicId);
if (topic != null) {
wasHidden = topic.hidden;
topic.hidden = req.hidden;
if (topic.hidden) {
topic.closed = true;
// topic.pinned = true;
// ArrayList<Integer> order = getCurrentPinnedOrder(chatId);
// order.remove((Integer) topicId);
// order.add(0, topicId);
// applyPinnedOrder(chatId, order);
}
updateTopicInUi(-chatId, topic, TOPIC_FLAG_PIN | TOPIC_FLAG_HIDE | TOPIC_FLAG_CLOSE);
getMessagesStorage().updateTopicData(-chatId, topic, TOPIC_FLAG_PIN | TOPIC_FLAG_HIDE | TOPIC_FLAG_CLOSE);
}
ConnectionsManager.getInstance(currentAccount).sendRequest(req, (res, err) -> {
if (err != null) {
}
});
}
public void pinTopic(long chatId, int topicId, boolean pin, BaseFragment fragment) {
TLRPC.TL_channels_updatePinnedForumTopic req = new TLRPC.TL_channels_updatePinnedForumTopic();
req.channel = getMessagesController().getInputChannel(chatId);
@ -611,13 +663,15 @@ public class TopicsController extends BaseController {
return;
}
applyPinnedOrder(chatId, prevOrder);
fragment.showDialog(
AndroidUtilities.runOnUIThread(() -> {
fragment.showDialog(
new AlertDialog.Builder(fragment.getContext())
.setTitle(LocaleController.getString("LimitReached", R.string.LimitReached))
.setMessage(LocaleController.formatString("LimitReachedPinnedTopics", R.string.LimitReachedPinnedTopics, MessagesController.getInstance(currentAccount).topicsPinnedLimit))
.setPositiveButton(LocaleController.getString("OK", R.string.OK), null)
.create()
);
.setTitle(LocaleController.getString("LimitReached", R.string.LimitReached))
.setMessage(LocaleController.formatString("LimitReachedPinnedTopics", R.string.LimitReachedPinnedTopics, MessagesController.getInstance(currentAccount).topicsPinnedLimit))
.setPositiveButton(LocaleController.getString("OK", R.string.OK), null)
.create()
);
});
} else if ("PINNED_TOPIC_NOT_MODIFIED".equals(error.text)) {
reloadTopics(chatId, false);
}
@ -751,6 +805,9 @@ public class TopicsController extends BaseController {
topic.unread_mentions_count = update.unreadMentions;
topicsByTopMsgId.put(messageHash(topic.top_message, -update.dialogId), topic);
}
if (update.totalMessagesCount > 0) {
topic.totalMessagesCount = update.totalMessagesCount;
}
changedDialogs.add(-update.dialogId);
}
}
@ -890,6 +947,9 @@ public class TopicsController extends BaseController {
if ((flags & TOPIC_FLAG_PIN) != 0) {
topic.pinned = forumTopic.pinned;
}
if ((flags & TOPIC_FLAG_HIDE) != 0) {
topic.hidden = forumTopic.hidden;
}
sortTopics(-dialogId);
}
}
@ -926,6 +986,7 @@ public class TopicsController extends BaseController {
}
public static class TopicUpdate {
public int totalMessagesCount = -1;
long dialogId;
int topicId;
int unreadMentions;
@ -951,6 +1012,25 @@ public class TopicsController extends BaseController {
v = 0;
}
openedTopicsBuChatId.put(chatId, v);
}
public void getTopicRepliesCount(long dialogId, int topicId) {
TLRPC.TL_forumTopic topic = findTopic(-dialogId, topicId);
if (topic != null) {
if (topic.totalMessagesCount == 0) {
TLRPC.TL_messages_getReplies req = new TLRPC.TL_messages_getReplies();
req.peer = getMessagesController().getInputPeer(dialogId);
req.msg_id = topicId;
req.limit = 1;
getConnectionsManager().sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> {
if (response != null) {
TLRPC.messages_Messages messages = (TLRPC.messages_Messages) response;
topic.totalMessagesCount = messages.count;
getMessagesStorage().updateTopicData(dialogId, topic, TOPIC_FLAG_TOTAL_MESSAGES_COUNT);
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.topicsDidLoaded, -dialogId, true);
}
}));
}
}
}
}

View File

@ -527,4 +527,34 @@ public class UserConfig extends BaseController {
}
return null;
}
int globalTtl = 0;
boolean ttlIsLoading = false;
long lastLoadingTime;
public int getGlobalTTl() {
return globalTtl;
}
public void loadGlobalTTl() {
if (ttlIsLoading || System.currentTimeMillis() - lastLoadingTime < 60 * 1000) {
return;
}
ttlIsLoading = true;
TLRPC.TL_messages_getDefaultHistoryTTL getDefaultHistoryTTL = new TLRPC.TL_messages_getDefaultHistoryTTL();
getConnectionsManager().sendRequest(getDefaultHistoryTTL, (response, error) -> AndroidUtilities.runOnUIThread(() -> {
if (response != null) {
globalTtl = ((TLRPC.TL_defaultHistoryTTL) response).period / 60;
getNotificationCenter().postNotificationName(NotificationCenter.didUpdateGlobalAutoDeleteTimer);
ttlIsLoading = false;
lastLoadingTime = System.currentTimeMillis();
}
}));
}
public void setGlobalTtl(int ttl) {
globalTtl = ttl;
}
}

View File

@ -27,6 +27,7 @@ public class VideoEditedInfo {
public long avatarStartTime = -1;
public float start;
public float end;
public int compressQuality;
public int rotationValue;
public int originalWidth;
public int originalHeight;

View File

@ -424,7 +424,7 @@ public class Browser {
try {
Intent viewIntent = new Intent(Intent.ACTION_VIEW, uri);
List<ResolveInfo> allActivities = ApplicationLoader.applicationContext.getPackageManager().queryIntentActivities(viewIntent, 0);
if (allActivities != null && allActivities.size() > 1) {
if (allActivities != null && allActivities.size() >= 1) {
return false;
}
} catch (Exception ignore) {

View File

@ -3059,7 +3059,11 @@ public class VoIPService extends Service implements SensorEventListener, AudioMa
}
am.abandonAudioFocus(this);
}
am.unregisterMediaButtonEventReceiver(new ComponentName(this, VoIPMediaButtonReceiver.class));
try {
am.unregisterMediaButtonEventReceiver(new ComponentName(this, VoIPMediaButtonReceiver.class));
} catch (Exception e) {
FileLog.e(e);
}
if (hasAudioFocus) {
am.abandonAudioFocus(this);
}

View File

@ -18,7 +18,6 @@ import org.telegram.messenger.FileLoader;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.ImageLoader;
import org.telegram.messenger.MessageObject;
import org.telegram.messenger.MessagesController;
import org.telegram.messenger.SharedConfig;
import org.telegram.messenger.Utilities;
@ -69,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 = 149;
public static final int LAYER = 150;
public static class TL_stats_megagroupStats extends TLObject {
public static int constructor = 0xef7ff916;
@ -3841,21 +3840,21 @@ public class TLRPC {
public static Peer TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
Peer result = null;
switch (constructor) {
case 0xa2a5371e:
result = new TL_peerChannel();
break;
case 0xbddde532:
result = new TL_peerChannel_layer131();
break;
case 0x59511722:
result = new TL_peerUser();
break;
case 0xa2a5371e:
result = new TL_peerChannel();
case 0x9db1bc6d:
result = new TL_peerUser_layer131();
break;
case 0x36c6019a:
result = new TL_peerChat();
break;
case 0x9db1bc6d:
result = new TL_peerUser_layer131();
break;
case 0xbad0e5bb:
result = new TL_peerChat_layer131();
break;
@ -4684,7 +4683,7 @@ public class TLRPC {
case 0x64199744:
result = new TL_secureFileEmpty();
break;
case 0xe0277a62:
case 0x7d09c27e:
result = new TL_secureFile();
break;
}
@ -6695,6 +6694,7 @@ public class TLRPC {
public static abstract class auth_SentCodeType extends TLObject {
public int flags;
public String url;
public int length;
public String pattern;
public String prefix;
@ -6727,6 +6727,9 @@ public class TLRPC {
case 0xc000bba2:
result = new TL_auth_sentCodeTypeSms();
break;
case 0xd9565c39:
result = new TL_auth_sentCodeTypeFragmentSms();
break;
}
if (result == null && exception) {
throw new RuntimeException(String.format("can't parse magic %x in auth_SentCodeType", constructor));
@ -6854,6 +6857,22 @@ public class TLRPC {
}
}
public static class TL_auth_sentCodeTypeFragmentSms extends auth_SentCodeType {
public static int constructor = 0xd9565c39;
public void readParams(AbstractSerializedData stream, boolean exception) {
url = stream.readString(exception);
length = stream.readInt32(exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
stream.writeString(url);
stream.writeInt32(length);
}
}
public static abstract class messages_StickerSetInstallResult extends TLObject {
public ArrayList<StickerSetCovered> sets = new ArrayList<>();
@ -7862,7 +7881,7 @@ public class TLRPC {
public static class TL_messageMediaInvoice extends MessageMedia {
public static int constructor = 0xf6a548d3;
public WebDocument photo;
public WebDocument webPhoto;
public void readParams(AbstractSerializedData stream, boolean exception) {
flags = stream.readInt32(exception);
@ -7871,7 +7890,7 @@ public class TLRPC {
title = stream.readString(exception);
description = stream.readString(exception);
if ((flags & 1) != 0) {
photo = WebDocument.TLdeserialize(stream, stream.readInt32(exception), exception);
webPhoto = WebDocument.TLdeserialize(stream, stream.readInt32(exception), exception);
}
if ((flags & 4) != 0) {
receipt_msg_id = stream.readInt32(exception);
@ -7892,7 +7911,7 @@ public class TLRPC {
stream.writeString(title);
stream.writeString(description);
if ((flags & 1) != 0) {
photo.serializeToStream(stream);
webPhoto.serializeToStream(stream);
}
if ((flags & 4) != 0) {
stream.writeInt32(receipt_msg_id);
@ -12061,6 +12080,7 @@ public class TLRPC {
public ArrayList<String> available_reactions_legacy = new ArrayList<>();
public int flags2;
public boolean can_delete_channel;
public boolean antispam;
public ChatReactions available_reactions;
public long inviterId; //custom
@ -14534,6 +14554,7 @@ public class TLRPC {
blocked = (flags & 4194304) != 0;
flags2 = stream.readInt32(exception);
can_delete_channel = (flags2 & 1) != 0;
antispam = (flags2 & 2) != 0;
id = stream.readInt64(exception);
about = stream.readString(exception);
if ((flags & 1) != 0) {
@ -14669,6 +14690,7 @@ public class TLRPC {
flags = blocked ? (flags | 4194304) : (flags &~ 4194304);
stream.writeInt32(flags);
flags2 = can_delete_channel ? (flags2 | 1) : (flags2 &~ 1);
flags2 = antispam ? (flags2 | 2) : (flags2 &~ 2);
stream.writeInt32(flags2);
stream.writeInt64(id);
stream.writeString(about);
@ -21139,6 +21161,37 @@ public class TLRPC {
}
}
public static class TL_exportedContactToken extends TLObject {
public static int constructor = 0x41bf109b;
public String url;
public int expires;
public static TL_exportedContactToken TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
if (TL_exportedContactToken.constructor != constructor) {
if (exception) {
throw new RuntimeException(String.format("can't parse magic %x in TL_exportedContactToken", constructor));
} else {
return null;
}
}
TL_exportedContactToken result = new TL_exportedContactToken();
result.readParams(stream, exception);
return result;
}
public void readParams(AbstractSerializedData stream, boolean exception) {
url = stream.readString(exception);
expires = stream.readInt32(exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
stream.writeString(url);
stream.writeInt32(expires);
}
}
public static class TL_botCommand extends TLObject {
public static int constructor = 0xc27ac8c7;
@ -21410,7 +21463,6 @@ public class TLRPC {
public static class TL_inputGroupCallStream extends InputFileLocation {
public static int constructor = 0x598a92a;
public int flags;
public TL_inputGroupCall call;
public long time_ms;
public int scale;
@ -22350,6 +22402,9 @@ public class TLRPC {
}
public void serializeToStream(AbstractSerializedData stream) {
if (username == null) {
flags = flags & ~8;
}
stream.writeInt32(constructor);
flags = self ? (flags | 1024) : (flags &~ 1024);
flags = contact ? (flags | 2048) : (flags &~ 2048);
@ -23993,6 +24048,9 @@ public class TLRPC {
result = new TL_messageActionUserJoined();
break;
case 0xb18a431c:
result = new TL_messageActionTopicEdit_layer149();
break;
case 0xc0944820:
result = new TL_messageActionTopicEdit();
break;
case 0x55555551:
@ -24004,9 +24062,12 @@ public class TLRPC {
case 0x55555552:
result = new TL_messageActionTTLChange();
break;
case 0xaa1afbfd:
case 0x3c134d7b:
result = new TL_messageActionSetMessagesTTL();
break;
case 0xaa1afbfd:
result = new TL_messageActionSetMessagesTTL_layer149();
break;
case 0xd95c6154:
result = new TL_messageActionSecureValuesSent();
break;
@ -24414,10 +24475,48 @@ public class TLRPC {
}
public static class TL_messageActionTopicEdit extends MessageAction {
public static int constructor = 0xb18a431c;
public static int constructor = 0xc0944820;
public long icon_emoji_id;
public boolean closed;
public boolean hidden;
public void readParams(AbstractSerializedData stream, boolean exception) {
flags = stream.readInt32(exception);
if ((flags & 1) != 0) {
title = stream.readString(exception);
}
if ((flags & 2) != 0) {
icon_emoji_id = stream.readInt64(exception);
}
if ((flags & 4) != 0) {
closed = stream.readBool(exception);
}
if ((flags & 8) != 0) {
hidden = stream.readBool(exception);
}
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt32(flags);
if ((flags & 1) != 0) {
stream.writeString(title);
}
if ((flags & 2) != 0) {
stream.writeInt64(icon_emoji_id);
}
if ((flags & 4) != 0) {
stream.writeBool(closed);
}
if ((flags & 8) != 0) {
stream.writeBool(hidden);
}
}
}
public static class TL_messageActionTopicEdit_layer149 extends TL_messageActionTopicEdit {
public static int constructor = 0xb18a431c;
public void readParams(AbstractSerializedData stream, boolean exception) {
flags = stream.readInt32(exception);
@ -24677,9 +24776,31 @@ public class TLRPC {
}
public static class TL_messageActionSetMessagesTTL extends MessageAction {
public static int constructor = 0xaa1afbfd;
public static int constructor = 0x3c134d7b;
public int period;
public long auto_setting_from;
public void readParams(AbstractSerializedData stream, boolean exception) {
flags = stream.readInt32(exception);
period = stream.readInt32(exception);
if ((flags & 1) != 0) {
auto_setting_from = stream.readInt64(exception);
}
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt32(flags);
stream.writeInt32(period);
if ((flags & 1) != 0) {
stream.writeInt64(auto_setting_from);
}
}
}
public static class TL_messageActionSetMessagesTTL_layer149 extends TL_messageActionSetMessagesTTL {
public static int constructor = 0xaa1afbfd;
public void readParams(AbstractSerializedData stream, boolean exception) {
period = stream.readInt32(exception);
@ -44148,6 +44269,9 @@ public class TLRPC {
case 0xd61ad6ee:
result = new TL_auth_codeTypeMissedCall();
break;
case 0x6ed998c:
result = new TL_auth_codeTypeFragmentSms();
break;
}
if (result == null && exception) {
throw new RuntimeException(String.format("can't parse magic %x in auth_CodeType", constructor));
@ -44195,6 +44319,15 @@ public class TLRPC {
}
}
public static class TL_auth_codeTypeFragmentSms extends auth_CodeType {
public static int constructor = 0x6ed998c;
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
}
}
public static abstract class messages_TranslatedText extends TLObject {
public static messages_TranslatedText TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
@ -51228,10 +51361,12 @@ public class TLRPC {
}
public static class TL_messages_createChat extends TLObject {
public static int constructor = 0x9cb126e;
public static int constructor = 0x34a818;
public int flags;
public ArrayList<InputUser> users = new ArrayList<>();
public String title;
public int ttl_period;
public TLObject deserializeResponse(AbstractSerializedData stream, int constructor, boolean exception) {
return Updates.TLdeserialize(stream, constructor, exception);
@ -51239,6 +51374,7 @@ public class TLRPC {
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt32(flags);
stream.writeInt32(0x1cb5c415);
int count = users.size();
stream.writeInt32(count);
@ -51246,6 +51382,9 @@ public class TLRPC {
users.get(a).serializeToStream(stream);
}
stream.writeString(title);
if ((flags & 1) != 0) {
stream.writeInt32(ttl_period);
}
}
}
@ -61607,18 +61746,24 @@ public class TLRPC {
public int pts;
public DraftMessage draft;
public int folder_id;
public int ttl_period;
public int last_message_date; //custom
public long id; //custom
public int pinnedNum; //custom
public boolean isFolder; //custom
public static Dialog TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
public static Dialog TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
Dialog result = null;
switch (constructor) {
case 0xa8edd0f5:
case 0xd58a08c6:
result = new TL_dialog();
break;
case 0xa8edd0f5:
result = new TL_dialog_layer149();
break;
case 0x71bd134c:
result = new TL_dialogFolder();
result.isFolder = true;
break;
}
if (result == null && exception) {
@ -61632,8 +61777,7 @@ public class TLRPC {
}
public static class TL_dialog extends Dialog {
public static int constructor = 0xa8edd0f5;
public int stableId = MessagesController.stableIdPointer++;
public static int constructor = 0xd58a08c6;
public void readParams(AbstractSerializedData stream, boolean exception) {
flags = stream.readInt32(exception);
@ -61646,7 +61790,7 @@ public class TLRPC {
unread_count = stream.readInt32(exception);
unread_mentions_count = stream.readInt32(exception);
unread_reactions_count = stream.readInt32(exception);
notify_settings = PeerNotifySettings.TLdeserialize(stream, stream.readInt32(exception), exception);
notify_settings = TL_peerNotifySettings.TLdeserialize(stream, stream.readInt32(exception), exception);
if ((flags & 1) != 0) {
pts = stream.readInt32(exception);
}
@ -61656,6 +61800,9 @@ public class TLRPC {
if ((flags & 16) != 0) {
folder_id = stream.readInt32(exception);
}
if ((flags & 32) != 0) {
ttl_period = stream.readInt32(exception);
}
}
public void serializeToStream(AbstractSerializedData stream) {
@ -61680,6 +61827,66 @@ public class TLRPC {
if ((flags & 16) != 0) {
stream.writeInt32(folder_id);
}
if ((flags & 32) != 0) {
stream.writeInt32(ttl_period);
}
}
}
public static class TL_dialog_layer149 extends TL_dialog {
public static int constructor = 0xa8edd0f5;
public void readParams(AbstractSerializedData stream, boolean exception) {
flags = stream.readInt32(exception);
pinned = (flags & 4) != 0;
unread_mark = (flags & 8) != 0;
peer = Peer.TLdeserialize(stream, stream.readInt32(exception), exception);
top_message = stream.readInt32(exception);
read_inbox_max_id = stream.readInt32(exception);
read_outbox_max_id = stream.readInt32(exception);
unread_count = stream.readInt32(exception);
unread_mentions_count = stream.readInt32(exception);
unread_reactions_count = stream.readInt32(exception);
notify_settings = PeerNotifySettings.TLdeserialize(stream, stream.readInt32(exception), exception);
if ((flags & 1) != 0) {
pts = stream.readInt32(exception);
}
if ((flags & 2) != 0) {
draft = DraftMessage.TLdeserialize(stream, stream.readInt32(exception), exception);
}
if ((flags & 16) != 0) {
folder_id = stream.readInt32(exception);
}
if ((flags & 32) != 0) {
ttl_period = stream.readInt32(exception);
}
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
flags = pinned ? (flags | 4) : (flags &~ 4);
flags = unread_mark ? (flags | 8) : (flags &~ 8);
stream.writeInt32(flags);
peer.serializeToStream(stream);
stream.writeInt32(top_message);
stream.writeInt32(read_inbox_max_id);
stream.writeInt32(read_outbox_max_id);
stream.writeInt32(unread_count);
stream.writeInt32(unread_mentions_count);
stream.writeInt32(unread_reactions_count);
notify_settings.serializeToStream(stream);
if ((flags & 1) != 0) {
stream.writeInt32(pts);
}
if ((flags & 2) != 0) {
draft.serializeToStream(stream);
}
if ((flags & 16) != 0) {
stream.writeInt32(folder_id);
}
if ((flags & 32) != 0) {
stream.writeInt32(ttl_period);
}
}
}
@ -64166,6 +64373,7 @@ public class TLRPC {
public boolean closed;
public boolean pinned;
public boolean isShort;
public boolean hidden;
public int id;
public int date;
public String title;
@ -64185,6 +64393,7 @@ public class TLRPC {
public Message topMessage; // custom
public String searchQuery; //custom
public int pinnedOrder; // custom
public int totalMessagesCount; // custom
public static TL_forumTopic TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
TL_forumTopic result = null;
@ -64214,6 +64423,7 @@ public class TLRPC {
closed = (flags & 4) != 0;
pinned = (flags & 8) != 0;
isShort = (flags & 32) != 0;
hidden = (flags & 64) != 0;
id = stream.readInt32(exception);
date = stream.readInt32(exception);
title = stream.readString(exception);
@ -64240,6 +64450,7 @@ public class TLRPC {
flags = closed ? (flags | 4) : (flags &~ 4);
flags = pinned ? (flags | 8) : (flags &~ 8);
flags = isShort ? (flags | 32) : (flags &~ 32);
flags = hidden ? (flags | 64) : (flags &~ 64);
stream.writeInt32(flags);
stream.writeInt32(id);
stream.writeInt32(date);
@ -64438,7 +64649,7 @@ public class TLRPC {
}
public static class TL_channels_editForumTopic extends TLObject {
public static int constructor = 0x6c883e2d;
public static int constructor = 0xf4dfa185;
public int flags;
public InputChannel channel;
@ -64446,6 +64657,7 @@ public class TLRPC {
public String title;
public long icon_emoji_id;
public boolean closed;
public boolean hidden;
public TLObject deserializeResponse(AbstractSerializedData stream, int constructor, boolean exception) {
return Updates.TLdeserialize(stream, constructor, exception);
@ -64465,6 +64677,9 @@ public class TLRPC {
if ((flags & 4) != 0) {
stream.writeBool(closed);
}
if ((flags & 8) != 0) {
stream.writeBool(hidden);
}
}
}
@ -64709,6 +64924,124 @@ public class TLRPC {
}
}
}
public static class TL_channels_toggleAntiSpam extends TLObject {
public static int constructor = 0x68f3e4eb;
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_channels_reportAntiSpamFalsePositive extends TLObject {
public static int constructor = 0xa850a693;
public InputChannel channel;
public int msg_id;
public TLObject deserializeResponse(AbstractSerializedData stream, int constructor, boolean exception) {
return Bool.TLdeserialize(stream, constructor, exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
channel.serializeToStream(stream);
stream.writeInt32(msg_id);
}
}
public static class TL_messages_setDefaultHistoryTTL extends TLObject {
public static int constructor = 0x9eb51445;
public int period;
public TLObject deserializeResponse(AbstractSerializedData stream, int constructor, boolean exception) {
return Bool.TLdeserialize(stream, constructor, exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt32(period);
}
}
public static class TL_messages_getDefaultHistoryTTL extends TLObject {
public static int constructor = 0x658b7188;
public TLObject deserializeResponse(AbstractSerializedData stream, int constructor, boolean exception) {
return TL_defaultHistoryTTL.TLdeserialize(stream, constructor, exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
}
}
public static class TL_defaultHistoryTTL extends TLObject {
public static int constructor = 0x43b46b20;
public int period;
public static TL_defaultHistoryTTL TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
if (TL_defaultHistoryTTL.constructor != constructor) {
if (exception) {
throw new RuntimeException(String.format("can't parse magic %x in TL_defaultHistoryTTL", constructor));
} else {
return null;
}
}
TL_defaultHistoryTTL result = new TL_defaultHistoryTTL();
result.readParams(stream, exception);
return result;
}
public void readParams(AbstractSerializedData stream, boolean exception) {
period = stream.readInt32(exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt32(period);
}
}
public static class TL_contacts_exportContactToken extends TLObject {
public static int constructor = 0xf8654027;
public TLObject deserializeResponse(AbstractSerializedData stream, int constructor, boolean exception) {
return TL_exportedContactToken.TLdeserialize(stream, constructor, exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
}
}
public static class TL_contacts_importContactToken extends TLObject {
public static int constructor = 0x13005788;
public String token;
public TLObject deserializeResponse(AbstractSerializedData stream, int constructor, boolean exception) {
return User.TLdeserialize(stream, constructor, exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
stream.writeString(token);
}
}
//functions
public static class Vector extends TLObject {

View File

@ -12,6 +12,7 @@ import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.app.Activity;
import android.content.Context;
import android.content.res.Configuration;
@ -48,6 +49,7 @@ import org.telegram.messenger.R;
import org.telegram.messenger.SharedConfig;
import org.telegram.ui.Adapters.FiltersView;
import org.telegram.ui.Components.AnimatedEmojiDrawable;
import org.telegram.ui.Components.BackupImageView;
import org.telegram.ui.Components.CubicBezierInterpolator;
import org.telegram.ui.Components.EllipsizeSpanAnimator;
import org.telegram.ui.Components.FireworksEffect;
@ -69,8 +71,9 @@ public class ActionBar extends FrameLayout {
}
}
private INavigationLayout.BackButtonState backButtonState;
private INavigationLayout.BackButtonState backButtonState = INavigationLayout.BackButtonState.BACK;
private ImageView backButtonImageView;
private BackupImageView avatarSearchImageView;
private Drawable backButtonDrawable;
private SimpleTextView[] titleTextView = new SimpleTextView[2];
private SimpleTextView subtitleTextView;
@ -117,6 +120,7 @@ public class ActionBar extends FrameLayout {
private boolean castShadows = true;
protected boolean isSearchFieldVisible;
public float searchFieldVisibleAlpha;
protected int itemsBackgroundColor;
protected int itemsActionModeBackgroundColor;
protected int itemsColor;
@ -130,10 +134,13 @@ public class ActionBar extends FrameLayout {
private boolean fromBottom;
private boolean centerScale;
private CharSequence subtitle;
private boolean drawBackButton;
private View.OnTouchListener interceptTouchEventListener;
private final Theme.ResourcesProvider resourcesProvider;
private PorterDuff.Mode colorFilterMode = PorterDuff.Mode.MULTIPLY;
SizeNotifierFrameLayout contentView;
boolean blurredBackground;
public Paint blurScrimPaint = new Paint();
@ -158,7 +165,14 @@ public class ActionBar extends FrameLayout {
});
}
public void setColorFilterMode(PorterDuff.Mode colorFilterMode) {
this.colorFilterMode = colorFilterMode;
}
public INavigationLayout.BackButtonState getBackButtonState() {
if (backButtonDrawable instanceof INavigationLayout.IBackButtonDrawable) {
return ((INavigationLayout.IBackButtonDrawable) backButtonDrawable).getBackButtonState();
}
return backButtonState;
}
@ -170,7 +184,7 @@ public class ActionBar extends FrameLayout {
backButtonImageView.setScaleType(ImageView.ScaleType.CENTER);
backButtonImageView.setBackgroundDrawable(Theme.createSelectorDrawable(itemsBackgroundColor));
if (itemsColor != 0) {
backButtonImageView.setColorFilter(new PorterDuffColorFilter(itemsColor, PorterDuff.Mode.MULTIPLY));
backButtonImageView.setColorFilter(new PorterDuffColorFilter(itemsColor, colorFilterMode));
}
backButtonImageView.setPadding(AndroidUtilities.dp(1), 0, 0, 0);
addView(backButtonImageView, LayoutHelper.createFrame(54, 54, Gravity.LEFT | Gravity.TOP));
@ -224,6 +238,23 @@ public class ActionBar extends FrameLayout {
invalidate();
}
public BackupImageView getSearchAvatarImageView() {
return avatarSearchImageView;
}
public void setSearchAvatarImageView(BackupImageView backupImageView) {
if (avatarSearchImageView == backupImageView) {
return;
}
if (avatarSearchImageView != null) {
removeView(avatarSearchImageView);
}
avatarSearchImageView = backupImageView;
if (avatarSearchImageView != null) {
addView(avatarSearchImageView);
}
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (supportsHolidayImage && !titleOverlayShown && !LocaleController.isRTL && ev.getAction() == MotionEvent.ACTION_DOWN) {
@ -252,9 +283,12 @@ public class ActionBar extends FrameLayout {
@Override
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
if (parentFragment != null && parentFragment.getParentLayout().isActionBarInCrossfade()) {
if (parentFragment != null && parentFragment.getParentLayout() != null && parentFragment.getParentLayout().isActionBarInCrossfade()) {
return false;
}
if (drawBackButton && child == backButtonImageView) {
return true;
}
boolean clip = shouldClipChild(child);
if (clip) {
@ -318,9 +352,6 @@ public class ActionBar extends FrameLayout {
}
backButtonImageView.setVisibility(resource == 0 ? GONE : VISIBLE);
backButtonImageView.setImageResource(resource);
if (resource == R.drawable.ic_ab_back) {
backButtonState = INavigationLayout.BackButtonState.BACK;
}
}
private void createSubtitleTextView() {
@ -380,7 +411,12 @@ public class ActionBar extends FrameLayout {
if (titleTextView[i] != null) {
return;
}
titleTextView[i] = new SimpleTextView(getContext());
titleTextView[i] = new SimpleTextView(getContext()) {
@Override
public void setAlpha(float alpha) {
super.setAlpha(alpha);
}
};
titleTextView[i].setGravity(Gravity.LEFT | Gravity.CENTER_VERTICAL);
if (titleColorToSet != 0) {
titleTextView[i].setTextColor(titleColorToSet);
@ -691,6 +727,15 @@ public class ActionBar extends FrameLayout {
}
actionModeAnimation = new AnimatorSet();
actionModeAnimation.playTogether(animators);
if (backgroundUpdateListener != null) {
ValueAnimator alphaUpdate = ValueAnimator.ofFloat(0, 1);
alphaUpdate.addUpdateListener(anm -> {
if (backgroundUpdateListener != null) {
backgroundUpdateListener.run();
}
});
actionModeAnimation.playTogether(alphaUpdate);
}
actionModeAnimation.setDuration(200);
actionModeAnimation.addListener(new AnimatorListenerAdapter() {
@Override
@ -844,6 +889,15 @@ public class ActionBar extends FrameLayout {
}
actionModeAnimation = new AnimatorSet();
actionModeAnimation.playTogether(animators);
if (backgroundUpdateListener != null) {
ValueAnimator alphaUpdate = ValueAnimator.ofFloat(0, 1);
alphaUpdate.addUpdateListener(anm -> {
if (backgroundUpdateListener != null) {
backgroundUpdateListener.run();
}
});
actionModeAnimation.playTogether(alphaUpdate);
}
actionModeAnimation.setDuration(200);
actionModeAnimation.addListener(new AnimatorListenerAdapter() {
@Override
@ -948,8 +1002,17 @@ public class ActionBar extends FrameLayout {
return actionMode != null && actionModeVisible && ((actionModeTag == null && tag == null) || (actionModeTag != null && actionModeTag.equals(tag)));
}
Runnable backgroundUpdateListener;
AnimatorSet searchVisibleAnimator;
public void listenToBackgroundUpdate(Runnable invalidate) {
backgroundUpdateListener = invalidate;
}
protected boolean onSearchChangedIgnoreTitles() {
return false;
}
public void onSearchFieldVisibilityChanged(boolean visible) {
isSearchFieldVisible = visible;
if (searchVisibleAnimator != null) {
@ -958,14 +1021,26 @@ public class ActionBar extends FrameLayout {
searchVisibleAnimator = new AnimatorSet();
final ArrayList<View> viewsToHide = new ArrayList<>();
if (titleTextView[0] != null) {
viewsToHide.add(titleTextView[0]);
final boolean ignoreTitles = onSearchChangedIgnoreTitles();
if (!ignoreTitles) {
if (titleTextView[0] != null) {
viewsToHide.add(titleTextView[0]);
}
if (subtitleTextView != null && !TextUtils.isEmpty(subtitle)) {
viewsToHide.add(subtitleTextView);
subtitleTextView.setVisibility(visible ? INVISIBLE : VISIBLE);
}
}
if (subtitleTextView != null && !TextUtils.isEmpty(subtitle)) {
viewsToHide.add(subtitleTextView);
subtitleTextView.setVisibility(visible ? INVISIBLE : VISIBLE);
}
ValueAnimator alphaUpdate = ValueAnimator.ofFloat(searchFieldVisibleAlpha, visible ? 1f : 0f);
alphaUpdate.addUpdateListener(anm -> {
searchFieldVisibleAlpha = (float) anm.getAnimatedValue();
if (backgroundUpdateListener != null) {
backgroundUpdateListener.run();
}
});
searchVisibleAnimator.playTogether(alphaUpdate);
for (int i = 0; i < viewsToHide.size(); i++) {
View view = viewsToHide.get(i);
@ -979,6 +1054,10 @@ public class ActionBar extends FrameLayout {
searchVisibleAnimator.playTogether(ObjectAnimator.ofFloat(view, View.SCALE_Y, visible ? 0.95f : 1f));
searchVisibleAnimator.playTogether(ObjectAnimator.ofFloat(view, View.SCALE_X, visible ? 0.95f : 1f));
}
if (avatarSearchImageView != null) {
avatarSearchImageView.setVisibility(View.VISIBLE);
searchVisibleAnimator.playTogether(ObjectAnimator.ofFloat(avatarSearchImageView, View.ALPHA, visible ? 1f : 0f));
}
centerScale = true;
requestLayout();
searchVisibleAnimator.addListener(new AnimatorListenerAdapter() {
@ -994,7 +1073,7 @@ public class ActionBar extends FrameLayout {
}
}
if (visible) {
if (visible && !ignoreTitles) {
if (titleTextView[0] != null) {
titleTextView[0].setVisibility(View.GONE);
}
@ -1002,16 +1081,24 @@ public class ActionBar extends FrameLayout {
titleTextView[1].setVisibility(View.GONE);
}
}
if (avatarSearchImageView != null) {
if (!visible) {
avatarSearchImageView.setVisibility(View.GONE);
}
}
}
});
searchVisibleAnimator.setDuration(150).start();
Drawable drawable = backButtonImageView.getDrawable();
if (drawable instanceof MenuDrawable) {
MenuDrawable menuDrawable = (MenuDrawable) drawable;
menuDrawable.setRotateToBack(true);
menuDrawable.setRotation(visible ? 1 : 0, true);
if (backButtonImageView != null) {
Drawable drawable = backButtonImageView.getDrawable();
if (drawable instanceof MenuDrawable) {
MenuDrawable menuDrawable = (MenuDrawable) drawable;
menuDrawable.setRotateToBack(true);
menuDrawable.setRotation(visible ? 1 : 0, true);
}
}
}
@ -1194,10 +1281,17 @@ public class ActionBar extends FrameLayout {
}
}
if (avatarSearchImageView != null) {
avatarSearchImageView.measure(
MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(42), MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(42), MeasureSpec.EXACTLY)
);
}
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
if (child.getVisibility() == GONE || child == titleTextView[0] || child == titleTextView[1] || child == subtitleTextView || child == menu || child == backButtonImageView || child == additionalSubtitleTextView) {
if (child.getVisibility() == GONE || child == titleTextView[0] || child == titleTextView[1] || child == subtitleTextView || child == menu || child == backButtonImageView || child == additionalSubtitleTextView || child == avatarSearchImageView) {
continue;
}
measureChildWithMargins(child, widthMeasureSpec, 0, MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.EXACTLY), 0);
@ -1250,10 +1344,19 @@ public class ActionBar extends FrameLayout {
additionalSubtitleTextView.layout(textLeft, additionalTop + textTop, textLeft + additionalSubtitleTextView.getMeasuredWidth(), additionalTop + textTop + additionalSubtitleTextView.getTextHeight());
}
if (avatarSearchImageView != null) {
avatarSearchImageView.layout(
AndroidUtilities.dp(56 + 8),
additionalTop + (getCurrentActionBarHeight() - avatarSearchImageView.getMeasuredHeight()) / 2,
AndroidUtilities.dp(56 + 8) + avatarSearchImageView.getMeasuredWidth(),
additionalTop + (getCurrentActionBarHeight() + avatarSearchImageView.getMeasuredHeight()) / 2
);
}
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
if (child.getVisibility() == GONE || child == titleTextView[0] || child == titleTextView[1] || child == subtitleTextView || child == menu || child == backButtonImageView || child == additionalSubtitleTextView) {
if (child.getVisibility() == GONE || child == titleTextView[0] || child == titleTextView[1] || child == subtitleTextView || child == menu || child == backButtonImageView || child == additionalSubtitleTextView || child == avatarSearchImageView) {
continue;
}
@ -1476,7 +1579,7 @@ public class ActionBar extends FrameLayout {
itemsColor = color;
if (backButtonImageView != null) {
if (itemsColor != 0) {
backButtonImageView.setColorFilter(new PorterDuffColorFilter(itemsColor, PorterDuff.Mode.MULTIPLY));
backButtonImageView.setColorFilter(new PorterDuffColorFilter(itemsColor, colorFilterMode));
Drawable drawable = backButtonImageView.getDrawable();
if (drawable instanceof BackDrawable) {
((BackDrawable) drawable).setColor(color);
@ -1709,4 +1812,12 @@ public class ActionBar extends FrameLayout {
public void setForceSkipTouches(boolean forceSkipTouches) {
this.forceSkipTouches = forceSkipTouches;
}
public void setDrawBackButton(boolean b) {
this.drawBackButton = b;
if (backButtonImageView != null) {
backButtonImageView.invalidate();
}
}
}

View File

@ -1606,6 +1606,10 @@ public class ActionBarLayout extends FrameLayout implements INavigationLayout, F
}
public void closeLastFragment(boolean animated, boolean forceNoAnimation) {
BaseFragment fragment = getLastFragment();
if (fragment != null && fragment.closeLastFragment()) {
return;
}
if (delegate != null && !delegate.needCloseLastFragment(this) || checkTransitionAnimation() || fragmentsStack.isEmpty()) {
return;
}
@ -2188,7 +2192,9 @@ public class ActionBarLayout extends FrameLayout implements INavigationLayout, F
oldFragment = null;
Runnable endRunnable = onCloseAnimationEndRunnable;
onCloseAnimationEndRunnable = null;
endRunnable.run();
if (endRunnable != null) {
endRunnable.run();
}
checkNeedRebuild();
checkNeedRebuild();
}
@ -2346,19 +2352,19 @@ public class ActionBarLayout extends FrameLayout implements INavigationLayout, F
}
}
private View findScrollingChild(ViewGroup parent, float x, float y) {
public static View findScrollingChild(ViewGroup parent, float x, float y) {
int n = parent.getChildCount();
for (int i = 0; i < n; i++) {
View child = parent.getChildAt(i);
if (child.getVisibility() != View.VISIBLE) {
continue;
}
child.getHitRect(rect);
if (rect.contains((int) x, (int) y)) {
child.getHitRect(AndroidUtilities.rectTmp2);
if (AndroidUtilities.rectTmp2.contains((int) x, (int) y)) {
if (child.canScrollHorizontally(-1)) {
return child;
} else if (child instanceof ViewGroup) {
View v = findScrollingChild((ViewGroup) child, x - rect.left, y - rect.top);
View v = findScrollingChild((ViewGroup) child, x - AndroidUtilities.rectTmp2.left, y - AndroidUtilities.rectTmp2.top);
if (v != null) {
return v;
}

View File

@ -80,10 +80,10 @@ public class ActionBarMenuItem extends FrameLayout {
public void setSearchPaddingStart(int padding) {
searchItemPaddingStart = padding;
if (searchContainer != null) {
((MarginLayoutParams)searchContainer.getLayoutParams()).leftMargin = AndroidUtilities.dp(padding);
((MarginLayoutParams) searchContainer.getLayoutParams()).leftMargin = AndroidUtilities.dp(padding);
searchContainer.setClipChildren(searchItemPaddingStart != 0);
searchContainer.setLayoutParams(searchContainer.getLayoutParams());
}
}
public static class ActionBarMenuItemSearchListener {
@ -1837,6 +1837,17 @@ public class ActionBarMenuItem extends FrameLayout {
}
}
public int getVisibleSubItemsCount() {
int count = 0;
for (int i = 0; i < popupLayout.getItemsCount(); ++i) {
View item = popupLayout.getItemAt(i);
if (item != null && item.getVisibility() == View.VISIBLE) {
count++;
}
}
return count;
}
public void requestFocusOnSearchView() {
if (searchContainer.getWidth() != 0 && !searchField.isFocused()) {
searchField.requestFocus();

View File

@ -1019,21 +1019,31 @@ public class ActionBarPopupWindow extends PopupWindow {
Theme.ResourcesProvider resourcesProvider;
String colorKey;
Drawable shadowDrawable;
public GapView(Context context, Theme.ResourcesProvider resourcesProvider) {
this(context, resourcesProvider, Theme.key_actionBarDefaultSubmenuSeparator);
}
public GapView(Context context, Theme.ResourcesProvider resourcesProvider, String colorKey) {
super(context);
this.resourcesProvider = resourcesProvider;
this.colorKey = colorKey;
setBackgroundColor(getThemedColor(colorKey));
}
private int getThemedColor(String key) {
Integer color = resourcesProvider != null ? resourcesProvider.getColor(key) : null;
return color != null ? color : Theme.getColor(key);
this.shadowDrawable = Theme.getThemedDrawable(getContext(), R.drawable.greydivider, Theme.key_windowBackgroundGrayShadow, resourcesProvider);
setBackgroundColor(Theme.getColor(colorKey, resourcesProvider));
}
public void setColor(int color) {
setBackgroundColor(color);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (shadowDrawable != null) {
shadowDrawable.setBounds(0, 0, getWidth(), getHeight());
shadowDrawable.draw(canvas);
}
}
}
}

View File

@ -44,8 +44,10 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.Emoji;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.LineProgressView;
@ -57,7 +59,7 @@ import org.telegram.ui.Components.spoilers.SpoilersTextView;
import java.util.ArrayList;
import java.util.Map;
public class AlertDialog extends Dialog implements Drawable.Callback {
public class AlertDialog extends Dialog implements Drawable.Callback, NotificationCenter.NotificationCenterDelegate {
private View customView;
private int customViewHeight = LayoutHelper.WRAP_CONTENT;
@ -594,7 +596,14 @@ public class AlertDialog extends Dialog implements Drawable.Callback {
contentScrollView.addView(scrollContainer, new ScrollView.LayoutParams(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
}
messageTextView = new SpoilersTextView(getContext(), false);
messageTextView = new SpoilersTextView(getContext(), false) {
@Override
public void setText(CharSequence text, BufferType type) {
text = Emoji.replaceEmoji(text, getPaint().getFontMetricsInt(), AndroidUtilities.dp(14), false);
super.setText(text, type);
}
};
NotificationCenter.listenEmojiLoading(messageTextView);
messageTextView.setTextColor(getThemedColor(topAnimationIsNew ? Theme.key_windowBackgroundWhiteGrayText : Theme.key_dialogTextBlack));
messageTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
messageTextView.setMovementMethod(new AndroidUtilities.LinkMovementMethodMy());
@ -955,6 +964,8 @@ public class AlertDialog extends Dialog implements Drawable.Callback {
}
window.setAttributes(params);
NotificationCenter.getGlobalInstance().addObserver(this, NotificationCenter.emojiLoaded);
}
@Override
@ -1095,8 +1106,18 @@ public class AlertDialog extends Dialog implements Drawable.Callback {
return false;
}
@Override
public void didReceivedNotification(int id, int account, Object... args) {
if (id == NotificationCenter.emojiLoaded) {
if (messageTextView != null) {
messageTextView.invalidate();
}
}
}
@Override
public void dismiss() {
NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.emojiLoaded);
if (onDismissListener != null) {
onDismissListener.onDismiss(this);
}

View File

@ -76,6 +76,7 @@ public abstract class BaseFragment {
protected boolean inTransitionAnimation = false;
protected boolean fragmentBeginToShow;
private boolean removingFromStack;
private PreviewDelegate previewDelegate;
public BaseFragment() {
classGuid = ConnectionsManager.generateClassGuid();
@ -262,7 +263,7 @@ public abstract class BaseFragment {
}
}
protected ActionBar createActionBar(Context context) {
public ActionBar createActionBar(Context context) {
ActionBar actionBar = new ActionBar(context, getResourceProvider());
actionBar.setBackgroundColor(getThemedColor(Theme.key_actionBarDefault));
actionBar.setItemsBackgroundColor(getThemedColor(Theme.key_actionBarDefaultSelector), false);
@ -290,7 +291,11 @@ public abstract class BaseFragment {
parentDialog.dismiss();
return;
}
finishFragment(true);
if (inPreviewMode && previewDelegate != null) {
previewDelegate.finishFragment();
} else {
finishFragment(true);
}
}
public void finishFragment(boolean animated) {
@ -514,6 +519,10 @@ public abstract class BaseFragment {
}
public void onSlideProgressFront(boolean isOpen, float progress) {
}
public void onTransitionAnimationProgress(boolean isOpen, float progress) {
}
@ -838,4 +847,25 @@ public abstract class BaseFragment {
public void drawOverlay(Canvas canvas, View parent) {
}
public void setPreviewOpenedProgress(float progress) {
}
public void setPreviewReplaceProgress(float progress) {
}
public boolean closeLastFragment() {
return false;
}
public void setPreviewDelegate(PreviewDelegate previewDelegate) {
this.previewDelegate = previewDelegate;
}
public interface PreviewDelegate {
void finishFragment();
}
}

View File

@ -816,7 +816,7 @@ public class BottomSheet extends Dialog {
textView.setTextColor(getThemedColor(Theme.key_featuredStickers_buttonText));
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
textView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
textView.setBackground(Theme.AdaptiveRipple.filledRect(getThemedColor(Theme.key_featuredStickers_addButton), 4));
textView.setBackground(Theme.AdaptiveRipple.filledRect(getThemedColor(Theme.key_featuredStickers_addButton), 6));
addView(textView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, 0, 16, 16, 16, 16));
}
}

View File

@ -245,7 +245,12 @@ public class EmojiThemes {
if (themeInfo == null) {
int settingsIndex = getSettingsIndex(index);
TLRPC.TL_theme tlTheme = getTlTheme(index);
Theme.ThemeInfo baseTheme = Theme.getTheme(Theme.getBaseThemeKey(tlTheme.settings.get(settingsIndex)));
Theme.ThemeInfo baseTheme;
if (tlTheme != null) {
baseTheme = Theme.getTheme(Theme.getBaseThemeKey(tlTheme.settings.get(settingsIndex)));
} else {
baseTheme = Theme.getTheme("Blue");
}
themeInfo = new Theme.ThemeInfo(baseTheme);
accent = themeInfo.createNewAccent(tlTheme, currentAccount, true, settingsIndex);
themeInfo.setCurrentAccentId(accent.id);

View File

@ -385,4 +385,8 @@ public interface INavigationLayout {
BACK,
MENU
}
interface IBackButtonDrawable {
BackButtonState getBackButtonState();
}
}

View File

@ -144,7 +144,7 @@ public class MenuDrawable extends Drawable {
canvas.save();
canvas.translate(getIntrinsicWidth() / 2 - AndroidUtilities.dp(9), getIntrinsicHeight() / 2);
canvas.translate(getIntrinsicWidth() / 2 - AndroidUtilities.dp(9) - AndroidUtilities.dp(1) * currentRotation, getIntrinsicHeight() / 2);
float endYDiff;
float endXDiff;
float startYDiff;

View File

@ -34,6 +34,7 @@ import android.view.accessibility.AccessibilityNodeInfo;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.Emoji;
import org.telegram.messenger.LocaleController;
import org.telegram.ui.Cells.DialogCell;
import org.telegram.ui.Components.AnimatedEmojiDrawable;
import org.telegram.ui.Components.AnimatedEmojiSpan;
@ -93,7 +94,7 @@ public class SimpleTextView extends View implements Drawable.Callback {
private boolean wasLayout;
private boolean rightDrawableOutside;
private boolean ellipsizeByGradient;
private boolean ellipsizeByGradient, ellipsizeByGradientLeft;
private int ellipsizeByGradientWidthDp = 16;
private int paddingRight;
@ -218,9 +219,17 @@ public class SimpleTextView extends View implements Drawable.Callback {
fadePaintBack.setShader(new LinearGradient(0, 0, AndroidUtilities.dp(6), 0, new int[]{0, 0xffffffff}, new float[]{0f, 1f}, Shader.TileMode.CLAMP));
fadePaintBack.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
}
if ((fadeEllpsizePaint == null || fadeEllpsizePaintWidth != AndroidUtilities.dp(ellipsizeByGradientWidthDp)) && ellipsizeByGradient) {
fadeEllpsizePaint = new Paint();
fadeEllpsizePaint.setShader(new LinearGradient(0, 0, fadeEllpsizePaintWidth = AndroidUtilities.dp(ellipsizeByGradientWidthDp), 0, new int[]{0, 0xffffffff}, new float[]{0f, 1f}, Shader.TileMode.CLAMP));
boolean ellipsizeLeft = getAlignment() == Layout.Alignment.ALIGN_NORMAL && LocaleController.isRTL || getAlignment() == Layout.Alignment.ALIGN_OPPOSITE && !LocaleController.isRTL;
if ((fadeEllpsizePaint == null || fadeEllpsizePaintWidth != AndroidUtilities.dp(ellipsizeByGradientWidthDp) || ellipsizeByGradientLeft != ellipsizeLeft) && ellipsizeByGradient) {
if (fadeEllpsizePaint == null) {
fadeEllpsizePaint = new Paint();
}
ellipsizeByGradientLeft = ellipsizeLeft;
if (ellipsizeByGradientLeft) {
fadeEllpsizePaint.setShader(new LinearGradient(0, 0, fadeEllpsizePaintWidth = AndroidUtilities.dp(ellipsizeByGradientWidthDp), 0, new int[]{0xffffffff, 0}, new float[]{0f, 1f}, Shader.TileMode.CLAMP));
} else {
fadeEllpsizePaint.setShader(new LinearGradient(0, 0, fadeEllpsizePaintWidth = AndroidUtilities.dp(ellipsizeByGradientWidthDp), 0, new int[]{0, 0xffffffff}, new float[]{0f, 1f}, Shader.TileMode.CLAMP));
}
fadeEllpsizePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
}
}
@ -254,6 +263,9 @@ public class SimpleTextView extends View implements Drawable.Callback {
}
private void calcOffset(int width) {
if (layout == null) {
return;
}
if (layout.getLineCount() > 0) {
textWidth = (int) Math.ceil(layout.getLineWidth(0));
if (fullLayout != null) {
@ -282,7 +294,7 @@ public class SimpleTextView extends View implements Drawable.Callback {
offsetX = -AndroidUtilities.dp(8);
}
offsetX += getPaddingLeft();
textDoesNotFit = textWidth > width;
textDoesNotFit = textWidth > (width - paddingRight);
if (fullLayout != null && fullLayoutAdditionalWidth > 0) {
fullLayoutLeftCharactersOffset = fullLayout.getPrimaryHorizontal(0) - firstLineLayout.getPrimaryHorizontal(0);
@ -659,6 +671,34 @@ public class SimpleTextView extends View implements Drawable.Callback {
public void setRightPadding(int padding) {
if (paddingRight != padding) {
paddingRight = padding;
int width = getMaxTextWidth() - getPaddingLeft() - getPaddingRight() - minusWidth;
if (leftDrawable != null) {
width -= leftDrawable.getIntrinsicWidth();
width -= drawablePadding;
}
int rightDrawableWidth = 0;
if (rightDrawable != null && !rightDrawableOutside) {
rightDrawableWidth = (int) (rightDrawable.getIntrinsicWidth() * rightDrawableScale);
width -= rightDrawableWidth;
width -= drawablePadding;
}
if (replacedText != null && replacedDrawable != null) {
if ((replacingDrawableTextIndex = text.toString().indexOf(replacedText)) < 0) {
width -= replacedDrawable.getIntrinsicWidth();
width -= drawablePadding;
}
}
if (canHideRightDrawable && rightDrawableWidth != 0 && !rightDrawableOutside) {
CharSequence string = TextUtils.ellipsize(text, textPaint, width, TextUtils.TruncateAt.END);
if (!text.equals(string)) {
rightDrawableHidden = true;
width += rightDrawableWidth;
width += drawablePadding;
}
}
calcOffset(width);
invalidate();
}
}
@ -831,9 +871,12 @@ public class SimpleTextView extends View implements Drawable.Callback {
canvas.translate(getMaxTextWidth() - paddingRight - AndroidUtilities.dp(6), 0);
canvas.drawRect(0, 0, AndroidUtilities.dp(6), getMeasuredHeight(), fadePaintBack);
canvas.restore();
} else if (ellipsizeByGradient && (!widthWrapContent || textDoesNotFit) && fadeEllpsizePaint != null) {
} else if (ellipsizeByGradient && textDoesNotFit && fadeEllpsizePaint != null) {
canvas.save();
canvas.translate(getMaxTextWidth() - paddingRight - fadeEllpsizePaintWidth - AndroidUtilities.dp(rightDrawable != null && !(rightDrawable instanceof AnimatedEmojiDrawable.SwapAnimatedEmojiDrawable) && rightDrawableOutside ? +2 : 0), 0);
updateFadePaints();
if (!ellipsizeByGradientLeft) {
canvas.translate(getMaxTextWidth() - paddingRight - fadeEllpsizePaintWidth - AndroidUtilities.dp(rightDrawable != null && !(rightDrawable instanceof AnimatedEmojiDrawable.SwapAnimatedEmojiDrawable) && rightDrawableOutside ? +2 : 0), 0);
}
canvas.drawRect(0, 0, fadeEllpsizePaintWidth, getMeasuredHeight(), fadeEllpsizePaint);
canvas.restore();
}

View File

@ -2913,7 +2913,7 @@ public class Theme {
public static Paint avatar_backgroundPaint;
public static Drawable listSelector;
public static Drawable[] avatarDrawables = new Drawable[12];
public static Drawable[] avatarDrawables = new Drawable[13];
public static Drawable moveUpDrawable;
@ -3011,6 +3011,7 @@ public class Theme {
public static TextPaint chat_msgTextPaint;
public static TextPaint chat_actionTextPaint;
public static TextPaint chat_actionTextPaint2;
public static TextPaint chat_unlockExtendedMediaTextPaint;
public static TextPaint chat_msgBotButtonPaint;
public static TextPaint chat_msgGameTextPaint;
@ -4048,6 +4049,7 @@ public class Theme {
public static final String key_paint_chatActionBackgroundSelected = "paintChatActionBackgroundSelected";
public static final String key_paint_chatMessageBackgroundSelected = "paintChatMessageBackgroundSelected";
public static final String key_paint_chatActionText = "paintChatActionText";
public static final String key_paint_chatActionText2 = "paintChatActionText2";
public static final String key_paint_chatBotButton = "paintChatBotButton";
public static final String key_paint_chatComposeBackground = "paintChatComposeBackground";
public static final String key_paint_chatTimeBackground = "paintChatTimeBackground";
@ -8799,6 +8801,7 @@ public class Theme {
avatarDrawables[9] = resources.getDrawable(R.drawable.msg_folders_archive);
avatarDrawables[10] = resources.getDrawable(R.drawable.msg_folders_private);
avatarDrawables[11] = resources.getDrawable(R.drawable.chats_replies);
avatarDrawables[12] = resources.getDrawable(R.drawable.other_chats);
if (dialogs_archiveAvatarDrawable != null) {
@ -9091,7 +9094,7 @@ public class Theme {
chat_timePaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG);
}
final float[] emojiSizePercents = new float[] {.7f, .52f, .37f, .28f, .25f, .19f};
final float[] emojiSizePercents = new float[] {.68f, .46f, .34f, .28f, .22f, .19f};
for (int i = 0; i < chat_msgTextPaintEmoji.length; ++i) {
chat_msgTextPaintEmoji[i] = new TextPaint(Paint.ANTI_ALIAS_FLAG);
chat_msgTextPaintEmoji[i].setTextSize(AndroidUtilities.dp(emojiSizePercents[i] * 120f));
@ -9185,6 +9188,7 @@ public class Theme {
chat_statusRecordPaint.setStyle(Paint.Style.STROKE);
chat_statusRecordPaint.setStrokeCap(Paint.Cap.ROUND);
chat_actionTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
chat_actionTextPaint2 = new TextPaint(Paint.ANTI_ALIAS_FLAG);
chat_actionTextPaint.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
chat_unlockExtendedMediaTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
chat_unlockExtendedMediaTextPaint.setTypeface(AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_ROBOTO_MEDIUM));
@ -9208,6 +9212,7 @@ public class Theme {
addChatPaint(key_paint_chatActionBackground, chat_actionBackgroundPaint, key_chat_serviceBackground);
addChatPaint(key_paint_chatActionBackgroundSelected, chat_actionBackgroundSelectedPaint, key_chat_serviceBackgroundSelected);
addChatPaint(key_paint_chatActionText, chat_actionTextPaint, key_chat_serviceText);
addChatPaint(key_paint_chatActionText2, chat_actionTextPaint2, key_chat_serviceText);
addChatPaint(key_paint_chatBotButton, chat_botButtonPaint, key_chat_botButtonText);
addChatPaint(key_paint_chatComposeBackground, chat_composeBackgroundPaint, key_chat_messagePanelBackground);
addChatPaint(key_paint_chatTimeBackground, chat_timeBackgroundPaint, key_chat_mediaTimeBackground);
@ -9522,6 +9527,7 @@ public class Theme {
chat_instantViewRectPaint.setStrokeWidth(AndroidUtilities.dp(1));
chat_pollTimerPaint.setStrokeWidth(AndroidUtilities.dp(1.1f));
chat_actionTextPaint.setTextSize(AndroidUtilities.dp(Math.max(16, SharedConfig.fontSize) - 2));
chat_actionTextPaint2.setTextSize(AndroidUtilities.dp(Math.max(16, SharedConfig.fontSize) - 2));
chat_unlockExtendedMediaTextPaint.setTextSize(AndroidUtilities.dp(Math.max(16, SharedConfig.fontSize)));
chat_contextResult_titleTextPaint.setTextSize(AndroidUtilities.dp(15));
chat_contextResult_descriptionTextPaint.setTextSize(AndroidUtilities.dp(13));
@ -9583,6 +9589,7 @@ public class Theme {
chat_statusPaint.setColor(getColor(key_chat_status));
chat_statusRecordPaint.setColor(getColor(key_chat_status));
chat_actionTextPaint.setColor(getColor(key_chat_serviceText));
chat_actionTextPaint2.setColor(getColor(key_chat_serviceText));
chat_actionTextPaint.linkColor = getColor(key_chat_serviceLink);
chat_unlockExtendedMediaTextPaint.setColor(getColor(key_chat_serviceText));
chat_contextResult_titleTextPaint.setColor(getColor(key_windowBackgroundWhiteBlackText));
@ -9827,6 +9834,7 @@ public class Theme {
setDrawableColor(chat_msgStickerViewsDrawable, 0xffffffff);
setDrawableColor(chat_msgStickerRepliesDrawable, 0xffffffff);
chat_actionTextPaint.setColor(0xffffffff);
chat_actionTextPaint2.setColor(0xffffffff);
chat_actionTextPaint.linkColor = 0xffffffff;
chat_unlockExtendedMediaTextPaint.setColor(0xffffffff);
chat_botButtonPaint.setColor(0xffffffff);
@ -9848,6 +9856,7 @@ public class Theme {
setDrawableColorByKey(chat_msgStickerViewsDrawable, key_chat_serviceText);
setDrawableColorByKey(chat_msgStickerRepliesDrawable, key_chat_serviceText);
chat_actionTextPaint.setColor(getColor(key_chat_serviceText));
chat_actionTextPaint2.setColor(getColor(key_chat_serviceText));
chat_actionTextPaint.linkColor = getColor(key_chat_serviceLink);
chat_unlockExtendedMediaTextPaint.setColor(getColor(key_chat_serviceText));
setDrawableColorByKey(chat_commentStickerDrawable, key_chat_serviceIcon);
@ -9974,6 +9983,10 @@ public class Theme {
setDrawableColorByKey(profile_verifiedCheckDrawable, key_profile_verifiedCheck);
}
public static Drawable getThemedDrawable(Context context, int resId, String key, Theme.ResourcesProvider resourcesProvider) {
return getThemedDrawable(context, resId, getColor(key, resourcesProvider));
}
public static Drawable getThemedDrawable(Context context, int resId, String key) {
return getThemedDrawable(context, resId, getColor(key));
}

View File

@ -24,11 +24,12 @@ import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.TextView;
import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.viewpager.widget.ViewPager;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.BuildVars;
import org.telegram.messenger.ChatObject;
import org.telegram.messenger.ContactsController;
import org.telegram.messenger.DialogObject;
@ -57,6 +58,7 @@ import org.telegram.ui.Components.BlurredRecyclerView;
import org.telegram.ui.Components.CombinedDrawable;
import org.telegram.ui.Components.FlickerLoadingView;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.ListView.AdapterWithDiffUtils;
import org.telegram.ui.Components.PullForegroundDrawable;
import org.telegram.ui.Components.RecyclerListView;
import org.telegram.ui.DialogsActivity;
@ -64,23 +66,24 @@ import org.telegram.ui.DialogsActivity;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Objects;
public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements DialogCell.DialogCellDelegate {
public final static int VIEW_TYPE_DIALOG = 0,
VIEW_TYPE_FLICKER = 1,
VIEW_TYPE_RECENTLY_VIEWED = 2,
VIEW_TYPE_DIVIDER = 3,
VIEW_TYPE_ME_URL = 4,
VIEW_TYPE_EMPTY = 5,
VIEW_TYPE_USER = 6,
VIEW_TYPE_HEADER = 7,
VIEW_TYPE_SHADOW = 8,
VIEW_TYPE_ARCHIVE = 9,
VIEW_TYPE_LAST_EMPTY = 10,
VIEW_TYPE_NEW_CHAT_HINT = 11,
VIEW_TYPE_TEXT = 12,
VIEW_TYPE_CONTACTS_FLICKER = 13,
VIEW_TYPE_HEADER_2 = 14;
VIEW_TYPE_FLICKER = 1,
VIEW_TYPE_RECENTLY_VIEWED = 2,
VIEW_TYPE_DIVIDER = 3,
VIEW_TYPE_ME_URL = 4,
VIEW_TYPE_EMPTY = 5,
VIEW_TYPE_USER = 6,
VIEW_TYPE_HEADER = 7,
VIEW_TYPE_SHADOW = 8,
VIEW_TYPE_ARCHIVE = 9,
VIEW_TYPE_LAST_EMPTY = 10,
VIEW_TYPE_NEW_CHAT_HINT = 11,
VIEW_TYPE_TEXT = 12,
VIEW_TYPE_CONTACTS_FLICKER = 13,
VIEW_TYPE_HEADER_2 = 14;
private Context mContext;
private ArchiveHintCell archiveHintCell;
@ -101,7 +104,11 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
private boolean showArchiveHint;
private boolean isReordering;
private long lastSortTime;
private boolean collapsedView;
RecyclerListView recyclerListView;
private PullForegroundDrawable pullForegroundDrawable;
ArrayList<ItemInternal> itemInternals = new ArrayList<>();
ArrayList<ItemInternal> oldItems = new ArrayList<>();
private Drawable arrowDrawable;
@ -109,6 +116,8 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
private boolean forceShowEmptyCell;
private DialogsActivity parentFragment;
private boolean isTransitionSupport;
private boolean fromDiffUtils;
public DialogsAdapter(DialogsActivity fragment, Context context, int type, int folder, boolean onlySelect, ArrayList<Long> selected, int account) {
mContext = context;
@ -129,6 +138,10 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
}
}
public void setRecyclerListView(RecyclerListView recyclerListView) {
this.recyclerListView = recyclerListView;
}
public void setOpenedDialogId(long id) {
openedDialogId = id;
}
@ -152,8 +165,7 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
}
public boolean isDataSetChanged() {
int current = currentCount;
return current != getItemCount() || current == 1;
return true;
}
public void setDialogsType(int type) {
@ -171,140 +183,115 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
@Override
public int getItemCount() {
MessagesController messagesController = MessagesController.getInstance(currentAccount);
ArrayList<TLRPC.Dialog> array = parentFragment.getDialogsArray(currentAccount, dialogsType, folderId, dialogsListFrozen);
dialogsCount = array.size();
if (!forceUpdatingContacts && !forceShowEmptyCell && dialogsType != 7 && dialogsType != 8 && dialogsType != 11 && dialogsCount == 0 && (folderId != 0 || messagesController.isLoadingDialogs(folderId) || !MessagesController.getInstance(currentAccount).isDialogsEndReached(folderId))) {
onlineContacts = null;
if (BuildVars.LOGS_ENABLED) {
FileLog.d("DialogsAdapter dialogsCount=" + dialogsCount + " dialogsType=" + dialogsType + " isLoadingDialogs=" + messagesController.isLoadingDialogs(folderId) + " isDialogsEndReached=" + MessagesController.getInstance(currentAccount).isDialogsEndReached(folderId));
currentCount = itemInternals.size();
return currentCount;
}
public int findDialogPosition(long dialogId) {
for (int i = 0; i < itemInternals.size(); i++) {
if (itemInternals.get(i).dialog != null && itemInternals.get(i).dialog.id == dialogId) {
return i;
}
if (folderId == 1 && showArchiveHint) {
return (currentCount = 2);
}
return (currentCount = 0);
}
if (dialogsCount == 0 && messagesController.isLoadingDialogs(folderId)) {
return (currentCount = 0);
}
int count = dialogsCount;
if (dialogsType == 7 || dialogsType == 8) {
if (dialogsCount == 0) {
count++;
}
return -1;
}
public int fixScrollGap(RecyclerListView animationSupportListView, int p, int offset, boolean hasHidenArchive, boolean oppened) {
int itemsToEnd = getItemCount() - p ;
int cellHeight = AndroidUtilities.dp(SharedConfig.useThreeLinesLayout ? 78 : 72);
int bottom = offset + animationSupportListView.getPaddingTop() + itemsToEnd * cellHeight + itemsToEnd - 1;
//fix height changed
int top = offset + animationSupportListView.getPaddingTop() - p * cellHeight - p;
if (oppened) {
bottom -= AndroidUtilities.dp(44);
} else {
if (!messagesController.isDialogsEndReached(folderId) || dialogsCount == 0) {
count++;
}
bottom += AndroidUtilities.dp(44);
}
boolean hasContacts = false;
if (hasHints) {
count += 2 + messagesController.hintDialogs.size();
} else if (dialogsType == 0 && folderId == 0 && messagesController.isDialogsEndReached(folderId)) {
if (ContactsController.getInstance(currentAccount).contacts.isEmpty() && !ContactsController.getInstance(currentAccount).doneLoadingContacts && !forceUpdatingContacts) {
onlineContacts = null;
if (BuildVars.LOGS_ENABLED) {
FileLog.d("DialogsAdapter loadingContacts=" + (ContactsController.getInstance(currentAccount).contacts.isEmpty() && !ContactsController.getInstance(currentAccount).doneLoadingContacts) + "dialogsCount=" + dialogsCount + " dialogsType=" + dialogsType);
}
return (currentCount = 0);
}
if (hasHidenArchive) {
top += cellHeight;
}
if (top > animationSupportListView.getPaddingTop()) {
return offset + animationSupportListView.getPaddingTop() - top;
}
if (bottom < animationSupportListView.getMeasuredHeight()) {
return offset + (animationSupportListView.getMeasuredHeight() - bottom);
}
return offset;
}
if (messagesController.getAllFoldersDialogsCount() <= 10 && ContactsController.getInstance(currentAccount).doneLoadingContacts && !ContactsController.getInstance(currentAccount).contacts.isEmpty()) {
if (onlineContacts == null || prevDialogsCount != dialogsCount || prevContactsCount != ContactsController.getInstance(currentAccount).contacts.size()) {
onlineContacts = new ArrayList<>(ContactsController.getInstance(currentAccount).contacts);
prevContactsCount = onlineContacts.size();
prevDialogsCount = messagesController.dialogs_dict.size();
long selfId = UserConfig.getInstance(currentAccount).clientUserId;
for (int a = 0, N = onlineContacts.size(); a < N; a++) {
long userId = onlineContacts.get(a).user_id;
if (userId == selfId || messagesController.dialogs_dict.get(userId) != null) {
onlineContacts.remove(a);
a--;
N--;
}
}
if (onlineContacts.isEmpty()) {
onlineContacts = null;
}
sortOnlineContacts(false);
private class ItemInternal extends AdapterWithDiffUtils.Item {
if (parentFragment.getContactsAlpha() == 0f) {
registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
@Override
public void onChanged() {
parentFragment.setContactsAlpha(0f);
parentFragment.animateContactsAlpha(1f);
TLRPC.Dialog dialog;
TLRPC.RecentMeUrl recentMeUrl;
TLRPC.TL_contact contact;
boolean isForumCell;
private boolean pinned;
private boolean isFolder;
unregisterAdapterDataObserver(this);
}
});
}
}
if (onlineContacts != null) {
count += onlineContacts.size() + 2;
hasContacts = true;
}
public ItemInternal(int viewType, TLRPC.Dialog dialog) {
super(viewType, true);
this.dialog = dialog;
if (dialog != null) {
pinned = dialog.pinned;
isFolder = dialog.isFolder;
isForumCell = MessagesController.getInstance(currentAccount).isForum(dialog.id);
}
}
if (folderId == 0 && !hasContacts && dialogsCount == 0 && forceUpdatingContacts) {
count += 3;
}
if (folderId == 0 && onlineContacts != null) {
if (!hasContacts) {
onlineContacts = null;
}
}
if (folderId == 1 && showArchiveHint) {
count += 2;
}
if (folderId == 0 && dialogsCount != 0) {
count++;
if (dialogsCount > 10 && dialogsType == 0) {
count++;
}
}
if (dialogsType == 11 || dialogsType == 13) {
count += 2;
} else if (dialogsType == 12) {
count += 1;
}
currentCount = count;
return count;
public ItemInternal(int viewTypeMeUrl, TLRPC.RecentMeUrl recentMeUrl) {
super(viewTypeMeUrl, true);
this.recentMeUrl = recentMeUrl;
}
public ItemInternal(int viewTypeEmpty) {
super(viewTypeEmpty, true);
}
public ItemInternal(int viewTypeUser, TLRPC.TL_contact tl_contact) {
super(viewTypeUser, true);
contact = tl_contact;
}
boolean compare(ItemInternal itemInternal) {
if (viewType != itemInternal.viewType) {
return false;
}
if (viewType == VIEW_TYPE_DIALOG) {
return dialog != null && itemInternal.dialog != null && dialog.id == itemInternal.dialog.id
&& isFolder == itemInternal.isFolder &&
isForumCell == itemInternal.isForumCell &&
pinned == itemInternal.pinned;
}
if (viewType == VIEW_TYPE_HEADER_2) {
return dialog != null && itemInternal.dialog != null && dialog.id == itemInternal.dialog.id && dialog.isFolder == itemInternal.dialog.isFolder;
}
if (viewType == VIEW_TYPE_ME_URL) {
return recentMeUrl != null && itemInternal.recentMeUrl != null && recentMeUrl.url != null && recentMeUrl.url.equals(recentMeUrl.url);
}
if (viewType == VIEW_TYPE_USER) {
return contact != null && itemInternal.contact != null && contact.user_id == itemInternal.contact.user_id;
}
return true;
}
@Override
public int hashCode() {
return Objects.hash(dialog, recentMeUrl, contact);
}
}
public TLObject getItem(int i) {
if (onlineContacts != null && (dialogsCount == 0 || i >= dialogsCount)) {
if (dialogsCount == 0) {
i -= 3;
} else {
i -= dialogsCount + 2;
}
if (i < 0 || i >= onlineContacts.size()) {
return null;
}
return MessagesController.getInstance(currentAccount).getUser(onlineContacts.get(i).user_id);
}
if (showArchiveHint) {
i -= 2;
} else if (dialogsType == 11 || dialogsType == 13) {
i -= 2;
} else if (dialogsType == 12) {
i -= 1;
}
ArrayList<TLRPC.Dialog> arrayList = parentFragment.getDialogsArray(currentAccount, dialogsType, folderId, dialogsListFrozen);
if (hasHints) {
int count = MessagesController.getInstance(currentAccount).hintDialogs.size();
if (i < 2 + count) {
return MessagesController.getInstance(currentAccount).hintDialogs.get(i - 1);
} else {
i -= count + 2;
}
}
if (i < 0 || i >= arrayList.size()) {
if (i < 0 || i >= itemInternals.size()) {
return null;
}
return arrayList.get(i);
if (itemInternals.get(i).dialog != null) {
return itemInternals.get(i).dialog;
} else if (itemInternals.get(i).contact != null) {
return itemInternals.get(i).contact;
} else if (itemInternals.get(i).recentMeUrl != null) {
return itemInternals.get(i).recentMeUrl;
}
return null;
}
public void sortOnlineContacts(boolean notify) {
@ -367,6 +354,10 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
dialogsListFrozen = frozen;
}
public boolean getDialogsListIsFrozen() {
return dialogsListFrozen;
}
public ViewPager getArchiveHintCellPager() {
return archiveHintCell != null ? archiveHintCell.getViewPager() : null;
}
@ -375,19 +366,71 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
hasHints = folderId == 0 && dialogsType == 0 && !isOnlySelect && !MessagesController.getInstance(currentAccount).hintDialogs.isEmpty();
}
public void updateList(RecyclerListView recyclerListView) {
oldItems.clear();
oldItems.addAll(itemInternals);
updateItemList();
if (recyclerListView != null && recyclerListView.getChildCount() > 0) {
LinearLayoutManager layoutManager = ((LinearLayoutManager) recyclerListView.getLayoutManager());
View view = null;
int position = -1;
int top = Integer.MAX_VALUE;
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) {
view = child;
position = childPosition;
top = child.getTop();
}
}
if (view != null) {
layoutManager.scrollToPositionWithOffset(position, view.getTop() - recyclerListView.getPaddingTop());
}
}
fromDiffUtils = true;
DiffUtil.calculateDiff(new DiffUtil.Callback() {
@Override
public int getOldListSize() {
return oldItems.size();
}
@Override
public int getNewListSize() {
return itemInternals.size();
}
@Override
public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
return oldItems.get(oldItemPosition).compare(itemInternals.get(newItemPosition));
}
@Override
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
return oldItems.get(oldItemPosition).viewType == itemInternals.get(newItemPosition).viewType;
}
}).dispatchUpdatesTo(this);
fromDiffUtils = false;
}
@Override
public void notifyDataSetChanged() {
updateHasHints();
updateItemList();
super.notifyDataSetChanged();
}
@Override
public void onViewAttachedToWindow(RecyclerView.ViewHolder holder) {
if (holder.itemView instanceof DialogCell) {
DialogCell dialogCell = (DialogCell) holder.itemView;
dialogCell.onReorderStateChanged(isReordering, false);
int position = fixPosition(holder.getAdapterPosition());
dialogCell.setDialogIndex(position);
// dialogCell.setDialogIndex(position);
// dialogCell.collapsed = collapsedView;
dialogCell.checkCurrentDialogIndex(dialogsListFrozen);
dialogCell.setChecked(selectedDialogs.contains(dialogCell.getDialogId()), false);
}
@ -413,6 +456,7 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
dialogCell.setArchivedPullAnimation(pullForegroundDrawable);
dialogCell.setPreloader(preloader);
dialogCell.setDialogCellDelegate(this);
dialogCell.setIsTransitionSupport(isTransitionSupport);
view = dialogCell;
}
break;
@ -564,6 +608,7 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
}
public int lastDialogsEmptyType = -1;
public int dialogsEmptyType() {
if (dialogsType == 7 || dialogsType == 8) {
if (MessagesController.getInstance(currentAccount).isDialogsEndReached(folderId)) {
@ -643,6 +688,11 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
}
cell.setChecked(selectedDialogs.contains(dialog.id), false);
cell.setDialog(dialog, dialogsType, folderId);
cell.checkHeight();
if (cell.collapsed != collapsedView) {
cell.collapsed = collapsedView;
cell.requestLayout();
}
if (preloader != null && i < 10) {
preloader.add(dialog.id);
}
@ -681,13 +731,8 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
}
case VIEW_TYPE_USER: {
UserCell cell = (UserCell) holder.itemView;
int position;
if (dialogsCount == 0) {
position = i - 3;
} else {
position = i - dialogsCount - 2;
}
TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(onlineContacts.get(position).user_id);
TLRPC.TL_contact contact = (TLRPC.TL_contact) getItem(i);
TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(contact.user_id);
cell.setData(user, null, null, 0);
break;
}
@ -755,113 +800,30 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
@Override
public int getItemViewType(int i) {
if (dialogsCount == 0 && forceUpdatingContacts) {
switch (i) {
case 0:
return VIEW_TYPE_EMPTY;
case 1:
return VIEW_TYPE_SHADOW;
case 2:
return VIEW_TYPE_HEADER;
case 3:
return VIEW_TYPE_CONTACTS_FLICKER;
}
} else if (onlineContacts != null) {
if (dialogsCount == 0) {
if (i == 0) {
return VIEW_TYPE_EMPTY;
} else if (i == 1) {
return VIEW_TYPE_SHADOW;
} else if (i == 2) {
return VIEW_TYPE_HEADER;
}
} else {
if (i < dialogsCount) {
return VIEW_TYPE_DIALOG;
} else if (i == dialogsCount) {
return VIEW_TYPE_SHADOW;
} else if (i == dialogsCount + 1) {
return VIEW_TYPE_HEADER;
} else if (i == currentCount - 1) {
return VIEW_TYPE_LAST_EMPTY;
}
}
return VIEW_TYPE_USER;
} else if (hasHints) {
int count = MessagesController.getInstance(currentAccount).hintDialogs.size();
if (i < 2 + count) {
if (i == 0) {
return VIEW_TYPE_RECENTLY_VIEWED;
} else if (i == 1 + count) {
return VIEW_TYPE_DIVIDER;
}
return VIEW_TYPE_ME_URL;
} else {
i -= 2 + count;
}
} else if (showArchiveHint) {
if (i == 0) {
return VIEW_TYPE_ARCHIVE;
} else if (i == 1) {
return VIEW_TYPE_SHADOW;
} else {
i -= 2;
}
} else if (dialogsType == 11 || dialogsType == 13) {
if (i == 0) {
return VIEW_TYPE_HEADER;
} else if (i == 1) {
return VIEW_TYPE_TEXT;
} else {
i -= 2;
}
} else if (dialogsType == 12) {
if (i == 0) {
return VIEW_TYPE_HEADER;
} else {
i -= 1;
}
}
if (folderId == 0 && dialogsCount > 10 && i == currentCount - 2 && dialogsType == 0) {
return VIEW_TYPE_NEW_CHAT_HINT;
}
int size = parentFragment.getDialogsArray(currentAccount, dialogsType, folderId, dialogsListFrozen).size();
if (i == size) {
if (!forceShowEmptyCell && dialogsType != 7 && dialogsType != 8 && !MessagesController.getInstance(currentAccount).isDialogsEndReached(folderId)) {
return VIEW_TYPE_FLICKER;
} else if (size == 0) {
return VIEW_TYPE_EMPTY;
} else {
return VIEW_TYPE_LAST_EMPTY;
}
} else if (i > size) {
return VIEW_TYPE_LAST_EMPTY;
}
if (dialogsType == 2 && getItem(i) instanceof DialogsActivity.DialogsHeader) {
return VIEW_TYPE_HEADER_2;
}
return VIEW_TYPE_DIALOG;
return itemInternals.get(i).viewType;
}
@Override
public void notifyItemMoved(int fromPosition, int toPosition) {
ArrayList<TLRPC.Dialog> dialogs = parentFragment.getDialogsArray(currentAccount, dialogsType, folderId, false);
int fromIndex = fixPosition(fromPosition);
int toIndex = fixPosition(toPosition);
TLRPC.Dialog fromDialog = dialogs.get(fromIndex);
TLRPC.Dialog toDialog = dialogs.get(toIndex);
if (dialogsType == 7 || dialogsType == 8) {
MessagesController.DialogFilter filter = MessagesController.getInstance(currentAccount).selectedDialogFilter[dialogsType == 8 ? 1 : 0];
int idx1 = filter.pinnedDialogs.get(fromDialog.id);
int idx2 = filter.pinnedDialogs.get(toDialog.id);
filter.pinnedDialogs.put(fromDialog.id, idx2);
filter.pinnedDialogs.put(toDialog.id, idx1);
} else {
int oldNum = fromDialog.pinnedNum;
fromDialog.pinnedNum = toDialog.pinnedNum;
toDialog.pinnedNum = oldNum;
if (!fromDiffUtils) {
ArrayList<TLRPC.Dialog> dialogs = parentFragment.getDialogsArray(currentAccount, dialogsType, folderId, false);
int fromIndex = fixPosition(fromPosition);
int toIndex = fixPosition(toPosition);
TLRPC.Dialog fromDialog = dialogs.get(fromIndex);
TLRPC.Dialog toDialog = dialogs.get(toIndex);
if (dialogsType == 7 || dialogsType == 8) {
MessagesController.DialogFilter filter = MessagesController.getInstance(currentAccount).selectedDialogFilter[dialogsType == 8 ? 1 : 0];
int idx1 = filter.pinnedDialogs.get(fromDialog.id);
int idx2 = filter.pinnedDialogs.get(toDialog.id);
filter.pinnedDialogs.put(fromDialog.id, idx2);
filter.pinnedDialogs.put(toDialog.id, idx1);
} else {
int oldNum = fromDialog.pinnedNum;
fromDialog.pinnedNum = toDialog.pinnedNum;
toDialog.pinnedNum = oldNum;
}
Collections.swap(dialogs, fromIndex, toIndex);
}
Collections.swap(dialogs, fromIndex, toIndex);
super.notifyItemMoved(fromPosition, toPosition);
}
@ -902,6 +864,34 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
return selectedDialogs.isEmpty();
}
public void setIsTransitionSupport() {
this.isTransitionSupport = true;
}
public void setCollapsedView(boolean collapsedView, RecyclerListView listView) {
this.collapsedView = collapsedView;
for (int i = 0; i < listView.getChildCount(); i++) {
if (listView.getChildAt(i) instanceof DialogCell) {
((DialogCell) listView.getChildAt(i)).collapsed = collapsedView;
}
}
for (int i = 0; i < listView.getCachedChildCount(); i++) {
if (listView.getCachedChildAt(i) instanceof DialogCell) {
((DialogCell) listView.getCachedChildAt(i)).collapsed = collapsedView;
}
}
for (int i = 0; i < listView.getHiddenChildCount(); i++) {
if (listView.getHiddenChildAt(i) instanceof DialogCell) {
((DialogCell) listView.getHiddenChildAt(i)).collapsed = collapsedView;
}
}
for (int i = 0; i < listView.getAttachedScrapChildCount(); i++) {
if (listView.getAttachedScrapChildAt(i) instanceof DialogCell) {
((DialogCell) listView.getAttachedScrapChildAt(i)).collapsed = collapsedView;
}
}
}
public static class DialogsPreloader {
private final int MAX_REQUEST_COUNT = 4;
@ -973,7 +963,7 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
private boolean preloadIsAvilable() {
return false;
// return DownloadController.getInstance(UserConfig.selectedAccount).getCurrentDownloadMask() != 0;
// return DownloadController.getInstance(UserConfig.selectedAccount).getCurrentDownloadMask() != 0;
}
public void updateList() {
@ -1029,7 +1019,7 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
}
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int size = parentFragment.getDialogsArray(currentAccount, dialogsType, folderId, dialogsListFrozen).size();
int size = itemInternals.size();
boolean hasArchive = dialogsType == 0 && MessagesController.getInstance(currentAccount).dialogs_dict.get(DialogObject.makeFolderDialogId(1)) != null;
View parent = (View) getParent();
int height;
@ -1051,7 +1041,17 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
}
height -= blurOffset;
int cellHeight = AndroidUtilities.dp(SharedConfig.useThreeLinesLayout ? 78 : 72);
int dialogsHeight = size * cellHeight + (size - 1);
int dialogsHeight = 0;
for (int i = 0; i < size; i++) {
if (itemInternals.get(i).viewType == VIEW_TYPE_DIALOG) {
if (itemInternals.get(i).isForumCell && !collapsedView) {
dialogsHeight += AndroidUtilities.dp(SharedConfig.useThreeLinesLayout ? 86 : 91);
} else {
dialogsHeight += cellHeight;
}
}
}
dialogsHeight += size - 1;
if (onlineContacts != null) {
dialogsHeight += onlineContacts.size() * AndroidUtilities.dp(58) + (onlineContacts.size() - 1) + AndroidUtilities.dp(52);
}
@ -1079,4 +1079,108 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), height);
}
}
private void updateItemList() {
itemInternals.clear();
updateHasHints();
MessagesController messagesController = MessagesController.getInstance(currentAccount);
ArrayList<TLRPC.Dialog> array = parentFragment.getDialogsArray(currentAccount, dialogsType, folderId, dialogsListFrozen);
dialogsCount = array.size();
if (!hasHints && dialogsType == 0 && folderId == 0 && messagesController.isDialogsEndReached(folderId) && !forceUpdatingContacts) {
if (messagesController.getAllFoldersDialogsCount() <= 10 && ContactsController.getInstance(currentAccount).doneLoadingContacts && !ContactsController.getInstance(currentAccount).contacts.isEmpty()) {
onlineContacts = new ArrayList<>(ContactsController.getInstance(currentAccount).contacts);
long selfId = UserConfig.getInstance(currentAccount).clientUserId;
for (int a = 0, N = onlineContacts.size(); a < N; a++) {
long userId = onlineContacts.get(a).user_id;
if (userId == selfId || messagesController.dialogs_dict.get(userId) != null) {
onlineContacts.remove(a);
a--;
N--;
}
}
if (onlineContacts.isEmpty()) {
onlineContacts = null;
} else {
sortOnlineContacts(false);
}
} else {
onlineContacts = null;
}
}
boolean stopUpdate = false;
if (collapsedView || isTransitionSupport) {
for (int k = 0; k < array.size(); k++) {
if (dialogsType == 2 && array.get(k) instanceof DialogsActivity.DialogsHeader) {
itemInternals.add(new ItemInternal(VIEW_TYPE_HEADER_2, array.get(k)));
} else {
itemInternals.add(new ItemInternal(VIEW_TYPE_DIALOG, array.get(k)));
}
}
return;
}
if (dialogsCount == 0 && forceUpdatingContacts) {
itemInternals.add(new ItemInternal(VIEW_TYPE_EMPTY));
itemInternals.add(new ItemInternal(VIEW_TYPE_SHADOW));
itemInternals.add(new ItemInternal(VIEW_TYPE_HEADER));
itemInternals.add(new ItemInternal(VIEW_TYPE_CONTACTS_FLICKER));
} else if (onlineContacts != null) {
if (dialogsCount == 0) {
itemInternals.add(new ItemInternal(VIEW_TYPE_EMPTY));
itemInternals.add(new ItemInternal(VIEW_TYPE_SHADOW));
itemInternals.add(new ItemInternal(VIEW_TYPE_HEADER));
} else {
for (int k = 0; k < array.size(); k++) {
itemInternals.add(new ItemInternal(VIEW_TYPE_DIALOG, array.get(k)));
}
itemInternals.add(new ItemInternal(VIEW_TYPE_SHADOW));
itemInternals.add(new ItemInternal(VIEW_TYPE_HEADER));
for (int k = 0; k < onlineContacts.size(); k++) {
itemInternals.add(new ItemInternal(VIEW_TYPE_USER, onlineContacts.get(k)));
}
itemInternals.add(new ItemInternal(VIEW_TYPE_LAST_EMPTY));
}
stopUpdate = true;
} else if (hasHints) {
int count = MessagesController.getInstance(currentAccount).hintDialogs.size();
itemInternals.add(new ItemInternal(VIEW_TYPE_RECENTLY_VIEWED));
for (int k = 0; k < count; k++) {
itemInternals.add(new ItemInternal(VIEW_TYPE_ME_URL, MessagesController.getInstance(currentAccount).hintDialogs.get(k)));
}
itemInternals.add(new ItemInternal(VIEW_TYPE_DIVIDER));
} else if (showArchiveHint) {
itemInternals.add(new ItemInternal(VIEW_TYPE_ARCHIVE));
itemInternals.add(new ItemInternal(VIEW_TYPE_SHADOW));
} else if (dialogsType == 11 || dialogsType == 13) {
itemInternals.add(new ItemInternal(VIEW_TYPE_HEADER));
itemInternals.add(new ItemInternal(VIEW_TYPE_TEXT));
} else if (dialogsType == 12) {
itemInternals.add(new ItemInternal(VIEW_TYPE_HEADER));
}
if (!stopUpdate) {
for (int k = 0; k < array.size(); k++) {
if (dialogsType == 2 && array.get(k) instanceof DialogsActivity.DialogsHeader) {
itemInternals.add(new ItemInternal(VIEW_TYPE_HEADER_2, array.get(k)));
} else {
itemInternals.add(new ItemInternal(VIEW_TYPE_DIALOG, array.get(k)));
}
}
}
if (!forceShowEmptyCell && dialogsType != 7 && dialogsType != 8 && !MessagesController.getInstance(currentAccount).isDialogsEndReached(folderId)) {
itemInternals.add(new ItemInternal(VIEW_TYPE_FLICKER));
} else if (dialogsCount == 0) {
itemInternals.add(new ItemInternal(VIEW_TYPE_EMPTY));
} else {
if (folderId == 0 && dialogsCount > 10 && dialogsType == 0) {
itemInternals.add(new ItemInternal(VIEW_TYPE_NEW_CHAT_HINT));
}
itemInternals.add(new ItemInternal(VIEW_TYPE_LAST_EMPTY));
}
}
}

View File

@ -49,6 +49,7 @@ import org.telegram.ui.Cells.HashtagSearchCell;
import org.telegram.ui.Cells.HintDialogCell;
import org.telegram.ui.Cells.ProfileSearchCell;
import org.telegram.ui.Cells.TextCell;
import org.telegram.ui.Cells.TopicSearchCell;
import org.telegram.ui.Components.FlickerLoadingView;
import org.telegram.ui.Components.ForegroundColorSpanThemable;
import org.telegram.ui.Components.RecyclerListView;
@ -64,25 +65,32 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
private final int VIEW_TYPE_PROFILE_CELL = 0;
private final int VIEW_TYPE_GRAY_SECTION = 1;
private final int VIEW_TYPE_DIALOG_CELL = 2;
private final int VIEW_TYPE_LOADING = 3;
private final int VIEW_TYPE_HASHTAG_CELL = 4;
private final int VIEW_TYPE_CATEGORY_LIST = 5;
private final int VIEW_TYPE_ADD_BY_PHONE = 6;
private final int VIEW_TYPE_TOPIC_CELL = 3;
private final int VIEW_TYPE_LOADING = 4;
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 Context mContext;
private Runnable searchRunnable;
private Runnable searchRunnable2;
private ArrayList<Object> searchResult = new ArrayList<>();
private ArrayList<TLRPC.TL_forumTopic> searchTopics = new ArrayList<>();
private ArrayList<CharSequence> searchResultNames = new ArrayList<>();
private ArrayList<MessageObject> searchForumResultMessages = new ArrayList<>();
private ArrayList<MessageObject> searchResultMessages = new ArrayList<>();
private ArrayList<String> searchResultHashtags = new ArrayList<>();
private String lastSearchText;
private boolean searchWas;
private int reqId = 0;
private int lastReqId;
private DialogsSearchAdapterDelegate delegate;
private int reqForumId = 0;
private int lastForumReqId;
public DialogsSearchAdapterDelegate delegate;
private int needMessagesSearch;
private boolean messagesSearchEndReached;
private boolean localMessagesSearchEndReached;
public int localMessagesLoadingRow = -1;
private String lastMessagesSearchString;
private String currentMessagesQuery;
private int nextSearchRate;
@ -105,6 +113,7 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
private ArrayList<RecentSearchObject> recentSearchObjects = new ArrayList<>();
private ArrayList<RecentSearchObject> filteredRecentSearchObjects = new ArrayList<>();
private ArrayList<RecentSearchObject> filtered2RecentSearchObjects = new ArrayList<>();
private String filteredRecentQuery = null;
private LongSparseArray<RecentSearchObject> recentSearchObjectsById = new LongSparseArray<>();
private ArrayList<FiltersView.DateData> localTipDates = new ArrayList<>();
@ -136,6 +145,7 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
void needClearList();
void runResultsEnterAnimation();
boolean isSelected(long dialogId);
long getSearchForumDialogId();
}
public static class CategoryAdapterRecycler extends RecyclerListView.SelectionAdapter {
@ -259,20 +269,144 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
}
public boolean isMessagesSearchEndReached() {
return messagesSearchEndReached;
return (delegate.getSearchForumDialogId() == 0 || localMessagesSearchEndReached) && messagesSearchEndReached;
}
public void loadMoreSearchMessages() {
if (reqId != 0) {
if (reqForumId != 0 && reqId != 0) {
return;
}
searchMessagesInternal(lastMessagesSearchString, lastMessagesSearchId);
if (delegate != null && delegate.getSearchForumDialogId() != 0 && !localMessagesSearchEndReached) {
searchForumMessagesInternal(lastMessagesSearchString, lastMessagesSearchId);
} else {
searchMessagesInternal(lastMessagesSearchString, lastMessagesSearchId);
}
}
public String getLastSearchString() {
return lastMessagesSearchString;
}
private void searchForumMessagesInternal(final String query, int searchId) {
if (delegate == null || delegate.getSearchForumDialogId() == 0) {
return;
}
if (needMessagesSearch == 0 || TextUtils.isEmpty(lastMessagesSearchString) && TextUtils.isEmpty(query)) {
return;
}
if (reqForumId != 0) {
ConnectionsManager.getInstance(currentAccount).cancelRequest(reqForumId, true);
reqForumId = 0;
}
if (TextUtils.isEmpty(query)) {
filteredRecentQuery = null;
searchResultMessages.clear();
searchForumResultMessages.clear();
lastForumReqId = 0;
lastMessagesSearchString = null;
searchWas = false;
notifyDataSetChanged();
return;
}
final long dialogId = delegate.getSearchForumDialogId();
final TLRPC.TL_messages_search req = new TLRPC.TL_messages_search();
req.limit = 20;
req.q = query;
req.filter = new TLRPC.TL_inputMessagesFilterEmpty();
req.peer = MessagesController.getInstance(currentAccount).getInputPeer(dialogId);
if (query.equals(lastMessagesSearchString) && !searchForumResultMessages.isEmpty()) {
req.add_offset = searchForumResultMessages.size();
}
lastMessagesSearchString = query;
final int currentReqId = ++lastForumReqId;
reqForumId = ConnectionsManager.getInstance(currentAccount).sendRequest(req, (response, error) -> {
final ArrayList<MessageObject> messageObjects = new ArrayList<>();
if (error == null) {
TLRPC.messages_Messages res = (TLRPC.messages_Messages) response;
LongSparseArray<TLRPC.Chat> chatsMap = new LongSparseArray<>();
LongSparseArray<TLRPC.User> usersMap = new LongSparseArray<>();
for (int a = 0; a < res.chats.size(); a++) {
TLRPC.Chat chat = res.chats.get(a);
chatsMap.put(chat.id, chat);
}
for (int a = 0; a < res.users.size(); a++) {
TLRPC.User user = res.users.get(a);
usersMap.put(user.id, user);
}
for (int a = 0; a < res.messages.size(); a++) {
TLRPC.Message message = res.messages.get(a);
MessageObject messageObject = new MessageObject(currentAccount, message, usersMap, chatsMap, false, true);
messageObjects.add(messageObject);
messageObject.setQuery(query);
}
}
AndroidUtilities.runOnUIThread(() -> {
if (currentReqId == lastForumReqId && (searchId <= 0 || searchId == lastSearchId)) {
waitingResponseCount--;
if (error == null) {
currentMessagesQuery = query;
TLRPC.messages_Messages res = (TLRPC.messages_Messages) response;
MessagesStorage.getInstance(currentAccount).putUsersAndChats(res.users, res.chats, true, true);
MessagesController.getInstance(currentAccount).putUsers(res.users, false);
MessagesController.getInstance(currentAccount).putChats(res.chats, false);
if (req.add_offset == 0) {
searchForumResultMessages.clear();
}
nextSearchRate = res.next_rate;
for (int a = 0; a < res.messages.size(); a++) {
TLRPC.Message message = res.messages.get(a);
long did = MessageObject.getDialogId(message);
int maxId = MessagesController.getInstance(currentAccount).deletedHistory.get(did);
if (maxId != 0 && message.id <= maxId) {
continue;
}
searchForumResultMessages.add(messageObjects.get(a));
}
searchWas = true;
localMessagesSearchEndReached = res.messages.size() != 20;
if (searchId > 0) {
lastMessagesSearchId = searchId;
if (lastLocalSearchId != searchId) {
searchResult.clear();
}
if (lastGlobalSearchId != searchId) {
searchAdapterHelper.clear();
}
}
searchAdapterHelper.mergeResults(searchResult, filtered2RecentSearchObjects);
if (delegate != null) {
delegate.searchStateChanged(waitingResponseCount > 0, true);
delegate.runResultsEnterAnimation();
}
notifyDataSetChanged();
}
}
reqForumId = 0;
});
}, ConnectionsManager.RequestFlagFailOnServerErrors);
}
private void searchTopics(final String query) {
searchTopics.clear();
if (delegate == null || delegate.getSearchForumDialogId() == 0) {
return;
}
if (!TextUtils.isEmpty(query)) {
long dialogId = delegate.getSearchForumDialogId();
ArrayList<TLRPC.TL_forumTopic> topics = MessagesController.getInstance(currentAccount).getTopicsController().getTopics(-dialogId);
String searchTrimmed = query.trim();
for (int i = 0; i < topics.size(); i++) {
if (topics.get(i) != null && topics.get(i).title.toLowerCase().contains(searchTrimmed)) {
searchTopics.add(topics.get(i));
topics.get(i).searchQuery = searchTrimmed;
}
}
}
notifyDataSetChanged();
}
private void searchMessagesInternal(final String query, int searchId) {
if (needMessagesSearch == 0 || TextUtils.isEmpty(lastMessagesSearchString) && TextUtils.isEmpty(query)) {
return;
@ -284,6 +418,7 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
if (TextUtils.isEmpty(query)) {
filteredRecentQuery = null;
searchResultMessages.clear();
searchForumResultMessages.clear();
lastReqId = 0;
lastMessagesSearchString = null;
searchWas = false;
@ -291,7 +426,7 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
return;
} else {
filterRecent(query);
searchAdapterHelper.mergeResults(searchResult, filteredRecentSearchObjects);
searchAdapterHelper.mergeResults(searchResult, filtered2RecentSearchObjects);
}
final TLRPC.TL_messages_searchGlobal req = new TLRPC.TL_messages_searchGlobal();
@ -354,7 +489,21 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
if (maxId != 0 && message.id <= maxId) {
continue;
}
searchResultMessages.add(messageObjects.get(a));
MessageObject msg = messageObjects.get(a);
if (!searchForumResultMessages.isEmpty()) {
boolean foundDuplicate = false;
for (int i = 0; i < searchForumResultMessages.size(); ++i) {
MessageObject msg2 = searchForumResultMessages.get(i);
if (msg2 != null && msg != null && msg.getId() == msg2.getId() && msg.getDialogId() == msg2.getDialogId()) {
foundDuplicate = true;
break;
}
}
if (foundDuplicate) {
continue;
}
}
searchResultMessages.add(msg);
long dialog_id = MessageObject.getDialogId(message);
ConcurrentHashMap<Long, Integer> read_max = message.out ? MessagesController.getInstance(currentAccount).dialogs_read_outbox_max : MessagesController.getInstance(currentAccount).dialogs_read_inbox_max;
Integer value = read_max.get(dialog_id);
@ -375,7 +524,7 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
searchAdapterHelper.clear();
}
}
searchAdapterHelper.mergeResults(searchResult, filteredRecentSearchObjects);
searchAdapterHelper.mergeResults(searchResult, filtered2RecentSearchObjects);
if (delegate != null) {
delegate.searchStateChanged(waitingResponseCount > 0, true);
delegate.runResultsEnterAnimation();
@ -545,8 +694,8 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
public void clearRecentSearch() {
StringBuilder queryFilter = null;
if (searchWas) {
while (filteredRecentSearchObjects.size() > 0) {
RecentSearchObject obj = filteredRecentSearchObjects.remove(0);
while (filtered2RecentSearchObjects.size() > 0) {
RecentSearchObject obj = filtered2RecentSearchObjects.remove(0);
recentSearchObjects.remove(obj);
recentSearchObjectsById.remove(obj.did);
if (queryFilter == null) {
@ -562,7 +711,7 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
queryFilter.append(")");
}
} else {
filteredRecentSearchObjects.clear();
filtered2RecentSearchObjects.clear();
recentSearchObjects.clear();
recentSearchObjectsById.clear();
queryFilter = new StringBuilder("1");
@ -613,6 +762,7 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
MessagesController.getInstance(currentAccount).putEncryptedChat((TLRPC.EncryptedChat) recentSearchObject.object, true);
}
}
filterRecent(null);
notifyDataSetChanged();
}
@ -660,7 +810,7 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
searchResultMessages.clear();
}
searchWas = true;
final int recentCount = filteredRecentSearchObjects.size();
final int recentCount = filtered2RecentSearchObjects.size();
for (int a = 0; a < result.size(); a++) {
Object obj = result.get(a);
long dialogId = 0;
@ -700,11 +850,13 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
}
boolean foundInRecent = false;
for (int j = 0; j < recentCount; ++j) {
RecentSearchObject o = filteredRecentSearchObjects.get(j);
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) {
foundInRecent = true;
break;
}
}
if (foundInRecent) {
@ -716,7 +868,7 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
MessagesController.getInstance(currentAccount).putUsers(encUsers, true);
searchResult = result;
searchResultNames = names;
searchAdapterHelper.mergeResults(searchResult, filteredRecentSearchObjects);
searchAdapterHelper.mergeResults(searchResult, filtered2RecentSearchObjects);
notifyDataSetChanged();
if (delegate != null) {
delegate.searchStateChanged(waitingResponseCount > 0, true);
@ -757,6 +909,7 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
} else {
query = null;
}
filterRecent(query);
if (TextUtils.isEmpty(query)) {
filteredRecentQuery = null;
searchAdapterHelper.unloadRecentHashtags();
@ -764,7 +917,7 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
searchResultNames.clear();
searchResultHashtags.clear();
searchAdapterHelper.mergeResults(null, null);
searchAdapterHelper.queryServerSearch(null, true, true, dialogsType != 11, dialogsType != 11, dialogsType == 2 || dialogsType == 11, 0, dialogsType == 0, 0, 0);
searchAdapterHelper.queryServerSearch(null, true, true, dialogsType != 11, dialogsType != 11, dialogsType == 2 || dialogsType == 11, 0, dialogsType == 0, 0, 0, delegate != null ? delegate.getSearchForumDialogId() : 0);
searchWas = false;
lastSearchId = 0;
waitingResponseCount = 0;
@ -773,7 +926,9 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
if (delegate != null) {
delegate.searchStateChanged(false, true);
}
searchTopics(null);
searchMessagesInternal(null, 0);
searchForumMessagesInternal(null, 0);
notifyDataSetChanged();
localTipDates.clear();
localTipArchive = false;
@ -781,8 +936,7 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
filtersDelegate.updateFiltersView(false, null, localTipDates, localTipArchive);
}
} else {
filterRecent(query);
searchAdapterHelper.mergeResults(searchResult, filteredRecentSearchObjects);
searchAdapterHelper.mergeResults(searchResult, filtered2RecentSearchObjects);
if (needMessagesSearch != 2 && (query.startsWith("#") && query.length() == 1)) {
messagesSearchEndReached = true;
if (searchAdapterHelper.loadRecentHashtags()) {
@ -822,14 +976,16 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
return;
}
if (needMessagesSearch != 2) {
searchAdapterHelper.queryServerSearch(query, true, dialogsType != 4, true, dialogsType != 4 && dialogsType != 11, dialogsType == 2 || dialogsType == 1, 0, dialogsType == 0, 0, searchId);
searchAdapterHelper.queryServerSearch(query, true, dialogsType != 4, true, dialogsType != 4 && dialogsType != 11, dialogsType == 2 || dialogsType == 1, 0, dialogsType == 0, 0, searchId, delegate != null ? delegate.getSearchForumDialogId() : 0);
} else {
waitingResponseCount -= 2;
}
if (needMessagesSearch == 0) {
waitingResponseCount--;
} else {
searchTopics(text);
searchMessagesInternal(text, searchId);
searchForumMessagesInternal(text, searchId);
}
});
}, 300);
@ -837,12 +993,12 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
}
public int getRecentItemsCount() {
ArrayList<RecentSearchObject> recent = searchWas ? filteredRecentSearchObjects : recentSearchObjects;
ArrayList<RecentSearchObject> recent = searchWas ? filtered2RecentSearchObjects : filteredRecentSearchObjects;
return (!recent.isEmpty() ? recent.size() + 1 : 0) + (!searchWas && !MediaDataController.getInstance(currentAccount).hints.isEmpty() ? 1 : 0);
}
public int getRecentResultsCount() {
ArrayList<RecentSearchObject> recent = searchWas ? filteredRecentSearchObjects : recentSearchObjects;
ArrayList<RecentSearchObject> recent = searchWas ? filtered2RecentSearchObjects : filteredRecentSearchObjects;
return recent != null ? recent.size() : 0;
}
@ -862,6 +1018,10 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
return count;
}
}
if (!searchTopics.isEmpty()) {
count++;
}
count += searchTopics.size();
int resultsCount = searchResult.size();
count += resultsCount;
int localServerCount = searchAdapterHelper.getLocalServerSearch().size();
@ -874,8 +1034,7 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
if (phoneCount > 3 && phoneCollapsed) {
phoneCount = 3;
}
int messagesCount = searchResultMessages.size();
if (resultsCount + localServerCount > 0 && getRecentItemsCount() > 0) {
if (resultsCount + localServerCount > 0 && (getRecentItemsCount() > 0 || !searchTopics.isEmpty())) {
count++;
}
if (globalCount != 0) {
@ -884,8 +1043,22 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
if (phoneCount != 0) {
count += phoneCount;
}
int localMessagesCount = searchForumResultMessages.size();
if (localMessagesCount != 0) {
count += 1 + localMessagesCount + (localMessagesSearchEndReached ? 0 : 1);
}
if (!localMessagesSearchEndReached) {
localMessagesLoadingRow = count;
}
int messagesCount = searchResultMessages.size();
if (!searchForumResultMessages.isEmpty() && !localMessagesSearchEndReached) {
messagesCount = 0;
}
if (messagesCount != 0) {
count += messagesCount + 1 + (messagesSearchEndReached ? 0 : 1);
count += 1 + messagesCount + (messagesSearchEndReached ? 0 : 1);
}
if (localMessagesSearchEndReached) {
localMessagesLoadingRow = count;
}
return currentItemCount = count;
}
@ -900,7 +1073,7 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
}
if (isRecentSearchDisplayed()) {
int offset = (!searchWas && !MediaDataController.getInstance(currentAccount).hints.isEmpty() ? 1 : 0);
ArrayList<RecentSearchObject> recent = searchWas ? filteredRecentSearchObjects : recentSearchObjects;
ArrayList<RecentSearchObject> recent = searchWas ? filtered2RecentSearchObjects : filteredRecentSearchObjects;
if (i > offset && i - 1 - offset < recent.size()) {
TLObject object = recent.get(i - 1 - offset).object;
if (object instanceof TLRPC.User) {
@ -919,12 +1092,18 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
i -= getRecentItemsCount();
}
}
if (!searchTopics.isEmpty()) {
if (i > 0 && i <= searchTopics.size()) {
return searchTopics.get(i - 1);
}
i -= 1 + searchTopics.size();
}
ArrayList<TLObject> globalSearch = searchAdapterHelper.getGlobalSearch();
ArrayList<TLObject> localServerSearch = searchAdapterHelper.getLocalServerSearch();
ArrayList<Object> phoneSearch = searchAdapterHelper.getPhoneSearch();
int localCount = searchResult.size();
int localServerCount = localServerSearch.size();
if (localCount + localServerCount > 0 && getRecentItemsCount() > 0) {
if (localCount + localServerCount > 0 && (getRecentItemsCount() > 0 || !searchTopics.isEmpty())) {
if (i == 0) {
return null;
}
@ -938,7 +1117,6 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
if (globalCount > 4 && globalSearchCollapsed) {
globalCount = 4;
}
int messagesCount = searchResultMessages.isEmpty() ? 0 : searchResultMessages.size() + 1;
if (i >= 0 && i < localCount) {
return searchResult.get(i);
}
@ -955,9 +1133,16 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
return globalSearch.get(i - 1);
}
i -= globalCount;
if (i > 0 && i < messagesCount) {
int localMessagesCount = searchForumResultMessages.isEmpty() ? 0 : searchForumResultMessages.size() + 1;
if (i > 0 && i <= searchForumResultMessages.size()) {
return searchForumResultMessages.get(i - 1);
}
i -= localMessagesCount + (!localMessagesSearchEndReached && !searchForumResultMessages.isEmpty() ? 1 : 0);
int messagesCount = searchResultMessages.isEmpty() ? 0 : searchResultMessages.size() + 1;
if (i > 0 && i <= searchResultMessages.size()) {
return searchResultMessages.get(i - 1);
}
// i -= messagesCount;
return null;
}
@ -970,7 +1155,7 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
}
if (isRecentSearchDisplayed()) {
int offset = (!searchWas && !MediaDataController.getInstance(currentAccount).hints.isEmpty() ? 1 : 0);
ArrayList<RecentSearchObject> recent = searchWas ? filteredRecentSearchObjects : recentSearchObjects;
ArrayList<RecentSearchObject> recent = searchWas ? filtered2RecentSearchObjects : filteredRecentSearchObjects;
if (i > offset && i - 1 - offset < recent.size()) {
return false;
} else {
@ -989,7 +1174,6 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
if (globalCount > 4 && globalSearchCollapsed) {
globalCount = 4;
}
int messagesCount = searchResultMessages.isEmpty() ? 0 : searchResultMessages.size() + 1;
if (i >= 0 && i < localCount) {
return false;
@ -1007,6 +1191,12 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
return true;
}
i -= globalCount;
int localMessagesCount = searchForumResultMessages.isEmpty() ? 0 : searchForumResultMessages.size() + 1;
if (i > 0 && i < localMessagesCount) {
return false;
}
i -= localMessagesCount;
int messagesCount = searchResultMessages.isEmpty() ? 0 : searchResultMessages.size() + 1;
if (i > 0 && i < messagesCount) {
return false;
}
@ -1037,11 +1227,14 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
case VIEW_TYPE_DIALOG_CELL:
view = new DialogCell(null, mContext, false, true) {
@Override
protected boolean isForumCell() {
public boolean isForumCell() {
return false;
}
};
break;
case VIEW_TYPE_TOPIC_CELL:
view = new TopicSearchCell(mContext);
break;
case VIEW_TYPE_LOADING:
FlickerLoadingView flickerLoadingView = new FlickerLoadingView(mContext);
flickerLoadingView.setViewType(FlickerLoadingView.DIALOG_TYPE);
@ -1140,11 +1333,14 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
}
position -= getRecentItemsCount();
}
if (!searchTopics.isEmpty()) {
position -= 1 + searchTopics.size();
}
ArrayList<TLObject> globalSearch = searchAdapterHelper.getGlobalSearch();
ArrayList<Object> phoneSearch = searchAdapterHelper.getPhoneSearch();
int localCount = searchResult.size();
int localServerCount = searchAdapterHelper.getLocalServerSearch().size();
if (localCount + localServerCount > 0 && getRecentItemsCount() > 0) {
if (localCount + localServerCount > 0 && (getRecentItemsCount() > 0 || !searchTopics.isEmpty())) {
position--;
}
int phoneCount = phoneSearch.size();
@ -1249,12 +1445,12 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
});
} else {
int rawPosition = position;
if (isRecentSearchDisplayed()) {
if (isRecentSearchDisplayed() || !searchTopics.isEmpty()) {
int offset = (!searchWas && !MediaDataController.getInstance(currentAccount).hints.isEmpty() ? 1 : 0);
if (position < offset) {
cell.setText(LocaleController.getString("ChatHints", R.string.ChatHints));
return;
} else if (position == offset) {
} else if (position == offset && isRecentSearchDisplayed()) {
if (!searchWas) {
cell.setText(LocaleController.getString("Recent", R.string.Recent), LocaleController.getString("ClearButton", R.string.ClearButton), v -> {
if (delegate != null) {
@ -1269,7 +1465,7 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
});
}
return;
} else if (position == getRecentItemsCount()) {
} else if (position == getRecentItemsCount() + (searchTopics.isEmpty() ? 0 : searchTopics.size() + 1)) {
cell.setText(LocaleController.getString("SearchAllChatsShort", R.string.SearchAllChatsShort));
return;
} else {
@ -1287,87 +1483,99 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
if (globalCount > 4 && globalSearchCollapsed) {
globalCount = 4;
}
int localMessagesCount = searchForumResultMessages.isEmpty() ? 0 : searchForumResultMessages.size() + 1;
int messagesCount = searchResultMessages.isEmpty() ? 0 : searchResultMessages.size() + 1;
position -= localCount + localServerCount;
String title;
String title = null;
boolean showMore = false;
Runnable onClick = null;
if (position >= 0 && position < phoneCount) {
title = LocaleController.getString("PhoneNumberSearch", R.string.PhoneNumberSearch);
if (searchAdapterHelper.getPhoneSearch().size() > 3) {
showMore = phoneCollapsed;
onClick = () -> {
phoneCollapsed = !phoneCollapsed;
cell.setRightText(phoneCollapsed ? LocaleController.getString("ShowMore", R.string.ShowMore) : LocaleController.getString("ShowLess", R.string.ShowLess));
notifyDataSetChanged();
};
if (!searchTopics.isEmpty()) {
if (position == 0) {
title = LocaleController.getString("Topics", R.string.Topics);
}
} else {
position -= phoneCount;
if (position >= 0 && position < globalCount) {
title = LocaleController.getString("GlobalSearch", R.string.GlobalSearch);
if (searchAdapterHelper.getGlobalSearch().size() > 3) {
showMore = globalSearchCollapsed;
position -= 1 + searchTopics.size();
}
if (title == null) {
position -= localCount + localServerCount;
if (position >= 0 && position < phoneCount) {
title = LocaleController.getString("PhoneNumberSearch", R.string.PhoneNumberSearch);
if (searchAdapterHelper.getPhoneSearch().size() > 3) {
showMore = phoneCollapsed;
onClick = () -> {
final long now = SystemClock.elapsedRealtime();
if (now - lastShowMoreUpdate < 300) {
return;
}
lastShowMoreUpdate = now;
int totalGlobalCount = globalSearch.isEmpty() ? 0 : globalSearch.size();
boolean disableRemoveAnimation = getItemCount() > rawPosition + Math.min(totalGlobalCount, globalSearchCollapsed ? 4 : Integer.MAX_VALUE) + 1;
if (itemAnimator != null) {
itemAnimator.setAddDuration(disableRemoveAnimation ? 45 : 200);
itemAnimator.setRemoveDuration(disableRemoveAnimation ? 80 : 200);
itemAnimator.setRemoveDelay(disableRemoveAnimation ? 270 : 0);
}
globalSearchCollapsed = !globalSearchCollapsed;
cell.setRightText(globalSearchCollapsed ? LocaleController.getString("ShowMore", R.string.ShowMore) : LocaleController.getString("ShowLess", R.string.ShowLess), globalSearchCollapsed);
showMoreHeader = null;
View parent = (View) cell.getParent();
if (parent instanceof RecyclerView) {
RecyclerView listView = (RecyclerView) parent;
final int nextGraySectionPosition = !globalSearchCollapsed ? rawPosition + 4 : rawPosition + totalGlobalCount + 1;
for (int i = 0; i < listView.getChildCount(); ++i) {
View child = listView.getChildAt(i);
if (listView.getChildAdapterPosition(child) == nextGraySectionPosition) {
showMoreHeader = child;
break;
}
}
}
if (!globalSearchCollapsed) {
notifyItemChanged(rawPosition + 3);
notifyItemRangeInserted(rawPosition + 4, (totalGlobalCount - 3));
} else {
notifyItemRangeRemoved(rawPosition + 4, (totalGlobalCount - 3));
if (disableRemoveAnimation) {
AndroidUtilities.runOnUIThread(() -> notifyItemChanged(rawPosition + 3), 350);
} else {
notifyItemChanged(rawPosition + 3);
}
}
if (cancelShowMoreAnimation != null) {
AndroidUtilities.cancelRunOnUIThread(cancelShowMoreAnimation);
}
if (disableRemoveAnimation) {
showMoreAnimation = true;
AndroidUtilities.runOnUIThread(cancelShowMoreAnimation = () -> {
showMoreAnimation = false;
showMoreHeader = null;
if (parent != null) {
parent.invalidate();
}
}, 400);
} else {
showMoreAnimation = false;
}
phoneCollapsed = !phoneCollapsed;
cell.setRightText(phoneCollapsed ? LocaleController.getString("ShowMore", R.string.ShowMore) : LocaleController.getString("ShowLess", R.string.ShowLess));
notifyDataSetChanged();
};
}
} else {
title = LocaleController.getString("SearchMessages", R.string.SearchMessages);
position -= phoneCount;
if (position >= 0 && position < globalCount) {
title = LocaleController.getString("GlobalSearch", R.string.GlobalSearch);
if (searchAdapterHelper.getGlobalSearch().size() > 3) {
showMore = globalSearchCollapsed;
onClick = () -> {
final long now = SystemClock.elapsedRealtime();
if (now - lastShowMoreUpdate < 300) {
return;
}
lastShowMoreUpdate = now;
int totalGlobalCount = globalSearch.isEmpty() ? 0 : globalSearch.size();
boolean disableRemoveAnimation = getItemCount() > rawPosition + Math.min(totalGlobalCount, globalSearchCollapsed ? 4 : Integer.MAX_VALUE) + 1;
if (itemAnimator != null) {
itemAnimator.setAddDuration(disableRemoveAnimation ? 45 : 200);
itemAnimator.setRemoveDuration(disableRemoveAnimation ? 80 : 200);
itemAnimator.setRemoveDelay(disableRemoveAnimation ? 270 : 0);
}
globalSearchCollapsed = !globalSearchCollapsed;
cell.setRightText(globalSearchCollapsed ? LocaleController.getString("ShowMore", R.string.ShowMore) : LocaleController.getString("ShowLess", R.string.ShowLess), globalSearchCollapsed);
showMoreHeader = null;
View parent = (View) cell.getParent();
if (parent instanceof RecyclerView) {
RecyclerView listView = (RecyclerView) parent;
final int nextGraySectionPosition = !globalSearchCollapsed ? rawPosition + 4 : rawPosition + totalGlobalCount + 1;
for (int i = 0; i < listView.getChildCount(); ++i) {
View child = listView.getChildAt(i);
if (listView.getChildAdapterPosition(child) == nextGraySectionPosition) {
showMoreHeader = child;
break;
}
}
}
if (!globalSearchCollapsed) {
notifyItemChanged(rawPosition + 3);
notifyItemRangeInserted(rawPosition + 4, (totalGlobalCount - 3));
} else {
notifyItemRangeRemoved(rawPosition + 4, (totalGlobalCount - 3));
if (disableRemoveAnimation) {
AndroidUtilities.runOnUIThread(() -> notifyItemChanged(rawPosition + 3), 350);
} else {
notifyItemChanged(rawPosition + 3);
}
}
if (cancelShowMoreAnimation != null) {
AndroidUtilities.cancelRunOnUIThread(cancelShowMoreAnimation);
}
if (disableRemoveAnimation) {
showMoreAnimation = true;
AndroidUtilities.runOnUIThread(cancelShowMoreAnimation = () -> {
showMoreAnimation = false;
showMoreHeader = null;
if (parent != null) {
parent.invalidate();
}
}, 400);
} else {
showMoreAnimation = false;
}
};
}
} else if (delegate != null && localMessagesCount > 0 && position - globalCount <= 1) {
TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(-delegate.getSearchForumDialogId());
title = LocaleController.formatString("SearchMessagesIn", R.string.SearchMessagesIn, (chat == null ? "null" : chat.title));
} else {
title = LocaleController.getString("SearchMessages", R.string.SearchMessages);
}
}
}
@ -1385,7 +1593,18 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
cell.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite));
cell.useSeparator = (position != getItemCount() - 1);
MessageObject messageObject = (MessageObject) getItem(position);
cell.setDialog(messageObject.getDialogId(), messageObject, messageObject.messageOwner.date, false, false);
boolean isLocalForum = searchForumResultMessages.contains(messageObject);
cell.useFromUserAsAvatar = isLocalForum;
if (messageObject == null) {
cell.setDialog(0, null, 0, false, false);
} else {
cell.setDialog(messageObject.getDialogId(), messageObject, messageObject.messageOwner.date, false, false);
}
break;
}
case VIEW_TYPE_TOPIC_CELL: {
TopicSearchCell topicSearchCell = (TopicSearchCell) holder.itemView;
topicSearchCell.setTopic((TLRPC.TL_forumTopic) getItem(position));
break;
}
case VIEW_TYPE_HASHTAG_CELL: {
@ -1431,10 +1650,18 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
}
i -= getRecentItemsCount();
}
if (!searchTopics.isEmpty()) {
if (i == 0) {
return VIEW_TYPE_GRAY_SECTION;
} else if (i <= searchTopics.size()) {
return VIEW_TYPE_TOPIC_CELL;
}
i -= 1 + searchTopics.size();
}
ArrayList<TLObject> globalSearch = searchAdapterHelper.getGlobalSearch();
int localCount = searchResult.size();
int localServerCount = searchAdapterHelper.getLocalServerSearch().size();
if (localCount + localServerCount > 0 && getRecentItemsCount() > 0) {
if (localCount + localServerCount > 0 && (getRecentItemsCount() > 0 || !searchTopics.isEmpty())) {
if (i == 0) {
return VIEW_TYPE_GRAY_SECTION;
}
@ -1449,6 +1676,10 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
globalCount = 4;
}
int messagesCount = searchResultMessages.isEmpty() ? 0 : searchResultMessages.size() + 1;
if (!searchForumResultMessages.isEmpty() && !localMessagesSearchEndReached) {
messagesCount = 0;
}
int localMessagesCount = (searchForumResultMessages.isEmpty() ? 0 : searchForumResultMessages.size() + 1);
if (i >= 0 && i < localCount) {
return VIEW_TYPE_PROFILE_CELL;
@ -1479,6 +1710,18 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
}
}
i -= globalCount;
if (localMessagesCount > 0) {
if (i >= 0 && (localMessagesSearchEndReached ? i < localMessagesCount : i <= localMessagesCount)) {
if (i == 0) {
return VIEW_TYPE_GRAY_SECTION;
} else if (i == localMessagesCount) {
return VIEW_TYPE_LOADING;
} else {
return VIEW_TYPE_DIALOG_CELL;
}
}
i -= localMessagesCount + (!localMessagesSearchEndReached ? 1 : 0);
}
if (i >= 0 && i < messagesCount) {
if (i == 0) {
return VIEW_TYPE_GRAY_SECTION;
@ -1502,8 +1745,16 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
public void filterRecent(String query) {
filteredRecentQuery = query;
filteredRecentSearchObjects.clear();
filtered2RecentSearchObjects.clear();
if (TextUtils.isEmpty(query)) {
filteredRecentSearchObjects.clear();
final int count = recentSearchObjects.size();
for (int i = 0; i < count; ++i) {
if (delegate != null && delegate.getSearchForumDialogId() == recentSearchObjects.get(i).did) {
continue;
}
filteredRecentSearchObjects.add(recentSearchObjects.get(i));
}
return;
}
String lowerCasedQuery = query.toLowerCase();
@ -1513,6 +1764,9 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
if (obj == null || obj.object == null) {
continue;
}
if (delegate != null && delegate.getSearchForumDialogId() == obj.did) {
continue;
}
String title = null, username = null;
if (obj.object instanceof TLRPC.Chat) {
title = ((TLRPC.Chat) obj.object).title;
@ -1525,9 +1779,9 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
}
if (title != null && wordStartsWith(title.toLowerCase(), lowerCasedQuery) ||
username != null && wordStartsWith(username.toLowerCase(), lowerCasedQuery)) {
filteredRecentSearchObjects.add(obj);
filtered2RecentSearchObjects.add(obj);
}
if (filteredRecentSearchObjects.size() >= 5) {
if (filtered2RecentSearchObjects.size() >= 5) {
break;
}
}

View File

@ -10,6 +10,8 @@ package org.telegram.ui.Adapters;
import android.util.Pair;
import androidx.collection.LongSparseArray;
import org.telegram.PhoneFormat.PhoneFormat;
import org.telegram.SQLite.SQLiteCursor;
import org.telegram.SQLite.SQLitePreparedStatement;
@ -28,7 +30,6 @@ import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ChatUsersActivity;
import org.telegram.ui.Components.ShareAlert;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@ -36,8 +37,6 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import androidx.collection.LongSparseArray;
public class SearchAdapterHelper {
public static class HashtagObject {
@ -108,9 +107,12 @@ public class SearchAdapterHelper {
return pendingRequestIds.size() > 0;
}
public void queryServerSearch(String query, boolean allowUsername, boolean allowChats, boolean allowBots, boolean allowSelf, boolean canAddGroupsOnly, long channelId, boolean phoneNumbers, int type, int searchId) {
queryServerSearch(query, allowUsername, allowChats, allowBots, allowSelf, canAddGroupsOnly, channelId, phoneNumbers, type, searchId, null);
queryServerSearch(query, allowUsername, allowChats, allowBots, allowSelf, canAddGroupsOnly, channelId, phoneNumbers, type, searchId, 0, null);
}
public void queryServerSearch(String query, boolean allowUsername, boolean allowChats, boolean allowBots, boolean allowSelf, boolean canAddGroupsOnly, long channelId, boolean phoneNumbers, int type, int searchId, Runnable onEnd) {
public void queryServerSearch(String query, boolean allowUsername, boolean allowChats, boolean allowBots, boolean allowSelf, boolean canAddGroupsOnly, long channelId, boolean phoneNumbers, int type, int searchId, long exceptDialogId) {
queryServerSearch(query, allowUsername, allowChats, allowBots, allowSelf, canAddGroupsOnly, channelId, phoneNumbers, type, searchId, exceptDialogId, null);
}
public void queryServerSearch(String query, boolean allowUsername, boolean allowChats, boolean allowBots, boolean allowSelf, boolean canAddGroupsOnly, long channelId, boolean phoneNumbers, int type, int searchId, long exceptDialogId, Runnable onEnd) {
for (int reqId : pendingRequestIds) {
ConnectionsManager.getInstance(currentAccount).cancelRequest(reqId, true);
}
@ -248,13 +250,13 @@ public class SearchAdapterHelper {
chat = chatsMap.get(peer.channel_id);
}
if (chat != null) {
if (!allowChats || canAddGroupsOnly && !ChatObject.canAddBotsToChat(chat)) {
if (!allowChats || canAddGroupsOnly && !ChatObject.canAddBotsToChat(chat) || -chat.id == exceptDialogId) {
continue;
}
localServerSearch.add(chat);
globalSearchMap.put(-chat.id, chat);
} else if (user != null) {
if (canAddGroupsOnly || !allowBots && user.bot || !allowSelf && user.self) {
if (canAddGroupsOnly || !allowBots && user.bot || !allowSelf && user.self || user.id == exceptDialogId) {
continue;
}
localServerSearch.add(user);

View File

@ -0,0 +1,334 @@
package org.telegram.ui;
import android.content.Context;
import android.transition.ChangeBounds;
import android.transition.Fade;
import android.transition.TransitionManager;
import android.transition.TransitionSet;
import android.view.Gravity;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R;
import org.telegram.tgnet.RequestDelegate;
import org.telegram.tgnet.TLObject;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.ActionBar;
import org.telegram.ui.ActionBar.AlertDialog;
import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Cells.HeaderCell;
import org.telegram.ui.Cells.RadioCell;
import org.telegram.ui.Cells.TextInfoPrivacyCell;
import org.telegram.ui.Components.AlertsCreator;
import org.telegram.ui.Components.BulletinFactory;
import org.telegram.ui.Components.CubicBezierInterpolator;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.StickerImageView;
import java.util.ArrayList;
public class AutoDeleteMessagesActivity extends BaseFragment implements NotificationCenter.NotificationCenterDelegate {
private final static int ONE_DAY = 60 * 24;
private final static int ONE_WEEK = 60 * 24 * 7;
private final static int ONE_MONTH = 60 * 24 * 31;
RadioCellInternal offCell;
RadioCellInternal afterOneDay;
RadioCellInternal afterOneWeek;
RadioCellInternal afterOneMonth;
RadioCellInternal customTimeButton;
LinearLayout checkBoxContainer;
ArrayList<RadioCellInternal> arrayList = new ArrayList<>();
public int startFromTtl = 0;
@Override
public boolean onFragmentCreate() {
startFromTtl = getUserConfig().getGlobalTTl();
if (startFromTtl < 0) {
startFromTtl = 0;
}
getUserConfig().loadGlobalTTl();
getNotificationCenter().addObserver(this, NotificationCenter.didUpdateGlobalAutoDeleteTimer);
return super.onFragmentCreate();
}
@Override
public void onFragmentDestroy() {
super.onFragmentDestroy();
getNotificationCenter().removeObserver(this, NotificationCenter.didUpdateGlobalAutoDeleteTimer);
}
@Override
public View createView(Context context) {
actionBar.setBackButtonImage(R.drawable.ic_ab_back);
actionBar.setAllowOverlayTitle(true);
actionBar.setTitle(LocaleController.getString("AutoDeleteMessages", R.string.AutoDeleteMessages));
actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() {
@Override
public void onItemClick(int id) {
if (id == -1) {
finishFragment();
}
}
});
fragmentView = new FrameLayout(context);
FrameLayout frameLayout = (FrameLayout) fragmentView;
frameLayout.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundGray));
ScrollView scrollView = new ScrollView(getContext());
LinearLayout mainContainer = new LinearLayout(getContext());
mainContainer.setOrientation(LinearLayout.VERTICAL);
scrollView.addView(mainContainer);
frameLayout.addView(scrollView);
FrameLayout stickerHeaderCell = new FrameLayout(context);
StickerImageView backupImageView = new StickerImageView(context, currentAccount);
backupImageView.setStickerNum(10);
stickerHeaderCell.addView(backupImageView, LayoutHelper.createFrame(130, 130, Gravity.CENTER));
mainContainer.addView(stickerHeaderCell, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 170));
checkBoxContainer = new LinearLayout(getContext());
checkBoxContainer.setOrientation(LinearLayout.VERTICAL);
checkBoxContainer.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite));
mainContainer.addView(checkBoxContainer, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
HeaderCell headerCell = new HeaderCell(getContext());
headerCell.setText(LocaleController.getString("MessageLifetime", R.string.MessageLifetime));
checkBoxContainer.addView(headerCell);
offCell = new RadioCellInternal(getContext());
offCell.setText(LocaleController.getString("ShortMessageLifetimeForever", R.string.ShortMessageLifetimeForever), false, true);
offCell.time = 0;
checkBoxContainer.addView(offCell);
afterOneDay = new RadioCellInternal(getContext());
afterOneDay.setText(LocaleController.getString("AutoDeleteAfter1Day", R.string.AutoDeleteAfter1Day), false, true);
afterOneDay.time = ONE_DAY;
checkBoxContainer.addView(afterOneDay);
afterOneWeek = new RadioCellInternal(getContext());
afterOneWeek.setText(LocaleController.getString("AutoDeleteAfter1Week", R.string.AutoDeleteAfter1Week), false, true);
afterOneWeek.time = ONE_WEEK;
checkBoxContainer.addView(afterOneWeek);
afterOneMonth = new RadioCellInternal(getContext());
afterOneMonth.setText(LocaleController.getString("AutoDeleteAfter1Month", R.string.AutoDeleteAfter1Month), false, true);
afterOneMonth.time = ONE_MONTH;
checkBoxContainer.addView(afterOneMonth);
customTimeButton = new RadioCellInternal(getContext());
customTimeButton.setText(LocaleController.getString("SetCustomTime", R.string.SetCustomTime), false, false);
customTimeButton.hideRadioButton();
checkBoxContainer.addView(customTimeButton);
arrayList.add(offCell);
arrayList.add(afterOneDay);
arrayList.add(afterOneWeek);
arrayList.add(afterOneMonth);
arrayList.add(customTimeButton);
updateItems();
TextInfoPrivacyCell textInfoPrivacyCell = new TextInfoPrivacyCell(context);
CharSequence infoText = AndroidUtilities.replaceSingleTag(LocaleController.getString("GlobalAutoDeleteInfo", R.string.GlobalAutoDeleteInfo), new Runnable() {
@Override
public void run() {
UsersSelectActivity usersSelectActivity = new UsersSelectActivity(UsersSelectActivity.TYPE_AUTO_DELETE_EXISTING_CHATS);
usersSelectActivity.setTtlPeriod(getSelectedTime());
usersSelectActivity.setDelegate((ids, flags) -> {
AndroidUtilities.runOnUIThread(() -> {
if (!ids.isEmpty()) {
for (int i = 0; i < ids.size(); i++) {
getMessagesController().setDialogHistoryTTL(ids.get(i), getSelectedTime() * 60);
}
if (getSelectedTime() > 0) {
BulletinFactory.of(AutoDeleteMessagesActivity.this).createSimpleBulletin(R.raw.fire_on, AndroidUtilities.replaceTags(LocaleController.formatString("AutodeleteTimerEnabledForChats", R.string.AutodeleteTimerEnabledForChats,
LocaleController.formatTTLString(getSelectedTime() * 60),
LocaleController.formatPluralString("Chats", ids.size(), ids.size())
))).show();
} else {
BulletinFactory.of(AutoDeleteMessagesActivity.this).createSimpleBulletin(R.raw.fire_off, LocaleController.formatString("AutodeleteTimerDisabledForChats", R.string.AutodeleteTimerDisabledForChats,
LocaleController.formatPluralString("Chats", ids.size(), ids.size())
)).show();
}
}
}, 100);
});
presentFragment(usersSelectActivity);
}
});
textInfoPrivacyCell.setText(infoText);
mainContainer.addView(textInfoPrivacyCell, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
selectDate(startFromTtl, false);
return fragmentView;
}
private void updateItems() {
for (int i = 0; i < arrayList.size(); i++) {
arrayList.get(i).setBackground(Theme.createSelectorWithBackgroundDrawable(Theme.getColor(Theme.key_windowBackgroundWhite), Theme.getColor(Theme.key_listSelector)));
arrayList.get(i).setOnClickListener(v -> {
if (v == customTimeButton) {
AlertsCreator.createAutoDeleteDatePickerDialog(getContext(), 1, null, new AlertsCreator.ScheduleDatePickerDelegate() {
@Override
public void didSelectDate(boolean notify, int scheduleDate) {
AndroidUtilities.runOnUIThread(() -> {
selectDate(scheduleDate, true);
}, 50);
}
});
} else {
int time = ((RadioCellInternal)v).time;
int selctedTime = getSelectedTime();
if (selctedTime == 0 && time > 0) {
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle(LocaleController.getString("MessageLifetime", R.string.MessageLifetime));
builder.setMessage(LocaleController.formatString("AutoDeleteConfirmMessage", R.string.AutoDeleteConfirmMessage, LocaleController.formatTTLString(time * 60)));
builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), (dialog, which) -> {
dialog.dismiss();
});
builder.setPositiveButton(LocaleController.getString("Enable", R.string.Enable), (dialog, which) -> {
dialog.dismiss();
selectRadioButton(v, true);
});
builder.show();
} else {
selectRadioButton(v, true);
}
}
});
}
}
private int getSelectedTime() {
for (int i = 0; i < arrayList.size(); i++) {
if (arrayList.get(i).isChecked()) {
return arrayList.get(i).time;
}
}
return startFromTtl;
}
private void selectDate(int scheduleDate, boolean showBulletin) {
TransitionSet transition = new TransitionSet();
ChangeBounds changeBounds = new ChangeBounds();
changeBounds.setDuration(150);
Fade in = new Fade(Fade.IN);
in.setDuration(150);
transition
.addTransition(new Fade(Fade.OUT).setDuration(150))
.addTransition(changeBounds)
.addTransition(in);
transition.setOrdering(TransitionSet.ORDERING_TOGETHER);
transition.setInterpolator(CubicBezierInterpolator.DEFAULT);
TransitionManager.beginDelayedTransition(checkBoxContainer, transition);
for (int i = 0; i < arrayList.size(); i++) {
if (arrayList.get(i).time == scheduleDate) {
selectRadioButton(arrayList.get(i), showBulletin);
return;
}
}
for (int i = 0; i < arrayList.size(); i++) {
if (arrayList.get(i).custom) {
checkBoxContainer.removeView(arrayList.get(i));
arrayList.remove(i);
i--;
}
}
int position = arrayList.size();
for (int i = 0; i < arrayList.size(); i++) {
if (scheduleDate < arrayList.get(i).time) {
position = i + 1;
break;
}
}
RadioCellInternal customTimeButton = new RadioCellInternal(getContext());
customTimeButton.custom = true;
customTimeButton.time = scheduleDate;
customTimeButton.setText(LocaleController.formatString("AutoDeleteAfterShort", R.string.AutoDeleteAfterShort, LocaleController.formatTTLString(scheduleDate * 60)), false, true);
arrayList.add(position, customTimeButton);
checkBoxContainer.addView(customTimeButton, position);
updateItems();
selectRadioButton(customTimeButton, showBulletin);
}
private void selectRadioButton(View v, boolean showBulletin) {
for (int i = 0; i < arrayList.size(); i++) {
if (arrayList.get(i) == v) {
arrayList.get(i).setChecked(true, fragmentBeginToShow);
} else {
arrayList.get(i).setChecked(false, fragmentBeginToShow);
}
}
if (showBulletin) {
int time = ((RadioCellInternal) v).time;
if (time > 0) {
String text = LocaleController.formatString("AutoDeleteGlobalTimerEnabled", R.string.AutoDeleteGlobalTimerEnabled, LocaleController.formatTTLString(time * 60));
BulletinFactory.of(this).createSimpleBulletin(R.raw.fire_on, AndroidUtilities.replaceTags(text)).show();
} else {
// String text = LocaleController.formatString("AutoDeleteGlobalTimerDisabled", R.string.AutoDeleteGlobalTimerDisabled);
// BulletinFactory.of(this).createSimpleBulletin(R.raw.fire_off, text).show();
}
}
}
@Override
public void didReceivedNotification(int id, int account, Object... args) {
// int newTTl = getUserConfig().getGlobalTTl();
// if (newTTl != startFromTtl) {
// startFromTtl = newTTl;
// selectDate(startFromTtl, false);
// }
}
private class RadioCellInternal extends RadioCell {
boolean custom;
int time;
public RadioCellInternal(Context context) {
super(context);
}
}
@Override
public void onPause() {
super.onPause();
for (int i = 0; i < arrayList.size(); i++) {
if (arrayList.get(i).isChecked()) {
if (arrayList.get(i).time != startFromTtl) {
startFromTtl = arrayList.get(i).time;
TLRPC.TL_messages_setDefaultHistoryTTL setDefaultHistoryTTL = new TLRPC.TL_messages_setDefaultHistoryTTL();
setDefaultHistoryTTL.period = arrayList.get(i).time * 60;
getConnectionsManager().sendRequest(setDefaultHistoryTTL, new RequestDelegate() {
@Override
public void run(TLObject response, TLRPC.TL_error error) {
}
});
getUserConfig().setGlobalTtl(startFromTtl);
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.didUpdateGlobalAutoDeleteTimer);
}
break;
}
}
}
}

View File

@ -33,6 +33,8 @@ import org.telegram.messenger.SharedConfig;
import org.telegram.messenger.UserConfig;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.AnimatedEmojiDrawable;
import org.telegram.ui.Components.AnimatedEmojiSpan;
import org.telegram.ui.Components.DotDividerSpan;
import org.telegram.ui.Components.MediaActionDrawable;
import org.telegram.ui.Components.RadialProgress2;
@ -49,9 +51,11 @@ public class AudioPlayerCell extends View implements DownloadController.FileDown
private int buttonY;
private int titleY = AndroidUtilities.dp(9);
private AnimatedEmojiSpan.EmojiGroupedSpans titleLayoutEmojis;
private StaticLayout titleLayout;
private int descriptionY = AndroidUtilities.dp(29);
private AnimatedEmojiSpan.EmojiGroupedSpans descriptionLayoutEmojis;
private StaticLayout descriptionLayout;
private MessageObject currentMessageObject;
@ -100,6 +104,7 @@ public class AudioPlayerCell extends View implements DownloadController.FileDown
int width = (int) Math.ceil(Theme.chat_contextResult_titleTextPaint.measureText(title));
CharSequence titleFinal = TextUtils.ellipsize(title.replace('\n', ' '), Theme.chat_contextResult_titleTextPaint, Math.min(width, maxWidth), TextUtils.TruncateAt.END);
titleLayout = new StaticLayout(titleFinal, Theme.chat_contextResult_titleTextPaint, maxWidth + AndroidUtilities.dp(4), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
titleLayoutEmojis = AnimatedEmojiSpan.update(AnimatedEmojiDrawable.CACHE_TYPE_MESSAGES, this, titleLayoutEmojis, titleLayout);
} catch (Exception e) {
FileLog.e(e);
}
@ -111,6 +116,7 @@ public class AudioPlayerCell extends View implements DownloadController.FileDown
}
CharSequence authorFinal = TextUtils.ellipsize(author, Theme.chat_contextResult_descriptionTextPaint, maxWidth, TextUtils.TruncateAt.END);
descriptionLayout = new StaticLayout(authorFinal, Theme.chat_contextResult_descriptionTextPaint, maxWidth + AndroidUtilities.dp(4), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
descriptionLayoutEmojis = AnimatedEmojiSpan.update(AnimatedEmojiDrawable.CACHE_TYPE_MESSAGES, this, descriptionLayoutEmojis, descriptionLayout);
} catch (Exception e) {
FileLog.e(e);
}
@ -145,12 +151,18 @@ public class AudioPlayerCell extends View implements DownloadController.FileDown
super.onDetachedFromWindow();
radialProgress.onDetachedFromWindow();
DownloadController.getInstance(currentAccount).removeLoadingFileObserver(this);
AnimatedEmojiSpan.release(this, titleLayoutEmojis);
AnimatedEmojiSpan.release(this, descriptionLayoutEmojis);
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
radialProgress.onAttachedToWindow();
titleLayoutEmojis = AnimatedEmojiSpan.update(AnimatedEmojiDrawable.CACHE_TYPE_MESSAGES, this, titleLayoutEmojis, titleLayout);
descriptionLayoutEmojis = AnimatedEmojiSpan.update(AnimatedEmojiDrawable.CACHE_TYPE_MESSAGES, this, descriptionLayoutEmojis, descriptionLayout);
}
public MessageObject getMessageObject() {
@ -268,6 +280,7 @@ public class AudioPlayerCell extends View implements DownloadController.FileDown
canvas.save();
canvas.translate(AndroidUtilities.dp(LocaleController.isRTL ? 8 : AndroidUtilities.leftBaseline), titleY);
titleLayout.draw(canvas);
AnimatedEmojiSpan.drawAnimatedEmojis(canvas, titleLayout, titleLayoutEmojis, 0, null, 0, 0, 0, 1f);
canvas.restore();
}
@ -276,6 +289,7 @@ public class AudioPlayerCell extends View implements DownloadController.FileDown
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();
}

View File

@ -761,7 +761,13 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
private void createLayout(CharSequence text, int width) {
int maxWidth = width - AndroidUtilities.dp(30);
invalidatePath = true;
textLayout = new StaticLayout(text, (TextPaint) getThemedPaint(Theme.key_paint_chatActionText), maxWidth, Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false);
TextPaint paint;
if (currentMessageObject != null && currentMessageObject.drawServiceWithDefaultTypeface) {
paint = (TextPaint) getThemedPaint(Theme.key_paint_chatActionText2);
} else {
paint = (TextPaint) getThemedPaint(Theme.key_paint_chatActionText);
}
textLayout = new StaticLayout(text, paint, maxWidth, Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false);
spoilersPool.addAll(spoilers);
spoilers.clear();
@ -845,7 +851,7 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
MessageObject messageObject = currentMessageObject;
if (messageObject != null) {
if (delegate.getTopicId() == 0 && MessageObject.isTopicActionMessage(messageObject)) {
TLRPC.TL_forumTopic topic = MessagesController.getInstance(currentAccount).getTopicsController().findTopic(-messageObject.getDialogId(), MessageObject.getTopicId(messageObject.messageOwner));
TLRPC.TL_forumTopic topic = MessagesController.getInstance(currentAccount).getTopicsController().findTopic(-messageObject.getDialogId(), MessageObject.getTopicId(messageObject.messageOwner, true));
text = ForumUtilities.createActionTextWithTopic(topic, messageObject);
}
if (text == null) {

View File

@ -53,7 +53,6 @@ import android.text.TextUtils;
import android.text.style.CharacterStyle;
import android.text.style.ClickableSpan;
import android.text.style.URLSpan;
import android.util.Log;
import android.util.Property;
import android.util.SparseArray;
import android.util.StateSet;
@ -75,7 +74,6 @@ import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import androidx.core.graphics.ColorUtils;
import androidx.core.math.MathUtils;
import org.telegram.PhoneFormat.PhoneFormat;
import org.telegram.messenger.AccountInstance;
@ -113,7 +111,6 @@ import org.telegram.tgnet.TLObject;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.ChatActivity;
import org.telegram.ui.Components.AnimatedColor;
import org.telegram.ui.Components.AnimatedEmojiDrawable;
import org.telegram.ui.Components.AnimatedEmojiSpan;
import org.telegram.ui.Components.AnimatedFileDrawable;
@ -128,7 +125,6 @@ import org.telegram.ui.Components.ClipRoundedDrawable;
import org.telegram.ui.Components.CubicBezierInterpolator;
import org.telegram.ui.Components.EmptyStubSpan;
import org.telegram.ui.Components.FloatSeekBarAccessibilityDelegate;
import org.telegram.ui.Components.Forum.ForumUtilities;
import org.telegram.ui.Components.Forum.MessageTopicButton;
import org.telegram.ui.Components.InfiniteProgress;
import org.telegram.ui.Components.LinkPath;
@ -224,6 +220,8 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
setAvatar(currentMessageObject);
}
}
} else if (id == NotificationCenter.emojiLoaded) {
invalidate();
}
}
@ -522,11 +520,15 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
return true;
}
default boolean didPressAnimatedEmoji(AnimatedEmojiSpan span) {
default boolean didPressAnimatedEmoji(ChatMessageCell cell, AnimatedEmojiSpan span) {
return false;
}
default void didPressTopicButton(ChatMessageCell cell) {}
default boolean shouldShowTopicButton() {
return false;
}
}
private final static int DOCUMENT_ATTACH_TYPE_NONE = 0;
@ -672,6 +674,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
private StaticLayout authorLayout;
private StaticLayout instantViewLayout;
private boolean drawInstantView;
private boolean pollInstantViewTouchesBottom;
private int drawInstantViewType;
private int imageBackgroundColor;
private float imageBackgroundIntensity;
@ -997,7 +1000,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
private int timeWidth;
private int timeTextWidth;
private int timeX;
private String currentTimeString;
private CharSequence currentTimeString;
private boolean drawTime = true;
private boolean forceNotDrawTime;
private Paint drillHolePaint;
@ -1440,7 +1443,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
return true;
} else {
if (link[0] instanceof AnimatedEmojiSpan && pressedEmoji == link[0]) {
if (delegate.didPressAnimatedEmoji(pressedEmoji)) {
if (delegate.didPressAnimatedEmoji(this, pressedEmoji)) {
resetPressedLink(1);
pressedEmoji = null;
return true;
@ -1523,7 +1526,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
}
} else if (pressedLinkType == 3) {
if (pressedEmoji != null) {
if (delegate.didPressAnimatedEmoji(pressedEmoji)) {
if (delegate.didPressAnimatedEmoji(this, pressedEmoji)) {
resetPressedLink(3);
pressedEmoji = null;
return true;
@ -1769,7 +1772,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
((ClickableSpan) pressedLink.getSpan()).onClick(this);
}
resetPressedLink(2);
} else if (pressedEmoji != null && delegate.didPressAnimatedEmoji(pressedEmoji)) {
} else if (pressedEmoji != null && delegate.didPressAnimatedEmoji(this, pressedEmoji)) {
pressedEmoji = null;
resetPressedLink(2);
} else {
@ -3031,6 +3034,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (currentMessageObject.hasValidGroupId() && currentMessagesGroup != null && !currentMessagesGroup.isDocuments) {
ViewGroup parent = (ViewGroup) getParent();
if (parent == null) {
return false;
}
for (int i = 0; i < parent.getChildCount(); i++) {
View v = parent.getChildAt(i);
if (v instanceof ChatMessageCell) {
@ -3656,6 +3662,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.startSpoilers);
NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.stopSpoilers);
NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.emojiLoaded);
NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.userInfoDidLoad);
cancelShakeAnimation();
@ -3714,6 +3721,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
NotificationCenter.getGlobalInstance().addObserver(this, NotificationCenter.startSpoilers);
NotificationCenter.getGlobalInstance().addObserver(this, NotificationCenter.stopSpoilers);
NotificationCenter.getGlobalInstance().addObserver(this, NotificationCenter.emojiLoaded);
NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.userInfoDidLoad);
// if (currentMessageObject != null) {
@ -4594,8 +4602,8 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
photo = null;
author = null;
document = null;
if (invoice.photo instanceof TLRPC.TL_webDocument) {
webDocument = WebFile.createWithWebDocument(invoice.photo);
if (invoice.webPhoto instanceof TLRPC.TL_webDocument) {
webDocument = WebFile.createWithWebDocument(invoice.webPhoto);
} else {
webDocument = null;
}
@ -5657,7 +5665,13 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
lastPoll = media.poll;
lastPollResults = media.results.results;
lastPollResultsVoters = media.results.total_voters;
if (media.poll.multiple_choice && !pollVoted && !pollClosed || !isBot && (media.poll.public_voters && pollVoted || pollClosed && media.results != null && media.results.total_voters != 0 && media.poll.public_voters)) {
if (
media.poll.multiple_choice && !pollVoted && !pollClosed ||
!isBot && media.poll.public_voters && (
pollVoted ||
pollClosed && media.results != null && media.results.total_voters != 0
)
) {
drawInstantView = true;
drawInstantViewType = 8;
createInstantViewButton();
@ -5815,10 +5829,11 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
setMessageObjectInternal(messageObject);
pollInstantViewTouchesBottom = false;
if (isBot && !drawInstantView) {
height -= AndroidUtilities.dp(10);
} else if (media.poll.public_voters || media.poll.multiple_choice) {
pollInstantViewTouchesBottom = true;
height += AndroidUtilities.dp(13);
}
totalHeight = AndroidUtilities.dp(46 + 27) + namesOffset + height;
@ -7580,7 +7595,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
}
if (pressedEmoji != null) {
// hadLongPress = true;
// if (delegate.didPressAnimatedEmoji(pressedEmoji)) {
// if (delegate.didPressAnimatedEmoji(this, pressedEmoji)) {
// pressedEmoji = null;
// resetPressedLink(-1);
// return true;
@ -8316,7 +8331,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
}
radii[a * 2] = radii[a * 2 + 1] = 0;
}
if (!out && !drawPinnedBottom && currentPosition == null && (currentMessageObject == null || currentMessageObject.type != MessageObject.TYPE_POLL)) {
if (!out && !drawPinnedBottom && currentPosition == null && (currentMessageObject == null || currentMessageObject.type != MessageObject.TYPE_POLL || pollInstantViewTouchesBottom)) {
path.moveTo(rect.left + AndroidUtilities.dp(6), rect.top);
path.lineTo(rect.left + AndroidUtilities.dp(6), rect.bottom - AndroidUtilities.dp(6) - AndroidUtilities.dp(2 + 3));
AndroidUtilities.rectTmp.set(
@ -9020,7 +9035,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (currentMessageObject.isOutOwner()) {
textX = getCurrentBackgroundLeft() + AndroidUtilities.dp(11) + getExtraTextX();
} else {
textX = getCurrentBackgroundLeft() + AndroidUtilities.dp(!mediaBackground && drawPinnedBottom ? 11 : 17) + getExtraTextX();
textX = getCurrentBackgroundLeft() + (currentMessageObject.type == MessageObject.TYPE_EMOJIS ? 0 : AndroidUtilities.dp(!mediaBackground && drawPinnedBottom ? 11 : 17)) + getExtraTextX();
}
if (hasGamePreview) {
textX += AndroidUtilities.dp(11);
@ -9063,13 +9078,13 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
Rect r = currentBackgroundDrawable.getBounds();
if (currentMessageObject.isOutOwner() && !mediaBackground && !pinnedBottom) {
canvas.clipRect(
r.left + AndroidUtilities.dp(4), r.top + AndroidUtilities.dp(4),
r.right - AndroidUtilities.dp(10), r.bottom - AndroidUtilities.dp(4)
r.left + AndroidUtilities.dp(4), r.top + AndroidUtilities.dp(4),
r.right - AndroidUtilities.dp(10), r.bottom - AndroidUtilities.dp(4)
);
} else {
canvas.clipRect(
r.left + AndroidUtilities.dp(4), r.top + AndroidUtilities.dp(4),
r.right - AndroidUtilities.dp(4), r.bottom - AndroidUtilities.dp(4)
r.left + AndroidUtilities.dp(4), r.top + AndroidUtilities.dp(4),
r.right - AndroidUtilities.dp(4), r.bottom - AndroidUtilities.dp(4)
);
}
}
@ -9114,21 +9129,6 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
Theme.chat_docBackPaint.setColor(getThemedColor(currentMessageObject.isOutOwner() ? Theme.key_chat_outBubble : Theme.key_chat_inBubble));
canvas.drawCircle(photoImage.getCenterX(), photoImage.getCenterY(), photoImage.getImageWidth() / 2, Theme.chat_docBackPaint);
}
} else if (currentMessageObject.type == MessageObject.TYPE_GEO) {
// rect.set(photoImage.getImageX(), photoImage.getImageY(), photoImage.getImageX2(), photoImage.getImageY2());
// Theme.chat_docBackPaint.setColor(getThemedColor(currentMessageObject.isOutOwner() ? Theme.key_chat_outLocationBackground : Theme.key_chat_inLocationBackground));
// int[] rad = photoImage.getRoundRadius();
// rectPath.reset();
// for (int a = 0; a < rad.length; a++) {
// radii[a * 2] = radii[a * 2 + 1] = rad[a];
// }
// rectPath.addRoundRect(rect, radii, Path.Direction.CW);
// rectPath.close();
// canvas.drawPath(rectPath, Theme.chat_docBackPaint);
//
// Drawable iconDrawable = Theme.chat_locationDrawable[currentMessageObject.isOutOwner() ? 1 : 0];
// setDrawableBounds(iconDrawable, rect.centerX() - iconDrawable.getIntrinsicWidth() / 2, rect.centerY() - iconDrawable.getIntrinsicHeight() / 2);
// iconDrawable.draw(canvas);
}
drawMediaCheckBox = mediaCheckBox != null && (checkBoxVisible || mediaCheckBox.getProgress() != 0 || checkBoxAnimationInProgress) && currentMessagesGroup != null;
if (drawMediaCheckBox && (mediaCheckBox.isChecked() || mediaCheckBox.getProgress() != 0 || checkBoxAnimationInProgress) && (!textIsSelectionMode())) {
@ -9237,7 +9237,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
}
}
if (documentAttachType == DOCUMENT_ATTACH_TYPE_GIF) {
if (photoImage.getVisible() && !hasGamePreview && !currentMessageObject.needDrawBluredPreview()) {
if (drawPhotoImage && photoImage.getVisible() && !hasGamePreview && !currentMessageObject.needDrawBluredPreview()) {
int oldAlpha = ((BitmapDrawable) Theme.chat_msgMediaMenuDrawable).getPaint().getAlpha();
Theme.chat_msgMediaMenuDrawable.setAlpha((int) (oldAlpha * controlsAlpha));
setDrawableBounds(Theme.chat_msgMediaMenuDrawable, otherX = (int) (photoImage.getImageX() + photoImage.getImageWidth() - AndroidUtilities.dp(14)), otherY = (int) (photoImage.getImageY() + AndroidUtilities.dp(8.1f)));
@ -10498,7 +10498,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
}
return firstLineWidth - AndroidUtilities.dp(31 + (isAvatarVisible ? 48 : 0));
} else if (currentMessageObject.type == MessageObject.TYPE_EMOJIS) {
return AndroidUtilities.displaySize.x - (currentMessageObject.textWidth + AndroidUtilities.dp(14)) - AndroidUtilities.dp(52) - (isAvatarVisible ? AndroidUtilities.dp(48) : 0);
return Math.max(currentMessageObject.textWidth, (int) ((AndroidUtilities.displaySize.x - AndroidUtilities.dp(52) - (isAvatarVisible ? AndroidUtilities.dp(48) : 0)) * .5f));
} else {
return backgroundWidth - AndroidUtilities.dp(mediaBackground ? 22 : 31);
}
@ -11534,7 +11534,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} else {
currentTimeString = timeString;
}
timeTextWidth = timeWidth = (int) Math.ceil(Theme.chat_timePaint.measureText(currentTimeString));
timeTextWidth = timeWidth = (int) Math.ceil(Theme.chat_timePaint.measureText(currentTimeString, 0, currentTimeString == null ? 0 : currentTimeString.length()));
if (currentMessageObject.scheduled && currentMessageObject.messageOwner.date == 0x7FFFFFFE) {
timeWidth -= AndroidUtilities.dp(8);
}
@ -11583,6 +11583,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
widthForSign -= AndroidUtilities.dp(96);
}
}
signString = Emoji.replaceEmoji(signString, Theme.chat_timePaint.getFontMetricsInt(), AndroidUtilities.dp(10), false);
int width = (int) Math.ceil(Theme.chat_timePaint.measureText(signString, 0, signString.length()));
if (width > widthForSign) {
if (widthForSign <= 0) {
@ -11593,7 +11594,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
width = widthForSign;
}
}
currentTimeString = signString + currentTimeString;
SpannableStringBuilder currentTimeStringBuilder = new SpannableStringBuilder(signString);
currentTimeStringBuilder.append(currentTimeString);
currentTimeString = currentTimeStringBuilder;
timeTextWidth += width;
timeWidth += width;
}
@ -11907,9 +11910,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
lastLine = TextUtils.ellipsize(lastLine, Theme.chat_forwardNamePaint, forwardedNameWidth, TextUtils.TruncateAt.END);
try {
lastLine = Emoji.replaceEmoji(lastLine, Theme.chat_forwardNamePaint.getFontMetricsInt(), AndroidUtilities.dp(14), false);
} catch (Exception ignore) {
}
;
} catch (Exception ignore) {}
try {
forwardedNameLayout[1] = new StaticLayout(lastLine, Theme.chat_forwardNamePaint, forwardedNameWidth + AndroidUtilities.dp(2), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
lastLine = TextUtils.ellipsize(AndroidUtilities.replaceTags(forwardedString), Theme.chat_forwardNamePaint, forwardedNameWidth, TextUtils.TruncateAt.END);
@ -11920,8 +11921,11 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
}
forwardNameOffsetX[0] = forwardedNameLayout[0].getLineLeft(0);
forwardNameOffsetX[1] = forwardedNameLayout[1].getLineLeft(0);
if (messageObject.type != MessageObject.TYPE_ROUND_VIDEO && !messageObject.isAnyKindOfSticker()) {
if (messageObject.type != MessageObject.TYPE_ROUND_VIDEO && !messageObject.isAnyKindOfSticker() || messageObject.type == MessageObject.TYPE_EMOJIS) {
namesOffset += AndroidUtilities.dp(8) + Theme.chat_forwardNamePaint.getTextSize() * 2;
if (messageObject.type == MessageObject.TYPE_EMOJIS) {
namesOffset += AndroidUtilities.dp(8);
}
}
} catch (Exception e) {
FileLog.e(e);
@ -11930,9 +11934,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
}
drawTopic = false;
if (!isThreadChat && !pinnedTop && (MessageObject.getTopicId(messageObject.messageOwner) != 0 || messageObject.replyToForumTopic != null)) {
if (!isThreadChat && (delegate != null && delegate.shouldShowTopicButton()) && !pinnedTop && (MessageObject.getTopicId(messageObject.messageOwner, ChatObject.isForum(currentChat)) != 0 || messageObject.replyToForumTopic != null)) {
if (currentPosition == null || currentPosition.minY == 0) {
int topicId = MessageObject.getTopicId(messageObject.messageOwner);
int topicId = messageObject.replyToForumTopic == null ? MessageObject.getTopicId(messageObject.messageOwner, ChatObject.isForum(currentChat)) : messageObject.replyToForumTopic.id;
TLRPC.TL_forumTopic topic = messageObject.replyToForumTopic == null ? MessagesController.getInstance(currentAccount).getTopicsController().findTopic(-messageObject.getDialogId(), topicId) : messageObject.replyToForumTopic;
if (topic != null) {
drawTopic = true;
@ -11967,9 +11971,11 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if ((!isThreadChat || messageObject.getReplyTopMsgId() != 0) && messageObject.hasValidReplyMessageObject() || messageObject.messageOwner.fwd_from != null && messageObject.isDice()) {
if (currentPosition == null || currentPosition.minY == 0) {
if (!messageObject.isAnyKindOfSticker() && messageObject.type != MessageObject.TYPE_ROUND_VIDEO) {
if (!messageObject.isAnyKindOfSticker() && messageObject.type != MessageObject.TYPE_ROUND_VIDEO || messageObject.type == MessageObject.TYPE_EMOJIS) {
namesOffset += AndroidUtilities.dp(14) + (Theme.chat_replyTextPaint.getTextSize() + Theme.chat_replyNamePaint.getTextSize());
if (messageObject.type != MessageObject.TYPE_TEXT) {
if (messageObject.type == MessageObject.TYPE_EMOJIS && !drawForwardedName) {
namesOffset += AndroidUtilities.dp(12);
} else if (messageObject.type != MessageObject.TYPE_TEXT) {
namesOffset += AndroidUtilities.dp(5);
}
}
@ -12511,7 +12517,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (replyNameLayout != null) {
replyHeight = AndroidUtilities.dp(7) + Theme.chat_replyNamePaint.getTextSize() + Theme.chat_replyTextPaint.getTextSize();
if (currentMessageObject.shouldDrawWithoutBackground()) {
if (currentMessageObject.shouldDrawWithoutBackground() && currentMessageObject.type != MessageObject.TYPE_EMOJIS) {
if (currentMessageObject.isOutOwner()) {
replyStartX = AndroidUtilities.dp(23);
if (isPlayingRound) {
@ -12534,6 +12540,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} else {
if (currentMessageObject.isOutOwner()) {
replyStartX = backgroundDrawableLeft + AndroidUtilities.dp(12) + getExtraTextX();
if (currentMessageObject.type == MessageObject.TYPE_EMOJIS) {
replyStartX -= Math.max(0, replyStartX + Math.max(replyNameWidth, replyTextWidth) + AndroidUtilities.dp(14) - AndroidUtilities.displaySize.x);
}
} else {
if (mediaBackground) {
replyStartX = backgroundDrawableLeft + AndroidUtilities.dp(12) + getExtraTextX();
@ -12541,6 +12550,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
replyStartX = backgroundDrawableLeft + AndroidUtilities.dp(drawPinnedBottom ? 12 : 18) + getExtraTextX();
}
}
if (currentMessageObject.type == MessageObject.TYPE_EMOJIS) {
replyStartX -= AndroidUtilities.dp(7);
}
forwardHeight = AndroidUtilities.dp(4) + (int) Theme.chat_forwardNamePaint.getTextSize() * 2;
replyStartY = AndroidUtilities.dp(12) + (drawNameLayout && nameLayout != null ? AndroidUtilities.dp(6) + (int) Theme.chat_namePaint.getTextSize() : 0) + (drawForwardedName && forwardedNameLayout[0] != null ? AndroidUtilities.dp(4) + forwardHeight : 0);
if (drawTopic && topicButton != null) {
@ -12819,37 +12831,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
}
if (checkBoxVisible || checkBoxAnimationInProgress) {
if (checkBoxVisible && checkBoxAnimationProgress == 1.0f || !checkBoxVisible && checkBoxAnimationProgress == 0.0f) {
checkBoxAnimationInProgress = false;
}
Interpolator interpolator = checkBoxVisible ? CubicBezierInterpolator.EASE_OUT : CubicBezierInterpolator.EASE_IN;
checkBoxTranslation = (int) Math.ceil(interpolator.getInterpolation(checkBoxAnimationProgress) * AndroidUtilities.dp(35));
if (!currentMessageObject.isOutOwner()) {
updateTranslation();
}
animateCheckboxTranslation();
int size = AndroidUtilities.dp(21);
checkBox.setBounds(AndroidUtilities.dp(8 - 35) + checkBoxTranslation, currentBackgroundDrawable.getBounds().bottom - AndroidUtilities.dp(8) - size, size, size);
if (checkBoxAnimationInProgress) {
long newTime = SystemClock.elapsedRealtime();
long dt = newTime - lastCheckBoxAnimationTime;
lastCheckBoxAnimationTime = newTime;
if (checkBoxVisible) {
checkBoxAnimationProgress += dt / 200.0f;
if (checkBoxAnimationProgress > 1.0f) {
checkBoxAnimationProgress = 1.0f;
}
} else {
checkBoxAnimationProgress -= dt / 200.0f;
if (checkBoxAnimationProgress <= 0.0f) {
checkBoxAnimationProgress = 0.0f;
}
}
invalidate();
((View) getParent()).invalidate();
}
}
if (!fromParent && drawBackgroundInParent()) {
@ -12992,6 +12976,39 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
canvas.restoreToCount(restoreCount);
}
private void animateCheckboxTranslation() {
if (checkBoxVisible || checkBoxAnimationInProgress) {
if (checkBoxVisible && checkBoxAnimationProgress == 1.0f || !checkBoxVisible && checkBoxAnimationProgress == 0.0f) {
checkBoxAnimationInProgress = false;
}
Interpolator interpolator = checkBoxVisible ? CubicBezierInterpolator.EASE_OUT : CubicBezierInterpolator.EASE_IN;
checkBoxTranslation = (int) Math.ceil(interpolator.getInterpolation(checkBoxAnimationProgress) * AndroidUtilities.dp(35));
if (!currentMessageObject.isOutOwner()) {
updateTranslation();
}
if (checkBoxAnimationInProgress) {
long newTime = SystemClock.elapsedRealtime();
long dt = newTime - lastCheckBoxAnimationTime;
lastCheckBoxAnimationTime = newTime;
if (checkBoxVisible) {
checkBoxAnimationProgress += dt / 200.0f;
if (checkBoxAnimationProgress > 1.0f) {
checkBoxAnimationProgress = 1.0f;
}
} else {
checkBoxAnimationProgress -= dt / 200.0f;
if (checkBoxAnimationProgress <= 0.0f) {
checkBoxAnimationProgress = 0.0f;
}
}
invalidate();
((View) getParent()).invalidate();
}
}
}
public boolean drawBackgroundInParent() {
if (canDrawBackgroundInParent && currentMessageObject != null && currentMessageObject.isOutOwner()) {
if (resourcesProvider != null) {
@ -13331,6 +13348,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
}
}
sideStartY = layoutHeight + transitionParams.deltaBottom - AndroidUtilities.dp(41);
if (currentMessageObject.type == MessageObject.TYPE_EMOJIS && currentMessageObject.textWidth < timeTextWidth) {
sideStartY -= AndroidUtilities.dp(22);
}
if (currentMessagesGroup != null) {
sideStartY += currentMessagesGroup.transitionParams.offsetBottom;
if (currentMessagesGroup.transitionParams.backgroundChangeBounds) {
@ -13536,6 +13556,8 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
currentBackgroundDrawable.drawCached(canvas, backgroundCacheParams);
currentBackgroundDrawable.setAlpha(255);
}
animateCheckboxTranslation();
}
public boolean hasNameLayout() {
@ -13761,7 +13783,25 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (drawForwardedNameLocal && forwardedNameLayoutLocal[0] != null && forwardedNameLayoutLocal[1] != null && (currentPosition == null || currentPosition.minY == 0 && currentPosition.minX == 0)) {
if (currentMessageObject.type == MessageObject.TYPE_ROUND_VIDEO || currentMessageObject.isAnyKindOfSticker()) {
Theme.chat_forwardNamePaint.setColor(getThemedColor(Theme.key_chat_stickerReplyNameText));
if (currentMessageObject.needDrawForwarded()) {
if (currentMessageObject.type == MessageObject.TYPE_EMOJIS) {
if (currentMessageObject.isOutOwner()) {
if (currentMessageObject.needDrawForwarded()) {
forwardNameXLocal = forwardNameX = backgroundDrawableLeft + AndroidUtilities.dp(11) + getExtraTextX();
forwardNameXLocal += transitionParams.deltaLeft;
} else {
forwardNameXLocal = transitionParams.animateForwardNameX;
}
int width = Math.max(forwardedNameWidthLocal + AndroidUtilities.dp(14), hasReply ? Math.max(replyNameWidth, replyTextWidth) + AndroidUtilities.dp(14) : 0);
forwardNameXLocal -= Math.max(0, forwardNameXLocal + width - AndroidUtilities.displaySize.x);
} else {
if (currentMessageObject.needDrawForwarded()) {
forwardNameXLocal = forwardNameX = backgroundDrawableLeft + AndroidUtilities.dp(mediaBackground || drawPinnedBottom ? 11 : 17) + getExtraTextX();
} else {
forwardNameXLocal = transitionParams.animateForwardNameX;
}
}
forwardNameXLocal -= AndroidUtilities.dp(7);
} else if (currentMessageObject.needDrawForwarded()) {
if (currentMessageObject.isOutOwner()) {
forwardNameXLocal = forwardNameX = AndroidUtilities.dp(23);
} else {
@ -13808,11 +13848,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
forwardNameY = AndroidUtilities.dp(10) + (drawNameLayout ? AndroidUtilities.dp(5) + (int) Theme.chat_namePaint.getTextSize() : 0) + (drawTopic && topicButton != null ? topicButton.height() + AndroidUtilities.dp(7 + (currentMessageObject.type != MessageObject.TYPE_TEXT ? 3 : 0)) : 0);
forwardHeight = AndroidUtilities.dp(4) + (int) Theme.chat_forwardNamePaint.getTextSize() * 2;
if (currentMessageObject.isOutOwner()) {
if (hasPsaHint) {
Theme.chat_forwardNamePaint.setColor(getThemedColor(Theme.key_chat_outPsaNameText));
} else {
Theme.chat_forwardNamePaint.setColor(getThemedColor(Theme.key_chat_outForwardedNameText));
}
Theme.chat_forwardNamePaint.setColor(getThemedColor(hasPsaHint ? Theme.key_chat_outPsaNameText : Theme.key_chat_outForwardedNameText));
if (currentMessageObject.needDrawForwarded()) {
forwardNameXLocal = forwardNameX = backgroundDrawableLeft + AndroidUtilities.dp(11) + getExtraTextX();
forwardNameXLocal += transitionParams.deltaLeft;
@ -13820,17 +13856,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
forwardNameXLocal = transitionParams.animateForwardNameX;
}
} else {
if (hasPsaHint) {
Theme.chat_forwardNamePaint.setColor(getThemedColor(Theme.key_chat_inPsaNameText));
} else {
Theme.chat_forwardNamePaint.setColor(getThemedColor(Theme.key_chat_inForwardedNameText));
}
Theme.chat_forwardNamePaint.setColor(getThemedColor(hasPsaHint ? Theme.key_chat_inPsaNameText : Theme.key_chat_inForwardedNameText));
if (currentMessageObject.needDrawForwarded()) {
if (mediaBackground) {
forwardNameXLocal = forwardNameX = backgroundDrawableLeft + AndroidUtilities.dp(11) + getExtraTextX();
} else {
forwardNameXLocal = forwardNameX = backgroundDrawableLeft + AndroidUtilities.dp(drawPinnedBottom ? 11 : 17) + getExtraTextX();
}
forwardNameXLocal = forwardNameX = backgroundDrawableLeft + AndroidUtilities.dp(mediaBackground || drawPinnedBottom ? 11 : 17) + getExtraTextX();
} else {
forwardNameXLocal = transitionParams.animateForwardNameX;
}
@ -13911,7 +13939,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (drawTopic && topicButton != null && (animatingAlpha > 0 && replyForwardAlpha > 0) && (currentPosition == null || currentPosition.minY == 0 && currentPosition.minX == 0)) {
float x, y;
if (currentMessageObject.shouldDrawWithoutBackground()) {
if (currentMessageObject.shouldDrawWithoutBackground() && currentMessageObject.type != MessageObject.TYPE_EMOJIS) {
if (currentMessageObject.isOutOwner()) {
x = AndroidUtilities.dp(23);
if (isPlayingRound) {
@ -14011,9 +14039,10 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
int offset = (int) Math.min(AndroidUtilities.dp(10), (replyHeight - AndroidUtilities.dp(35)) / 1.5f + AndroidUtilities.dp(10));
forwardNameX = replyStartX - replyTextOffset + offset + (needReplyImage ? offset - AndroidUtilities.dp(1) + replyHeight : 0);
if ((currentPosition == null || currentPosition.minY == 0 && currentPosition.minX == 0) && !(enterTransitionInProgress && !currentMessageObject.isVoice())) {
int restoreToCount = -1;
if (getAlpha() * replyForwardAlpha != 1f) {
AndroidUtilities.rectTmp.set(0, 0, getWidth(), getHeight());
canvas.saveLayerAlpha(AndroidUtilities.rectTmp, (int) (0xFF * getAlpha() * replyForwardAlpha), Canvas.ALL_SAVE_FLAG);
restoreToCount = canvas.saveLayerAlpha(AndroidUtilities.rectTmp, (int) (0xFF * getAlpha() * replyForwardAlpha), Canvas.ALL_SAVE_FLAG);
}
int leftRad, rightRad, bottomRad = AndroidUtilities.dp(Math.min(2, SharedConfig.bubbleRadius));
@ -14084,8 +14113,8 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
canvas.restore();
}
if (getAlpha() * replyForwardAlpha != 1f) {
canvas.restore();
if (restoreToCount >= 0) {
canvas.restoreToCount(restoreToCount);
}
}
}
@ -14302,7 +14331,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
buttonX -= AndroidUtilities.dp(10);
}
commentButtonRect.set(
buttonX - AndroidUtilities.dp((currentMessageObject == null || !currentMessageObject.isOut()) && !drawPinnedBottom && currentPosition == null && (currentMessageObject == null || currentMessageObject.type != MessageObject.TYPE_POLL) ? 6 : 0),
buttonX - AndroidUtilities.dp((currentMessageObject == null || !currentMessageObject.isOut()) && !drawPinnedBottom && currentPosition == null && (currentMessageObject == null || currentMessageObject.type != MessageObject.TYPE_POLL || pollInstantViewTouchesBottom) ? 6 : 0),
(int) buttonY,
endX - AndroidUtilities.dp(14),
layoutHeight - AndroidUtilities.dp(h)
@ -16240,7 +16269,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
instantButtonRect.set(textX, instantY, textX + instantWidth, instantY + AndroidUtilities.dp(44));
if (selectorDrawable[0] != null && selectorDrawableMaskType[0] == 2) {
selectorDrawable[0].setBounds(textX, instantY, textX + instantWidth, instantY + AndroidUtilities.dp(44));
selectorDrawable[0].setBounds(textX - AndroidUtilities.dp(pollInstantViewTouchesBottom ? 6 : 0), instantY, textX + instantWidth, instantY + AndroidUtilities.dp(44));
selectorDrawable[0].draw(canvas);
}
if (instantViewLayout != null) {
@ -18014,14 +18043,14 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
}
if (edited && !lastDrawingEdited && timeLayout != null) {
String editedStr = LocaleController.getString("EditedMessage", R.string.EditedMessage);
String text = timeLayout.getText().toString();
int i = text.indexOf(editedStr);
CharSequence text = timeLayout.getText();
int i = text.toString().indexOf(editedStr);
if (i >= 0) {
if (i == 0) {
animateEditedLayout = new StaticLayout(editedStr, Theme.chat_timePaint, timeTextWidth + AndroidUtilities.dp(100), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder();
spannableStringBuilder.append(editedStr);
spannableStringBuilder.append(text.substring(editedStr.length()));
spannableStringBuilder.append(text.subSequence(editedStr.length(), text.length()));
spannableStringBuilder.setSpan(new EmptyStubSpan(), 0, editedStr.length(), 0);
animateTimeLayout = new StaticLayout(spannableStringBuilder, Theme.chat_timePaint, timeTextWidth + AndroidUtilities.dp(100), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
animateEditedWidthDiff = timeWidth - lastTimeWidth;

View File

@ -68,7 +68,7 @@ public class CheckBoxCell extends FrameLayout {
} else {
textView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.CENTER_VERTICAL);
if (type == 2) {
addView(textView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, (LocaleController.isRTL ? 0 : 29), 0, (LocaleController.isRTL ? 29 : 0), 0));
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));
@ -238,7 +238,7 @@ public class CheckBoxCell extends FrameLayout {
@Override
protected void onDraw(Canvas canvas) {
if (needDivider) {
int offset = currentType == TYPE_CHECK_BOX_ROUND ? 50 : 20;
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);
}
}

View File

@ -10,28 +10,27 @@ package org.telegram.ui.Cells;
import android.content.Context;
import android.graphics.Canvas;
import android.text.TextUtils;
import android.util.TypedValue;
import android.graphics.drawable.Drawable;
import android.view.Gravity;
import android.widget.FrameLayout;
import android.widget.TextView;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ContactsController;
import org.telegram.messenger.ImageLocation;
import org.telegram.messenger.LocaleController;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.SimpleTextView;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.AvatarDrawable;
import org.telegram.ui.Components.BackupImageView;
import org.telegram.ui.Components.CheckBoxSquare;
import org.telegram.ui.Components.CombinedDrawable;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.Switch;
public class CheckBoxUserCell extends FrameLayout {
private TextView textView;
private SimpleTextView textView;
private BackupImageView imageView;
private CheckBoxSquare checkBox;
private Switch checkBox;
private AvatarDrawable avatarDrawable;
private boolean needDivider;
@ -40,23 +39,21 @@ public class CheckBoxUserCell extends FrameLayout {
public CheckBoxUserCell(Context context, boolean alert) {
super(context);
textView = new TextView(context);
textView = new SimpleTextView(context);
textView.setTextColor(Theme.getColor(alert ? Theme.key_dialogTextBlack : Theme.key_windowBackgroundWhiteBlackText));
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
textView.setLines(1);
textView.setMaxLines(1);
textView.setSingleLine(true);
textView.setEllipsize(TextUtils.TruncateAt.END);
textView.setTextSize(16);
textView.setEllipsizeByGradient(true);
textView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.CENTER_VERTICAL);
addView(textView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, (LocaleController.isRTL ? 21 : 94), 0, (LocaleController.isRTL ? 94 : 21), 0));
addView(textView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, (LocaleController.isRTL ? 21 : 69), 0, (LocaleController.isRTL ? 69 : 21), 0));
avatarDrawable = new AvatarDrawable();
imageView = new BackupImageView(context);
imageView.setRoundRadius(AndroidUtilities.dp(36));
addView(imageView, LayoutHelper.createFrame(36, 36, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, 48, 7, 48, 0));
addView(imageView, LayoutHelper.createFrame(36, 36, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, 23, 7, 23, 0));
checkBox = new CheckBoxSquare(context, alert, null);
addView(checkBox, LayoutHelper.createFrame(18, 18, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, (LocaleController.isRTL ? 0 : 21), 16, (LocaleController.isRTL ? 21 : 0), 0));
checkBox = new Switch(context, null);
checkBox.setColors(Theme.key_switchTrack, Theme.key_switchTrackChecked, Theme.key_windowBackgroundWhite, Theme.key_windowBackgroundWhite);
addView(checkBox, LayoutHelper.createFrame(37, 20, (LocaleController.isRTL ? Gravity.LEFT : Gravity.RIGHT) | Gravity.CENTER_VERTICAL, 22, 0, 22, 0));
}
@Override
@ -72,9 +69,22 @@ public class CheckBoxUserCell extends FrameLayout {
return currentUser;
}
private static Drawable verifiedDrawable;
private Drawable getVerifiedDrawable() {
if (verifiedDrawable == null) {
verifiedDrawable = new CombinedDrawable(Theme.dialogs_verifiedDrawable, Theme.dialogs_verifiedCheckDrawable);
}
return verifiedDrawable;
}
public void setUser(TLRPC.User user, boolean checked, boolean divider) {
currentUser = user;
textView.setText(ContactsController.formatName(user.first_name, user.last_name));
if (user != null) {
textView.setText(ContactsController.formatName(user.first_name, user.last_name));
} else {
textView.setText("");
}
textView.setRightDrawable(user != null && user.verified ? getVerifiedDrawable() : null);
checkBox.setChecked(checked, false);
avatarDrawable.setInfo(user);
imageView.setForUserOrChat(user, avatarDrawable);
@ -90,11 +100,11 @@ public class CheckBoxUserCell extends FrameLayout {
return checkBox.isChecked();
}
public TextView getTextView() {
public SimpleTextView getTextView() {
return textView;
}
public CheckBoxSquare getCheckBox() {
public Switch getCheckBox() {
return checkBox;
}

View File

@ -21,8 +21,10 @@ import android.widget.FrameLayout;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ChatObject;
import org.telegram.messenger.Emoji;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MessagesController;
import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R;
import org.telegram.messenger.UserConfig;
import org.telegram.messenger.UserObject;
@ -86,7 +88,14 @@ public class GroupCreateUserCell extends FrameLayout {
avatarImageView.setRoundRadius(AndroidUtilities.dp(24));
addView(avatarImageView, LayoutHelper.createFrame(46, 46, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 0 : (13 + padding), 6, LocaleController.isRTL ? (13 + padding) : 0, 0));
nameTextView = new SimpleTextView(context);
nameTextView = new SimpleTextView(context) {
@Override
public boolean setText(CharSequence value, boolean force) {
value = Emoji.replaceEmoji(value, getPaint().getFontMetricsInt(), AndroidUtilities.dp(14), false);
return super.setText(value, force);
}
};
NotificationCenter.listenEmojiLoading(nameTextView);
nameTextView.setTextColor(Theme.getColor(forceDarkTheme ? Theme.key_voipgroup_nameText : Theme.key_windowBackgroundWhiteBlackText));
nameTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
nameTextView.setTextSize(16);
@ -203,6 +212,7 @@ public class GroupCreateUserCell extends FrameLayout {
TLRPC.FileLocation photo = null;
String newName = null;
TLRPC.Chat currentChat = null;
if (currentObject instanceof String) {
((LayoutParams) nameTextView.getLayoutParams()).topMargin = AndroidUtilities.dp(15);
avatarImageView.getLayoutParams().width = avatarImageView.getLayoutParams().height = AndroidUtilities.dp(38);
@ -332,7 +342,7 @@ public class GroupCreateUserCell extends FrameLayout {
avatarImageView.setForUserOrChat(currentUser, avatarDrawable);
} else {
TLRPC.Chat currentChat = (TLRPC.Chat) currentObject;
currentChat = (TLRPC.Chat) currentObject;
if (currentChat.photo != null) {
photo = currentChat.photo.photo_small;
}
@ -394,6 +404,8 @@ public class GroupCreateUserCell extends FrameLayout {
}
}
avatarImageView.setRoundRadius(currentChat != null && currentChat.forum ? AndroidUtilities.dp(14) : AndroidUtilities.dp(24));
if (currentStatus != null) {
statusTextView.setText(currentStatus, true);
statusTextView.setTag(Theme.key_windowBackgroundWhiteGrayText);
@ -435,4 +447,8 @@ public class GroupCreateUserCell extends FrameLayout {
info.setChecked(true);
}
}
public SimpleTextView getStatusTextView() {
return statusTextView;
}
}

View File

@ -89,6 +89,18 @@ public class HeaderCell extends FrameLayout {
textView.setMinHeight(AndroidUtilities.dp(height = value) - ((LayoutParams) textView.getLayoutParams()).topMargin);
}
public void setTopMargin(int topMargin) {
((LayoutParams) textView.getLayoutParams()).topMargin = AndroidUtilities.dp(topMargin);
setHeight(height);
}
public void setBottomMargin(int bottomMargin) {
((LayoutParams) textView.getLayoutParams()).bottomMargin = AndroidUtilities.dp(bottomMargin);
if (textView2 != null) {
((LayoutParams) textView2.getLayoutParams()).bottomMargin = AndroidUtilities.dp(bottomMargin);
}
}
public void setEnabled(boolean value, ArrayList<Animator> animators) {
if (animators != null) {
animators.add(ObjectAnimator.ofFloat(textView, View.ALPHA, value ? 1.0f : 0.5f));

View File

@ -20,7 +20,9 @@ import android.widget.TextView;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.DialogObject;
import org.telegram.messenger.Emoji;
import org.telegram.messenger.MessagesController;
import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.UserConfig;
import org.telegram.messenger.UserObject;
import org.telegram.tgnet.ConnectionsManager;
@ -59,7 +61,14 @@ public class HintDialogCell extends FrameLayout {
imageView.setRoundRadius(AndroidUtilities.dp(27));
addView(imageView, LayoutHelper.createFrame(54, 54, Gravity.TOP | Gravity.CENTER_HORIZONTAL, 0, 7, 0, 0));
nameTextView = new TextView(context);
nameTextView = new TextView(context) {
@Override
public void setText(CharSequence text, BufferType type) {
text = Emoji.replaceEmoji(text, getPaint().getFontMetricsInt(), AndroidUtilities.dp(10), false);
super.setText(text, type);
}
};
NotificationCenter.listenEmojiLoading(nameTextView);
nameTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText));
nameTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 12);
nameTextView.setMaxLines(1);

View File

@ -12,14 +12,13 @@ import android.content.Context;
import android.graphics.Canvas;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.text.TextUtils;
import android.view.Gravity;
import android.widget.FrameLayout;
import android.widget.ImageView;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ChatObject;
import org.telegram.messenger.ImageLocation;
import org.telegram.messenger.Emoji;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MessagesController;
import org.telegram.messenger.R;
@ -242,7 +241,7 @@ public class ManageChatUserCell extends FrameLayout {
nameTextView.setText(currentName);
} else {
lastName = newName == null ? UserObject.getUserName(currentUser) : newName;
nameTextView.setText(lastName);
nameTextView.setText(Emoji.replaceEmoji(lastName, nameTextView.getPaint().getFontMetricsInt(), AndroidUtilities.dp(15), false));
}
if (currrntStatus != null) {
statusTextView.setTextColor(statusColor);

View File

@ -116,7 +116,7 @@ public class PaymentInfoCell extends FrameLayout {
}
public void setInvoice(TLRPC.TL_messageMediaInvoice invoice, String botname) {
setInfo(invoice.title, invoice.description, invoice.photo, botname, invoice);
setInfo(invoice.title, invoice.description, invoice.webPhoto, botname, invoice);
}
public void setReceipt(TLRPC.TL_payments_paymentReceipt receipt, String botname) {

View File

@ -114,6 +114,9 @@ public class RadioCell extends FrameLayout {
}
}
public void hideRadioButton() {
radioButton.setVisibility(View.GONE);
}
@Override
protected void onDraw(Canvas canvas) {
if (needDivider) {

View File

@ -10,12 +10,16 @@ package org.telegram.ui.Cells;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.Shader;
import android.graphics.drawable.Drawable;
import android.text.SpannableStringBuilder;
import android.text.TextUtils;
import android.util.Log;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
@ -23,11 +27,12 @@ import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.ImageLocation;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MessagesController;
import org.telegram.messenger.R;
@ -40,15 +45,13 @@ import org.telegram.ui.Components.AnimatedFloat;
import org.telegram.ui.Components.AvatarDrawable;
import org.telegram.ui.Components.BackupImageView;
import org.telegram.ui.Components.CombinedDrawable;
import org.telegram.ui.Components.CubicBezierInterpolator;
import org.telegram.ui.Components.DotDividerSpan;
import org.telegram.ui.Components.FlickerLoadingView;
import org.telegram.ui.Components.LayoutHelper;
import java.util.Locale;
public class SessionCell extends FrameLayout {
private int currentType;
private TextView nameTextView;
private TextView onlineTextView;
private TextView detailTextView;
@ -71,6 +74,8 @@ public class SessionCell extends FrameLayout {
linearLayout.setOrientation(LinearLayout.HORIZONTAL);
linearLayout.setWeightSum(1);
currentType = type;
if (type == 1) {
addView(linearLayout, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 30, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, (LocaleController.isRTL ? 15 : 49), 11, (LocaleController.isRTL ? 49 : 15), 0));
@ -83,19 +88,19 @@ public class SessionCell extends FrameLayout {
} else {
placeholderImageView = new BackupImageView(context);
placeholderImageView.setRoundRadius(AndroidUtilities.dp(10));
addView(placeholderImageView, LayoutHelper.createFrame(42, 42, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, (LocaleController.isRTL ? 0 : 16), 13, (LocaleController.isRTL ? 16 : 0), 0));
addView(placeholderImageView, LayoutHelper.createFrame(42, 42, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, (LocaleController.isRTL ? 0 : 16), 9, (LocaleController.isRTL ? 16 : 0), 0));
imageView = new BackupImageView(context);
imageView.setRoundRadius(AndroidUtilities.dp(10));
addView(imageView, LayoutHelper.createFrame(42, 42, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, (LocaleController.isRTL ? 0 : 16), 13, (LocaleController.isRTL ? 16 : 0), 0));
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), 11, (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), 7.333f, (LocaleController.isRTL ? 72 : 15), 0));
}
nameTextView = new TextView(context);
nameTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText));
nameTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
nameTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, type == 0 ? 15 : 16);
nameTextView.setLines(1);
nameTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
nameTextView.setMaxLines(1);
@ -104,7 +109,7 @@ public class SessionCell extends FrameLayout {
nameTextView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP);
onlineTextView = new TextView(context);
onlineTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
onlineTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, type == 0 ? 12 : 13);
onlineTextView.setGravity((LocaleController.isRTL ? Gravity.LEFT : Gravity.RIGHT) | Gravity.TOP);
if (LocaleController.isRTL) {
@ -127,23 +132,23 @@ public class SessionCell extends FrameLayout {
detailTextView = new TextView(context);
detailTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText));
detailTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
detailTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, type == 0 ? 13 : 14);
detailTextView.setLines(1);
detailTextView.setMaxLines(1);
detailTextView.setSingleLine(true);
detailTextView.setEllipsize(TextUtils.TruncateAt.END);
detailTextView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP);
addView(detailTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, leftMargin, 36, rightMargin, 0));
addView(detailTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, leftMargin, type == 0 ? 28 : 36, rightMargin, 0));
detailExTextView = new TextView(context);
detailExTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText3));
detailExTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
detailExTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, type == 0 ? 13 : 14);
detailExTextView.setLines(1);
detailExTextView.setMaxLines(1);
detailExTextView.setSingleLine(true);
detailExTextView.setEllipsize(TextUtils.TruncateAt.END);
detailExTextView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP);
addView(detailExTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, leftMargin, 59, rightMargin, 0));
addView(detailExTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, leftMargin, type == 0 ? 46 : 59, rightMargin, 0));
}
private void setContentAlpha(float alpha) {
@ -172,7 +177,7 @@ public class SessionCell extends FrameLayout {
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(90) + (needDivider ? 1 : 0), MeasureSpec.EXACTLY));
super.onMeasure(MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(currentType == 0 ? 70 : 90) + (needDivider ? 1 : 0), MeasureSpec.EXACTLY));
}
public void setSession(TLObject object, boolean divider) {
@ -288,52 +293,106 @@ public class SessionCell extends FrameLayout {
}
String deviceModel = session.device_model.toLowerCase();
int iconId;
String colorKey;
String colorKey, colorKey2;
if (deviceModel.contains("safari")) {
iconId = R.drawable.device_web_safari;
colorKey = Theme.key_avatar_backgroundPink;
colorKey2 = Theme.key_avatar_background2Pink;
} else if (deviceModel.contains("edge")) {
iconId = R.drawable.device_web_edge;
colorKey = Theme.key_avatar_backgroundPink;
colorKey2 = Theme.key_avatar_background2Pink;
} else if (deviceModel.contains("chrome")) {
iconId = R.drawable.device_web_chrome;
colorKey = Theme.key_avatar_backgroundPink;
colorKey2 = Theme.key_avatar_background2Pink;
} else if (deviceModel.contains("opera")) {
iconId = R.drawable.device_web_opera;
colorKey = Theme.key_avatar_backgroundPink;
colorKey2 = Theme.key_avatar_background2Pink;
} else if (deviceModel.contains("firefox")) {
iconId = R.drawable.device_web_firefox;
colorKey = Theme.key_avatar_backgroundPink;
colorKey2 = Theme.key_avatar_background2Pink;
} else if (deviceModel.contains("vivaldi")) {
iconId = R.drawable.device_web_other;
colorKey = Theme.key_avatar_backgroundPink;
colorKey2 = Theme.key_avatar_background2Pink;
} else if (platform.contains("ios")) {
iconId = deviceModel.contains("ipad") ? R.drawable.device_tablet_ios : R.drawable.device_phone_ios;
colorKey = Theme.key_avatar_backgroundBlue;
colorKey2 = Theme.key_avatar_background2Blue;
} else if (platform.contains("windows")) {
iconId = R.drawable.device_desktop_win;
colorKey = Theme.key_avatar_backgroundCyan;
colorKey2 = Theme.key_avatar_background2Cyan;
} else if (platform.contains("macos")) {
iconId = R.drawable.device_desktop_osx;
colorKey = Theme.key_avatar_backgroundCyan;
colorKey2 = Theme.key_avatar_background2Cyan;
} else if (platform.contains("android")) {
iconId = deviceModel.contains("tab") ? R.drawable.device_tablet_android : R.drawable.device_phone_android;
colorKey = Theme.key_avatar_backgroundGreen;
colorKey2 = Theme.key_avatar_background2Green;
} else {
if (session.app_name.toLowerCase().contains("desktop")) {
iconId = R.drawable.device_desktop_other;
colorKey = Theme.key_avatar_backgroundCyan;
colorKey2 = Theme.key_avatar_background2Cyan;
} else {
iconId = R.drawable.device_web_other;
colorKey = Theme.key_avatar_backgroundPink;
colorKey2 = Theme.key_avatar_background2Pink;
}
}
Drawable iconDrawable = ContextCompat.getDrawable(ApplicationLoader.applicationContext, iconId).mutate();
iconDrawable.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_avatar_text), PorterDuff.Mode.SRC_IN));
CombinedDrawable combinedDrawable = new CombinedDrawable(Theme.createCircleDrawable(AndroidUtilities.dp(42), Theme.getColor(colorKey)), iconDrawable);
Drawable bgDrawable = new CircleGradientDrawable(AndroidUtilities.dp(42), Theme.getColor(colorKey), Theme.getColor(colorKey2));
CombinedDrawable combinedDrawable = new CombinedDrawable(bgDrawable, iconDrawable);
return combinedDrawable;
}
public static class CircleGradientDrawable extends Drawable {
private Paint paint;
private int size, colorTop, colorBottom;
public CircleGradientDrawable(int size, int colorTop, int colorBottom) {
this.size = size;
this.colorTop = colorTop;
this.colorBottom = colorBottom;
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setShader(new LinearGradient(0, 0, 0, size, new int[] {colorTop, colorBottom}, new float[] {0, 1}, Shader.TileMode.CLAMP));
}
@Override
public void draw(@NonNull Canvas canvas) {
canvas.drawCircle(getBounds().centerX(), getBounds().centerY(), Math.min(getBounds().width(), getBounds().height()) / 2f, paint);
}
@Override
public void setAlpha(int i) {
paint.setAlpha(i);
}
@Override
public void setColorFilter(@Nullable ColorFilter colorFilter) {}
@Override
public int getOpacity() {
return PixelFormat.TRANSPARENT;
}
@Override
public int getIntrinsicHeight() {
return size;
}
@Override
public int getIntrinsicWidth() {
return size;
}
}
@Override
protected void onDraw(Canvas canvas) {
float stubAlpha = showStubValue.set(showStub ? 1 : 0);
@ -381,7 +440,7 @@ public class SessionCell extends FrameLayout {
this.globalGradient = globalGradient;
showStub = true;
Drawable iconDrawable = ContextCompat.getDrawable(ApplicationLoader.applicationContext, AndroidUtilities.isTablet() ? R.drawable.device_tablet_android : R.drawable.device_phone_android).mutate();
Drawable iconDrawable = ContextCompat.getDrawable(ApplicationLoader.applicationContext, AndroidUtilities.isTablet() ? R.drawable.device_tablet_android : R.drawable.device_phone_android).mutate();
iconDrawable.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_avatar_text), PorterDuff.Mode.SRC_IN));
CombinedDrawable combinedDrawable = new CombinedDrawable(Theme.createCircleDrawable(AndroidUtilities.dp(42), Theme.getColor(Theme.key_avatar_backgroundGreen)), iconDrawable);
if (placeholderImageView != null) {

View File

@ -27,8 +27,10 @@ import androidx.dynamicanimation.animation.SpringForce;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ContactsController;
import org.telegram.messenger.DialogObject;
import org.telegram.messenger.Emoji;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MessagesController;
import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R;
import org.telegram.messenger.UserConfig;
import org.telegram.messenger.UserObject;
@ -80,7 +82,14 @@ public class ShareDialogCell extends FrameLayout {
addView(imageView, LayoutHelper.createFrame(56, 56, Gravity.TOP | Gravity.CENTER_HORIZONTAL, 0, 7, 0, 0));
}
nameTextView = new TextView(context);
nameTextView = new TextView(context) {
@Override
public void setText(CharSequence text, BufferType type) {
text = Emoji.replaceEmoji(text, getPaint().getFontMetricsInt(), AndroidUtilities.dp(10), false);
super.setText(text, type);
}
};
NotificationCenter.listenEmojiLoading(nameTextView);
nameTextView.setTextColor(getThemedColor(type == TYPE_CALL ? Theme.key_voipgroup_nameText : Theme.key_dialogTextBlack));
nameTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 12);
nameTextView.setMaxLines(2);

View File

@ -32,6 +32,8 @@ import org.telegram.messenger.UserConfig;
import org.telegram.messenger.Utilities;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.AnimatedEmojiDrawable;
import org.telegram.ui.Components.AnimatedEmojiSpan;
import org.telegram.ui.Components.CheckBox2;
import org.telegram.ui.Components.DotDividerSpan;
import org.telegram.ui.Components.FlickerLoadingView;
@ -55,11 +57,14 @@ public class SharedAudioCell extends FrameLayout implements DownloadController.F
private int titleY = AndroidUtilities.dp(9);
private StaticLayout titleLayout;
AnimatedEmojiSpan.EmojiGroupedSpans titleLayoutEmojis;
private int descriptionY = AndroidUtilities.dp(29);
AnimatedEmojiSpan.EmojiGroupedSpans descriptionLayoutEmojis;
private StaticLayout descriptionLayout;
private int captionY = AndroidUtilities.dp(29);
AnimatedEmojiSpan.EmojiGroupedSpans captionLayoutEmojis;
private StaticLayout captionLayout;
private MessageObject currentMessageObject;
@ -159,6 +164,7 @@ public class SharedAudioCell extends FrameLayout implements DownloadController.F
}
CharSequence titleFinal = TextUtils.ellipsize(title, Theme.chat_contextResult_titleTextPaint, maxWidth - dateWidth, TextUtils.TruncateAt.END);
titleLayout = new StaticLayout(titleFinal, Theme.chat_contextResult_titleTextPaint, maxWidth + AndroidUtilities.dp(4) - dateWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
titleLayoutEmojis = AnimatedEmojiSpan.update(AnimatedEmojiDrawable.CACHE_TYPE_MESSAGES, this, titleLayoutEmojis, titleLayout);
} catch (Exception e) {
FileLog.e(e);
}
@ -170,6 +176,7 @@ public class SharedAudioCell extends FrameLayout implements DownloadController.F
sequence = TextUtils.ellipsize(AndroidUtilities.ellipsizeCenterEnd(sequence, currentMessageObject.highlightedWords.get(0), maxWidth, captionTextPaint, 130), captionTextPaint, maxWidth, TextUtils.TruncateAt.END);
captionLayout = new StaticLayout(sequence, captionTextPaint, maxWidth + AndroidUtilities.dp(4), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
}
captionLayoutEmojis = AnimatedEmojiSpan.update(AnimatedEmojiDrawable.CACHE_TYPE_MESSAGES, this, captionLayoutEmojis, captionLayout);
}
try {
if (viewType == VIEW_TYPE_GLOBAL_SEARCH && (currentMessageObject.isVoice() || currentMessageObject.isRoundVideo())) {
@ -190,6 +197,7 @@ public class SharedAudioCell extends FrameLayout implements DownloadController.F
author = TextUtils.ellipsize(author, paint, maxWidth, TextUtils.TruncateAt.END);
descriptionLayout = new StaticLayout(author, paint, maxWidth + AndroidUtilities.dp(4), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
}
descriptionLayoutEmojis = AnimatedEmojiSpan.update(AnimatedEmojiDrawable.CACHE_TYPE_MESSAGES, this, descriptionLayoutEmojis, descriptionLayout);
} catch (Exception e) {
FileLog.e(e);
}
@ -249,6 +257,10 @@ public class SharedAudioCell extends FrameLayout implements DownloadController.F
NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.messagePlayingDidReset);
NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.messagePlayingPlayStateChanged);
NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.messagePlayingDidStart);
titleLayoutEmojis = AnimatedEmojiSpan.update(AnimatedEmojiDrawable.CACHE_TYPE_MESSAGES, this, titleLayoutEmojis, titleLayout);
descriptionLayoutEmojis = AnimatedEmojiSpan.update(AnimatedEmojiDrawable.CACHE_TYPE_MESSAGES, this, descriptionLayoutEmojis, descriptionLayout);
captionLayoutEmojis = AnimatedEmojiSpan.update(AnimatedEmojiDrawable.CACHE_TYPE_MESSAGES, this, captionLayoutEmojis, captionLayout);
}
@Override
@ -259,6 +271,10 @@ public class SharedAudioCell extends FrameLayout implements DownloadController.F
NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.messagePlayingDidReset);
NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.messagePlayingPlayStateChanged);
NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.messagePlayingDidStart);
AnimatedEmojiSpan.release(this, titleLayoutEmojis);
AnimatedEmojiSpan.release(this, descriptionLayoutEmojis);
AnimatedEmojiSpan.release(this, captionLayoutEmojis);
}
public MessageObject getMessage() {
@ -617,6 +633,7 @@ public class SharedAudioCell extends FrameLayout implements DownloadController.F
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();
}
@ -633,6 +650,7 @@ public class SharedAudioCell extends FrameLayout implements DownloadController.F
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();
}

View File

@ -42,6 +42,7 @@ import org.telegram.messenger.UserConfig;
import org.telegram.messenger.Utilities;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.AnimatedEmojiSpan;
import org.telegram.ui.Components.BackupImageView;
import org.telegram.ui.Components.CheckBox2;
import org.telegram.ui.Components.CubicBezierInterpolator;
@ -63,7 +64,7 @@ public class SharedDocumentCell extends FrameLayout implements DownloadControlle
private BackupImageView thumbImageView;
private TextView nameTextView;
private TextView extTextView;
private TextView dateTextView;
private AnimatedEmojiSpan.TextViewEmojis dateTextView;
private RLottieImageView statusImageView;
private LineProgressView progressView;
private CheckBox2 checkBox;
@ -211,7 +212,7 @@ public class SharedDocumentCell extends FrameLayout implements DownloadControlle
addView(statusImageView, LayoutHelper.createFrame(14, 14, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 8 : 70, 33, LocaleController.isRTL ? 72 : 8, 0));
}
dateTextView = new TextView(context);
dateTextView = new AnimatedEmojiSpan.TextViewEmojis(context);
dateTextView.setTextColor(getThemedColor(Theme.key_windowBackgroundWhiteGrayText3));
dateTextView.setLines(1);
dateTextView.setMaxLines(1);

View File

@ -11,7 +11,6 @@ package org.telegram.ui.Cells;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.CornerPathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
@ -34,19 +33,22 @@ import android.widget.FrameLayout;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.Emoji;
import org.telegram.messenger.FileLoader;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.ImageLocation;
import org.telegram.messenger.ImageReceiver;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MediaDataController;
import org.telegram.messenger.MessageObject;
import org.telegram.messenger.FileLoader;
import org.telegram.messenger.FileLog;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.AnimatedEmojiDrawable;
import org.telegram.ui.Components.AnimatedEmojiSpan;
import org.telegram.ui.Components.CheckBox2;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.LetterDrawable;
import org.telegram.ui.Components.LinkPath;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.LinkSpanDrawable;
import org.telegram.ui.Components.TextStyleSpan;
import org.telegram.ui.Components.spoilers.SpoilerEffect;
import org.telegram.ui.FilteredSearchView;
@ -90,8 +92,8 @@ public class SharedLinkCell extends FrameLayout {
if (checkingForLongPress && getParent() != null && currentPressCount == pressCount) {
checkingForLongPress = false;
performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
if (pressedLink >= 0) {
delegate.onLinkPress(links.get(pressedLink).toString(), true);
if (pressedLinkIndex >= 0) {
delegate.onLinkPress(links.get(pressedLinkIndex).toString(), true);
}
MotionEvent event = MotionEvent.obtain(0, 0, MotionEvent.ACTION_CANCEL, 0, 0, 0);
onTouchEvent(event);
@ -121,9 +123,10 @@ public class SharedLinkCell extends FrameLayout {
}
}
private LinkSpanDrawable.LinkCollector linksCollector = new LinkSpanDrawable.LinkCollector(this);
private boolean linkPreviewPressed;
private LinkPath urlPath;
private int pressedLink;
private int pressedLinkIndex;
private LinkSpanDrawable pressedLink;
private ImageReceiver linkImageView;
private boolean drawLinkImageView;
@ -170,6 +173,7 @@ public class SharedLinkCell extends FrameLayout {
private StaticLayout dateLayout;
private int fromInfoLayoutY = AndroidUtilities.dp(30);
private StaticLayout fromInfoLayout;
private AnimatedEmojiSpan.EmojiGroupedSpans fromInfoLayoutEmojis;
private Theme.ResourcesProvider resourcesProvider;
private int viewType;
@ -190,9 +194,6 @@ public class SharedLinkCell extends FrameLayout {
this.viewType = viewType;
setFocusable(true);
urlPath = new LinkPath();
urlPath.setUseRoundRect(true);
titleTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
titleTextPaint.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
titleTextPaint.setColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText, resourcesProvider));
@ -477,6 +478,7 @@ public class SharedLinkCell extends FrameLayout {
if (viewType == VIEW_TYPE_GLOBAL_SEARCH) {
fromInfoLayout = ChatMessageCell.generateStaticLayout(FilteredSearchView.createFromInfoString(message), description2TextPaint, maxWidth, maxWidth, 0, desctiptionLines);
fromInfoLayoutEmojis = AnimatedEmojiSpan.update(AnimatedEmojiDrawable.CACHE_TYPE_MESSAGES, this, fromInfoLayoutEmojis, fromInfoLayout);
}
int height = 0;
@ -538,6 +540,7 @@ public class SharedLinkCell extends FrameLayout {
if (drawLinkImageView) {
linkImageView.onDetachedFromWindow();
}
AnimatedEmojiSpan.release(this, fromInfoLayoutEmojis);
}
@Override
@ -546,6 +549,7 @@ public class SharedLinkCell extends FrameLayout {
if (drawLinkImageView) {
linkImageView.onAttachedToWindow();
}
fromInfoLayoutEmojis = AnimatedEmojiSpan.update(AnimatedEmojiDrawable.CACHE_TYPE_MESSAGES, this, fromInfoLayoutEmojis, fromInfoLayout);
}
@Override
@ -562,15 +566,18 @@ public class SharedLinkCell extends FrameLayout {
if (layout.getLineCount() > 0) {
int height = layout.getLineBottom(layout.getLineCount() - 1);
int linkPosX = AndroidUtilities.dp(LocaleController.isRTL ? 8 : AndroidUtilities.leftBaseline);
if (x >= linkPosX + layout.getLineLeft(0) && x <= linkPosX + layout.getLineWidth(0) && y >= linkY + offset && y <= linkY + offset + height) {
if (
x >= linkPosX + layout.getLineLeft(0) && x <= linkPosX + layout.getLineWidth(0) &&
y >= linkY + offset && y <= linkY + offset + height
) {
ok = true;
if (event.getAction() == MotionEvent.ACTION_DOWN) {
resetPressedLink();
spoilerPressed = null;
if (linkSpoilers.get(a, null) != null) {
for (SpoilerEffect eff : linkSpoilers.get(a)) {
if (eff.getBounds().contains(x - linkPosX, y - linkY - offset)) {
resetPressedLink();
spoilerPressed = eff;
spoilerTypePressed = SPOILER_TYPE_LINK;
break;
@ -581,24 +588,30 @@ public class SharedLinkCell extends FrameLayout {
if (spoilerPressed != null) {
result = true;
} else {
pressedLink = a;
linkPreviewPressed = true;
startCheckLongPress();
try {
urlPath.setCurrentLayout(layout, 0, 0);
layout.getSelectionPath(0, layout.getText().length(), urlPath);
} catch (Exception e) {
FileLog.e(e);
if (pressedLinkIndex != a || pressedLink == null || !linkPreviewPressed) {
resetPressedLink();
pressedLinkIndex = a;
pressedLink = new LinkSpanDrawable(null, resourcesProvider, x - linkPosX, y - linkY - offset);
LinkPath urlPath = pressedLink.obtainNewPath();
linkPreviewPressed = true;
linksCollector.addLink(pressedLink);
startCheckLongPress();
try {
urlPath.setCurrentLayout(layout, 0, linkPosX, linkY + offset);
layout.getSelectionPath(0, layout.getText().length(), urlPath);
} catch (Exception e) {
FileLog.e(e);
}
}
result = true;
}
} else if (linkPreviewPressed) {
try {
TLRPC.WebPage webPage = pressedLink == 0 && message.messageOwner.media != null ? message.messageOwner.media.webpage : null;
TLRPC.WebPage webPage = pressedLinkIndex == 0 && message.messageOwner.media != null ? message.messageOwner.media.webpage : null;
if (webPage != null && webPage.embed_url != null && webPage.embed_url.length() != 0) {
delegate.needOpenWebView(webPage, message);
} else {
delegate.onLinkPress(links.get(pressedLink).toString(), false);
delegate.onLinkPress(links.get(pressedLinkIndex).toString(), false);
}
} catch (Exception e) {
FileLog.e(e);
@ -738,7 +751,9 @@ public class SharedLinkCell extends FrameLayout {
}
protected void resetPressedLink() {
pressedLink = -1;
linksCollector.clear(true);
pressedLinkIndex = -1;
pressedLink = null;
linkPreviewPressed = false;
cancelCheckLongPress();
invalidate();
@ -751,8 +766,6 @@ public class SharedLinkCell extends FrameLayout {
checkBox.setChecked(checked, animated);
}
private Paint urlPaint;
@Override
protected void onDraw(Canvas canvas) {
if (viewType == VIEW_TYPE_GLOBAL_SEARCH) {
@ -815,16 +828,8 @@ public class SharedLinkCell extends FrameLayout {
path.addRect(b.left, b.top, b.right, b.bottom, Path.Direction.CW);
}
}
if (urlPaint == null) {
urlPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
urlPaint.setPathEffect(new CornerPathEffect(AndroidUtilities.dp(4)));
}
urlPaint.setColor(Theme.getColor(Theme.key_chat_linkSelectBackground, resourcesProvider));
canvas.save();
canvas.clipPath(path, Region.Op.DIFFERENCE);
if (pressedLink == a) {
canvas.drawPath(urlPath, urlPaint);
}
layout.draw(canvas);
canvas.restore();
@ -834,10 +839,6 @@ public class SharedLinkCell extends FrameLayout {
if (spoilers != null && !spoilers.isEmpty())
spoilers.get(0).getRipplePath(path);
canvas.clipPath(path);
if (pressedLink == a) {
canvas.drawPath(urlPath, urlPaint);
}
layout.draw(canvas);
canvas.restore();
@ -848,12 +849,17 @@ public class SharedLinkCell extends FrameLayout {
offset += layout.getLineBottom(layout.getLineCount() - 1);
}
}
if (linksCollector.draw(canvas)) {
invalidate();
}
}
if (fromInfoLayout != null) {
canvas.save();
canvas.translate(AndroidUtilities.dp(LocaleController.isRTL ? 8 : AndroidUtilities.leftBaseline), fromInfoLayoutY );
fromInfoLayout.draw(canvas);
AnimatedEmojiSpan.drawAnimatedEmojis(canvas, fromInfoLayout, fromInfoLayoutEmojis, 0, null, 0, 0, 0, 1f);
canvas.restore();
}
letterDrawable.draw(canvas);

View File

@ -33,10 +33,10 @@ import android.widget.TextView;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.DocumentObject;
import org.telegram.messenger.Emoji;
import org.telegram.messenger.FileLoader;
import org.telegram.messenger.ImageLocation;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MediaDataController;
import org.telegram.messenger.MessageObject;
import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R;
@ -50,10 +50,7 @@ import org.telegram.ui.Components.Easings;
import org.telegram.ui.Components.ForegroundColorSpanThemable;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.Premium.PremiumButtonView;
import org.telegram.ui.Components.Premium.PremiumFeatureBottomSheet;
import org.telegram.ui.Components.RadialProgressView;
import org.telegram.ui.LaunchActivity;
import org.telegram.ui.PremiumPreviewFragment;
import java.util.ArrayList;
import java.util.Locale;
@ -182,7 +179,14 @@ public class StickerSetCell extends FrameLayout {
}
});
textView = new TextView(context);
textView = new TextView(context) {
@Override
public void setText(CharSequence text, BufferType type) {
text = Emoji.replaceEmoji(text, getPaint().getFontMetricsInt(), AndroidUtilities.dp(14), false);
super.setText(text, type);
}
};
NotificationCenter.listenEmojiLoading(textView);
textView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText));
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
textView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));

View File

@ -10,6 +10,7 @@ package org.telegram.ui.Cells;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.Drawable;
@ -39,11 +40,17 @@ public class TextCell extends FrameLayout {
private int leftPadding;
private boolean needDivider;
private int offsetFromImage = 71;
public int heightDp = 48;
public int imageLeft = 21;
private boolean inDialogs;
private boolean prioritizeTitleOverValue;
private Theme.ResourcesProvider resourcesProvider;
private boolean attached;
private int loadingSize;
private boolean drawLoading;
private boolean measureDelay;
private float loadingProgress;
private float drawLoadingProgress;
public TextCell(Context context) {
@ -97,6 +104,10 @@ public class TextCell extends FrameLayout {
setFocusable(true);
}
public boolean isChecked() {
return checkBox != null && checkBox.isChecked();
}
public Switch getCheckBox() {
return checkBox;
}
@ -129,7 +140,7 @@ public class TextCell extends FrameLayout {
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = AndroidUtilities.dp(48);
int height = AndroidUtilities.dp(heightDp);
if (prioritizeTitleOverValue) {
textView.measure(MeasureSpec.makeMeasureSpec(width - AndroidUtilities.dp(71 + leftPadding), MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(20), MeasureSpec.EXACTLY));
@ -301,6 +312,21 @@ public class TextCell extends FrameLayout {
}
}
public void setTextAndCheck(String text, boolean checked, boolean divider) {
imageLeft = 21;
offsetFromImage = 71;
textView.setText(text);
imageView.setVisibility(GONE);
valueImageView.setVisibility(GONE);
needDivider = divider;
if (checkBox != null) {
checkBox.setVisibility(VISIBLE);
checkBox.setChecked(checked, false);
}
needDivider = divider;
setWillNotDraw(!needDivider);
}
public void setTextAndCheckAndIcon(String text, boolean checked, int resId, boolean divider) {
imageLeft = 21;
offsetFromImage = 71;
@ -318,6 +344,23 @@ public class TextCell extends FrameLayout {
setWillNotDraw(!needDivider);
}
public void setTextAndCheckAndIcon(String text, boolean checked, Drawable resDrawable, boolean divider) {
imageLeft = 21;
offsetFromImage = 71;
textView.setText(text);
valueTextView.setVisibility(GONE);
valueImageView.setVisibility(GONE);
if (checkBox != null) {
checkBox.setVisibility(VISIBLE);
checkBox.setChecked(checked, false);
}
imageView.setVisibility(VISIBLE);
imageView.setPadding(0, AndroidUtilities.dp(7), 0, 0);
imageView.setImageDrawable(resDrawable);
needDivider = divider;
setWillNotDraw(!needDivider);
}
public void setTextAndValueDrawable(String text, Drawable drawable, boolean divider) {
imageLeft = 21;
offsetFromImage = 71;
@ -411,4 +454,71 @@ public class TextCell extends FrameLayout {
super.onDetachedFromWindow();
attached = false;
}
public void setDrawLoading(boolean drawLoading, int size, boolean animated) {
this.drawLoading = drawLoading;
this.loadingSize = size;
if (!animated) {
drawLoadingProgress = drawLoading ? 1f : 0f;
} else {
measureDelay = true;
}
invalidate();
}
Paint paint;
private boolean incrementLoadingProgress;
private int changeProgressStartDelay;
@Override
protected void dispatchDraw(Canvas canvas) {
if (drawLoading || drawLoadingProgress != 0) {
if (paint == null) {
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Theme.getColor(Theme.key_dialogSearchBackground, resourcesProvider));
}
//LocaleController.isRTL ? Gravity.LEFT : Gravity.RIGHT;
if (incrementLoadingProgress) {
loadingProgress += 16 / 1000f;
if (loadingProgress > 1f) {
loadingProgress = 1f;
incrementLoadingProgress = false;
}
} else {
loadingProgress -= 16 / 1000f;
if (loadingProgress < 0) {
loadingProgress = 0;
incrementLoadingProgress = true;
}
}
if (changeProgressStartDelay > 0) {
changeProgressStartDelay -= 15;
} else if (drawLoading && drawLoadingProgress != 1f) {
drawLoadingProgress += 16 / 150f;
if (drawLoadingProgress > 1f) {
drawLoadingProgress = 1f;
}
} else if (!drawLoading && drawLoadingProgress != 0) {
drawLoadingProgress -= 16 / 150f;
if (drawLoadingProgress < 0) {
drawLoadingProgress = 0;
}
}
float alpha = (0.6f + 0.4f * loadingProgress) * drawLoadingProgress;
paint.setAlpha((int) (255 * alpha));
int cy = getMeasuredHeight() >> 1;
AndroidUtilities.rectTmp.set(getMeasuredWidth() - AndroidUtilities.dp(11) - AndroidUtilities.dp(loadingSize), cy - AndroidUtilities.dp(3), getMeasuredWidth() - AndroidUtilities.dp(11), cy + AndroidUtilities.dp(3));
if (LocaleController.isRTL) {
AndroidUtilities.rectTmp.left = getMeasuredWidth() - AndroidUtilities.rectTmp.left;
AndroidUtilities.rectTmp.right = getMeasuredWidth() - AndroidUtilities.rectTmp.right;
}
canvas.drawRoundRect(AndroidUtilities.rectTmp, AndroidUtilities.dp(3), AndroidUtilities.dp(3), paint);
invalidate();
}
valueTextView.setAlpha(1f - drawLoadingProgress);
super.dispatchDraw(canvas);
}
}

View File

@ -19,7 +19,6 @@ import android.widget.TextView;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.R;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.Switch;
@ -169,6 +168,10 @@ public class TextCheckCell2 extends FrameLayout {
return checkBox.isChecked();
}
public Switch getCheckBox() {
return checkBox;
}
@Override
protected void onDraw(Canvas canvas) {
if (needDivider) {

View File

@ -13,7 +13,6 @@ import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.util.Log;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.HapticFeedbackConstants;
@ -27,7 +26,6 @@ import android.widget.TextView;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.Emoji;
import org.telegram.messenger.LocaleController;
import org.telegram.ui.ActionBar.SimpleTextView;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.LinkSpanDrawable;
@ -146,6 +144,9 @@ public class TextDetailCell extends FrameLayout {
public void setImageClickListener(View.OnClickListener clickListener) {
imageView.setOnClickListener(clickListener);
if (clickListener == null) {
imageView.setClickable(false);
}
}
public void setTextWithEmojiAndValue(CharSequence text, CharSequence value, boolean divider) {

View File

@ -1800,6 +1800,10 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
yOffset = lastBlock.textYOffset;
}
if (lastLayout == null) {
return -1;
}
if (y < 0) {
y = 1;
}

View File

@ -215,11 +215,19 @@ public class TextSettingsCell extends FrameLayout {
MarginLayoutParams params = (MarginLayoutParams) textView.getLayoutParams();
if (resId == 0) {
imageView.setVisibility(GONE);
params.leftMargin = 0;
if (LocaleController.isRTL) {
params.rightMargin = AndroidUtilities.dp(this.padding);
} else {
params.leftMargin = AndroidUtilities.dp(this.padding);
}
} else {
imageView.setImageResource(resId);
imageView.setVisibility(VISIBLE);
params.leftMargin = AndroidUtilities.dp(71);
if (LocaleController.isRTL) {
params.rightMargin = AndroidUtilities.dp(71);
} else {
params.leftMargin = AndroidUtilities.dp(71);
}
}
}

View File

@ -45,6 +45,9 @@ public class TopicExceptionCell extends FrameLayout {
public void setTopic(long dialogId, TLRPC.TL_forumTopic topic) {
ForumUtilities.setTopicIcon(backupImageView, topic);
if (backupImageView != null && backupImageView.getImageReceiver() != null && backupImageView.getImageReceiver().getDrawable() instanceof ForumUtilities.GeneralTopicDrawable) {
((ForumUtilities.GeneralTopicDrawable) backupImageView.getImageReceiver().getDrawable()).setColor(Theme.getColor(Theme.key_chats_archiveBackground));
}
title.setText(topic.title);
subtitle.setText(MessagesController.getInstance(UserConfig.selectedAccount).getMutedString(dialogId, topic.id));
}

View File

@ -57,6 +57,9 @@ public class TopicSearchCell extends FrameLayout {
textView.setText(AndroidUtilities.highlightText(topic.title, topic.searchQuery, null));
}
ForumUtilities.setTopicIcon(backupImageView, topic);
if (backupImageView != null && backupImageView.getImageReceiver() != null && backupImageView.getImageReceiver().getDrawable() instanceof ForumUtilities.GeneralTopicDrawable) {
((ForumUtilities.GeneralTopicDrawable) backupImageView.getImageReceiver().getDrawable()).setColor(Theme.getColor(Theme.key_chats_archiveBackground));
}
}
public TLRPC.TL_forumTopic getTopic() {

View File

@ -42,7 +42,6 @@ import org.telegram.ui.Components.BackupImageView;
import org.telegram.ui.Components.CheckBox;
import org.telegram.ui.Components.CheckBoxSquare;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.Premium.PremiumGradient;
import org.telegram.ui.NotificationsSettingsActivity;
public class UserCell extends FrameLayout implements NotificationCenter.NotificationCenterDelegate {
@ -546,6 +545,8 @@ public class UserCell extends FrameLayout implements NotificationCenter.Notifica
avatarImageView.setImageDrawable(avatarDrawable);
}
avatarImageView.setRoundRadius(currentChat != null && currentChat.forum ? AndroidUtilities.dp(14) : AndroidUtilities.dp(24));
nameTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText, resourcesProvider));
if (adminTextView != null) {
adminTextView.setTextColor(Theme.getColor(Theme.key_profile_creatorIcon, resourcesProvider));

View File

@ -12,15 +12,16 @@ import android.content.Context;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.Typeface;
import android.text.TextUtils;
import android.view.Gravity;
import android.widget.FrameLayout;
import android.widget.ImageView;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ChatObject;
import org.telegram.messenger.Emoji;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MessagesController;
import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R;
import org.telegram.messenger.UserConfig;
import org.telegram.messenger.UserObject;
@ -79,7 +80,14 @@ public class UserCell2 extends FrameLayout {
avatarImageView.setRoundRadius(AndroidUtilities.dp(24));
addView(avatarImageView, LayoutHelper.createFrame(48, 48, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 0 : 7 + padding, 11, LocaleController.isRTL ? 7 + padding : 0, 0));
nameTextView = new SimpleTextView(context);
nameTextView = new SimpleTextView(context) {
@Override
public boolean setText(CharSequence value) {
value = Emoji.replaceEmoji(value, getPaint().getFontMetricsInt(), AndroidUtilities.dp(15), false);
return super.setText(value);
}
};
NotificationCenter.listenEmojiLoading(nameTextView);
nameTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText, resourcesProvider));
nameTextView.setTextSize(17);
nameTextView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP);
@ -296,6 +304,8 @@ public class UserCell2 extends FrameLayout {
avatarImageView.setImageDrawable(avatarDrawable);
}
avatarImageView.setRoundRadius(currentChat != null && currentChat.forum ? AndroidUtilities.dp(14) : AndroidUtilities.dp(24));
if (imageView.getVisibility() == VISIBLE && currentDrawable == 0 || imageView.getVisibility() == GONE && currentDrawable != 0) {
imageView.setVisibility(currentDrawable == 0 ? GONE : VISIBLE);
imageView.setImageResource(currentDrawable);

View File

@ -25,22 +25,31 @@ import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextPaint;
import android.text.TextUtils;
import android.text.style.CharacterStyle;
import android.text.style.ClickableSpan;
import android.text.style.DynamicDrawableSpan;
import android.text.style.ImageSpan;
import android.text.style.URLSpan;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.TextureView;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewOutlineProvider;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.EditText;
import android.widget.FrameLayout;
@ -48,6 +57,7 @@ import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.collection.LongSparseArray;
import androidx.core.content.FileProvider;
import androidx.recyclerview.widget.ChatListItemAnimator;
@ -74,6 +84,7 @@ import org.telegram.messenger.MessagesController;
import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R;
import org.telegram.messenger.UserConfig;
import org.telegram.messenger.UserObject;
import org.telegram.messenger.Utilities;
import org.telegram.messenger.browser.Browser;
import org.telegram.tgnet.ConnectionsManager;
@ -81,6 +92,8 @@ import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.ActionBar;
import org.telegram.ui.ActionBar.ActionBarMenu;
import org.telegram.ui.ActionBar.ActionBarMenuItem;
import org.telegram.ui.ActionBar.ActionBarMenuSubItem;
import org.telegram.ui.ActionBar.ActionBarPopupWindow;
import org.telegram.ui.ActionBar.AlertDialog;
import org.telegram.ui.ActionBar.BackDrawable;
import org.telegram.ui.ActionBar.BaseFragment;
@ -94,8 +107,10 @@ import org.telegram.ui.Cells.ChatMessageCell;
import org.telegram.ui.Cells.ChatUnreadCell;
import org.telegram.ui.Components.AdminLogFilterAlert;
import org.telegram.ui.Components.AlertsCreator;
import org.telegram.ui.Components.Bulletin;
import org.telegram.ui.Components.BulletinFactory;
import org.telegram.ui.Components.ChatAvatarContainer;
import org.telegram.ui.Components.ChatScrimPopupContainerLayout;
import org.telegram.ui.Components.ClearHistoryAlert;
import org.telegram.ui.Components.EmbedBottomSheet;
import org.telegram.ui.Components.InviteLinkBottomSheet;
@ -265,6 +280,14 @@ public class ChannelAdminLogActivity extends BaseFragment implements Notificatio
NotificationCenter.getGlobalInstance().addObserver(this, NotificationCenter.didSetNewWallpapper);
loadMessages(true);
loadAdmins();
Bulletin.addDelegate(this, new Bulletin.Delegate() {
@Override
public int getBottomOffset(int tag) {
return AndroidUtilities.dp(51);
}
});
return true;
}
@ -695,7 +718,7 @@ public class ChannelAdminLogActivity extends BaseFragment implements Notificatio
child.layout(childLeft, childTop, childLeft + width, childTop + height);
}
updateMessagesVisisblePart();
updateMessagesVisiblePart();
notifyHeightChanged();
}
@ -844,7 +867,12 @@ public class ChannelAdminLogActivity extends BaseFragment implements Notificatio
return result;
}
};
chatListView.setOnItemClickListener((view, position) -> createMenu(view));
chatListView.setOnItemClickListener(new RecyclerListView.OnItemClickListenerExtended() {
@Override
public void onItemClick(View view, int position, float x, float y) {
createMenu(view, x, y);
}
});
chatListView.setTag(1);
chatListView.setVerticalScrollBarEnabled(true);
chatListView.setAdapter(chatAdapter = new ChatActivityAdapter(context));
@ -945,7 +973,7 @@ public class ChannelAdminLogActivity extends BaseFragment implements Notificatio
}
}
checkScrollForLoad(true);
updateMessagesVisisblePart();
updateMessagesVisiblePart();
}
});
if (scrollToPositionOnRecreate != -1) {
@ -1108,7 +1136,33 @@ public class ChannelAdminLogActivity extends BaseFragment implements Notificatio
return fragmentView;
}
private ActionBarPopupWindow scrimPopupWindow;
private int scrimPopupX, scrimPopupY;
private void closeMenu() {
if (scrimPopupWindow != null) {
scrimPopupWindow.dismiss();
}
}
private final static int OPTION_COPY = 3;
private final static int OPTION_SAVE_TO_GALLERY = 4;
private final static int OPTION_APPLY_FILE = 5;
private final static int OPTION_SHARE = 6;
private final static int OPTION_SAVE_TO_GALLERY2 = 7;
private final static int OPTION_SAVE_STICKER = 9;
private final static int OPTION_SAVE_TO_DOWNLOADS_OR_MUSIC = 10;
private final static int OPTION_SAVE_TO_GIFS = 11;
private final static int OPTION_ADD_CONTACT = 15;
private final static int OPTION_COPY_PHONE = 16;
private final static int OPTION_CALL = 17;
private final static int OPTION_RESTRICT = 33;
private final static int OPTION_REPORT_FALSE_POSITIVE = 34;
private boolean createMenu(View v) {
return createMenu(v, 0, 0);
}
private boolean createMenu(View v, float x, float y) {
MessageObject message = null;
if (v instanceof ChatMessageCell) {
message = ((ChatMessageCell) v).getMessageObject();
@ -1123,14 +1177,56 @@ public class ChannelAdminLogActivity extends BaseFragment implements Notificatio
if (getParentActivity() == null) {
return false;
}
AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity());
ArrayList<CharSequence> items = new ArrayList<>();
final ArrayList<Integer> options = new ArrayList<>();
final ArrayList<Integer> icons = new ArrayList<>();
if (message.currentEvent != null && message.currentEvent.action instanceof TLRPC.TL_channelAdminLogEventActionDeleteMessage && message.currentEvent.user_id == getMessagesController().telegramAntispamUserId) {
if (v instanceof ChatActionCell) {
SpannableString arrow = new SpannableString(">");
Drawable arrowDrawable = getContext().getResources().getDrawable(R.drawable.attach_arrow_right).mutate();
arrowDrawable.setColorFilter(new PorterDuffColorFilter(getThemedColor(Theme.key_undo_cancelColor), PorterDuff.Mode.MULTIPLY));
arrowDrawable.setBounds(0, 0, AndroidUtilities.dp(10), AndroidUtilities.dp(10));
arrow.setSpan(new ImageSpan(arrowDrawable, DynamicDrawableSpan.ALIGN_CENTER), 0, arrow.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
SpannableStringBuilder link = new SpannableStringBuilder();
link
.append(LocaleController.getString("EventLogFilterGroupInfo", R.string.EventLogFilterGroupInfo))
.append("")
.append(arrow)
.append("")
.append(LocaleController.getString("ChannelAdministrators", R.string.ChannelAdministrators));
link.setSpan(new ClickableSpan() {
@Override
public void onClick(@NonNull View view) {
finishFragment();
}
@Override
public void updateDrawState(@NonNull TextPaint ds) {
super.updateDrawState(ds);
ds.setUnderlineText(false);
}
}, 0, link.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
CharSequence text = LocaleController.getString("ChannelAntiSpamInfo2", R.string.ChannelAntiSpamInfo2);
text = AndroidUtilities.replaceCharSequence("%s", text, link);
Bulletin bulletin = BulletinFactory.of(this).createSimpleBulletin(R.raw.msg_antispam, LocaleController.getString("ChannelAntiSpamUser", R.string.ChannelAntiSpamUser), text);
bulletin.setDuration(Bulletin.DURATION_PROLONG);
bulletin.show();
return true;
}
items.add(LocaleController.getString("ReportFalsePositive", R.string.ReportFalsePositive));
icons.add(R.drawable.msg_notspam);
options.add(OPTION_REPORT_FALSE_POSITIVE);
items.add(null);
icons.add(null);
options.add(null);
}
if (selectedObject.type == MessageObject.TYPE_TEXT || selectedObject.caption != null) {
items.add(LocaleController.getString("Copy", R.string.Copy));
options.add(3);
icons.add(R.drawable.msg_copy);
options.add(OPTION_COPY);
}
if (type == 1) {
if (selectedObject.currentEvent != null && selectedObject.currentEvent.action instanceof TLRPC.TL_channelAdminLogEventActionChangeStickerSet) {
@ -1162,60 +1258,79 @@ public class ChannelAdminLogActivity extends BaseFragment implements Notificatio
} else if (type == 3) {
if (selectedObject.messageOwner.media instanceof TLRPC.TL_messageMediaWebPage && MessageObject.isNewGifDocument(selectedObject.messageOwner.media.webpage.document)) {
items.add(LocaleController.getString("SaveToGIFs", R.string.SaveToGIFs));
options.add(11);
icons.add(R.drawable.msg_gif);
options.add(OPTION_SAVE_TO_GIFS);
}
} else if (type == 4) {
if (selectedObject.isVideo()) {
items.add(LocaleController.getString("SaveToGallery", R.string.SaveToGallery));
options.add(4);
icons.add(R.drawable.msg_gallery);
options.add(OPTION_SAVE_TO_GALLERY);
items.add(LocaleController.getString("ShareFile", R.string.ShareFile));
options.add(6);
icons.add(R.drawable.msg_share);
options.add(OPTION_SHARE);
} else if (selectedObject.isMusic()) {
items.add(LocaleController.getString("SaveToMusic", R.string.SaveToMusic));
options.add(10);
icons.add(R.drawable.msg_download);
options.add(OPTION_SAVE_TO_DOWNLOADS_OR_MUSIC);
items.add(LocaleController.getString("ShareFile", R.string.ShareFile));
options.add(6);
icons.add(R.drawable.msg_share);
options.add(OPTION_SHARE);
} else if (selectedObject.getDocument() != null) {
if (MessageObject.isNewGifDocument(selectedObject.getDocument())) {
items.add(LocaleController.getString("SaveToGIFs", R.string.SaveToGIFs));
options.add(11);
icons.add(R.drawable.msg_gif);
options.add(OPTION_SAVE_TO_GIFS);
}
items.add(LocaleController.getString("SaveToDownloads", R.string.SaveToDownloads));
options.add(10);
icons.add(R.drawable.msg_download);
options.add(OPTION_SAVE_TO_DOWNLOADS_OR_MUSIC);
items.add(LocaleController.getString("ShareFile", R.string.ShareFile));
options.add(6);
icons.add(R.drawable.msg_share);
options.add(OPTION_SHARE);
} else {
items.add(LocaleController.getString("SaveToGallery", R.string.SaveToGallery));
options.add(4);
icons.add(R.drawable.msg_gallery);
options.add(OPTION_SAVE_TO_GALLERY);
}
} else if (type == 5) {
items.add(LocaleController.getString("ApplyLocalizationFile", R.string.ApplyLocalizationFile));
options.add(5);
icons.add(R.drawable.msg_language);
options.add(OPTION_APPLY_FILE);
items.add(LocaleController.getString("SaveToDownloads", R.string.SaveToDownloads));
options.add(10);
icons.add(R.drawable.msg_download);
options.add(OPTION_SAVE_TO_DOWNLOADS_OR_MUSIC);
items.add(LocaleController.getString("ShareFile", R.string.ShareFile));
options.add(6);
icons.add(R.drawable.msg_share);
options.add(OPTION_SHARE);
} else if (type == 10) {
items.add(LocaleController.getString("ApplyThemeFile", R.string.ApplyThemeFile));
options.add(5);
icons.add(R.drawable.msg_theme);
options.add(OPTION_APPLY_FILE);
items.add(LocaleController.getString("SaveToDownloads", R.string.SaveToDownloads));
options.add(10);
icons.add(R.drawable.msg_download);
options.add(OPTION_SAVE_TO_DOWNLOADS_OR_MUSIC);
items.add(LocaleController.getString("ShareFile", R.string.ShareFile));
options.add(6);
icons.add(R.drawable.msg_share);
options.add(OPTION_SHARE);
} else if (type == 6) {
items.add(LocaleController.getString("SaveToGallery", R.string.SaveToGallery));
options.add(7);
icons.add(R.drawable.msg_gallery);
options.add(OPTION_SAVE_TO_GALLERY2);
items.add(LocaleController.getString("SaveToDownloads", R.string.SaveToDownloads));
options.add(10);
icons.add(R.drawable.msg_download);
options.add(OPTION_SAVE_TO_DOWNLOADS_OR_MUSIC);
items.add(LocaleController.getString("ShareFile", R.string.ShareFile));
options.add(6);
icons.add(R.drawable.msg_share);
options.add(OPTION_SHARE);
} else if (type == 7) {
if (selectedObject.isMask()) {
items.add(LocaleController.getString("AddToMasks", R.string.AddToMasks));
} else {
items.add(LocaleController.getString("AddToStickers", R.string.AddToStickers));
}
options.add(9);
icons.add(R.drawable.msg_sticker);
options.add(OPTION_SAVE_STICKER);
} else if (type == 8) {
long uid = selectedObject.messageOwner.media.user_id;
TLRPC.User user = null;
@ -1224,29 +1339,156 @@ public class ChannelAdminLogActivity extends BaseFragment implements Notificatio
}
if (user != null && user.id != UserConfig.getInstance(currentAccount).getClientUserId() && ContactsController.getInstance(currentAccount).contactsDict.get(user.id) == null) {
items.add(LocaleController.getString("AddContactTitle", R.string.AddContactTitle));
options.add(15);
icons.add(R.drawable.msg_addcontact);
options.add(OPTION_ADD_CONTACT);
}
if (!TextUtils.isEmpty(selectedObject.messageOwner.media.phone_number)) {
items.add(LocaleController.getString("Copy", R.string.Copy));
options.add(16);
icons.add(R.drawable.msg_copy);
options.add(OPTION_COPY_PHONE);
items.add(LocaleController.getString("Call", R.string.Call));
options.add(17);
icons.add(R.drawable.msg_calls);
options.add(OPTION_CALL);
}
}
if (options.isEmpty()) {
return false;
}
final CharSequence[] finalItems = items.toArray(new CharSequence[0]);
builder.setItems(finalItems, (dialogInterface, i) -> {
if (selectedObject == null || i < 0 || i >= options.size()) {
boolean callbackSent = false;
Runnable proceed = () -> {
if (options.isEmpty()) {
return;
}
processSelectedOption(options.get(i));
});
builder.setTitle(LocaleController.getString("Message", R.string.Message));
showDialog(builder.create());
ActionBarPopupWindow.ActionBarPopupWindowLayout popupLayout = new ActionBarPopupWindow.ActionBarPopupWindowLayout(getParentActivity(), R.drawable.popup_fixed_alert, getResourceProvider(), 0);
popupLayout.setMinimumWidth(AndroidUtilities.dp(200));
Rect backgroundPaddings = new Rect();
Drawable shadowDrawable = getParentActivity().getResources().getDrawable(R.drawable.popup_fixed_alert).mutate();
shadowDrawable.getPadding(backgroundPaddings);
popupLayout.setBackgroundColor(getThemedColor(Theme.key_actionBarDefaultSubmenuBackground));
for (int a = 0, N = items.size(); a < N; ++a) {
if (options.get(a) == null) {
popupLayout.addView(new ActionBarPopupWindow.GapView(getContext(), getResourceProvider()), LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 8));
} else {
ActionBarMenuSubItem cell = new ActionBarMenuSubItem(getParentActivity(), a == 0, a == N - 1, getResourceProvider());
cell.setMinimumWidth(AndroidUtilities.dp(200));
cell.setTextAndIcon(items.get(a), icons.get(a));
final Integer option = options.get(a);
popupLayout.addView(cell);
final int i = a;
cell.setOnClickListener(v1 -> {
if (selectedObject == null || i >= options.size()) {
return;
}
processSelectedOption(option);
});
}
}
ChatScrimPopupContainerLayout scrimPopupContainerLayout = new ChatScrimPopupContainerLayout(contentView.getContext()) {
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
closeMenu();
}
return super.dispatchKeyEvent(event);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
boolean b = super.dispatchTouchEvent(ev);
if (ev.getAction() == MotionEvent.ACTION_DOWN && !b) {
closeMenu();
}
return b;
}
};
scrimPopupContainerLayout.addView(popupLayout, LayoutHelper.createLinearRelatively(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT, 0, 0, 0, 0));
scrimPopupContainerLayout.setPopupWindowLayout(popupLayout);
scrimPopupWindow = new ActionBarPopupWindow(scrimPopupContainerLayout, LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT) {
@Override
public void dismiss() {
super.dismiss();
if (scrimPopupWindow != this) {
return;
}
Bulletin.hideVisible();
scrimPopupWindow = null;
}
};
scrimPopupWindow.setPauseNotifications(true);
scrimPopupWindow.setDismissAnimationDuration(220);
scrimPopupWindow.setOutsideTouchable(true);
scrimPopupWindow.setClippingEnabled(true);
scrimPopupWindow.setAnimationStyle(R.style.PopupContextAnimation);
scrimPopupWindow.setFocusable(true);
scrimPopupContainerLayout.measure(View.MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(1000), View.MeasureSpec.AT_MOST), View.MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(1000), View.MeasureSpec.AT_MOST));
scrimPopupWindow.setInputMethodMode(ActionBarPopupWindow.INPUT_METHOD_NOT_NEEDED);
scrimPopupWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING);
scrimPopupWindow.getContentView().setFocusableInTouchMode(true);
popupLayout.setFitItems(true);
int popupX = v.getLeft() + (int) x - scrimPopupContainerLayout.getMeasuredWidth() + backgroundPaddings.left - AndroidUtilities.dp(28);
if (popupX < AndroidUtilities.dp(6)) {
popupX = AndroidUtilities.dp(6);
} else if (popupX > chatListView.getMeasuredWidth() - AndroidUtilities.dp(6) - scrimPopupContainerLayout.getMeasuredWidth()) {
popupX = chatListView.getMeasuredWidth() - AndroidUtilities.dp(6) - scrimPopupContainerLayout.getMeasuredWidth();
}
if (AndroidUtilities.isTablet()) {
int[] location = new int[2];
fragmentView.getLocationInWindow(location);
popupX += location[0];
}
int totalHeight = contentView.getHeight();
int height = scrimPopupContainerLayout.getMeasuredHeight() + AndroidUtilities.dp(48);
int keyboardHeight = contentView.measureKeyboardHeight();
if (keyboardHeight > AndroidUtilities.dp(20)) {
totalHeight += keyboardHeight;
}
int popupY;
if (height < totalHeight) {
popupY = (int) (chatListView.getY() + v.getTop() + y);
if (height - backgroundPaddings.top - backgroundPaddings.bottom > AndroidUtilities.dp(240)) {
popupY += AndroidUtilities.dp(240) - height;
}
if (popupY < chatListView.getY() + AndroidUtilities.dp(24)) {
popupY = (int) (chatListView.getY() + AndroidUtilities.dp(24));
} else if (popupY > totalHeight - height - AndroidUtilities.dp(8)) {
popupY = totalHeight - height - AndroidUtilities.dp(8);
}
} else {
popupY = inBubbleMode ? 0 : AndroidUtilities.statusBarHeight;
}
final int finalPopupX = scrimPopupX = popupX;
final int finalPopupY = scrimPopupY = popupY;
scrimPopupContainerLayout.setMaxHeight(totalHeight - popupY);
scrimPopupWindow.showAtLocation(chatListView, Gravity.LEFT | Gravity.TOP, finalPopupX, finalPopupY);
scrimPopupWindow.dimBehind();
};
if (
ChatObject.canBlockUsers(currentChat) &&
message.currentEvent != null && message.currentEvent.action instanceof TLRPC.TL_channelAdminLogEventActionDeleteMessage && message.currentEvent.user_id == getMessagesController().telegramAntispamUserId &&
message.messageOwner != null && message.messageOwner.from_id != null && !UserObject.isUserSelf(getMessagesController().getUser(message.messageOwner.from_id.user_id))
) {
TLRPC.User user = getMessagesController().getUser(selectedObject.messageOwner.from_id.user_id);
if (user != null) {
callbackSent = true;
getMessagesController().checkIsInChat(true, currentChat, user, (isInChat, rights, rank) -> {
if (isInChat) {
items.add(LocaleController.getString("BanUser", R.string.BanUser));
icons.add(R.drawable.msg_block2);
options.add(OPTION_RESTRICT);
}
AndroidUtilities.runOnUIThread(proceed);
});
}
}
if (!callbackSent) {
proceed.run();
}
return true;
}
@ -1366,15 +1608,17 @@ public class ChannelAdminLogActivity extends BaseFragment implements Notificatio
}
private void processSelectedOption(int option) {
closeMenu();
if (selectedObject == null) {
return;
}
switch (option) {
case 3: {
case OPTION_COPY: {
AndroidUtilities.addToClipboard(getMessageContent(selectedObject, 0, true));
BulletinFactory.of(ChannelAdminLogActivity.this).createCopyBulletin(LocaleController.getString("MessageCopied", R.string.MessageCopied)).show();
break;
}
case 4: {
case OPTION_SAVE_TO_GALLERY: {
String path = selectedObject.messageOwner.attachPath;
if (path != null && path.length() > 0) {
File temp = new File(path);
@ -1395,7 +1639,7 @@ public class ChannelAdminLogActivity extends BaseFragment implements Notificatio
}
break;
}
case 5: {
case OPTION_APPLY_FILE: {
File locFile = null;
if (selectedObject.messageOwner.attachPath != null && selectedObject.messageOwner.attachPath.length() != 0) {
File f = new File(selectedObject.messageOwner.attachPath);
@ -1458,7 +1702,7 @@ public class ChannelAdminLogActivity extends BaseFragment implements Notificatio
}
break;
}
case 6: {
case OPTION_SHARE: {
String path = selectedObject.messageOwner.attachPath;
if (path != null && path.length() > 0) {
File temp = new File(path);
@ -1488,7 +1732,7 @@ public class ChannelAdminLogActivity extends BaseFragment implements Notificatio
}
break;
}
case 7: {
case OPTION_SAVE_TO_GALLERY2: {
String path = selectedObject.messageOwner.attachPath;
if (path != null && path.length() > 0) {
File temp = new File(path);
@ -1507,11 +1751,11 @@ public class ChannelAdminLogActivity extends BaseFragment implements Notificatio
MediaController.saveFile(path, getParentActivity(), 0, null, null);
break;
}
case 9: {
case OPTION_SAVE_STICKER: {
showDialog(new StickersAlert(getParentActivity(), this, selectedObject.getInputStickerSet(), null, null));
break;
}
case 10: {
case OPTION_SAVE_TO_DOWNLOADS_OR_MUSIC: {
if (Build.VERSION.SDK_INT >= 23 && (Build.VERSION.SDK_INT <= 28 || BuildVars.NO_SCOPED_STORAGE) && getParentActivity().checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
getParentActivity().requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 4);
selectedObject = null;
@ -1534,12 +1778,12 @@ public class ChannelAdminLogActivity extends BaseFragment implements Notificatio
MediaController.saveFile(path, getParentActivity(), selectedObject.isMusic() ? 3 : 2, fileName, selectedObject.getDocument() != null ? selectedObject.getDocument().mime_type : "");
break;
}
case 11: {
case OPTION_SAVE_TO_GIFS: {
TLRPC.Document document = selectedObject.getDocument();
MessagesController.getInstance(currentAccount).saveGif(selectedObject, document);
break;
}
case 15: {
case OPTION_ADD_CONTACT: {
Bundle args = new Bundle();
args.putLong("user_id", selectedObject.messageOwner.media.user_id);
args.putString("phone", selectedObject.messageOwner.media.phone_number);
@ -1547,11 +1791,12 @@ public class ChannelAdminLogActivity extends BaseFragment implements Notificatio
presentFragment(new ContactAddActivity(args));
break;
}
case 16: {
case OPTION_COPY_PHONE: {
AndroidUtilities.addToClipboard(selectedObject.messageOwner.media.phone_number);
BulletinFactory.of(ChannelAdminLogActivity.this).createCopyBulletin(LocaleController.getString("PhoneCopied", R.string.PhoneCopied)).show();
break;
}
case 17: {
case OPTION_CALL: {
try {
Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + selectedObject.messageOwner.media.phone_number));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
@ -1561,6 +1806,33 @@ public class ChannelAdminLogActivity extends BaseFragment implements Notificatio
}
break;
}
case OPTION_REPORT_FALSE_POSITIVE: {
TLRPC.TL_channels_reportAntiSpamFalsePositive req = new TLRPC.TL_channels_reportAntiSpamFalsePositive();
req.channel = getMessagesController().getInputChannel(currentChat.id);
req.msg_id = selectedObject.getRealId();
getConnectionsManager().sendRequest(req, (res, err) -> {
AndroidUtilities.runOnUIThread(() -> {
if (res instanceof TLRPC.TL_boolTrue) {
BulletinFactory.of(this).createSimpleBulletin(R.raw.msg_antispam, LocaleController.getString("ChannelAntiSpamFalsePositiveReported", R.string.ChannelAntiSpamFalsePositiveReported)).show();
} else if (res instanceof TLRPC.TL_boolFalse) {
BulletinFactory.of(this).createSimpleBulletin(R.raw.error, LocaleController.getString("UnknownError", R.string.UnknownError)).show();
} else {
BulletinFactory.of(this).createSimpleBulletin(R.raw.error, LocaleController.getString("UnknownError", R.string.UnknownError)).show();
}
});
});
break;
}
case OPTION_RESTRICT: {
getMessagesController().deleteParticipantFromChat(currentChat.id, getMessagesController().getInputPeer(selectedObject.messageOwner.from_id));
if (currentChat != null && selectedObject.messageOwner.from_id instanceof TLRPC.TL_peerUser && BulletinFactory.canShowBulletin(this)) {
TLRPC.User user = getMessagesController().getUser(selectedObject.messageOwner.from_id.user_id);
if (user != null) {
BulletinFactory.createRemoveFromChatBulletin(this, user, currentChat.title).show();
}
}
break;
}
}
selectedObject = null;
}
@ -1640,6 +1912,16 @@ public class ChannelAdminLogActivity extends BaseFragment implements Notificatio
getMessagesController().putUsers(res.users, false);
getMessagesController().putChats(res.chats, false);
admins = res.participants;
if (currentChat != null) {
TLRPC.ChatFull chatFull = getMessagesController().getChatFull(currentChat.id);
if (chatFull != null && chatFull.antispam) {
TLRPC.ChannelParticipant antispamParticipant = new TLRPC.ChannelParticipant() {};
antispamParticipant.user_id = getMessagesController().telegramAntispamUserId;
antispamParticipant.peer = getMessagesController().getPeer(antispamParticipant.user_id);
loadAntispamUser(getMessagesController().telegramAntispamUserId);
admins.add(0, antispamParticipant);
}
}
if (visibleDialog instanceof AdminLogFilterAlert) {
((AdminLogFilterAlert) visibleDialog).setCurrentAdmins(admins);
}
@ -1648,6 +1930,28 @@ public class ChannelAdminLogActivity extends BaseFragment implements Notificatio
ConnectionsManager.getInstance(currentAccount).bindRequestToGuid(reqId, classGuid);
}
private void loadAntispamUser(long userId) {
if (getMessagesController().getUser(userId) != null) {
return;
}
TLRPC.TL_users_getUsers req = new TLRPC.TL_users_getUsers();
TLRPC.TL_inputUser inputUser = new TLRPC.TL_inputUser();
inputUser.user_id = userId;
req.id.add(inputUser);
ConnectionsManager.getInstance(currentAccount).sendRequest(req, (res, err) -> {
if (res instanceof TLRPC.Vector) {
ArrayList<Object> objects = ((TLRPC.Vector) res).objects;
ArrayList<TLRPC.User> users = new ArrayList<>();
for (int i = 0; i < objects.size(); ++i) {
if (objects.get(i) instanceof TLRPC.User) {
users.add((TLRPC.User) objects.get(i));
}
}
getMessagesController().putUsers(users, false);
}
});
}
@Override
public void onRemoveFromParent() {
MediaController.getInstance().setTextureView(videoTextureView, null, null, false);
@ -1741,7 +2045,7 @@ public class ChannelAdminLogActivity extends BaseFragment implements Notificatio
}
}
private void updateMessagesVisisblePart() {
private void updateMessagesVisiblePart() {
if (chatListView == null) {
return;
}

View File

@ -343,7 +343,7 @@ public class ChannelCreateActivity extends BaseFragment implements NotificationC
createAfterUpload = true;
return;
}
doneRequestId = MessagesController.getInstance(currentAccount).createChat(nameTextView.getText().toString(), new ArrayList<>(), descriptionTextView.getText().toString(), ChatObject.CHAT_TYPE_CHANNEL, false, null, null, ChannelCreateActivity.this);
doneRequestId = MessagesController.getInstance(currentAccount).createChat(nameTextView.getText().toString(), new ArrayList<>(), descriptionTextView.getText().toString(), ChatObject.CHAT_TYPE_CHANNEL, false, null, null, 0, ChannelCreateActivity.this);
} else if (currentStep == 1) {
if (!isPrivate) {
if (descriptionTextView.length() == 0) {

View File

@ -323,6 +323,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
public boolean shareAlertDebugTopicsSlowMotion;
public boolean justCreatedTopic = false;
public boolean justCreatedChat = false;
protected TLRPC.Chat currentChat;
protected TLRPC.User currentUser;
protected TLRPC.EncryptedChat currentEncryptedChat;
@ -394,6 +395,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
private FrameLayout mentiondownButton;
private SimpleTextView mentiondownButtonCounter;
private ImageView mentiondownButtonImage;
private Bulletin messageSeenPrivacyBulletin;
private int reactionsMentionCount;
private FrameLayout reactionsMentiondownButton;
@ -1501,6 +1503,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
int migrated_to = arguments.getInt("migrated_to", 0);
scrollToTopOnResume = arguments.getBoolean("scrollToTopOnResume", false);
needRemovePreviousSameChatActivity = arguments.getBoolean("need_remove_previous_same_chat_activity", true);
justCreatedChat = arguments.getBoolean("just_created_chat", false);
if (chatId != 0) {
currentChat = getMessagesController().getChat(chatId);
@ -1705,7 +1708,6 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
getNotificationCenter().addObserver(this, NotificationCenter.chatAvailableReactionsUpdated);
getNotificationCenter().addObserver(this, NotificationCenter.dialogsUnreadReactionsCounterChanged);
getNotificationCenter().addObserver(this, NotificationCenter.groupStickersDidLoad);
getNotificationCenter().addObserver(this, NotificationCenter.chatSwithcedToForum);
super.onFragmentCreate();
@ -1824,7 +1826,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
}
if (AndroidUtilities.isTablet() && !isComments) {
getNotificationCenter().postNotificationName(NotificationCenter.openedChatChanged, dialog_id, false);
getNotificationCenter().postNotificationName(NotificationCenter.openedChatChanged, dialog_id, getTopicId(), false);
}
if (currentUser != null && !UserObject.isReplyUser(currentUser)) {
@ -1867,6 +1869,10 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}, timeout * 1000L);
}
if (isTopic) {
getMessagesController().getTopicsController().getTopicRepliesCount(dialog_id, getTopicId());
}
return true;
}
@ -2030,14 +2036,13 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
getNotificationCenter().removeObserver(this, NotificationCenter.didLoadSendAsPeers);
getNotificationCenter().removeObserver(this, NotificationCenter.dialogsUnreadReactionsCounterChanged);
getNotificationCenter().removeObserver(this, NotificationCenter.groupStickersDidLoad);
getNotificationCenter().removeObserver(this, NotificationCenter.chatSwithcedToForum);
if (currentEncryptedChat != null) {
getNotificationCenter().removeObserver(this, NotificationCenter.didVerifyMessagesStickers);
}
NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.needSetDayNightTheme);
if (chatMode == 0 && AndroidUtilities.isTablet()) {
getNotificationCenter().postNotificationName(NotificationCenter.openedChatChanged, dialog_id, true);
getNotificationCenter().postNotificationName(NotificationCenter.openedChatChanged, dialog_id, getTopicId(), true);
}
if (currentUser != null) {
MediaController.getInstance().stopMediaObserver();
@ -2622,7 +2627,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
attachItem.setVisibility(View.GONE);
}
}
if (threadMessageId == 0 && !UserObject.isReplyUser(currentUser) || threadMessageObject != null && threadMessageObject.getRepliesCount() == 0) {
if (threadMessageId == 0 && !UserObject.isReplyUser(currentUser) || threadMessageObject != null && threadMessageObject.getRepliesCount() < 10) {
searchItem.setVisibility(View.GONE);
}
searchItemVisible = false;
@ -2695,7 +2700,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
});
searchItem.setSearchFieldHint(LocaleController.getString("Search", R.string.Search));
if (threadMessageId == 0 && !UserObject.isReplyUser(currentUser) || threadMessageObject != null && threadMessageObject.getRepliesCount() == 0) {
if (threadMessageId == 0 && !UserObject.isReplyUser(currentUser) || threadMessageObject != null && threadMessageObject.getRepliesCount() < 10) {
searchItem.setVisibility(View.GONE);
}
searchItemVisible = false;
@ -4636,7 +4641,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (chatMode != 0 || threadMessageObjects != null && threadMessageObjects.contains(message) ||
getMessageType(message) == 1 && (message.getDialogId() == mergeDialogId || message.needDrawBluredPreview()) ||
currentEncryptedChat == null && message.getId() < 0 ||
bottomOverlayChat != null && bottomOverlayChat.getVisibility() == View.VISIBLE && !(bottomOverlayChatWaitsReply && message != null && (MessageObject.getTopicId(message.messageOwner) != 0 || message.wasJustSent)) ||
bottomOverlayChat != null && bottomOverlayChat.getVisibility() == View.VISIBLE && !(bottomOverlayChatWaitsReply && message != null && (MessageObject.getTopicId(message.messageOwner, ChatObject.isForum(currentChat)) != 0 || message.wasJustSent)) ||
currentChat != null && (ChatObject.isNotInChat(currentChat) && !isThreadChat() || ChatObject.isChannel(currentChat) && !ChatObject.canPost(currentChat) && !currentChat.megagroup || !ChatObject.canSendMessages(currentChat)) ||
textSelectionHelper.isSelectionMode()) {
slidingView.setSlidingOffset(0);
@ -4875,7 +4880,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
private boolean isSkeletonVisible() {
if (justCreatedTopic || currentUser != null || !SharedConfig.animationsEnabled()) {
if (justCreatedTopic || justCreatedChat || currentUser != null || !SharedConfig.animationsEnabled()) {
return false;
}
int childHeight = 0;
@ -5035,6 +5040,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
int wasOutlineAlpha = skeletonOutlinePaint.getAlpha();
skeletonServicePaint.setAlpha((int) (0xFF * topSkeletonAlpha));
skeletonPaint.setAlpha((int) (topSkeletonAlpha * alpha));
skeletonOutlinePaint.setAlpha((int) (wasOutlineAlpha * alpha));
while (lastTop > blurredViewTopOffset) {
lastTop -= AndroidUtilities.dp(3f);
@ -5109,6 +5115,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
skeletonColor0 = color0;
skeletonColor1 = color1;
skeletonGradient = new LinearGradient(0, 0, skeletonGradientWidth = AndroidUtilities.dp(200), 0, new int[]{color1, color0, color0, color1}, new float[]{0.0f, 0.4f, 0.6f, 1f}, Shader.TileMode.CLAMP);
skeletonTotalTranslation = -skeletonGradientWidth * 2;
skeletonPaint.setShader(skeletonGradient);
int outlineColor = Color.argb(dark ? 0x2B : 0x60, 0xFF, 0xFF, 0xFF);
@ -6000,7 +6007,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
boolean computingScroll;
@Override
public int getStarForFixGap() {
public int getStartForFixGap() {
int padding = (int) chatListViewPaddingTop;
if (isThreadChat() && (!isTopic || topicStarterMessageObject != null) && pinnedMessageView != null && pinnedMessageView.getVisibility() == View.VISIBLE) {
padding -= Math.max(0, AndroidUtilities.dp(48) + pinnedMessageEnterOffset);
@ -7769,7 +7776,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
}
if (ChatObject.isForum(currentChat) && !isTopic && replyingMessageObject != null) {
int topicId = replyingMessageObject.replyToForumTopic != null ? replyingMessageObject.replyToForumTopic.id : MessageObject.getTopicId(replyingMessageObject.messageOwner);
int topicId = replyingMessageObject.replyToForumTopic != null ? replyingMessageObject.replyToForumTopic.id : MessageObject.getTopicId(replyingMessageObject.messageOwner, true);
if (topicId != 0) {
getMediaDataController().cleanDraft(dialog_id, topicId, false);
}
@ -8296,7 +8303,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
replyCloseImageView.setOnClickListener(v -> {
if (forwardingMessages == null || forwardingMessages.messages.isEmpty()) {
if (ChatObject.isForum(currentChat) && !isTopic && replyingMessageObject != null) {
int topicId = MessageObject.getTopicId(replyingMessageObject.messageOwner);
int topicId = MessageObject.getTopicId(replyingMessageObject.messageOwner, true);
if (topicId != 0) {
getMediaDataController().cleanDraft(dialog_id, topicId, false);
}
@ -10345,7 +10352,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
@Override
public void onDismissAnimationStart() {
chatAttachAlert.setFocusable(false);
if (chatAttachAlert != null) {
chatAttachAlert.setFocusable(false);
}
chatActivityEnterView.getEditField().requestFocus();
if (chatAttachAlert != null && chatAttachAlert.isShowing()) {
AndroidUtilities.requestAdjustResize(getParentActivity(), classGuid);
@ -10714,6 +10723,19 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
return false;
}
public boolean checkSlowModeAlert() {
CharSequence time = chatActivityEnterView.getSlowModeTimer();
if (time != null) {
new AlertDialog.Builder(getContext())
.setTitle(LocaleController.getString("Slowmode", R.string.Slowmode))
.setMessage(AndroidUtilities.replaceTags(LocaleController.formatString("SlowModeHint", R.string.SlowModeHint, time)))
.setPositiveButton(LocaleController.getString("OK", R.string.OK), null)
.show();
return false;
}
return true;
}
private void hideHints(boolean scroll) {
if (!scroll) {
if (slowModeHint != null) {
@ -11531,8 +11553,10 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
public void openPollCreate(Boolean quiz) {
PollCreateActivity pollCreateActivity = new PollCreateActivity(ChatActivity.this, quiz);
pollCreateActivity.setDelegate((poll, params, notify, scheduleDate) -> {
getSendMessagesHelper().sendMessage(poll, dialog_id, replyingMessageObject, getThreadMessage(), null, params, notify, scheduleDate);
afterMessageSend();
if (checkSlowModeAlert()) {
getSendMessagesHelper().sendMessage(poll, dialog_id, replyingMessageObject, getThreadMessage(), null, params, notify, scheduleDate);
afterMessageSend();
}
});
presentFragment(pollCreateActivity);
}
@ -11540,13 +11564,15 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
@Override
public void didSelectFiles(ArrayList<String> files, String caption, ArrayList<MessageObject> fmessages, boolean notify, int scheduleDate) {
fillEditingMediaWithCaption(caption, null);
if (!fmessages.isEmpty() && !TextUtils.isEmpty(caption)) {
SendMessagesHelper.getInstance(currentAccount).sendMessage(caption, dialog_id, null, null, null, true, null, null, null, true, 0, null, false);
caption = null;
if (checkSlowModeAlert()) {
if (!fmessages.isEmpty() && !TextUtils.isEmpty(caption)) {
SendMessagesHelper.getInstance(currentAccount).sendMessage(caption, dialog_id, null, null, null, true, null, null, null, true, 0, null, false);
caption = null;
}
getSendMessagesHelper().sendMessage(fmessages, dialog_id, false, false, true, 0);
SendMessagesHelper.prepareSendingDocuments(getAccountInstance(), files, files, null, caption, null, dialog_id, replyingMessageObject, getThreadMessage(), null, editingMessageObject, notify, scheduleDate);
afterMessageSend();
}
getSendMessagesHelper().sendMessage(fmessages, dialog_id, false, false,true, 0);
SendMessagesHelper.prepareSendingDocuments(getAccountInstance(), files, files, null, caption, null, dialog_id, replyingMessageObject, getThreadMessage(), null, editingMessageObject, notify, scheduleDate);
afterMessageSend();
}
@Override
@ -11567,6 +11593,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (photos.isEmpty()) {
return;
}
if (!checkSlowModeAlert()) {
return;
}
boolean hasNoGifs = false;
for (int a = 0; a < photos.size(); a++) {
SendMessagesHelper.SendingMediaInfo info = photos.get(a);
@ -11778,6 +11807,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (arrayList == null || arrayList.isEmpty()) {
return;
}
if (!checkSlowModeAlert()) {
return;
}
if ((scheduleDate != 0) == (chatMode == MODE_SCHEDULED)) {
waitingForSendingMessageLoad = true;
}
@ -14241,7 +14273,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
private void updateTopicTitleIcon() {
if (forumTopic != null && avatarContainer != null) {
avatarContainer.getAvatarImageView().setVisibility(View.VISIBLE);
ForumUtilities.setTopicIcon(avatarContainer.getAvatarImageView(), forumTopic, true);
ForumUtilities.setTopicIcon(avatarContainer.getAvatarImageView(), forumTopic, true, themeDelegate);
}
}
@ -16630,7 +16662,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (forwardEndReached[0]) {
forwardEndReached[0] = false;
hideForwardEndReached = false;
chatAdapter.notifyItemInserted(0);
if (chatAdapter != null) {
chatAdapter.notifyItemInserted(0);
}
}
getMessagesController().addToViewsQueue(threadMessageObject);
} else {
@ -17167,7 +17201,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (object == null && replaceObjects != null) {
object = replaceObjects.get(mid);
}
if (object != null && (!isTopic || getTopicId() == MessageObject.getTopicId(object.messageOwner))) {
if (object != null && (!isTopic || getTopicId() == MessageObject.getTopicId(object.messageOwner, ChatObject.isForum(currentChat)))) {
pinnedMessageIds.add(mid);
pinnedMessageObjects.put(mid, object);
if (replaceObjects == null) {
@ -17562,7 +17596,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
i--;
continue;
}
int messageTopicId = MessageObject.getTopicId(pinnedMessageObjects.get(messageId).messageOwner);
int messageTopicId = MessageObject.getTopicId(pinnedMessageObjects.get(messageId).messageOwner, true);
if (getTopicId() != messageTopicId) {
pinnedMessageObjects.remove(messageId);
pinnedMessageIds.remove(i);
@ -17809,24 +17843,13 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
} else if (id == NotificationCenter.topicsDidLoaded) {
if (isTopic) {
updateTopicTitleIcon();
updateTopicHeader();
updateBottomOverlay();
updateTopPanel(true);
if (avatarContainer != null) {
avatarContainer.updateSubtitle();
}
}
} else if (id == NotificationCenter.chatSwithcedToForum) {
// long chatId = (long) args[0];
// if (-dialog_id == chatId) {
// if (chatMode == 0 && getMessagesController().getChat(-dialog_id).forum) {
// if (getParentLayout() != null) {
// if (getParentLayout().checkTransitionAnimation()) {
// AndroidUtilities.runOnUIThread(() -> {
// TopicsFragment.prepareToSwitchAnimation(ChatActivity.this);
// }, 500);
// } else {
// TopicsFragment.prepareToSwitchAnimation(ChatActivity.this);
// }
// }
}
}
@ -18633,6 +18656,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (!isAd && placeToPaste < sponsoredMessagesCount && (currentChat == null || ChatObject.isChannelAndNotMegaGroup(currentChat))) {
placeToPaste = sponsoredMessagesCount;
}
if (obj.messageOwner.action instanceof TLRPC.TL_messageActionSetMessagesTTL && messages.size() == 2) {
placeToPaste = 1;
}
if (dayArray == null) {
dayArray = new ArrayList<>();
messagesByDays.put(obj.dateKey, dayArray);
@ -20065,7 +20091,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
private void updateTopicHeader() {
avatarContainer.setTitle(forumTopic.title);
if (avatarContainer != null && forumTopic != null) {
avatarContainer.setTitle(forumTopic.title);
}
updateTopicTitleIcon();
}
@ -21033,7 +21061,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
int chatWithAdminDate = preferences.getInt("dialog_bar_chat_with_date" + did, 0);
boolean showAddMembersToGroup = preferences.getBoolean("dialog_bar_invite" + did, false);
TLRPC.EmojiStatus showEmojiStatusReport = currentUser != null && (showReport || showBlock) && (currentUser.emoji_status instanceof TLRPC.TL_emojiStatus || currentUser.emoji_status instanceof TLRPC.TL_emojiStatusUntil && ((TLRPC.TL_emojiStatusUntil) currentUser.emoji_status).until > (int) (System.currentTimeMillis() / 1000)) ? currentUser.emoji_status : null;
boolean showRestartTopic = !isInPreviewMode() && forumTopic != null && forumTopic.closed && ChatObject.canManageTopic(currentAccount, currentChat, forumTopic);
boolean showRestartTopic = !isInPreviewMode() && forumTopic != null && forumTopic.closed && !forumTopic.hidden && ChatObject.canManageTopic(currentAccount, currentChat, forumTopic);
if (showRestartTopic) {
shownRestartTopic = true;
}
@ -21630,7 +21658,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (replyMessage.replyToForumTopic != null) {
draftThreadId = replyMessage.replyToForumTopic.id;
} else {
draftThreadId = MessageObject.getTopicId(replyMessage.messageOwner);
draftThreadId = MessageObject.getTopicId(replyMessage.messageOwner, ChatObject.isForum(currentChat));
}
} else {
draftThreadId = threadMessageId;
@ -22269,7 +22297,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
message.isSponsored() || type == 1 && message.getDialogId() == mergeDialogId ||
message.messageOwner.action instanceof TLRPC.TL_messageActionSecureValuesSent ||
currentEncryptedChat == null && message.getId() < 0 ||
bottomOverlayChat != null && bottomOverlayChat.getVisibility() == View.VISIBLE && !(bottomOverlayChatWaitsReply && selectedObject != null && (MessageObject.getTopicId(selectedObject.messageOwner) != 0 || selectedObject.wasJustSent)) ||
bottomOverlayChat != null && bottomOverlayChat.getVisibility() == View.VISIBLE && !(bottomOverlayChatWaitsReply && selectedObject != null && (MessageObject.getTopicId(selectedObject.messageOwner, ChatObject.isForum(currentChat)) != 0 || selectedObject.wasJustSent)) ||
currentChat != null && (ChatObject.isNotInChat(currentChat) && !isThreadChat() || ChatObject.isChannel(currentChat) && !ChatObject.canPost(currentChat) && !currentChat.megagroup || !ChatObject.canSendMessages(currentChat))) {
allowChatActions = false;
}
@ -22322,28 +22350,31 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
undoView.showWithAction(dialog_id, action, currentUser, userInfo != null ? userInfo.ttl_period : chatInfo.ttl_period, null, null);
}
}
}, true, getResourceProvider());
}, true, 0, getResourceProvider());
autoDeletePopupWrapper.updateItems(userInfo != null ? userInfo.ttl_period : chatInfo.ttl_period);
optionsView = autoDeletePopupWrapper.windowLayout;
} else if (type >= 0 || type == -1 && single && (message.isSending() || message.isEditing()) && currentEncryptedChat == null) {
selectedObject = message;
selectedObjectGroup = groupedMessages;
messageTextToTranslate = getMessageCaption(selectedObject, selectedObjectGroup);
if (messageTextToTranslate == null && selectedObject.isPoll()) {
try {
TLRPC.Poll poll = ((TLRPC.TL_messageMediaPoll) selectedObject.messageOwner.media).poll;
StringBuilder pollText = new StringBuilder();
pollText = new StringBuilder(poll.question).append("\n");
for (TLRPC.TL_pollAnswer answer : poll.answers)
pollText.append("\n\uD83D\uDD18 ").append(answer.text);
messageTextToTranslate = pollText.toString();
} catch (Exception e) {}
}
if (messageTextToTranslate == null) {
messageTextToTranslate = getMessageContent(selectedObject, 0, false);
}
if (messageTextToTranslate != null && Emoji.fullyConsistsOfEmojis(messageTextToTranslate)) {
messageTextToTranslate = null; // message fully consists of emojis, do not translate
if (selectedObject.type != MessageObject.TYPE_EMOJIS && selectedObject.type != MessageObject.TYPE_ANIMATED_STICKER && selectedObject.type != MessageObject.TYPE_STICKER) {
messageTextToTranslate = getMessageCaption(selectedObject, selectedObjectGroup);
if (messageTextToTranslate == null && selectedObject.isPoll()) {
try {
TLRPC.Poll poll = ((TLRPC.TL_messageMediaPoll) selectedObject.messageOwner.media).poll;
StringBuilder pollText = new StringBuilder();
pollText = new StringBuilder(poll.question).append("\n");
for (TLRPC.TL_pollAnswer answer : poll.answers)
pollText.append("\n\uD83D\uDD18 ").append(answer.text);
messageTextToTranslate = pollText.toString();
} catch (Exception e) {
}
}
if (messageTextToTranslate == null) {
messageTextToTranslate = getMessageContent(selectedObject, 0, false);
}
if (messageTextToTranslate != null && Emoji.fullyConsistsOfEmojis(messageTextToTranslate)) {
messageTextToTranslate = null; // message fully consists of emojis, do not translate
}
}
if (message.isSponsored() && !getMessagesController().premiumLocked) {
@ -23111,17 +23142,13 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
int totalHeight = contentView.getHeightWithKeyboard();
int availableHeight = totalHeight - scrimPopupY - AndroidUtilities.dp(46 + 16) - (isReactionsAvailable ? AndroidUtilities.dp(52) : 0);
// if (SharedConfig.messageSeenHintCount > 0 && contentView.getKeyboardHeight() < AndroidUtilities.dp(20)) {
availableHeight -= AndroidUtilities.dp(52);
Bulletin bulletin = BulletinFactory.of(Bulletin.BulletinWindow.make(getContext()), themeDelegate).createErrorBulletin(AndroidUtilities.replaceTags(LocaleController.getString("MessageSeenTooltipMessage", R.string.MessageSeenTooltipMessage)));
bulletin.setDuration(4000);
bulletin.show();
if (SharedConfig.messageSeenHintCount > 0 && contentView.getKeyboardHeight() < AndroidUtilities.dp(20)) {
messageSeenPrivacyBulletin = BulletinFactory.of(Bulletin.BulletinWindow.make(getContext()), themeDelegate).createErrorBulletin(AndroidUtilities.replaceTags(LocaleController.getString("MessageSeenTooltipMessage", R.string.MessageSeenTooltipMessage)));
messageSeenPrivacyBulletin.setDuration(4000);
messageSeenPrivacyBulletin.show();
SharedConfig.updateMessageSeenHintCount(SharedConfig.messageSeenHintCount - 1);
// } else if (contentView.getKeyboardHeight() > AndroidUtilities.dp(20)) {
// availableHeight -= contentView.getKeyboardHeight() / 3f;
// }
}
listView2.requestLayout();
linearLayout.requestLayout();
@ -23175,9 +23202,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
if (addGap) {
View gap = new FrameLayout(contentView.getContext());
gap.setBackgroundColor(getThemedColor(Theme.key_actionBarDefaultSubmenuSeparator));
popupLayout.addView(gap, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 8));
popupLayout.addView(new ActionBarPopupWindow.GapView(contentView.getContext(), themeDelegate), LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 8));
}
if (popupLayout.getSwipeBack() != null) {
@ -23331,7 +23356,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
return true;
};
TLRPC.InputPeer inputPeer = getMessagesController().getInputPeer(dialog_id);
int messageId = selectedObject.messageOwner.id;
int messageId = selectedObject == null || selectedObject.messageOwner == null ? 0 : selectedObject.messageOwner.id;
if (LanguageDetector.hasSupport()) {
final String[] fromLang = {null};
cell.setVisibility(View.GONE);
@ -23342,7 +23367,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
fromLang[0] = lang;
if (fromLang[0] != null && (!fromLang[0].equals(toLang) || fromLang[0].equals("und")) && (
translateButtonEnabled && !RestrictedLanguagesSelectActivity.getRestrictedLanguages().contains(fromLang[0]) ||
(currentChat != null && (currentChat.has_link || ChatObject.isPublic(currentChat))) && ("uk".equals(fromLang[0]) || "ru".equals(fromLang[0]))
(currentChat != null && (currentChat.has_link || ChatObject.isPublic(currentChat)) || selectedObject.messageOwner.fwd_from != null) && ("uk".equals(fromLang[0]) || "ru".equals(fromLang[0]))
)) {
cell.setVisibility(View.VISIBLE);
}
@ -23573,7 +23598,10 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (scrimPopupWindow != this) {
return;
}
Bulletin.hideVisible();
if (Bulletin.getVisibleBulletin() == messageSeenPrivacyBulletin && messageSeenPrivacyBulletin != null) {
messageSeenPrivacyBulletin.hide();
messageSeenPrivacyBulletin = null;
}
scrimPopupWindow = null;
menuDeleteItem = null;
scrimPopupWindowItems = null;
@ -24183,7 +24211,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
} else {
saveMessageToGallery(selectedObject);
if (getParentActivity() != null) {
BulletinFactory.createSaveToGalleryBulletin(this, selectedObject.isVideo(), themeDelegate).show();
BulletinFactory.of(this).createDownloadBulletin(selectedObject.isVideo() ? BulletinFactory.FileType.VIDEO : BulletinFactory.FileType.PHOTO, themeDelegate).show();
}
}
break;
@ -24663,7 +24691,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
break;
}
case OPTION_VIEW_IN_TOPIC: {
int topicId = MessageObject.getTopicId(selectedObject.messageOwner);
int topicId = MessageObject.getTopicId(selectedObject.messageOwner, true);
if (topicId != 0) {
TLRPC.TL_forumTopic topic = getMessagesController().getTopicsController().findTopic(currentChat.id, topicId);
if (topic != null) {
@ -25227,19 +25255,25 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
public void sendAudio(ArrayList<MessageObject> audios, CharSequence caption, boolean notify, int scheduleDate) {
fillEditingMediaWithCaption(caption, null);
SendMessagesHelper.prepareSendingAudioDocuments(getAccountInstance(), audios, caption != null ? caption : null, dialog_id, replyingMessageObject, getThreadMessage(), editingMessageObject, notify, scheduleDate);
afterMessageSend();
if (checkSlowModeAlert()) {
fillEditingMediaWithCaption(caption, null);
SendMessagesHelper.prepareSendingAudioDocuments(getAccountInstance(), audios, caption != null ? caption : null, dialog_id, replyingMessageObject, getThreadMessage(), editingMessageObject, notify, scheduleDate);
afterMessageSend();
}
}
public void sendContact(TLRPC.User user, boolean notify, int scheduleDate) {
getSendMessagesHelper().sendMessage(user, dialog_id, replyingMessageObject, getThreadMessage(), null, null, notify, scheduleDate);
afterMessageSend();
if (checkSlowModeAlert()) {
getSendMessagesHelper().sendMessage(user, dialog_id, replyingMessageObject, getThreadMessage(), null, null, notify, scheduleDate);
afterMessageSend();
}
}
public void sendPoll(TLRPC.TL_messageMediaPoll poll, HashMap<String, String> params, boolean notify, int scheduleDate) {
getSendMessagesHelper().sendMessage(poll, dialog_id, replyingMessageObject, getThreadMessage(), null, params, notify, scheduleDate);
afterMessageSend();
if (checkSlowModeAlert()) {
getSendMessagesHelper().sendMessage(poll, dialog_id, replyingMessageObject, getThreadMessage(), null, params, notify, scheduleDate);
afterMessageSend();
}
}
public void sendMedia(MediaController.PhotoEntry photoEntry, VideoEditedInfo videoEditedInfo, boolean notify, int scheduleDate, boolean forceDocument) {
@ -25782,7 +25816,11 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
username = username.toLowerCase();
if (ChatObject.hasPublicLink(currentChat, username) ||
currentUser != null && !TextUtils.isEmpty(currentUser.username) && username.equals(currentUser.username.toLowerCase())) {
shakeContent();
if (avatarContainer != null) {
avatarContainer.openProfile(false);
} else {
shakeContent();
}
} else if (str.startsWith("@")) {
getMessagesController().openByUserName(username, ChatActivity.this, 0);
} else {
@ -26447,7 +26485,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
didPressInstantButton(cell, 10);
return;
}
openProfile(user);
openProfile(user, ChatObject.isForum(currentChat) || isThreadChat());
}
@Override
@ -26550,9 +26588,17 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
private void openProfile(TLRPC.User user) {
openProfile(user, false);
}
private void openProfile(TLRPC.User user, boolean expandPhoto) {
if (user != null && user.id != getUserConfig().getClientUserId()) {
if (user.photo == null || user.photo instanceof TLRPC.TL_userProfilePhotoEmpty) {
expandPhoto = false;
}
Bundle args = new Bundle();
args.putLong("user_id", user.id);
args.putBoolean("expandPhoto", expandPhoto);
ProfileActivity fragment = new ProfileActivity(args);
fragment.setPlayProfileAnimation(currentUser != null && currentUser.id == user.id ? 1 : 0);
AndroidUtilities.setAdjustResizeToNothing(getParentActivity(), classGuid);
@ -26561,9 +26607,14 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
private void openProfile(TLRPC.Chat chat) {
openProfile(chat, false);
}
private void openProfile(TLRPC.Chat chat, boolean expandPhoto) {
if (chat != null) {
Bundle args = new Bundle();
args.putLong("chat_id", chat.id);
args.putBoolean("expandPhoto", expandPhoto);
presentFragment(new ProfileActivity(args));
}
}
@ -26875,7 +26926,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
@Override
public boolean didPressAnimatedEmoji(AnimatedEmojiSpan span) {
public boolean didPressAnimatedEmoji(ChatMessageCell cell, AnimatedEmojiSpan span) {
if (getMessagesController().premiumLocked || span == null || span.standard) {
return false;
}
@ -26884,29 +26935,25 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (document == null) {
return false;
}
TLRPC.InputStickerSet inputStickerSet = MessageObject.getInputStickerSet(document);
if (inputStickerSet == null) {
return false;
}
TLRPC.TL_messages_stickerSet set = MediaDataController.getInstance(currentAccount).getStickerSet(inputStickerSet, false);
if (set == null || set.set == null) {
return false;
}
BulletinFactory.of(ChatActivity.this).createEmojiBulletin(document, AndroidUtilities.replaceTags(LocaleController.formatString("MessageContainsEmojiPackSingle", R.string.MessageContainsEmojiPackSingle, set.set.title)), LocaleController.getString("ViewAction", R.string.ViewAction), () -> {
Bulletin bulletin = BulletinFactory.of(ChatActivity.this).createContainsEmojiBulletin(document, false, set -> {
ArrayList<TLRPC.InputStickerSet> inputSets = new ArrayList<>(1);
inputSets.add(inputStickerSet);
inputSets.add(set);
EmojiPacksAlert alert = new EmojiPacksAlert(ChatActivity.this, getParentActivity(), themeDelegate, inputSets);
alert.setCalcMandatoryInsets(isKeyboardVisible());
showDialog(alert);
}).show();
return true;
});
if (bulletin != null) {
bulletin.show();
return true;
}
return false;
}
@Override
public void didPressTopicButton(ChatMessageCell cell) {
MessageObject message = cell.getMessageObject();
if (message != null) {
int topicId = MessageObject.getTopicId(message.messageOwner);
int topicId = MessageObject.getTopicId(message.messageOwner, true);
if (topicId != 0) {
TLRPC.TL_forumTopic topic = getMessagesController().getTopicsController().findTopic(currentChat.id, topicId);
if (topic != null) {
@ -26916,6 +26963,11 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
}
@Override
public boolean shouldShowTopicButton() {
return true;
}
@Override
public void didPressExtendedMediaPreview(ChatMessageCell cell, TLRPC.KeyboardButton button) {
getSendMessagesHelper().sendCallback(true, cell.getMessageObject(), button, ChatActivity.this);
@ -26988,7 +27040,11 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
return;
}
if (message.isDice()) {
undoView.showWithAction(0, chatActivityEnterView.getVisibility() == View.VISIBLE && bottomOverlay.getVisibility() != View.VISIBLE ? UndoView.ACTION_DICE_INFO : UndoView.ACTION_DICE_NO_SEND_INFO, message.getDiceEmoji(), null, () -> getSendMessagesHelper().sendMessage(message.getDiceEmoji(), dialog_id, replyingMessageObject, getThreadMessage(), null, false, null, null, null, true, 0, null, false));
undoView.showWithAction(0, chatActivityEnterView.getVisibility() == View.VISIBLE && bottomOverlay.getVisibility() != View.VISIBLE ? UndoView.ACTION_DICE_INFO : UndoView.ACTION_DICE_NO_SEND_INFO, message.getDiceEmoji(), null, () -> {
if (checkSlowModeAlert()) {
getSendMessagesHelper().sendMessage(message.getDiceEmoji(), dialog_id, replyingMessageObject, getThreadMessage(), null, false, null, null, null, true, 0, null, false);
}
});
} else if (message.isAnimatedEmoji() && (!message.isAnimatedAnimatedEmoji() || emojiAnimationsOverlay.supports(MessageObject.findAnimatedEmojiEmoticon(message.getDocument())) && currentUser != null) || message.isPremiumSticker()) {
restartSticker(cell);
emojiAnimationsOverlay.onTapItem(cell, ChatActivity.this, true);
@ -28225,18 +28281,19 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
} else {
if (privateMsgUrlPattern == null) {
privateMsgUrlPattern = Pattern.compile("(https://)?t.me/c/([0-9]+)/([0-9]+)");
privateMsgUrlPattern = Pattern.compile("(https://)?t.me/c/([0-9]+)/([0-9]+)/?([0-9]+)?");
}
Matcher matcher = privateMsgUrlPattern.matcher(urlFinal);
if (matcher.find(2) && matcher.find(3)) {
if (matcher.find(2) && matcher.find(3) && !matcher.find(4)) {
long channelId = Long.parseLong(matcher.group(2));
int messageId = Integer.parseInt(matcher.group(3));
if (channelId == currentChat.id && messageId != 0) {
Uri data = Uri.parse(urlFinal);
int threadId = Utilities.parseInt(data.getQueryParameter("thread"));
int topicId = Utilities.parseInt(data.getQueryParameter("topic"));
int commentId = Utilities.parseInt(data.getQueryParameter("comment"));
if (threadId != 0 || commentId != 0) {
if (threadId != 0 || topicId != 0 || commentId != 0) {
return false;
} else {
showScrollToMessageError = true;
@ -28868,9 +28925,6 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
themeDescriptions.add(new ThemeDescription(emptyView, ThemeDescription.FLAG_SERVICEBACKGROUND, null, null, null, null, Theme.key_chat_serviceBackground));
themeDescriptions.add(new ThemeDescription(bigEmptyView, ThemeDescription.FLAG_SERVICEBACKGROUND, null, null, null, null, Theme.key_chat_serviceBackground));
themeDescriptions.add(new ThemeDescription(chatListView, ThemeDescription.FLAG_SERVICEBACKGROUND, new Class[]{ChatLoadingCell.class}, new String[]{"textView"}, null, null, null, Theme.key_chat_serviceBackground));
themeDescriptions.add(new ThemeDescription(chatListView, ThemeDescription.FLAG_PROGRESSBAR, new Class[]{ChatLoadingCell.class}, new String[]{"textView"}, null, null, null, Theme.key_chat_serviceText));
if (mentionContainer != null) {
themeDescriptions.add(new ThemeDescription(mentionContainer.getListView(), ThemeDescription.FLAG_TEXTCOLOR, new Class[]{BotSwitchCell.class}, new String[]{"textView"}, null, null, null, Theme.key_chat_botSwitchToInlineText));
themeDescriptions.add(new ThemeDescription(mentionContainer.getListView(), ThemeDescription.FLAG_TEXTCOLOR, new Class[]{MentionCell.class}, new String[]{"nameTextView"}, null, null, null, Theme.key_windowBackgroundWhiteBlackText));

View File

@ -68,7 +68,6 @@ import org.telegram.ui.Cells.TextSettingsCell;
import org.telegram.ui.Components.AlertsCreator;
import org.telegram.ui.Components.AvatarDrawable;
import org.telegram.ui.Components.BackupImageView;
import org.telegram.ui.Components.Bulletin;
import org.telegram.ui.Components.BulletinFactory;
import org.telegram.ui.Components.CombinedDrawable;
import org.telegram.ui.Components.CubicBezierInterpolator;
@ -830,7 +829,9 @@ public class ChatEditActivity extends BaseFragment implements ImageUpdater.Image
settingsSectionCell.setBackground(combinedDrawable);
linearLayout1.addView(settingsSectionCell, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
if (forumsCell != null) {
settingsSectionCell.setText(LocaleController.getString(R.string.ForumToggleDescription));
settingsSectionCell.setText(LocaleController.getString("ForumToggleDescription", R.string.ForumToggleDescription));
} else {
settingsSectionCell.setText(LocaleController.getString("ChannelSignMessagesInfo", R.string.ChannelSignMessagesInfo));
}
}

View File

@ -490,7 +490,6 @@ public class ChatEditTypeActivity extends BaseFragment implements NotificationCe
public void onClick(@NonNull View view) {
Browser.openUrl(getContext(), "https://fragment.com/username/" + username);
}
@Override
public void updateDrawState(@NonNull TextPaint ds) {
super.updateDrawState(ds);
@ -507,6 +506,46 @@ public class ChatEditTypeActivity extends BaseFragment implements NotificationCe
}
super.setText(text);
}
ValueAnimator translateAnimator;
int prevHeight = -1;
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
if (prevHeight != -1 && linearLayout != null) {
ArrayList<View> viewsToTranslate = new ArrayList<>();
boolean passedMe = false;
for (int i = 0; i < linearLayout.getChildCount(); ++i) {
View child = linearLayout.getChildAt(i);
if (passedMe) {
viewsToTranslate.add(child);
} else if (child == this) {
passedMe = true;
}
}
float diff = prevHeight - getHeight();
if (translateAnimator != null) {
translateAnimator.cancel();
}
translateAnimator = ValueAnimator.ofFloat(0, 1);
translateAnimator.addUpdateListener(anm -> {
float t = 1f - (float) anm.getAnimatedValue();
for (int i = 0; i < viewsToTranslate.size(); ++i) {
View view = viewsToTranslate.get(i);
if (view != null) {
view.setTranslationY(diff * t);
}
}
});
translateAnimator.setInterpolator(CubicBezierInterpolator.EASE_OUT_QUINT);
translateAnimator.setDuration(350);
translateAnimator.start();
}
prevHeight = getHeight();
}
};
checkTextView.setBackgroundDrawable(Theme.getThemedDrawable(context, R.drawable.greydivider_bottom, Theme.key_windowBackgroundGrayShadow));
checkTextView.setBottomPadding(6);
@ -846,7 +885,7 @@ public class ChatEditTypeActivity extends BaseFragment implements NotificationCe
@Override
protected void onMeasure(int widthSpec, int heightSpec) {
super.onMeasure(widthSpec, MeasureSpec.makeMeasureSpec(999999999, MeasureSpec.AT_MOST));
super.onMeasure(widthSpec, MeasureSpec.makeMeasureSpec(9999999, MeasureSpec.AT_MOST));
}
public class TouchHelperCallback extends ItemTouchHelper.Callback {

View File

@ -59,6 +59,7 @@ import org.telegram.ui.Cells.LoadingCell;
import org.telegram.ui.Cells.ManageChatTextCell;
import org.telegram.ui.Cells.ManageChatUserCell;
import org.telegram.ui.Cells.ShadowSectionCell;
import org.telegram.ui.Cells.TextCell;
import org.telegram.ui.Cells.TextCheckCell2;
import org.telegram.ui.Cells.TextInfoPrivacyCell;
import org.telegram.ui.Cells.TextSettingsCell;
@ -124,6 +125,9 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
private int gigaInfoRow;
private int recentActionsRow;
private boolean antiSpamToggleLoading;
private int antiSpamRow;
private int antiSpamInfoRow;
private int addNewRow;
private int addNew2Row;
private int removedUsersRow;
@ -233,6 +237,8 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
return;
}
recentActionsRow = -1;
antiSpamRow = -1;
antiSpamInfoRow = -1;
addNewRow = -1;
addNew2Row = -1;
addNewSectionRow = -1;
@ -364,7 +370,12 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
} else if (type == TYPE_ADMIN) {
if (ChatObject.isChannel(currentChat) && currentChat.megagroup && !currentChat.gigagroup && (info == null || info.participants_count <= 200 || !isChannel && info.can_set_stickers)) {
recentActionsRow = rowCount++;
addNewSectionRow = rowCount++;
if (ChatObject.hasAdminRights(currentChat)) {
antiSpamRow = rowCount++;
antiSpamInfoRow = rowCount++;
} else {
addNewSectionRow = rowCount++;
}
}
if (ChatObject.canAddAdmins(currentChat)) {
@ -839,6 +850,36 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
} else if (position == recentActionsRow) {
presentFragment(new ChannelAdminLogActivity(currentChat));
return;
} else if (position == antiSpamRow) {
final TextCell textCell = (TextCell) view;
if (info != null && !info.antispam && info.participants_count < getMessagesController().telegramAntispamGroupSizeMin) {
BulletinFactory.of(this).createSimpleBulletin(R.raw.msg_antispam, AndroidUtilities.replaceTags(LocaleController.formatPluralString("ChannelAntiSpamForbidden", getMessagesController().telegramAntispamGroupSizeMin))).show();
} else if (info != null && ChatObject.canUserDoAdminAction(currentChat, ChatObject.ACTION_DELETE_MESSAGES) && !antiSpamToggleLoading) {
antiSpamToggleLoading = true;
boolean wasAntispam = info.antispam;
TLRPC.TL_channels_toggleAntiSpam req = new TLRPC.TL_channels_toggleAntiSpam();
req.channel = getMessagesController().getInputChannel(chatId);
textCell.setChecked(req.enabled = (info.antispam = !info.antispam));
textCell.getCheckBox().setIcon(ChatObject.canUserDoAdminAction(currentChat, ChatObject.ACTION_DELETE_MESSAGES) && (info == null || info.antispam || info.participants_count >= getMessagesController().telegramAntispamGroupSizeMin) ? 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 && !"".equals(err.text)) {
AndroidUtilities.runOnUIThread(() -> {
if (getParentActivity() == null) {
return;
}
textCell.setChecked(info.antispam = wasAntispam);
textCell.getCheckBox().setIcon(ChatObject.canUserDoAdminAction(currentChat, ChatObject.ACTION_DELETE_MESSAGES) && (info == null || !info.antispam || info.participants_count >= getMessagesController().telegramAntispamGroupSizeMin) ? 0 : R.drawable.permission_locked);
BulletinFactory.of(ChatUsersActivity.this).createSimpleBulletin(R.raw.error, LocaleController.getString("UnknownError", R.string.UnknownError)).show();
});
}
antiSpamToggleLoading = false;
});
}
return;
} else if (position == removedUsersRow) {
Bundle args = new Bundle();
args.putLong("chat_id", chatId);
@ -2551,7 +2592,7 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
} else {
searchInProgress = false;
}
searchAdapterHelper.queryServerSearch(query, selectType != SELECT_TYPE_MEMBERS, false, true, false, false, ChatObject.isChannel(currentChat) ? chatId : 0, false, type, 1, addContacts);
searchAdapterHelper.queryServerSearch(query, selectType != SELECT_TYPE_MEMBERS, false, true, false, false, ChatObject.isChannel(currentChat) ? chatId : 0, false, type, 1, 0, addContacts);
});
}
@ -2869,7 +2910,7 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
}
return true;
}
return viewType == 0 || viewType == 2 || viewType == 6;
return viewType == 0 || viewType == 2 || viewType == 6 || viewType == 12 && ChatObject.canUserDoAdminAction(currentChat, ChatObject.ACTION_DELETE_MESSAGES);
}
@Override
@ -2944,6 +2985,12 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
flickerLoadingView.setLayoutParams(new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
view = flickerLoadingView;
break;
case 12:
TextCell textCell = new TextCell(mContext, 23, false, true, getResourceProvider());
textCell.heightDp = 50;
textCell.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite));
view = textCell;
break;
case 9:
default:
SlideChooseView chooseView = new SlideChooseView(mContext);
@ -3068,7 +3115,10 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
break;
case 1:
TextInfoPrivacyCell privacyCell = (TextInfoPrivacyCell) holder.itemView;
if (position == participantsInfoRow) {
if (position == antiSpamInfoRow) {
privacyCell.setText(LocaleController.getString("ChannelAntiSpamInfo", R.string.ChannelAntiSpamInfo));
privacyCell.setBackgroundDrawable(Theme.getThemedDrawable(mContext, R.drawable.greydivider, Theme.key_windowBackgroundGrayShadow));
} else if (position == participantsInfoRow) {
if (type == TYPE_BANNED || type == TYPE_KICKED) {
if (isChannel) {
privacyCell.setText(LocaleController.getString("NoBlockedChannel2", R.string.NoBlockedChannel2));
@ -3130,7 +3180,7 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
}
}
} else if (position == recentActionsRow) {
actionCell.setText(LocaleController.getString("EventLog", R.string.EventLog), null, R.drawable.msg_log, false);
actionCell.setText(LocaleController.getString("EventLog", R.string.EventLog), null, R.drawable.msg_log, antiSpamRow > recentActionsRow);
} else if (position == addNew2Row) {
actionCell.setColors(Theme.key_windowBackgroundWhiteBlueIcon, Theme.key_windowBackgroundWhiteBlueButton);
boolean showDivider = !(loadingUsers && !firstLoaded) && membersHeaderRow == -1 && !participants.isEmpty();
@ -3241,6 +3291,13 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
flickerLoadingView.setItemsCount(1);
}
break;
case 12:
TextCell textCell = (TextCell) holder.itemView;
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);
}
break;
}
}
@ -3263,7 +3320,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) {
} else if (position == participantsInfoRow || position == slowmodeInfoRow || position == gigaInfoRow || position == antiSpamInfoRow) {
return 1;
} else if (position == blockedEmptyRow) {
return 4;
@ -3280,6 +3337,8 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
return 10;
} else if (position == loadingUserCellRow) {
return 11;
} else if (position == antiSpamRow) {
return 12;
}
return 0;
}

View File

@ -21,6 +21,10 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import androidx.collection.LongSparseArray;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MessageObject;
@ -29,18 +33,14 @@ import org.telegram.messenger.R;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.BottomSheet;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Cells.CheckBoxCell;
import org.telegram.ui.Cells.CheckBoxUserCell;
import org.telegram.ui.Cells.ShadowSectionCell;
import org.telegram.ui.Cells.TextCell;
import org.telegram.ui.ContentPreviewViewer;
import java.util.ArrayList;
import java.util.regex.Pattern;
import androidx.collection.LongSparseArray;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
public class AdminLogFilterAlert extends BottomSheet {
public interface AdminLogFilterAlertDelegate {
@ -222,10 +222,10 @@ public class AdminLogFilterAlert extends BottomSheet {
}
});
listView.setOnItemClickListener((view, position) -> {
if (view instanceof CheckBoxCell) {
CheckBoxCell cell = (CheckBoxCell) view;
if (view instanceof TextCell) {
TextCell cell = (TextCell) view;
boolean isChecked = cell.isChecked();
cell.setChecked(!isChecked, true);
cell.setChecked(!isChecked);
if (position == 0) {
if (isChecked) {
currentFilter = new TLRPC.TL_channelAdminLogEventsFilter();
@ -242,7 +242,7 @@ public class AdminLogFilterAlert extends BottomSheet {
RecyclerView.ViewHolder holder = listView.findContainingViewHolder(child);
int pos = holder.getAdapterPosition();
if (holder.getItemViewType() == 0 && pos > 0 && pos < allAdminsRow - 1) {
((CheckBoxCell) child).setChecked(!isChecked, true);
((TextCell) child).setChecked(!isChecked);
}
}
} else if (position == allAdminsRow) {
@ -268,10 +268,6 @@ public class AdminLogFilterAlert extends BottomSheet {
currentFilter.unban = currentFilter.kick = currentFilter.unkick = currentFilter.promote =
currentFilter.demote = currentFilter.info = currentFilter.settings = currentFilter.pinned =
currentFilter.edit = currentFilter.delete = currentFilter.group_call = currentFilter.invites = true;
RecyclerView.ViewHolder holder = listView.findViewHolderForAdapterPosition(0);
if (holder != null) {
((CheckBoxCell) holder.itemView).setChecked(false, true);
}
}
if (position == restrictionsRow) {
currentFilter.kick = currentFilter.ban = currentFilter.unkick = currentFilter.unban = !currentFilter.kick;
@ -294,6 +290,16 @@ public class AdminLogFilterAlert extends BottomSheet {
} else if (position == invitesRow) {
currentFilter.invites = !currentFilter.invites;
}
RecyclerView.ViewHolder holder = listView.findViewHolderForAdapterPosition(0);
if (holder != null) {
boolean isAllChecked = (
currentFilter.join && currentFilter.leave && currentFilter.invite && currentFilter.ban &&
currentFilter.unban && currentFilter.kick && currentFilter.unkick && currentFilter.promote &&
currentFilter.demote && currentFilter.info && currentFilter.settings && currentFilter.pinned &&
currentFilter.edit && currentFilter.delete && currentFilter.group_call && currentFilter.invites
);
((TextCell) holder.itemView).setChecked(isAllChecked);
}
}
if (currentFilter != null &&
!currentFilter.join && !currentFilter.leave && !currentFilter.invite && !currentFilter.ban &&
@ -312,7 +318,7 @@ public class AdminLogFilterAlert extends BottomSheet {
selectedAdmins = new LongSparseArray<>();
RecyclerView.ViewHolder holder = listView.findViewHolderForAdapterPosition(allAdminsRow);
if (holder != null) {
((CheckBoxCell) holder.itemView).setChecked(false, true);
((TextCell) holder.itemView).setChecked(false);
}
for (int a = 0; a < currentAdmins.size(); a++) {
TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(MessageObject.getPeerId(currentAdmins.get(a).peer));
@ -415,7 +421,7 @@ public class AdminLogFilterAlert extends BottomSheet {
FrameLayout view = null;
switch (viewType) {
case 0:
view = new CheckBoxCell(context, 1, 21, resourcesProvider);
view = new TextCell(context, 23, false, true, resourcesProvider);
break;
case 1:
ShadowSectionCell shadowSectionCell = new ShadowSectionCell(context, 18);
@ -435,35 +441,6 @@ public class AdminLogFilterAlert extends BottomSheet {
public void onViewAttachedToWindow(RecyclerView.ViewHolder holder) {
int position = holder.getAdapterPosition();
switch (holder.getItemViewType()) {
case 0: {
CheckBoxCell cell = (CheckBoxCell) holder.itemView;
if (position == 0) {
cell.setChecked(currentFilter == null, false);
} else if (position == restrictionsRow) {
cell.setChecked(currentFilter == null || currentFilter.kick && currentFilter.ban && currentFilter.unkick && currentFilter.unban, false);
} else if (position == adminsRow) {
cell.setChecked(currentFilter == null || currentFilter.promote && currentFilter.demote, false);
} else if (position == membersRow) {
cell.setChecked(currentFilter == null || currentFilter.invite && currentFilter.join, false);
} else if (position == infoRow) {
cell.setChecked(currentFilter == null || currentFilter.info, false);
} else if (position == deleteRow) {
cell.setChecked(currentFilter == null || currentFilter.delete, false);
} else if (position == editRow) {
cell.setChecked(currentFilter == null || currentFilter.edit, false);
} else if (position == pinnedRow) {
cell.setChecked(currentFilter == null || currentFilter.pinned, false);
} else if (position == leavingRow) {
cell.setChecked(currentFilter == null || currentFilter.leave, false);
} else if (position == callsRow) {
cell.setChecked(currentFilter == null || currentFilter.group_call, false);
} else if (position == invitesRow) {
cell.setChecked(currentFilter == null || currentFilter.invites, false);
} else if (position == allAdminsRow) {
cell.setChecked(selectedAdmins == null, false);
}
break;
}
case 2: {
CheckBoxUserCell userCell = (CheckBoxUserCell) holder.itemView;
long userId = MessageObject.getPeerId(currentAdmins.get(position - allAdminsRow - 1).peer);
@ -477,35 +454,35 @@ public class AdminLogFilterAlert extends BottomSheet {
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
switch (holder.getItemViewType()) {
case 0: {
CheckBoxCell cell = (CheckBoxCell) holder.itemView;
TextCell cell = (TextCell) holder.itemView;
if (position == 0) {
cell.setText(LocaleController.getString("EventLogFilterAll", R.string.EventLogFilterAll), "", currentFilter == null, true);
cell.setTextAndCheck(LocaleController.getString("EventLogFilterAll", R.string.EventLogFilterAll), currentFilter == null, true);
} else if (position == restrictionsRow) {
cell.setText(LocaleController.getString("EventLogFilterNewRestrictions", R.string.EventLogFilterNewRestrictions), "", currentFilter == null || currentFilter.kick && currentFilter.ban && currentFilter.unkick && currentFilter.unban, true);
cell.setTextAndCheck(LocaleController.getString("EventLogFilterNewRestrictions", R.string.EventLogFilterNewRestrictions), currentFilter == null || currentFilter.kick && currentFilter.ban && currentFilter.unkick && currentFilter.unban, true);
} else if (position == adminsRow) {
cell.setText(LocaleController.getString("EventLogFilterNewAdmins", R.string.EventLogFilterNewAdmins), "", currentFilter == null || currentFilter.promote && currentFilter.demote, true);
cell.setTextAndCheck(LocaleController.getString("EventLogFilterNewAdmins", R.string.EventLogFilterNewAdmins), currentFilter == null || currentFilter.promote && currentFilter.demote, true);
} else if (position == membersRow) {
cell.setText(LocaleController.getString("EventLogFilterNewMembers", R.string.EventLogFilterNewMembers), "", currentFilter == null || currentFilter.invite && currentFilter.join, true);
cell.setTextAndCheck(LocaleController.getString("EventLogFilterNewMembers", R.string.EventLogFilterNewMembers), currentFilter == null || currentFilter.invite && currentFilter.join, true);
} else if (position == infoRow) {
if (isMegagroup) {
cell.setText(LocaleController.getString("EventLogFilterGroupInfo", R.string.EventLogFilterGroupInfo), "", currentFilter == null || currentFilter.info, true);
cell.setTextAndCheck(LocaleController.getString("EventLogFilterGroupInfo", R.string.EventLogFilterGroupInfo), currentFilter == null || currentFilter.info, true);
} else {
cell.setText(LocaleController.getString("EventLogFilterChannelInfo", R.string.EventLogFilterChannelInfo), "", currentFilter == null || currentFilter.info, true);
cell.setTextAndCheck(LocaleController.getString("EventLogFilterChannelInfo", R.string.EventLogFilterChannelInfo), currentFilter == null || currentFilter.info, true);
}
} else if (position == deleteRow) {
cell.setText(LocaleController.getString("EventLogFilterDeletedMessages", R.string.EventLogFilterDeletedMessages), "", currentFilter == null || currentFilter.delete, true);
cell.setTextAndCheck(LocaleController.getString("EventLogFilterDeletedMessages", R.string.EventLogFilterDeletedMessages), currentFilter == null || currentFilter.delete, true);
} else if (position == editRow) {
cell.setText(LocaleController.getString("EventLogFilterEditedMessages", R.string.EventLogFilterEditedMessages), "", currentFilter == null || currentFilter.edit, true);
cell.setTextAndCheck(LocaleController.getString("EventLogFilterEditedMessages", R.string.EventLogFilterEditedMessages), currentFilter == null || currentFilter.edit, true);
} else if (position == pinnedRow) {
cell.setText(LocaleController.getString("EventLogFilterPinnedMessages", R.string.EventLogFilterPinnedMessages), "", currentFilter == null || currentFilter.pinned, true);
cell.setTextAndCheck(LocaleController.getString("EventLogFilterPinnedMessages", R.string.EventLogFilterPinnedMessages), currentFilter == null || currentFilter.pinned, true);
} else if (position == leavingRow) {
cell.setText(LocaleController.getString("EventLogFilterLeavingMembers", R.string.EventLogFilterLeavingMembers), "", currentFilter == null || currentFilter.leave, callsRow != -1);
cell.setTextAndCheck(LocaleController.getString("EventLogFilterLeavingMembers", R.string.EventLogFilterLeavingMembers), currentFilter == null || currentFilter.leave, callsRow != -1);
} else if (position == callsRow) {
cell.setText(LocaleController.getString("EventLogFilterCalls", R.string.EventLogFilterCalls), "", currentFilter == null || currentFilter.group_call, false);
cell.setTextAndCheck(LocaleController.getString("EventLogFilterCalls", R.string.EventLogFilterCalls), currentFilter == null || currentFilter.group_call, false);
} else if (position == invitesRow) {
cell.setText(LocaleController.getString("EventLogFilterInvites", R.string.EventLogFilterInvites), "", currentFilter == null || currentFilter.invites, true);
cell.setTextAndCheck(LocaleController.getString("EventLogFilterInvites", R.string.EventLogFilterInvites), currentFilter == null || currentFilter.invites, true);
} else if (position == allAdminsRow) {
cell.setText(LocaleController.getString("EventLogAllAdmins", R.string.EventLogAllAdmins), "", selectedAdmins == null, true);
cell.setTextAndCheck(LocaleController.getString("EventLogAllAdmins", R.string.EventLogAllAdmins), selectedAdmins == null, true);
}
break;
}

View File

@ -49,7 +49,6 @@ import android.view.HapticFeedbackConstants;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewOutlineProvider;
import android.view.WindowManager;
import android.view.inputmethod.EditorInfo;
@ -1033,6 +1032,7 @@ public class AlertsCreator {
cell.setTag(a);
cell.setCheckColor(Theme.getColor(Theme.key_radioBackground), Theme.getColor(Theme.key_dialogRadioBackgroundChecked));
cell.setTextAndValue(arrayList.get(a), SharedConfig.mapPreviewType == types.get(a));
cell.setBackground(Theme.createSelectorDrawable(Theme.getColor(Theme.key_listSelector), Theme.RIPPLE_MASK_ALL));
linearLayout.addView(cell);
cell.setOnClickListener(v -> {
Integer which = (Integer) v.getTag();
@ -1065,26 +1065,19 @@ public class AlertsCreator {
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
int year, month;
int currentYear = calendar.get(Calendar.YEAR);
int currentMonth = calendar.get(Calendar.MONTH);
int currentDay = calendar.get(Calendar.DAY_OF_MONTH);
if (currentYear > yearPicker.getValue()) {
yearPicker.setValue(currentYear);
//yearPicker.finishScroll();
}
if (yearPicker.getValue() == currentYear) {
if (currentMonth > monthPicker.getValue()) {
monthPicker.setValue(currentMonth);
//monthPicker.finishScroll();
}
if (currentMonth == monthPicker.getValue()) {
if (currentDay > dayPicker.getValue()) {
dayPicker.setValue(currentDay);
//dayPicker.finishScroll();
}
}
}
yearPicker.setMinValue(currentYear);
year = yearPicker.getValue();
monthPicker.setMinValue(year == currentYear ? currentMonth : 0);
month = monthPicker.getValue();
dayPicker.setMinValue(year == currentYear && month == currentMonth ? currentDay : 1);
}
public static void showOpenUrlAlert(BaseFragment fragment, String url, boolean punycode, boolean ask) {
@ -1136,7 +1129,7 @@ public class AlertsCreator {
if (fragment == null || fragment.getParentActivity() == null) {
return null;
}
final TextView message = new TextView(fragment.getParentActivity());
final LinkSpanDrawable.LinksTextView message = new LinkSpanDrawable.LinksTextView(fragment.getParentActivity(), fragment.getResourceProvider());
Spannable spanned = new SpannableString(Html.fromHtml(LocaleController.getString("AskAQuestionInfo", R.string.AskAQuestionInfo).replace("\n", "<br>")));
URLSpan[] spans = spanned.getSpans(0, spanned.length(), URLSpan.class);
for (int i = 0; i < spans.length; i++) {
@ -1284,15 +1277,15 @@ public class AlertsCreator {
if (user != null) {
if (UserObject.isReplyUser(user)) {
avatarDrawable.setSmallSize(true);
avatarDrawable.setScaleSize(.8f);
avatarDrawable.setAvatarType(AvatarDrawable.AVATAR_TYPE_REPLIES);
imageView.setImage(null, null, avatarDrawable, user);
} else if (user.id == selfUserId) {
avatarDrawable.setSmallSize(true);
avatarDrawable.setScaleSize(.8f);
avatarDrawable.setAvatarType(AvatarDrawable.AVATAR_TYPE_SAVED);
imageView.setImage(null, null, avatarDrawable, user);
} else {
avatarDrawable.setSmallSize(false);
avatarDrawable.setScaleSize(1f);
avatarDrawable.setInfo(user);
imageView.setForUserOrChat(user, avatarDrawable);
}
@ -1462,15 +1455,15 @@ public class AlertsCreator {
if (user != null) {
if (UserObject.isReplyUser(user)) {
avatarDrawable.setSmallSize(true);
avatarDrawable.setScaleSize(.8f);
avatarDrawable.setAvatarType(AvatarDrawable.AVATAR_TYPE_REPLIES);
imageView.setImage(null, null, avatarDrawable, user);
} else if (user.id == selfUserId) {
avatarDrawable.setSmallSize(true);
avatarDrawable.setScaleSize(.8f);
avatarDrawable.setAvatarType(AvatarDrawable.AVATAR_TYPE_SAVED);
imageView.setImage(null, null, avatarDrawable, user);
} else {
avatarDrawable.setSmallSize(false);
avatarDrawable.setScaleSize(1f);
avatarDrawable.setInfo(user);
imageView.setForUserOrChat(user, avatarDrawable);
}
@ -1745,7 +1738,7 @@ public class AlertsCreator {
AvatarDrawable avatarDrawable = new AvatarDrawable();
avatarDrawable.setTextSize(AndroidUtilities.dp(12));
avatarDrawable.setSmallSize(false);
avatarDrawable.setScaleSize(1f);
avatarDrawable.setInfo(user);
BackupImageView imageView = new BackupImageView(context);
@ -2276,34 +2269,50 @@ public class AlertsCreator {
calendar.setTimeInMillis(systemTime);
int currentYear = calendar.get(Calendar.YEAR);
int currentDay = calendar.get(Calendar.DAY_OF_YEAR);
int maxDay = 0, maxHour = 0, maxMinute = 0;
if (maxDate > 0) {
maxDate *= 1000;
calendar.setTimeInMillis(systemTime + maxDate);
calendar.set(Calendar.HOUR_OF_DAY, 23);
calendar.set(Calendar.MINUTE, 59);
calendar.set(Calendar.HOUR_OF_DAY, maxHour = 23);
calendar.set(Calendar.MINUTE, maxMinute = 59);
calendar.set(Calendar.SECOND, 59);
maxDay = 7; // ???
maxDate = calendar.getTimeInMillis();
}
calendar.setTimeInMillis(systemTime + 60000L);
int minDay = 1;
int minHour = calendar.get(Calendar.HOUR_OF_DAY);
int minMinute = calendar.get(Calendar.MINUTE);
calendar.setTimeInMillis(System.currentTimeMillis() + (long) day * 24 * 3600 * 1000);
calendar.set(Calendar.HOUR_OF_DAY, hour);
calendar.set(Calendar.MINUTE, minute);
long currentTime = calendar.getTimeInMillis();
calendar.setTimeInMillis(currentTime);
dayPicker.setMinValue(0);
if (maxDate > 0) {
dayPicker.setMaxValue(maxDay);
}
day = dayPicker.getValue();
hourPicker.setMinValue(day == 0 ? minHour : 0);
if (maxDate > 0) {
hourPicker.setMaxValue(day == maxDay ? maxHour : 23);
}
hour = hourPicker.getValue();
minutePicker.setMinValue(day == 0 && hour == minHour ? minMinute : 0);
if (maxDate > 0) {
minutePicker.setMaxValue(day == maxDay && hour == maxHour ? maxMinute : 59);
}
minute = minutePicker.getValue();
if (currentTime <= systemTime + 60000L) {
calendar.setTimeInMillis(systemTime + 60000L);
if (currentDay != calendar.get(Calendar.DAY_OF_YEAR)) {
dayPicker.setValue(day = 1);
}
hourPicker.setValue(hour = calendar.get(Calendar.HOUR_OF_DAY));
minutePicker.setValue(minute = calendar.get(Calendar.MINUTE));
} else if (maxDate > 0 && currentTime > maxDate) {
calendar.setTimeInMillis(maxDate);
dayPicker.setValue(day = 7);
hourPicker.setValue(hour = calendar.get(Calendar.HOUR_OF_DAY));
minutePicker.setValue(minute = calendar.get(Calendar.MINUTE));
}
int selectedYear = calendar.get(Calendar.YEAR);
@ -3019,7 +3028,7 @@ public class AlertsCreator {
return builder;
}
public static BottomSheet.Builder createAutoDeleteDatePickerDialog(Context context, Theme.ResourcesProvider resourcesProvider, final ScheduleDatePickerDelegate datePickerDelegate) {
public static BottomSheet.Builder createAutoDeleteDatePickerDialog(Context context, int type, Theme.ResourcesProvider resourcesProvider, final ScheduleDatePickerDelegate datePickerDelegate) {
if (context == null) {
return null;
}
@ -3128,7 +3137,7 @@ public class AlertsCreator {
linearLayout.setWeightSum(1.0f);
container.addView(linearLayout, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, 1f, 0, 0, 12, 0, 12));
TextView buttonTextView = new TextView(context) {
AnimatedTextView buttonTextView = new AnimatedTextView(context, true, true, false) {
@Override
public CharSequence getAccessibilityClassName() {
return Button.class.getName();
@ -3137,17 +3146,22 @@ public class AlertsCreator {
linearLayout.addView(numberPicker, LayoutHelper.createLinear(0, 54 * 5, 1f));
buttonTextView.setPadding(AndroidUtilities.dp(34), 0, AndroidUtilities.dp(34), 0);
buttonTextView.setPadding(0, 0, 0, 0);
buttonTextView.setGravity(Gravity.CENTER);
buttonTextView.setTextColor(datePickerColors.buttonTextColor);
buttonTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
buttonTextView.setTextSize(AndroidUtilities.dp(14));
buttonTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
buttonTextView.setBackgroundDrawable(Theme.createSimpleSelectorRoundRectDrawable(AndroidUtilities.dp(4), datePickerColors.buttonBackgroundColor, datePickerColors.buttonBackgroundPressedColor));
buttonTextView.setText(LocaleController.getString("AutoDeleteConfirm", R.string.AutoDeleteConfirm));
container.addView(buttonTextView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 48, Gravity.LEFT | Gravity.BOTTOM, 16, 15, 16, 16));
buttonTextView.setText(LocaleController.getString("DisableAutoDeleteTimer", R.string.DisableAutoDeleteTimer));
final NumberPicker.OnValueChangeListener onValueChangeListener = (picker, oldVal, newVal) -> {
try {
if (newVal == 0) {
buttonTextView.setText(LocaleController.getString("DisableAutoDeleteTimer", R.string.DisableAutoDeleteTimer));
} else {
buttonTextView.setText(LocaleController.getString("SetAutoDeleteTimer", R.string.SetAutoDeleteTimer));
}
container.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
} catch (Exception ignore) {
@ -3503,9 +3517,7 @@ public class AlertsCreator {
}
private static void checkCalendarDate(long minDate, NumberPicker dayPicker, NumberPicker monthPicker, NumberPicker yearPicker) {
int day = dayPicker.getValue();
int month = monthPicker.getValue();
int year = yearPicker.getValue();
int month, year;
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(minDate);
@ -3517,43 +3529,20 @@ public class AlertsCreator {
int maxMonth = calendar.get(Calendar.MONTH);
int maxDay = calendar.get(Calendar.DAY_OF_MONTH);
if (year > maxYear) {
yearPicker.setValue(year = maxYear);
}
if (year == maxYear) {
if (month > maxMonth) {
monthPicker.setValue(month = maxMonth);
}
if (month == maxMonth) {
if (day > maxDay) {
dayPicker.setValue(day = maxDay);
}
}
}
yearPicker.setMaxValue(maxYear);
yearPicker.setMinValue(minYear);
year = yearPicker.getValue();
if (year < minYear) {
yearPicker.setValue(year = minYear);
}
if (year == minYear) {
if (month < minMonth) {
monthPicker.setValue(month = minMonth);
}
if (month == minMonth) {
if (day < minDay) {
dayPicker.setValue(day = minDay);
}
}
}
monthPicker.setMaxValue(year == maxYear ? maxMonth : 11);
monthPicker.setMinValue(year == minYear ? minMonth : 0);
month = monthPicker.getValue();
calendar.set(Calendar.YEAR, year);
calendar.set(Calendar.MONTH, month);
int daysInMonth = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
dayPicker.setMaxValue(daysInMonth);
if (day > daysInMonth) {
day = daysInMonth;
dayPicker.setValue(day);
}
dayPicker.setMaxValue(year == maxYear && month == maxMonth ? Math.min(maxDay, daysInMonth) : daysInMonth);
dayPicker.setMinValue(year == minYear && month == minMonth ? minDay : 1);
}
public static BottomSheet.Builder createCalendarPickerDialog(Context context, long minDate, final MessagesStorage.IntCallback callback, Theme.ResourcesProvider resourcesProvider) {
@ -3653,39 +3642,17 @@ public class AlertsCreator {
linearLayout.addView(monthPicker, LayoutHelper.createLinear(0, 54 * 5, 0.5f));
monthPicker.setFormatter(value -> {
switch (value) {
case 0: {
return LocaleController.getString("January", R.string.January);
}
case 1: {
return LocaleController.getString("February", R.string.February);
}
case 2: {
return LocaleController.getString("March", R.string.March);
}
case 3: {
return LocaleController.getString("April", R.string.April);
}
case 4: {
return LocaleController.getString("May", R.string.May);
}
case 5: {
return LocaleController.getString("June", R.string.June);
}
case 6: {
return LocaleController.getString("July", R.string.July);
}
case 7: {
return LocaleController.getString("August", R.string.August);
}
case 8: {
return LocaleController.getString("September", R.string.September);
}
case 9: {
return LocaleController.getString("October", R.string.October);
}
case 10: {
return LocaleController.getString("November", R.string.November);
}
case 0: return LocaleController.getString("January", R.string.January);
case 1: return LocaleController.getString("February", R.string.February);
case 2: return LocaleController.getString("March", R.string.March);
case 3: return LocaleController.getString("April", R.string.April);
case 4: return LocaleController.getString("May", R.string.May);
case 5: return LocaleController.getString("June", R.string.June);
case 6: return LocaleController.getString("July", R.string.July);
case 7: return LocaleController.getString("August", R.string.August);
case 8: return LocaleController.getString("September", R.string.September);
case 9: return LocaleController.getString("October", R.string.October);
case 10: return LocaleController.getString("November", R.string.November);
case 11:
default: {
return LocaleController.getString("December", R.string.December);

View File

@ -0,0 +1,75 @@
package org.telegram.ui.Components;
import android.content.Context;
import android.os.Build;
import android.view.Gravity;
import android.widget.FrameLayout;
import androidx.annotation.NonNull;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.ui.ActionBar.ActionBar;
import org.telegram.ui.ActionBar.Theme;
public class AnimatedAvatarContainer extends FrameLayout {
boolean occupyStatusBar = true;
private int leftPadding = AndroidUtilities.dp(8);
AnimatedTextView titleTextView;
AnimatedTextView subtitleTextView;
public AnimatedAvatarContainer(@NonNull Context context) {
super(context);
titleTextView = new AnimatedTextView(context, true, true, true);
titleTextView.setTextColor(Theme.getColor(Theme.key_actionBarDefaultTitle));
titleTextView.setTextSize(AndroidUtilities.dp(18));
titleTextView.setGravity(Gravity.LEFT);
titleTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
titleTextView.setPadding(0, AndroidUtilities.dp(6), 0, AndroidUtilities.dp(12));
addView(titleTextView);
subtitleTextView = new AnimatedTextView(context, true, true, true);
subtitleTextView.setTag(Theme.key_actionBarDefaultSubtitle);
subtitleTextView.setTextColor(Theme.getColor(Theme.key_actionBarDefaultTitle));
subtitleTextView.setTextSize(AndroidUtilities.dp(14));
subtitleTextView.setGravity(Gravity.LEFT);
subtitleTextView.setPadding(0, 0, AndroidUtilities.dp(10), 0);
addView(subtitleTextView);
titleTextView.getDrawable().setAllowCancel(true);
subtitleTextView.getDrawable().setAllowCancel(true);
titleTextView.setAnimationProperties(1f, 0, 150, CubicBezierInterpolator.DEFAULT);
subtitleTextView.setAnimationProperties(1f, 0, 150, CubicBezierInterpolator.DEFAULT);
setClipChildren(false);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = MeasureSpec.getSize(widthMeasureSpec) + titleTextView.getPaddingRight();
int availableWidth = width - AndroidUtilities.dp( 16);
titleTextView.measure(MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(24 + 8) + titleTextView.getPaddingRight(), MeasureSpec.AT_MOST));
subtitleTextView.measure(MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(20), MeasureSpec.AT_MOST));
setMeasuredDimension(width, MeasureSpec.getSize(heightMeasureSpec));
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
int actionBarHeight = ActionBar.getCurrentActionBarHeight();
int viewTop = (actionBarHeight - AndroidUtilities.dp(42)) / 2 + (Build.VERSION.SDK_INT >= 21 && occupyStatusBar ? AndroidUtilities.statusBarHeight : 0);
int l = leftPadding;
if (subtitleTextView.getVisibility() != GONE) {
titleTextView.layout(l, viewTop + AndroidUtilities.dp(1f) - titleTextView.getPaddingTop(), l + titleTextView.getMeasuredWidth(), viewTop + titleTextView.getTextHeight() + AndroidUtilities.dp(1.3f) - titleTextView.getPaddingTop() + titleTextView.getPaddingBottom());
} else {
titleTextView.layout(l, viewTop + AndroidUtilities.dp(11) - titleTextView.getPaddingTop(), l + titleTextView.getMeasuredWidth(), viewTop + titleTextView.getTextHeight() + AndroidUtilities.dp(11) - titleTextView.getPaddingTop() + titleTextView.getPaddingBottom());
}
subtitleTextView.layout(l, viewTop + AndroidUtilities.dp(20), l + subtitleTextView.getMeasuredWidth(), viewTop + subtitleTextView.getTextHeight() + AndroidUtilities.dp(24));
}
public AnimatedTextView getTitle() {
return titleTextView;
}
public AnimatedTextView getSubtitleTextView() {
return subtitleTextView;
}
}

View File

@ -1,5 +1,6 @@
package org.telegram.ui.Components;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Paint;
@ -12,6 +13,7 @@ import android.text.style.CharacterStyle;
import android.text.style.ReplacementSpan;
import android.util.LongSparseArray;
import android.view.View;
import android.widget.TextView;
import androidx.annotation.NonNull;
@ -831,6 +833,43 @@ public class AnimatedEmojiSpan extends ReplacementSpan {
return newText;
}
public static class TextViewEmojis extends TextView {
public TextViewEmojis(Context context) {
super(context);
}
AnimatedEmojiSpan.EmojiGroupedSpans stack;
@Override
public void setText(CharSequence text, TextView.BufferType type) {
super.setText(text, type);
stack = AnimatedEmojiSpan.update(AnimatedEmojiDrawable.CACHE_TYPE_MESSAGES, this, stack, getLayout());
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
stack = AnimatedEmojiSpan.update(AnimatedEmojiDrawable.CACHE_TYPE_MESSAGES, this, stack, getLayout());
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
stack = AnimatedEmojiSpan.update(AnimatedEmojiDrawable.CACHE_TYPE_MESSAGES, this, stack, getLayout());
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
AnimatedEmojiSpan.release(this, stack);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
AnimatedEmojiSpan.drawAnimatedEmojis(canvas, getLayout(), stack, 0, null, 0, 0, 0, 1f);
}
}
public interface InvalidateHolder {
void invalidate();
}

View File

@ -17,7 +17,6 @@ import android.text.Layout;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.text.TextUtils;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.accessibility.AccessibilityNodeInfo;
@ -26,7 +25,6 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.ui.ActionBar.Theme;
import java.util.ArrayList;
import java.util.Arrays;
@ -72,6 +70,7 @@ public class AnimatedTextView extends View {
private boolean startFromEnd;
private Runnable onAnimationFinishListener;
private boolean allowCancel;
public AnimatedTextDrawable() {
this(false, false, false);
@ -83,6 +82,10 @@ public class AnimatedTextView extends View {
this.startFromEnd = startFromEnd;
}
public void setAllowCancel(boolean allowCancel) {
this.allowCancel = allowCancel;
}
public void setOnAnimationFinishListener(Runnable listener) {
onAnimationFinishListener = listener;
}
@ -93,7 +96,7 @@ public class AnimatedTextView extends View {
canvas.translate(bounds.left, bounds.top);
int fullWidth = bounds.width();
int fullHeight = bounds.height();
if (currentLayout != null && oldLayout != null) {
if (currentLayout != null && oldLayout != null && t != 1) {
int width = AndroidUtilities.lerp(oldWidth, currentWidth, t);
int height = AndroidUtilities.lerp(oldHeight, currentHeight, t);
canvas.translate(0, (fullHeight - height) / 2f);
@ -122,7 +125,7 @@ public class AnimatedTextView extends View {
x += fullWidth - lwidth;
}
}
canvas.translate(x, y);
canvas.translate(Math.round(x), Math.round(y));
currentLayout[i].draw(canvas);
canvas.restore();
}
@ -147,7 +150,7 @@ public class AnimatedTextView extends View {
x += fullWidth - oldWidth;
}
}
canvas.translate(x, y);
canvas.translate(Math.round(x), Math.round(y));
oldLayout[i].draw(canvas);
canvas.restore();
}
@ -170,7 +173,7 @@ public class AnimatedTextView extends View {
x += fullWidth - currentWidth;
}
}
canvas.translate(x, 0);
canvas.translate(Math.round(x), 0);
currentLayout[i].draw(canvas);
canvas.restore();
}
@ -205,7 +208,12 @@ public class AnimatedTextView extends View {
text = "";
}
if (animated) {
if (isAnimating()) {
if (allowCancel) {
if (animator != null) {
animator.cancel();
animator = null;
}
} else if (isAnimating()) {
toSetText = text;
toSetTextMoveDown = moveDown;
return;
@ -635,6 +643,10 @@ public class AnimatedTextView extends View {
textPaint.setTextSize(textSizePx);
}
public float getTextSize() {
return textPaint.getTextSize();
}
public void setTextColor(int color) {
textPaint.setColor(color);
}
@ -761,10 +773,17 @@ public class AnimatedTextView extends View {
public void setText(CharSequence text, boolean animated, boolean moveDown) {
animated = !first && animated;
first = false;
if (animated && drawable.isAnimating()) {
toSetText = text;
toSetMoveDown = moveDown;
return;
if (animated) {
if (drawable.allowCancel) {
if (drawable.animator != null) {
drawable.animator.cancel();
drawable.animator = null;
}
} else if (drawable.isAnimating()) {
toSetText = text;
toSetMoveDown = moveDown;
return;
}
}
int wasWidth = drawable.getWidth();
drawable.setBounds(getPaddingLeft(), getPaddingTop(), lastMaxWidth - getPaddingRight(), getMeasuredHeight() - getPaddingBottom());

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