use of org.telegram.ui.Components.EmptyStubSpan in project Telegram-FOSS by Telegram-FOSS-Team.
the class SimpleTextView method createLayout.
protected boolean createLayout(int width) {
CharSequence text = this.text;
replacingDrawableTextIndex = -1;
if (text != null) {
try {
if (leftDrawable != null) {
width -= leftDrawable.getIntrinsicWidth();
width -= drawablePadding;
}
if (rightDrawable != null) {
int dw = (int) (rightDrawable.getIntrinsicWidth() * rightDrawableScale);
width -= dw;
width -= drawablePadding;
}
if (replacedText != null && replacedDrawable != null) {
replacingDrawableTextIndex = text.toString().indexOf(replacedText);
if (replacingDrawableTextIndex >= 0) {
SpannableStringBuilder builder = SpannableStringBuilder.valueOf(text);
builder.setSpan(new DialogCell.FixedWidthSpan(replacedDrawable.getIntrinsicWidth()), replacingDrawableTextIndex, replacingDrawableTextIndex + replacedText.length(), 0);
text = builder;
} else {
width -= replacedDrawable.getIntrinsicWidth();
width -= drawablePadding;
}
}
if (buildFullLayout) {
CharSequence string = TextUtils.ellipsize(text, textPaint, width, TextUtils.TruncateAt.END);
if (!string.equals(text)) {
fullLayout = StaticLayoutEx.createStaticLayout(text, 0, text.length(), textPaint, width, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false, TextUtils.TruncateAt.END, width, fullTextMaxLines, false);
if (fullLayout != null) {
int end = fullLayout.getLineEnd(0);
int start = fullLayout.getLineStart(1);
CharSequence substr = text.subSequence(0, end);
SpannableStringBuilder full = SpannableStringBuilder.valueOf(text);
full.setSpan(new EmptyStubSpan(), 0, start, 0);
CharSequence part;
if (end < string.length()) {
part = string.subSequence(end, string.length());
} else {
part = "…";
}
firstLineLayout = new StaticLayout(string, 0, string.length(), textPaint, scrollNonFitText ? AndroidUtilities.dp(2000) : width + AndroidUtilities.dp(8), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
layout = new StaticLayout(substr, 0, substr.length(), textPaint, scrollNonFitText ? AndroidUtilities.dp(2000) : width + AndroidUtilities.dp(8), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
if (layout.getLineLeft(0) != 0) {
part = "\u200F" + part;
}
partLayout = new StaticLayout(part, 0, part.length(), textPaint, scrollNonFitText ? AndroidUtilities.dp(2000) : width + AndroidUtilities.dp(8), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
fullLayout = StaticLayoutEx.createStaticLayout(full, 0, full.length(), textPaint, width + AndroidUtilities.dp(8) + fullLayoutAdditionalWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false, TextUtils.TruncateAt.END, width + fullLayoutAdditionalWidth, fullTextMaxLines, false);
}
} else {
layout = new StaticLayout(string, 0, string.length(), textPaint, scrollNonFitText ? AndroidUtilities.dp(2000) : width + AndroidUtilities.dp(8), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
fullLayout = null;
partLayout = null;
firstLineLayout = null;
}
} else if (maxLines > 1) {
layout = StaticLayoutEx.createStaticLayout(text, 0, text.length(), textPaint, width, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false, TextUtils.TruncateAt.END, width, maxLines, false);
} else {
CharSequence string;
if (scrollNonFitText) {
string = text;
} else {
string = TextUtils.ellipsize(text, textPaint, width, TextUtils.TruncateAt.END);
}
/*if (layout != null && TextUtils.equals(layout.getText(), string)) {
calcOffset(width);
return false;
}*/
layout = new StaticLayout(string, 0, string.length(), textPaint, scrollNonFitText ? AndroidUtilities.dp(2000) : width + AndroidUtilities.dp(8), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
}
spoilersPool.addAll(spoilers);
spoilers.clear();
if (layout != null && layout.getText() instanceof Spannable) {
SpoilerEffect.addSpoilers(this, layout, spoilersPool, spoilers);
}
calcOffset(width);
} catch (Exception ignore) {
}
} else {
layout = null;
textWidth = 0;
textHeight = 0;
}
invalidate();
return true;
}
use of org.telegram.ui.Components.EmptyStubSpan in project Telegram-FOSS by Telegram-FOSS-Team.
the class DialogCell method update.
public void update(int mask, boolean animated) {
if (customDialog != null) {
lastMessageDate = customDialog.date;
lastUnreadState = customDialog.unread_count != 0;
unreadCount = customDialog.unread_count;
drawPin = customDialog.pinned;
dialogMuted = customDialog.muted;
avatarDrawable.setInfo(customDialog.id, customDialog.name, null);
avatarImage.setImage(null, "50_50", avatarDrawable, null, 0);
thumbImage.setImageBitmap((BitmapDrawable) null);
} else {
int oldUnreadCount = unreadCount;
boolean oldHasReactionsMentions = reactionMentionCount != 0;
boolean oldMarkUnread = markUnread;
if (isDialogCell) {
TLRPC.Dialog dialog = MessagesController.getInstance(currentAccount).dialogs_dict.get(currentDialogId);
if (dialog != null) {
if (mask == 0) {
clearingDialog = MessagesController.getInstance(currentAccount).isClearingDialog(dialog.id);
message = MessagesController.getInstance(currentAccount).dialogMessage.get(dialog.id);
lastUnreadState = message != null && message.isUnread();
if (dialog instanceof TLRPC.TL_dialogFolder) {
unreadCount = MessagesStorage.getInstance(currentAccount).getArchiveUnreadCount();
mentionCount = 0;
reactionMentionCount = 0;
} else {
unreadCount = dialog.unread_count;
mentionCount = dialog.unread_mentions_count;
reactionMentionCount = dialog.unread_reactions_count;
}
markUnread = dialog.unread_mark;
currentEditDate = message != null ? message.messageOwner.edit_date : 0;
lastMessageDate = dialog.last_message_date;
if (dialogsType == 7 || dialogsType == 8) {
MessagesController.DialogFilter filter = MessagesController.getInstance(currentAccount).selectedDialogFilter[dialogsType == 8 ? 1 : 0];
drawPin = filter != null && filter.pinnedDialogs.indexOfKey(dialog.id) >= 0;
} else {
drawPin = currentDialogFolderId == 0 && dialog.pinned;
}
if (message != null) {
lastSendState = message.messageOwner.send_state;
}
}
} else {
unreadCount = 0;
mentionCount = 0;
reactionMentionCount = 0;
currentEditDate = 0;
lastMessageDate = 0;
clearingDialog = false;
}
} else {
drawPin = false;
}
if (mask != 0) {
boolean continueUpdate = false;
if (user != null && (mask & MessagesController.UPDATE_MASK_STATUS) != 0) {
user = MessagesController.getInstance(currentAccount).getUser(user.id);
invalidate();
}
if (isDialogCell) {
if ((mask & MessagesController.UPDATE_MASK_USER_PRINT) != 0) {
CharSequence printString = MessagesController.getInstance(currentAccount).getPrintingString(currentDialogId, 0, true);
if (lastPrintString != null && printString == null || lastPrintString == null && printString != null || lastPrintString != null && !lastPrintString.equals(printString)) {
continueUpdate = true;
}
}
}
if (!continueUpdate && (mask & MessagesController.UPDATE_MASK_MESSAGE_TEXT) != 0) {
if (message != null && message.messageText != lastMessageString) {
continueUpdate = true;
}
}
if (!continueUpdate && (mask & MessagesController.UPDATE_MASK_CHAT) != 0 && chat != null) {
TLRPC.Chat newChat = MessagesController.getInstance(currentAccount).getChat(chat.id);
if ((newChat.call_active && newChat.call_not_empty) != hasCall) {
continueUpdate = true;
}
}
if (!continueUpdate && (mask & MessagesController.UPDATE_MASK_AVATAR) != 0) {
if (chat == null) {
continueUpdate = true;
}
}
if (!continueUpdate && (mask & MessagesController.UPDATE_MASK_NAME) != 0) {
if (chat == null) {
continueUpdate = true;
}
}
if (!continueUpdate && (mask & MessagesController.UPDATE_MASK_CHAT_AVATAR) != 0) {
if (user == null) {
continueUpdate = true;
}
}
if (!continueUpdate && (mask & MessagesController.UPDATE_MASK_CHAT_NAME) != 0) {
if (user == null) {
continueUpdate = true;
}
}
if (!continueUpdate && (mask & MessagesController.UPDATE_MASK_READ_DIALOG_MESSAGE) != 0) {
if (message != null && lastUnreadState != message.isUnread()) {
lastUnreadState = message.isUnread();
continueUpdate = true;
}
if (isDialogCell) {
TLRPC.Dialog dialog = MessagesController.getInstance(currentAccount).dialogs_dict.get(currentDialogId);
int newCount;
int newMentionCount;
int newReactionCout = 0;
if (dialog instanceof TLRPC.TL_dialogFolder) {
newCount = MessagesStorage.getInstance(currentAccount).getArchiveUnreadCount();
newMentionCount = 0;
} else if (dialog != null) {
newCount = dialog.unread_count;
newMentionCount = dialog.unread_mentions_count;
newReactionCout = dialog.unread_reactions_count;
} else {
newCount = 0;
newMentionCount = 0;
}
if (dialog != null && (unreadCount != newCount || markUnread != dialog.unread_mark || mentionCount != newMentionCount || reactionMentionCount != newReactionCout)) {
unreadCount = newCount;
mentionCount = newMentionCount;
markUnread = dialog.unread_mark;
reactionMentionCount = newReactionCout;
continueUpdate = true;
}
}
}
if (!continueUpdate && (mask & MessagesController.UPDATE_MASK_SEND_STATE) != 0) {
if (message != null && lastSendState != message.messageOwner.send_state) {
lastSendState = message.messageOwner.send_state;
continueUpdate = true;
}
}
if (!continueUpdate) {
invalidate();
return;
}
}
user = null;
chat = null;
encryptedChat = null;
long dialogId;
if (currentDialogFolderId != 0) {
dialogMuted = false;
message = findFolderTopMessage();
if (message != null) {
dialogId = message.getDialogId();
} else {
dialogId = 0;
}
} else {
dialogMuted = isDialogCell && MessagesController.getInstance(currentAccount).isDialogMuted(currentDialogId);
dialogId = currentDialogId;
}
if (dialogId != 0) {
if (DialogObject.isEncryptedDialog(dialogId)) {
encryptedChat = MessagesController.getInstance(currentAccount).getEncryptedChat(DialogObject.getEncryptedChatId(dialogId));
if (encryptedChat != null) {
user = MessagesController.getInstance(currentAccount).getUser(encryptedChat.user_id);
}
} else if (DialogObject.isUserDialog(dialogId)) {
user = MessagesController.getInstance(currentAccount).getUser(dialogId);
} else {
chat = MessagesController.getInstance(currentAccount).getChat(-dialogId);
if (!isDialogCell && chat != null && chat.migrated_to != null) {
TLRPC.Chat chat2 = MessagesController.getInstance(currentAccount).getChat(chat.migrated_to.channel_id);
if (chat2 != null) {
chat = chat2;
}
}
}
if (useMeForMyMessages && user != null && message.isOutOwner()) {
user = MessagesController.getInstance(currentAccount).getUser(UserConfig.getInstance(currentAccount).clientUserId);
}
}
if (currentDialogFolderId != 0) {
Theme.dialogs_archiveAvatarDrawable.setCallback(this);
avatarDrawable.setAvatarType(AvatarDrawable.AVATAR_TYPE_ARCHIVED);
avatarImage.setImage(null, null, avatarDrawable, null, user, 0);
} else {
if (user != null) {
avatarDrawable.setInfo(user);
if (UserObject.isReplyUser(user)) {
avatarDrawable.setAvatarType(AvatarDrawable.AVATAR_TYPE_REPLIES);
avatarImage.setImage(null, null, avatarDrawable, null, user, 0);
} else if (UserObject.isUserSelf(user) && !useMeForMyMessages) {
avatarDrawable.setAvatarType(AvatarDrawable.AVATAR_TYPE_SAVED);
avatarImage.setImage(null, null, avatarDrawable, null, user, 0);
} else {
avatarImage.setForUserOrChat(user, avatarDrawable);
}
} else if (chat != null) {
avatarDrawable.setInfo(chat);
avatarImage.setForUserOrChat(chat, avatarDrawable);
}
}
if (animated && (oldUnreadCount != unreadCount || oldMarkUnread != markUnread) && (System.currentTimeMillis() - lastDialogChangedTime) > 100) {
if (countAnimator != null) {
countAnimator.cancel();
}
countAnimator = ValueAnimator.ofFloat(0, 1f);
countAnimator.addUpdateListener(valueAnimator -> {
countChangeProgress = (float) valueAnimator.getAnimatedValue();
invalidate();
});
countAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
countChangeProgress = 1f;
countOldLayout = null;
countAnimationStableLayout = null;
countAnimationInLayout = null;
invalidate();
}
});
if ((oldUnreadCount == 0 || markUnread) && !(!markUnread && oldMarkUnread)) {
countAnimator.setDuration(220);
countAnimator.setInterpolator(new OvershootInterpolator());
} else if (unreadCount == 0) {
countAnimator.setDuration(150);
countAnimator.setInterpolator(CubicBezierInterpolator.DEFAULT);
} else {
countAnimator.setDuration(430);
countAnimator.setInterpolator(CubicBezierInterpolator.DEFAULT);
}
if (drawCount && countLayout != null) {
String oldStr = String.valueOf(oldUnreadCount);
String newStr = String.valueOf(unreadCount);
if (oldStr.length() == newStr.length()) {
SpannableStringBuilder oldSpannableStr = new SpannableStringBuilder(oldStr);
SpannableStringBuilder newSpannableStr = new SpannableStringBuilder(newStr);
SpannableStringBuilder stableStr = new SpannableStringBuilder(newStr);
for (int i = 0; i < oldStr.length(); i++) {
if (oldStr.charAt(i) == newStr.charAt(i)) {
oldSpannableStr.setSpan(new EmptyStubSpan(), i, i + 1, 0);
newSpannableStr.setSpan(new EmptyStubSpan(), i, i + 1, 0);
} else {
stableStr.setSpan(new EmptyStubSpan(), i, i + 1, 0);
}
}
int countOldWidth = Math.max(AndroidUtilities.dp(12), (int) Math.ceil(Theme.dialogs_countTextPaint.measureText(oldStr)));
countOldLayout = new StaticLayout(oldSpannableStr, Theme.dialogs_countTextPaint, countOldWidth, Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false);
countAnimationStableLayout = new StaticLayout(stableStr, Theme.dialogs_countTextPaint, countOldWidth, Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false);
countAnimationInLayout = new StaticLayout(newSpannableStr, Theme.dialogs_countTextPaint, countOldWidth, Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false);
} else {
countOldLayout = countLayout;
}
}
countWidthOld = countWidth;
countLeftOld = countLeft;
countAnimationIncrement = unreadCount > oldUnreadCount;
countAnimator.start();
}
boolean newHasReactionsMentions = reactionMentionCount != 0;
if (animated && (newHasReactionsMentions != oldHasReactionsMentions)) {
if (reactionsMentionsAnimator != null) {
reactionsMentionsAnimator.cancel();
}
reactionsMentionsChangeProgress = 0;
reactionsMentionsAnimator = ValueAnimator.ofFloat(0, 1f);
reactionsMentionsAnimator.addUpdateListener(valueAnimator -> {
reactionsMentionsChangeProgress = (float) valueAnimator.getAnimatedValue();
invalidate();
});
reactionsMentionsAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
reactionsMentionsChangeProgress = 1f;
invalidate();
}
});
if (newHasReactionsMentions) {
reactionsMentionsAnimator.setDuration(220);
reactionsMentionsAnimator.setInterpolator(new OvershootInterpolator());
} else {
reactionsMentionsAnimator.setDuration(150);
reactionsMentionsAnimator.setInterpolator(CubicBezierInterpolator.DEFAULT);
}
reactionsMentionsAnimator.start();
}
}
if (getMeasuredWidth() != 0 || getMeasuredHeight() != 0) {
buildLayout();
} else {
requestLayout();
}
if (!animated) {
dialogMutedProgress = dialogMuted ? 1f : 0f;
if (countAnimator != null) {
countAnimator.cancel();
}
}
invalidate();
}
Aggregations