mirror of https://github.com/NekoX-Dev/NekoX.git
353 lines
14 KiB
Java
353 lines
14 KiB
Java
/*
|
|
* This is the source code of Telegram for Android v. 5.x.x.
|
|
* It is licensed under GNU GPL v. 2 or later.
|
|
* You should have received a copy of the license in this archive (see LICENSE).
|
|
*
|
|
* Copyright Nikolai Kudashov, 2013-2018.
|
|
*/
|
|
|
|
package org.telegram.ui.Cells;
|
|
|
|
import android.content.Context;
|
|
import android.graphics.Canvas;
|
|
import android.graphics.drawable.BitmapDrawable;
|
|
import android.graphics.drawable.Drawable;
|
|
import android.text.Layout;
|
|
import android.text.Spannable;
|
|
import android.text.SpannableStringBuilder;
|
|
import android.text.Spanned;
|
|
import android.text.StaticLayout;
|
|
import android.text.TextUtils;
|
|
import android.text.style.ClickableSpan;
|
|
import android.text.style.URLSpan;
|
|
import android.view.MotionEvent;
|
|
import android.view.View;
|
|
import android.view.accessibility.AccessibilityNodeInfo;
|
|
|
|
import org.telegram.messenger.AndroidUtilities;
|
|
import org.telegram.messenger.Emoji;
|
|
import org.telegram.messenger.FileLoader;
|
|
import org.telegram.messenger.FileLog;
|
|
import org.telegram.messenger.FileRefController;
|
|
import org.telegram.messenger.ImageLoader;
|
|
import org.telegram.messenger.ImageLocation;
|
|
import org.telegram.messenger.ImageReceiver;
|
|
import org.telegram.messenger.LocaleController;
|
|
import org.telegram.messenger.MessageObject;
|
|
import org.telegram.messenger.R;
|
|
import org.telegram.messenger.SharedConfig;
|
|
import org.telegram.tgnet.TLObject;
|
|
import org.telegram.tgnet.TLRPC;
|
|
import org.telegram.ui.ActionBar.Theme;
|
|
import org.telegram.ui.Components.LinkPath;
|
|
import org.telegram.ui.Components.TypefaceSpan;
|
|
import org.telegram.ui.Components.URLSpanNoUnderline;
|
|
|
|
import java.util.Objects;
|
|
|
|
public class BotHelpCell extends View {
|
|
|
|
private StaticLayout textLayout;
|
|
private String oldText;
|
|
|
|
private String currentPhotoKey;
|
|
|
|
private int width;
|
|
private int height;
|
|
private int textX;
|
|
private int textY;
|
|
public boolean wasDraw;
|
|
|
|
private ClickableSpan pressedLink;
|
|
private LinkPath urlPath = new LinkPath();
|
|
|
|
private BotHelpCellDelegate delegate;
|
|
private Theme.ResourcesProvider resourcesProvider;
|
|
|
|
private int photoHeight;
|
|
private ImageReceiver imageReceiver;
|
|
private boolean isPhotoVisible;
|
|
private boolean isTextVisible;
|
|
private int imagePadding = AndroidUtilities.dp(4);
|
|
|
|
private boolean animating;
|
|
|
|
public interface BotHelpCellDelegate {
|
|
void didPressUrl(String url);
|
|
}
|
|
|
|
public BotHelpCell(Context context, Theme.ResourcesProvider resourcesProvider) {
|
|
super(context);
|
|
this.resourcesProvider = resourcesProvider;
|
|
|
|
imageReceiver = new ImageReceiver(this);
|
|
imageReceiver.setInvalidateAll(true);
|
|
imageReceiver.setCrossfadeWithOldImage(true);
|
|
imageReceiver.setCrossfadeDuration(300);
|
|
}
|
|
|
|
public void setDelegate(BotHelpCellDelegate botHelpCellDelegate) {
|
|
delegate = botHelpCellDelegate;
|
|
}
|
|
|
|
private void resetPressedLink() {
|
|
if (pressedLink != null) {
|
|
pressedLink = null;
|
|
}
|
|
invalidate();
|
|
}
|
|
|
|
public void setText(boolean bot, String text) {
|
|
setText(bot, text, null, null);
|
|
}
|
|
|
|
public void setText(boolean bot, String text, TLObject imageOrAnimation, TLRPC.BotInfo botInfo) {
|
|
boolean photoVisible = imageOrAnimation != null;
|
|
boolean textVisible = !TextUtils.isEmpty(text);
|
|
if ((text == null || text.length() == 0) && !photoVisible) {
|
|
setVisibility(GONE);
|
|
return;
|
|
}
|
|
if (text == null) {
|
|
text = "";
|
|
}
|
|
if (text != null && text.equals(oldText) && isPhotoVisible == photoVisible) {
|
|
return;
|
|
}
|
|
isPhotoVisible = photoVisible;
|
|
isTextVisible = textVisible;
|
|
if (isPhotoVisible) {
|
|
String photoKey = FileRefController.getKeyForParentObject(botInfo);
|
|
if (!Objects.equals(currentPhotoKey, photoKey)) {
|
|
currentPhotoKey = photoKey;
|
|
if (imageOrAnimation instanceof TLRPC.TL_photo) {
|
|
TLRPC.Photo photo = (TLRPC.Photo) imageOrAnimation;
|
|
imageReceiver.setImage(ImageLocation.getForPhoto(FileLoader.getClosestPhotoSizeWithSize(photo.sizes, 400), photo), "400_400", null, "jpg", botInfo, 0);
|
|
} else if (imageOrAnimation instanceof TLRPC.Document) {
|
|
TLRPC.Document doc = (TLRPC.Document) imageOrAnimation;
|
|
TLRPC.PhotoSize photoThumb = FileLoader.getClosestPhotoSizeWithSize(doc.thumbs, 400);
|
|
BitmapDrawable strippedThumb = null;
|
|
if (SharedConfig.getDevicePerformanceClass() != SharedConfig.PERFORMANCE_CLASS_LOW) {
|
|
for (TLRPC.PhotoSize photoSize : doc.thumbs) {
|
|
if (photoSize instanceof TLRPC.TL_photoStrippedSize) {
|
|
strippedThumb = new BitmapDrawable(getResources(), ImageLoader.getStrippedPhotoBitmap(photoSize.bytes, "b"));
|
|
}
|
|
}
|
|
}
|
|
imageReceiver.setImage(ImageLocation.getForDocument(doc), ImageLoader.AUTOPLAY_FILTER, ImageLocation.getForDocument(MessageObject.getDocumentVideoThumb(doc), doc), null, ImageLocation.getForDocument(photoThumb, doc), "86_86_b", strippedThumb, doc.size, "mp4", botInfo, 0);
|
|
}
|
|
|
|
int topRadius = AndroidUtilities.dp(SharedConfig.bubbleRadius) - AndroidUtilities.dp(2), bottomRadius = AndroidUtilities.dp(4);
|
|
if (!isTextVisible) {
|
|
bottomRadius = topRadius;
|
|
}
|
|
imageReceiver.setRoundRadius(topRadius, topRadius, bottomRadius, bottomRadius);
|
|
}
|
|
}
|
|
oldText = AndroidUtilities.getSafeString(text);
|
|
setVisibility(VISIBLE);
|
|
int maxWidth;
|
|
if (AndroidUtilities.isTablet()) {
|
|
maxWidth = (int) (AndroidUtilities.getMinTabletSide() * 0.7f);
|
|
} else {
|
|
maxWidth = (int) (Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y) * 0.7f);
|
|
}
|
|
if (isTextVisible) {
|
|
String[] lines = text.split("\n");
|
|
SpannableStringBuilder stringBuilder = new SpannableStringBuilder();
|
|
String help = LocaleController.getString(R.string.BotInfoTitle);
|
|
if (bot) {
|
|
stringBuilder.append(help);
|
|
stringBuilder.append("\n\n");
|
|
}
|
|
for (int a = 0; a < lines.length; a++) {
|
|
stringBuilder.append(lines[a].trim());
|
|
if (a != lines.length - 1) {
|
|
stringBuilder.append("\n");
|
|
}
|
|
}
|
|
MessageObject.addLinks(false, stringBuilder);
|
|
if (bot) {
|
|
stringBuilder.setSpan(new TypefaceSpan(AndroidUtilities.getTypeface("fonts/rmedium.ttf")), 0, help.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
|
}
|
|
Emoji.replaceEmoji(stringBuilder, Theme.chat_msgTextPaint.getFontMetricsInt(), AndroidUtilities.dp(20), false);
|
|
try {
|
|
textLayout = new StaticLayout(stringBuilder, Theme.chat_msgTextPaint, maxWidth - (isPhotoVisible ? AndroidUtilities.dp(5) : 0), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
|
|
width = 0;
|
|
height = textLayout.getHeight() + AndroidUtilities.dp(4 + 18);
|
|
int count = textLayout.getLineCount();
|
|
for (int a = 0; a < count; a++) {
|
|
width = (int) Math.ceil(Math.max(width, textLayout.getLineWidth(a) + textLayout.getLineLeft(a)));
|
|
}
|
|
if (width > maxWidth || isPhotoVisible) {
|
|
width = maxWidth;
|
|
}
|
|
} catch (Exception e) {
|
|
FileLog.e(e);
|
|
}
|
|
} else if (isPhotoVisible) {
|
|
width = maxWidth;
|
|
}
|
|
width += AndroidUtilities.dp(4 + 18);
|
|
|
|
if (isPhotoVisible) {
|
|
height += (photoHeight = (int) (width * 0.5625)) + AndroidUtilities.dp(4); // 16:9
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public boolean onTouchEvent(MotionEvent event) {
|
|
float x = event.getX();
|
|
float y = event.getY();
|
|
|
|
boolean result = false;
|
|
if (textLayout != null) {
|
|
if (event.getAction() == MotionEvent.ACTION_DOWN || pressedLink != null && event.getAction() == MotionEvent.ACTION_UP) {
|
|
if (event.getAction() == MotionEvent.ACTION_DOWN) {
|
|
resetPressedLink();
|
|
try {
|
|
int x2 = (int) (x - textX);
|
|
int y2 = (int) (y - textY);
|
|
int line = textLayout.getLineForVertical(y2);
|
|
int off = textLayout.getOffsetForHorizontal(line, x2);
|
|
|
|
float left = textLayout.getLineLeft(line);
|
|
if (left <= x2 && left + textLayout.getLineWidth(line) >= x2) {
|
|
Spannable buffer = (Spannable) textLayout.getText();
|
|
ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class);
|
|
if (link.length != 0) {
|
|
resetPressedLink();
|
|
pressedLink = link[0];
|
|
result = true;
|
|
try {
|
|
int start = buffer.getSpanStart(pressedLink);
|
|
urlPath.setCurrentLayout(textLayout, start, 0);
|
|
textLayout.getSelectionPath(start, buffer.getSpanEnd(pressedLink), urlPath);
|
|
} catch (Exception e) {
|
|
FileLog.e(e);
|
|
}
|
|
} else {
|
|
resetPressedLink();
|
|
}
|
|
} else {
|
|
resetPressedLink();
|
|
}
|
|
} catch (Exception e) {
|
|
resetPressedLink();
|
|
FileLog.e(e);
|
|
}
|
|
} else if (pressedLink != null) {
|
|
try {
|
|
if (pressedLink instanceof URLSpanNoUnderline) {
|
|
String url = ((URLSpanNoUnderline) pressedLink).getURL();
|
|
if (url.startsWith("@") || url.startsWith("#") || url.startsWith("/")) {
|
|
if (delegate != null) {
|
|
delegate.didPressUrl(url);
|
|
}
|
|
}
|
|
} else {
|
|
if (pressedLink instanceof URLSpan) {
|
|
if (delegate != null) {
|
|
delegate.didPressUrl(((URLSpan) pressedLink).getURL());
|
|
}
|
|
} else {
|
|
pressedLink.onClick(this);
|
|
}
|
|
}
|
|
} catch (Exception e) {
|
|
FileLog.e(e);
|
|
}
|
|
resetPressedLink();
|
|
result = true;
|
|
}
|
|
} else if (event.getAction() == MotionEvent.ACTION_CANCEL) {
|
|
resetPressedLink();
|
|
}
|
|
}
|
|
return result || super.onTouchEvent(event);
|
|
}
|
|
|
|
@Override
|
|
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
|
setMeasuredDimension(MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.EXACTLY), height + AndroidUtilities.dp(8));
|
|
}
|
|
|
|
@Override
|
|
protected void onDraw(Canvas canvas) {
|
|
int x = (getWidth() - width) / 2;
|
|
int y = photoHeight;
|
|
y += AndroidUtilities.dp(2);
|
|
Drawable shadowDrawable = Theme.chat_msgInMediaDrawable.getShadowDrawable();
|
|
if (shadowDrawable != null) {
|
|
shadowDrawable.setBounds(x, y, width + x, height + y);
|
|
shadowDrawable.draw(canvas);
|
|
}
|
|
int w = AndroidUtilities.displaySize.x;
|
|
int h = AndroidUtilities.displaySize.y;
|
|
if (getParent() instanceof View) {
|
|
View view = (View) getParent();
|
|
w = view.getMeasuredWidth();
|
|
h = view.getMeasuredHeight();
|
|
}
|
|
Theme.MessageDrawable drawable = (Theme.MessageDrawable) getThemedDrawable(Theme.key_drawable_msgInMedia);
|
|
drawable.setTop((int) getY(), w, h, false, false);
|
|
drawable.setBounds(x, 0, width + x, height);
|
|
drawable.draw(canvas);
|
|
|
|
imageReceiver.setImageCoords(x + imagePadding, imagePadding, width - imagePadding * 2, photoHeight - imagePadding);
|
|
imageReceiver.draw(canvas);
|
|
|
|
Theme.chat_msgTextPaint.setColor(getThemedColor(Theme.key_chat_messageTextIn));
|
|
Theme.chat_msgTextPaint.linkColor = getThemedColor(Theme.key_chat_messageLinkIn);
|
|
canvas.save();
|
|
canvas.translate(textX = AndroidUtilities.dp(isPhotoVisible ? 14 : 11) + x, textY = AndroidUtilities.dp(11) + y);
|
|
if (pressedLink != null) {
|
|
canvas.drawPath(urlPath, Theme.chat_urlPaint);
|
|
}
|
|
if (textLayout != null) {
|
|
textLayout.draw(canvas);
|
|
}
|
|
canvas.restore();
|
|
wasDraw = true;
|
|
}
|
|
|
|
@Override
|
|
protected void onAttachedToWindow() {
|
|
super.onAttachedToWindow();
|
|
imageReceiver.onAttachedToWindow();
|
|
}
|
|
|
|
@Override
|
|
protected void onDetachedFromWindow() {
|
|
super.onDetachedFromWindow();
|
|
imageReceiver.onDetachedFromWindow();
|
|
wasDraw = false;
|
|
}
|
|
|
|
@Override
|
|
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
|
|
super.onInitializeAccessibilityNodeInfo(info);
|
|
if (textLayout != null) {
|
|
info.setText(textLayout.getText());
|
|
}
|
|
}
|
|
|
|
public boolean animating() {
|
|
return animating;
|
|
}
|
|
|
|
public void setAnimating(boolean animating) {
|
|
this.animating = animating;
|
|
}
|
|
|
|
private int getThemedColor(String key) {
|
|
Integer color = resourcesProvider != null ? resourcesProvider.getColor(key) : null;
|
|
return color != null ? color : Theme.getColor(key);
|
|
}
|
|
|
|
private Drawable getThemedDrawable(String drawableKey) {
|
|
Drawable drawable = resourcesProvider != null ? resourcesProvider.getDrawable(drawableKey) : null;
|
|
return drawable != null ? drawable : Theme.getThemeDrawable(drawableKey);
|
|
}
|
|
}
|