use of org.telegram.ui.Components.URLSpanBotCommand in project Telegram-FOSS by Telegram-FOSS-Team.
the class ChatMessageCell method checkGameMotionEvent.
private boolean checkGameMotionEvent(MotionEvent event) {
if (!hasGamePreview) {
return false;
}
int x = (int) event.getX();
int y = (int) event.getY();
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (drawPhotoImage && drawImageButton && buttonState != -1 && x >= buttonX && x <= buttonX + AndroidUtilities.dp(48) && y >= buttonY && y <= buttonY + AndroidUtilities.dp(48) && radialProgress.getIcon() != MediaActionDrawable.ICON_NONE) {
buttonPressed = 1;
invalidate();
return true;
} else if (drawPhotoImage && photoImage.isInsideImage(x, y)) {
gamePreviewPressed = true;
return true;
} else if (descriptionLayout != null && y >= descriptionY) {
try {
x -= unmovedTextX + AndroidUtilities.dp(10) + descriptionX;
y -= descriptionY;
final int line = descriptionLayout.getLineForVertical(y);
final int off = descriptionLayout.getOffsetForHorizontal(line, x);
final float left = descriptionLayout.getLineLeft(line);
if (left <= x && left + descriptionLayout.getLineWidth(line) >= x) {
Spannable buffer = (Spannable) currentMessageObject.linkDescription;
ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class);
boolean ignore = false;
if (link.length == 0 || link[0] instanceof URLSpanBotCommand && !URLSpanBotCommand.enabled) {
ignore = true;
}
if (!ignore) {
pressedLink = link[0];
linkBlockNum = -10;
pressedLinkType = 2;
resetUrlPaths(false);
try {
LinkPath path = obtainNewUrlPath(false);
int[] pos = getRealSpanStartAndEnd(buffer, pressedLink);
path.setCurrentLayout(descriptionLayout, pos[0], 0);
descriptionLayout.getSelectionPath(pos[0], pos[1], path);
} catch (Exception e) {
FileLog.e(e);
}
invalidate();
return true;
}
}
} catch (Exception e) {
FileLog.e(e);
}
}
} else if (event.getAction() == MotionEvent.ACTION_UP) {
if (pressedLinkType == 2 || gamePreviewPressed || buttonPressed != 0) {
if (buttonPressed != 0) {
buttonPressed = 0;
playSoundEffect(SoundEffectConstants.CLICK);
didPressButton(true, false);
invalidate();
} else if (pressedLink != null) {
if (pressedLink instanceof URLSpan) {
Browser.openUrl(getContext(), ((URLSpan) pressedLink).getURL());
} else if (pressedLink instanceof ClickableSpan) {
((ClickableSpan) pressedLink).onClick(this);
}
resetPressedLink(2);
} else {
gamePreviewPressed = false;
for (int a = 0; a < botButtons.size(); a++) {
BotButton button = botButtons.get(a);
if (button.button instanceof TLRPC.TL_keyboardButtonGame) {
playSoundEffect(SoundEffectConstants.CLICK);
delegate.didPressBotButton(this, button.button);
invalidate();
break;
}
}
resetPressedLink(2);
return true;
}
} else {
resetPressedLink(2);
}
}
return false;
}
use of org.telegram.ui.Components.URLSpanBotCommand in project Telegram-FOSS by Telegram-FOSS-Team.
the class MessageObject method addEntitiesToText.
public static boolean addEntitiesToText(CharSequence text, ArrayList<TLRPC.MessageEntity> entities, boolean out, boolean usernames, boolean photoViewer, boolean useManualParse) {
if (!(text instanceof Spannable)) {
return false;
}
Spannable spannable = (Spannable) text;
URLSpan[] spans = spannable.getSpans(0, text.length(), URLSpan.class);
boolean hasUrls = spans != null && spans.length > 0;
if (entities.isEmpty()) {
return hasUrls;
}
byte t;
if (photoViewer) {
t = 2;
} else if (out) {
t = 1;
} else {
t = 0;
}
ArrayList<TextStyleSpan.TextStyleRun> runs = new ArrayList<>();
ArrayList<TLRPC.MessageEntity> entitiesCopy = new ArrayList<>(entities);
Collections.sort(entitiesCopy, (o1, o2) -> {
if (o1.offset > o2.offset) {
return 1;
} else if (o1.offset < o2.offset) {
return -1;
}
return 0;
});
for (int a = 0, N = entitiesCopy.size(); a < N; a++) {
TLRPC.MessageEntity entity = entitiesCopy.get(a);
if (entity.length <= 0 || entity.offset < 0 || entity.offset >= text.length()) {
continue;
} else if (entity.offset + entity.length > text.length()) {
entity.length = text.length() - entity.offset;
}
if (!useManualParse || entity instanceof TLRPC.TL_messageEntityBold || entity instanceof TLRPC.TL_messageEntityItalic || entity instanceof TLRPC.TL_messageEntityStrike || entity instanceof TLRPC.TL_messageEntityUnderline || entity instanceof TLRPC.TL_messageEntityBlockquote || entity instanceof TLRPC.TL_messageEntityCode || entity instanceof TLRPC.TL_messageEntityPre || entity instanceof TLRPC.TL_messageEntityMentionName || entity instanceof TLRPC.TL_inputMessageEntityMentionName || entity instanceof TLRPC.TL_messageEntityTextUrl || entity instanceof TLRPC.TL_messageEntitySpoiler) {
if (spans != null && spans.length > 0) {
for (int b = 0; b < spans.length; b++) {
if (spans[b] == null) {
continue;
}
int start = spannable.getSpanStart(spans[b]);
int end = spannable.getSpanEnd(spans[b]);
if (entity.offset <= start && entity.offset + entity.length >= start || entity.offset <= end && entity.offset + entity.length >= end) {
spannable.removeSpan(spans[b]);
spans[b] = null;
}
}
}
}
TextStyleSpan.TextStyleRun newRun = new TextStyleSpan.TextStyleRun();
newRun.start = entity.offset;
newRun.end = newRun.start + entity.length;
TLRPC.MessageEntity urlEntity = null;
if (entity instanceof TLRPC.TL_messageEntitySpoiler) {
newRun.flags = TextStyleSpan.FLAG_STYLE_SPOILER;
} else if (entity instanceof TLRPC.TL_messageEntityStrike) {
newRun.flags = TextStyleSpan.FLAG_STYLE_STRIKE;
} else if (entity instanceof TLRPC.TL_messageEntityUnderline) {
newRun.flags = TextStyleSpan.FLAG_STYLE_UNDERLINE;
} else if (entity instanceof TLRPC.TL_messageEntityBlockquote) {
newRun.flags = TextStyleSpan.FLAG_STYLE_QUOTE;
} else if (entity instanceof TLRPC.TL_messageEntityBold) {
newRun.flags = TextStyleSpan.FLAG_STYLE_BOLD;
} else if (entity instanceof TLRPC.TL_messageEntityItalic) {
newRun.flags = TextStyleSpan.FLAG_STYLE_ITALIC;
} else if (entity instanceof TLRPC.TL_messageEntityCode || entity instanceof TLRPC.TL_messageEntityPre) {
newRun.flags = TextStyleSpan.FLAG_STYLE_MONO;
} else if (entity instanceof TLRPC.TL_messageEntityMentionName) {
if (!usernames) {
continue;
}
newRun.flags = TextStyleSpan.FLAG_STYLE_MENTION;
newRun.urlEntity = entity;
} else if (entity instanceof TLRPC.TL_inputMessageEntityMentionName) {
if (!usernames) {
continue;
}
newRun.flags = TextStyleSpan.FLAG_STYLE_MENTION;
newRun.urlEntity = entity;
} else {
if (useManualParse && !(entity instanceof TLRPC.TL_messageEntityTextUrl)) {
continue;
}
if ((entity instanceof TLRPC.TL_messageEntityUrl || entity instanceof TLRPC.TL_messageEntityTextUrl) && Browser.isPassportUrl(entity.url)) {
continue;
}
if (entity instanceof TLRPC.TL_messageEntityMention && !usernames) {
continue;
}
newRun.flags = TextStyleSpan.FLAG_STYLE_URL;
newRun.urlEntity = entity;
}
for (int b = 0, N2 = runs.size(); b < N2; b++) {
TextStyleSpan.TextStyleRun run = runs.get(b);
if (newRun.start > run.start) {
if (newRun.start >= run.end) {
continue;
}
if (newRun.end < run.end) {
TextStyleSpan.TextStyleRun r = new TextStyleSpan.TextStyleRun(newRun);
r.merge(run);
b++;
N2++;
runs.add(b, r);
r = new TextStyleSpan.TextStyleRun(run);
r.start = newRun.end;
b++;
N2++;
runs.add(b, r);
} else {
TextStyleSpan.TextStyleRun r = new TextStyleSpan.TextStyleRun(newRun);
r.merge(run);
r.end = run.end;
b++;
N2++;
runs.add(b, r);
}
int temp = newRun.start;
newRun.start = run.end;
run.end = temp;
} else {
if (run.start >= newRun.end) {
continue;
}
int temp = run.start;
if (newRun.end == run.end) {
run.merge(newRun);
} else if (newRun.end < run.end) {
TextStyleSpan.TextStyleRun r = new TextStyleSpan.TextStyleRun(run);
r.merge(newRun);
r.end = newRun.end;
b++;
N2++;
runs.add(b, r);
run.start = newRun.end;
} else {
TextStyleSpan.TextStyleRun r = new TextStyleSpan.TextStyleRun(newRun);
r.start = run.end;
b++;
N2++;
runs.add(b, r);
run.merge(newRun);
}
newRun.end = temp;
}
}
if (newRun.start < newRun.end) {
runs.add(newRun);
}
}
int count = runs.size();
for (int a = 0; a < count; a++) {
TextStyleSpan.TextStyleRun run = runs.get(a);
boolean setRun = false;
String url = run.urlEntity != null ? TextUtils.substring(text, run.urlEntity.offset, run.urlEntity.offset + run.urlEntity.length) : null;
if (run.urlEntity instanceof TLRPC.TL_messageEntityBotCommand) {
spannable.setSpan(new URLSpanBotCommand(url, t, run), run.start, run.end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
} else if (run.urlEntity instanceof TLRPC.TL_messageEntityHashtag || run.urlEntity instanceof TLRPC.TL_messageEntityMention || run.urlEntity instanceof TLRPC.TL_messageEntityCashtag) {
spannable.setSpan(new URLSpanNoUnderline(url, run), run.start, run.end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
} else if (run.urlEntity instanceof TLRPC.TL_messageEntityEmail) {
spannable.setSpan(new URLSpanReplacement("mailto:" + url, run), run.start, run.end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
} else if (run.urlEntity instanceof TLRPC.TL_messageEntityUrl) {
hasUrls = true;
String lowerCase = url.toLowerCase();
if (!lowerCase.contains("://")) {
spannable.setSpan(new URLSpanBrowser("http://" + url, run), run.start, run.end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
} else {
spannable.setSpan(new URLSpanBrowser(url, run), run.start, run.end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
} else if (run.urlEntity instanceof TLRPC.TL_messageEntityBankCard) {
hasUrls = true;
spannable.setSpan(new URLSpanNoUnderline("card:" + url, run), run.start, run.end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
} else if (run.urlEntity instanceof TLRPC.TL_messageEntityPhone) {
hasUrls = true;
String tel = PhoneFormat.stripExceptNumbers(url);
if (url.startsWith("+")) {
tel = "+" + tel;
}
spannable.setSpan(new URLSpanBrowser("tel:" + tel, run), run.start, run.end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
} else if (run.urlEntity instanceof TLRPC.TL_messageEntityTextUrl) {
spannable.setSpan(new URLSpanReplacement(run.urlEntity.url, run), run.start, run.end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
} else if (run.urlEntity instanceof TLRPC.TL_messageEntityMentionName) {
spannable.setSpan(new URLSpanUserMention("" + ((TLRPC.TL_messageEntityMentionName) run.urlEntity).user_id, t, run), run.start, run.end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
} else if (run.urlEntity instanceof TLRPC.TL_inputMessageEntityMentionName) {
spannable.setSpan(new URLSpanUserMention("" + ((TLRPC.TL_inputMessageEntityMentionName) run.urlEntity).user_id.user_id, t, run), run.start, run.end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
} else if ((run.flags & TextStyleSpan.FLAG_STYLE_MONO) != 0) {
spannable.setSpan(new URLSpanMono(spannable, run.start, run.end, t, run), run.start, run.end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
} else {
setRun = true;
spannable.setSpan(new TextStyleSpan(run), run.start, run.end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
if (!setRun && (run.flags & TextStyleSpan.FLAG_STYLE_SPOILER) != 0) {
spannable.setSpan(new TextStyleSpan(run), run.start, run.end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
return hasUrls;
}
use of org.telegram.ui.Components.URLSpanBotCommand in project Telegram-FOSS by Telegram-FOSS-Team.
the class ChatMessageCell method checkCaptionMotionEvent.
private boolean checkCaptionMotionEvent(MotionEvent event) {
if (!(currentCaption instanceof Spannable) || captionLayout == null) {
return false;
}
if (event.getAction() == MotionEvent.ACTION_DOWN || (linkPreviewPressed || pressedLink != null) && event.getAction() == MotionEvent.ACTION_UP) {
int x = (int) event.getX();
int y = (int) event.getY();
if (x >= captionX && x <= captionX + captionWidth && y >= captionY && y <= captionY + captionHeight) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
try {
x -= captionX;
y -= captionY;
final int line = captionLayout.getLineForVertical(y);
final int off = captionLayout.getOffsetForHorizontal(line, x);
final float left = captionLayout.getLineLeft(line);
if (left <= x && left + captionLayout.getLineWidth(line) >= x) {
Spannable buffer = (Spannable) currentCaption;
CharacterStyle[] link = buffer.getSpans(off, off, ClickableSpan.class);
if (link == null || link.length == 0) {
link = buffer.getSpans(off, off, URLSpanMono.class);
}
boolean ignore = false;
if (link.length == 0 || link[0] instanceof URLSpanBotCommand && !URLSpanBotCommand.enabled) {
ignore = true;
}
if (!ignore) {
pressedLink = link[0];
pressedLinkType = 3;
resetUrlPaths(false);
try {
LinkPath path = obtainNewUrlPath(false);
int[] pos = getRealSpanStartAndEnd(buffer, pressedLink);
path.setCurrentLayout(captionLayout, pos[0], 0);
captionLayout.getSelectionPath(pos[0], pos[1], path);
} catch (Exception e) {
FileLog.e(e);
}
invalidateWithParent();
return true;
}
}
} catch (Exception e) {
FileLog.e(e);
}
} else if (pressedLinkType == 3) {
delegate.didPressUrl(this, pressedLink, false);
resetPressedLink(3);
return true;
}
} else {
resetPressedLink(3);
}
}
return false;
}
use of org.telegram.ui.Components.URLSpanBotCommand in project Telegram-FOSS by Telegram-FOSS-Team.
the class ChatMessageCell method checkLinkPreviewMotionEvent.
private boolean checkLinkPreviewMotionEvent(MotionEvent event) {
if (currentMessageObject.type != 0 || !hasLinkPreview) {
return false;
}
int x = (int) event.getX();
int y = (int) event.getY();
if (x >= unmovedTextX && x <= unmovedTextX + backgroundWidth && y >= textY + currentMessageObject.textHeight && y <= textY + currentMessageObject.textHeight + linkPreviewHeight + AndroidUtilities.dp(8 + (drawInstantView ? 46 : 0))) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (descriptionLayout != null && y >= descriptionY) {
try {
int checkX = x - (unmovedTextX + AndroidUtilities.dp(10) + descriptionX);
int checkY = y - descriptionY;
if (checkY <= descriptionLayout.getHeight()) {
final int line = descriptionLayout.getLineForVertical(checkY);
final int off = descriptionLayout.getOffsetForHorizontal(line, checkX);
final float left = descriptionLayout.getLineLeft(line);
if (left <= checkX && left + descriptionLayout.getLineWidth(line) >= checkX) {
Spannable buffer = (Spannable) currentMessageObject.linkDescription;
ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class);
boolean ignore = false;
if (link.length == 0 || link[0] instanceof URLSpanBotCommand && !URLSpanBotCommand.enabled) {
ignore = true;
}
if (!ignore) {
pressedLink = link[0];
linkBlockNum = -10;
pressedLinkType = 2;
resetUrlPaths(false);
startCheckLongPress();
try {
LinkPath path = obtainNewUrlPath(false);
int[] pos = getRealSpanStartAndEnd(buffer, pressedLink);
path.setCurrentLayout(descriptionLayout, pos[0], 0);
descriptionLayout.getSelectionPath(pos[0], pos[1], path);
} catch (Exception e) {
FileLog.e(e);
}
invalidate();
return true;
}
}
}
} catch (Exception e) {
FileLog.e(e);
}
}
if (pressedLink == null) {
int side = AndroidUtilities.dp(48);
boolean area2 = false;
if (miniButtonState >= 0) {
int offset = AndroidUtilities.dp(27);
area2 = x >= buttonX + offset && x <= buttonX + offset + side && y >= buttonY + offset && y <= buttonY + offset + side;
}
if (area2) {
miniButtonPressed = 1;
invalidate();
return true;
} else if (drawVideoImageButton && buttonState != -1 && x >= videoButtonX && x <= videoButtonX + AndroidUtilities.dp(26 + 8) + Math.max(infoWidth, docTitleWidth) && y >= videoButtonY && y <= videoButtonY + AndroidUtilities.dp(30)) {
videoButtonPressed = 1;
invalidate();
return true;
} else if (drawPhotoImage && drawImageButton && buttonState != -1 && (!checkOnlyButtonPressed && photoImage.isInsideImage(x, y) || x >= buttonX && x <= buttonX + AndroidUtilities.dp(48) && y >= buttonY && y <= buttonY + AndroidUtilities.dp(48) && radialProgress.getIcon() != MediaActionDrawable.ICON_NONE)) {
buttonPressed = 1;
invalidate();
return true;
} else if (drawInstantView) {
instantPressed = true;
selectorDrawableMaskType[0] = 0;
if (Build.VERSION.SDK_INT >= 21 && selectorDrawable[0] != null) {
if (selectorDrawable[0].getBounds().contains(x, y)) {
selectorDrawable[0].setHotspot(x, y);
selectorDrawable[0].setState(pressedState);
instantButtonPressed = true;
}
}
invalidate();
return true;
} else if (documentAttachType != DOCUMENT_ATTACH_TYPE_DOCUMENT && drawPhotoImage && photoImage.isInsideImage(x, y)) {
linkPreviewPressed = true;
TLRPC.WebPage webPage = currentMessageObject.messageOwner.media.webpage;
if (documentAttachType == DOCUMENT_ATTACH_TYPE_GIF && buttonState == -1 && SharedConfig.autoplayGifs && (photoImage.getAnimation() == null || !TextUtils.isEmpty(webPage.embed_url))) {
linkPreviewPressed = false;
return false;
}
return true;
}
}
} else if (event.getAction() == MotionEvent.ACTION_UP) {
if (instantPressed) {
if (delegate != null) {
delegate.didPressInstantButton(this, drawInstantViewType);
}
playSoundEffect(SoundEffectConstants.CLICK);
if (Build.VERSION.SDK_INT >= 21 && selectorDrawable[0] != null) {
selectorDrawable[0].setState(StateSet.NOTHING);
}
instantPressed = instantButtonPressed = false;
invalidate();
} else if (pressedLinkType == 2 || buttonPressed != 0 || miniButtonPressed != 0 || videoButtonPressed != 0 || linkPreviewPressed) {
if (videoButtonPressed == 1) {
videoButtonPressed = 0;
playSoundEffect(SoundEffectConstants.CLICK);
didPressButton(true, true);
invalidate();
} else if (buttonPressed != 0) {
buttonPressed = 0;
playSoundEffect(SoundEffectConstants.CLICK);
if (drawVideoImageButton) {
didClickedImage();
} else {
didPressButton(true, false);
}
invalidate();
} else if (miniButtonPressed != 0) {
miniButtonPressed = 0;
playSoundEffect(SoundEffectConstants.CLICK);
didPressMiniButton(true);
invalidate();
} else if (pressedLink != null) {
if (pressedLink instanceof URLSpan) {
delegate.didPressUrl(this, pressedLink, false);
} else if (pressedLink instanceof ClickableSpan) {
((ClickableSpan) pressedLink).onClick(this);
}
resetPressedLink(2);
} else {
if (documentAttachType == DOCUMENT_ATTACH_TYPE_ROUND) {
if (!MediaController.getInstance().isPlayingMessage(currentMessageObject) || MediaController.getInstance().isMessagePaused()) {
delegate.needPlayMessage(currentMessageObject);
} else {
MediaController.getInstance().pauseMessage(currentMessageObject);
}
} else if (documentAttachType == DOCUMENT_ATTACH_TYPE_GIF && drawImageButton) {
if (buttonState == -1) {
if (SharedConfig.autoplayGifs) {
delegate.didPressImage(this, lastTouchX, lastTouchY);
} else {
buttonState = 2;
currentMessageObject.gifState = 1;
photoImage.setAllowStartAnimation(false);
photoImage.stopAnimation();
radialProgress.setIcon(getIconForCurrentState(), false, true);
invalidate();
playSoundEffect(SoundEffectConstants.CLICK);
}
} else if (buttonState == 2 || buttonState == 0) {
didPressButton(true, false);
playSoundEffect(SoundEffectConstants.CLICK);
}
} else {
TLRPC.WebPage webPage = currentMessageObject.messageOwner.media.webpage;
if (webPage != null && !TextUtils.isEmpty(webPage.embed_url)) {
delegate.needOpenWebView(currentMessageObject, webPage.embed_url, webPage.site_name, webPage.title, webPage.url, webPage.embed_width, webPage.embed_height);
} else if (buttonState == -1 || buttonState == 3) {
delegate.didPressImage(this, lastTouchX, lastTouchY);
playSoundEffect(SoundEffectConstants.CLICK);
} else if (webPage != null) {
Browser.openUrl(getContext(), webPage.url);
}
}
resetPressedLink(2);
return true;
}
} else {
resetPressedLink(2);
}
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
if (instantButtonPressed && Build.VERSION.SDK_INT >= 21 && selectorDrawable[0] != null) {
selectorDrawable[0].setHotspot(x, y);
}
}
}
return false;
}
use of org.telegram.ui.Components.URLSpanBotCommand in project Telegram-FOSS by Telegram-FOSS-Team.
the class ChatMessageCell method checkTextBlockMotionEvent.
private boolean checkTextBlockMotionEvent(MotionEvent event) {
if (currentMessageObject.type != 0 || currentMessageObject.textLayoutBlocks == null || currentMessageObject.textLayoutBlocks.isEmpty() || !(currentMessageObject.messageText instanceof Spannable)) {
return false;
}
if (event.getAction() == MotionEvent.ACTION_DOWN || event.getAction() == MotionEvent.ACTION_UP && pressedLinkType == 1) {
int x = (int) event.getX();
int y = (int) event.getY();
if (x >= textX && y >= textY && x <= textX + currentMessageObject.textWidth && y <= textY + currentMessageObject.textHeight) {
y -= textY;
int blockNum = 0;
for (int a = 0; a < currentMessageObject.textLayoutBlocks.size(); a++) {
if (currentMessageObject.textLayoutBlocks.get(a).textYOffset > y) {
break;
}
blockNum = a;
}
try {
MessageObject.TextLayoutBlock block = currentMessageObject.textLayoutBlocks.get(blockNum);
x -= textX - (block.isRtl() ? currentMessageObject.textXOffset : 0);
y -= block.textYOffset;
final int line = block.textLayout.getLineForVertical(y);
final int off = block.charactersOffset + block.textLayout.getOffsetForHorizontal(line, x);
final float left = block.textLayout.getLineLeft(line);
if (left <= x && left + block.textLayout.getLineWidth(line) >= x) {
Spannable buffer = (Spannable) currentMessageObject.messageText;
CharacterStyle[] link = buffer.getSpans(off, off, ClickableSpan.class);
boolean isMono = false;
if (link == null || link.length == 0) {
link = buffer.getSpans(off, off, URLSpanMono.class);
isMono = true;
}
boolean ignore = false;
if (link.length == 0 || link[0] instanceof URLSpanBotCommand && !URLSpanBotCommand.enabled) {
ignore = true;
}
if (!ignore) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
pressedLink = link[0];
linkBlockNum = blockNum;
pressedLinkType = 1;
resetUrlPaths(false);
try {
LinkPath path = obtainNewUrlPath(false);
int[] pos = getRealSpanStartAndEnd(buffer, pressedLink);
pos[0] -= block.charactersOffset;
pos[1] -= block.charactersOffset;
path.setCurrentLayout(block.textLayout, pos[0], 0);
block.textLayout.getSelectionPath(pos[0], pos[1], path);
if (pos[1] >= block.charactersEnd) {
for (int a = blockNum + 1; a < currentMessageObject.textLayoutBlocks.size(); a++) {
MessageObject.TextLayoutBlock nextBlock = currentMessageObject.textLayoutBlocks.get(a);
CharacterStyle[] nextLink;
if (isMono) {
nextLink = buffer.getSpans(nextBlock.charactersOffset, nextBlock.charactersOffset, URLSpanMono.class);
} else {
nextLink = buffer.getSpans(nextBlock.charactersOffset, nextBlock.charactersOffset, ClickableSpan.class);
}
if (nextLink == null || nextLink.length == 0 || nextLink[0] != pressedLink) {
break;
}
path = obtainNewUrlPath(false);
path.setCurrentLayout(nextBlock.textLayout, 0, nextBlock.textYOffset - block.textYOffset);
int p1 = pos[1] + block.charactersOffset - nextBlock.charactersOffset;
nextBlock.textLayout.getSelectionPath(0, p1, path);
if (p1 < nextBlock.charactersEnd - 1) {
break;
}
}
}
if (pos[0] <= block.charactersOffset) {
int offsetY = 0;
for (int a = blockNum - 1; a >= 0; a--) {
MessageObject.TextLayoutBlock nextBlock = currentMessageObject.textLayoutBlocks.get(a);
CharacterStyle[] nextLink;
if (isMono) {
nextLink = buffer.getSpans(nextBlock.charactersEnd - 1, nextBlock.charactersEnd - 1, URLSpanMono.class);
} else {
nextLink = buffer.getSpans(nextBlock.charactersEnd - 1, nextBlock.charactersEnd - 1, ClickableSpan.class);
}
if (nextLink == null || nextLink.length == 0 || nextLink[0] != pressedLink) {
break;
}
path = obtainNewUrlPath(false);
offsetY -= nextBlock.height;
int p0 = pos[0] + block.charactersOffset - nextBlock.charactersOffset;
int p1 = pos[1] + block.charactersOffset - nextBlock.charactersOffset;
path.setCurrentLayout(nextBlock.textLayout, p0, offsetY);
nextBlock.textLayout.getSelectionPath(p0, p1, path);
if (p0 > nextBlock.charactersOffset) {
break;
}
}
}
} catch (Exception e) {
FileLog.e(e);
}
invalidate();
return true;
} else {
if (link[0] == pressedLink) {
delegate.didPressUrl(this, pressedLink, false);
resetPressedLink(1);
return true;
}
}
}
}
} catch (Exception e) {
FileLog.e(e);
}
} else {
resetPressedLink(1);
}
}
return false;
}
Aggregations