Search in sources :

Example 1 with EmptyStubSpan

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;
}
Also used : DialogCell(org.telegram.ui.Cells.DialogCell) StaticLayout(android.text.StaticLayout) EmptyStubSpan(org.telegram.ui.Components.EmptyStubSpan) TextPaint(android.text.TextPaint) Paint(android.graphics.Paint) SpannableStringBuilder(android.text.SpannableStringBuilder) Spannable(android.text.Spannable)

Example 2 with EmptyStubSpan

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();
}
Also used : OvershootInterpolator(android.view.animation.OvershootInterpolator) MessagesController(org.telegram.messenger.MessagesController) StaticLayout(android.text.StaticLayout) EmptyStubSpan(org.telegram.ui.Components.EmptyStubSpan) TextPaint(android.text.TextPaint) Paint(android.graphics.Paint) SuppressLint(android.annotation.SuppressLint) TLRPC(org.telegram.tgnet.TLRPC) Animator(android.animation.Animator) ValueAnimator(android.animation.ValueAnimator) AnimatorListenerAdapter(android.animation.AnimatorListenerAdapter) SpannableStringBuilder(android.text.SpannableStringBuilder)

Aggregations

Paint (android.graphics.Paint)2 SpannableStringBuilder (android.text.SpannableStringBuilder)2 StaticLayout (android.text.StaticLayout)2 TextPaint (android.text.TextPaint)2 EmptyStubSpan (org.telegram.ui.Components.EmptyStubSpan)2 Animator (android.animation.Animator)1 AnimatorListenerAdapter (android.animation.AnimatorListenerAdapter)1 ValueAnimator (android.animation.ValueAnimator)1 SuppressLint (android.annotation.SuppressLint)1 Spannable (android.text.Spannable)1 OvershootInterpolator (android.view.animation.OvershootInterpolator)1 MessagesController (org.telegram.messenger.MessagesController)1 TLRPC (org.telegram.tgnet.TLRPC)1 DialogCell (org.telegram.ui.Cells.DialogCell)1