Search in sources :

Example 91 with ForegroundColorSpan

use of android.text.style.ForegroundColorSpan in project actor-platform by actorapp.

the class DialogView method buildLayout.

@Override
public DialogLayout buildLayout(Dialog arg, int width, int height) {
    if (!isStylesLoaded) {
        isStylesLoaded = true;
        ActorStyle style = ActorSDK.sharedActor().style;
        Context context = getContext();
        titlePaint = createTextPaint(Fonts.medium(), 16, style.getDialogsTitleColor());
        titleSecurePaint = createTextPaint(Fonts.medium(), 16, style.getDialogsTitleSecureColor());
        datePaint = createTextPaint(Fonts.regular(), 14, style.getDialogsTimeColor());
        textPaint = createTextPaint(Fonts.regular(), 16, style.getDialogsTimeColor());
        textActivePaint = createTextPaint(Fonts.regular(), 16, style.getDialogsActiveTextColor());
        senderTextColor = style.getDialogsActiveTextColor();
        groupIcon = new TintDrawable(context.getResources().getDrawable(R.drawable.ic_group_black_18dp), style.getDialogsTitleColor());
        channelIcon = new TintDrawable(context.getResources().getDrawable(R.drawable.ic_megaphone_18dp_black), style.getDialogsTitleColor());
        botIcon = new TintDrawable(context.getResources().getDrawable(R.drawable.ic_robot_black_18dp), style.getDialogsTitleColor());
        secretIcon = new TintDrawable(context.getResources().getDrawable(R.drawable.ic_lock_black_18dp), style.getDialogsTitleSecureColor());
        counterTextPaint = createTextPaint(Fonts.medium(), 14, style.getDialogsCounterTextColor());
        counterTextPaint.setTextAlign(Paint.Align.CENTER);
        counterBgPaint = createFilledPaint(style.getDialogsCounterBackgroundColor());
        fillPaint = createFilledPaint(Color.BLACK);
        placeholderColors = ActorSDK.sharedActor().style.getDefaultAvatarPlaceholders();
        avatarBorder = new Paint();
        avatarBorder.setStyle(Paint.Style.STROKE);
        avatarBorder.setAntiAlias(true);
        avatarBorder.setColor(0x19000000);
        avatarBorder.setStrokeWidth(1);
        avatarTextColor = createTextPaint(Fonts.regular(), 20, Color.WHITE);
        avatarTextColor.setTextAlign(Paint.Align.CENTER);
        typingText = messenger().getFormatter().formatTyping();
        stateSent = new TintDrawable(context.getResources().getDrawable(R.drawable.msg_check_1), style.getDialogsStateSentColor());
        stateReceived = new TintDrawable(context.getResources().getDrawable(R.drawable.msg_check_2), style.getDialogsStateDeliveredColor());
        stateRead = new TintDrawable(context.getResources().getDrawable(R.drawable.msg_check_2), style.getDialogsStateReadColor());
    }
    DialogLayout res = new DialogLayout();
    res.setPlaceholderIndex(Math.abs(arg.getPeer().getPeerId()) % placeholderColors.length);
    res.setShortName(buildShortName(arg.getDialogTitle()));
    if (arg.getDialogAvatar() != null) {
        AvatarImage image = getAvatarImage(arg.getDialogAvatar());
        if (image != null) {
            String desc = messenger().findDownloadedDescriptor(image.getFileReference().getFileId());
            if (desc != null) {
                ImageRequest request = ImageRequestBuilder.newBuilderWithSource(Uri.fromFile(new File(desc))).setResizeOptions(new ResizeOptions(Screen.dp(52), Screen.dp(52))).setImageType(ImageRequest.ImageType.SMALL).build();
                res.setImageRequest(request);
            } else {
                InvalidationContext invalidationContext = getCurrentLayoutContext();
                messenger().bindRawFile(image.getFileReference(), true, new FileCallback() {

                    @Override
                    public void onNotDownloaded() {
                        if (invalidationContext.isCancelled()) {
                            messenger().unbindRawFile(image.getFileReference().getFileId(), false, this);
                        }
                    }

                    @Override
                    public void onDownloading(float progress) {
                        if (invalidationContext.isCancelled()) {
                            messenger().unbindRawFile(image.getFileReference().getFileId(), false, this);
                        }
                    }

                    @Override
                    public void onDownloaded(FileSystemReference reference) {
                        messenger().unbindRawFile(image.getFileReference().getFileId(), false, this);
                        invalidationContext.invalidate();
                    }
                });
            }
        }
    }
    // Top Row
    int maxTitleWidth = (width - Screen.dp(72)) - Screen.dp(8);
    if (arg.getDate() > 0) {
        String dateText = messenger().getFormatter().formatShortDate(arg.getDate());
        int dateWidth = (int) datePaint.measureText(dateText);
        res.setDate(dateText, dateWidth);
        maxTitleWidth -= dateWidth + Screen.dp(16);
    }
    if (arg.getPeer().getPeerType() == PeerType.GROUP) {
        if (arg.isChannel()) {
            res.setTitleIcon(channelIcon);
            res.setTitleIconTop(Screen.dp(33));
        } else {
            res.setTitleIcon(groupIcon);
            res.setTitleIconTop(Screen.dp(33));
        }
        maxTitleWidth -= Screen.dp(16 + /*icon width*/
        4);
    } else if (arg.getPeer().getPeerType() == PeerType.PRIVATE_ENCRYPTED) {
        res.setTitleIcon(secretIcon);
        res.setTitleIconTop(Screen.dp(31));
        maxTitleWidth -= Screen.dp(16 + /*icon width*/
        4);
    } else if (arg.getPeer().getPeerType() == PeerType.PRIVATE) {
        if (arg.isBot()) {
            res.setTitleIcon(botIcon);
            res.setTitleIconTop(Screen.dp(33));
            maxTitleWidth -= Screen.dp(16 + /*icon width*/
            4);
        }
    }
    if (arg.getSenderId() == messenger().myUid()) {
        if (arg.isRead()) {
            res.setState(stateRead);
        } else if (arg.isReceived()) {
            res.setState(stateReceived);
        } else {
            res.setState(stateSent);
        }
        maxTitleWidth -= Screen.dp(20);
    }
    res.setTitleLayout(singleLineText(arg.getDialogTitle(), arg.getPeer().getPeerType() == PeerType.PRIVATE_ENCRYPTED ? titleSecurePaint : titlePaint, maxTitleWidth));
    // Second Row
    int maxWidth = width - Screen.dp(72) - Screen.dp(8);
    if (arg.getUnreadCount() > 0) {
        String counterText = "" + arg.getUnreadCount();
        int counterWidth = (int) counterTextPaint.measureText(counterText) + Screen.sp(10);
        counterWidth = Math.max(counterWidth, Screen.dp(22));
        res.setCounter(counterText, counterWidth);
        maxWidth -= counterWidth + Screen.dp(8);
    }
    if (arg.getSenderId() > 0) {
        String contentText = messenger().getFormatter().formatContentText(arg.getSenderId(), arg.getMessageType(), arg.getText().replace("\n", " "), arg.getRelatedUid(), arg.isChannel());
        if (arg.getPeer().getPeerType() == PeerType.GROUP) {
            if (messenger().getFormatter().isLargeDialogMessage(arg.getMessageType())) {
                res.setTextLayout(singleLineText(handleEmoji(contentText), textActivePaint, maxWidth));
            } else {
                String senderName = messenger().getFormatter().formatPerformerName(arg.getSenderId()) + ": ";
                if (arg.getMessageType() == ContentType.TEXT) {
                    SpannableStringBuilder builder = new SpannableStringBuilder();
                    builder.append(senderName);
                    builder.setSpan(new ForegroundColorSpan(senderTextColor), 0, senderName.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
                    builder.append(contentText);
                    res.setTextLayout(singleLineText(builder, textPaint, maxWidth));
                } else {
                    CharSequence contentResult = handleEmoji(senderName, contentText);
                    res.setTextLayout(singleLineText(contentResult, textActivePaint, maxWidth));
                }
            }
        } else {
            if (arg.getMessageType() == ContentType.TEXT) {
                res.setTextLayout(singleLineText(handleEmoji(contentText), textPaint, maxWidth));
            } else {
                res.setTextLayout(singleLineText(handleEmoji(contentText), textActivePaint, maxWidth));
            }
        }
    }
    return res;
}
Also used : Context(android.content.Context) FileSystemReference(im.actor.runtime.files.FileSystemReference) ForegroundColorSpan(android.text.style.ForegroundColorSpan) TintDrawable(im.actor.sdk.view.TintDrawable) TextPaint(android.text.TextPaint) Paint(android.graphics.Paint) TextPaint(android.text.TextPaint) Paint(android.graphics.Paint) FileCallback(im.actor.core.viewmodel.FileCallback) ActorStyle(im.actor.sdk.ActorStyle) ResizeOptions(com.facebook.imagepipeline.common.ResizeOptions) ImageRequest(com.facebook.imagepipeline.request.ImageRequest) AvatarImage(im.actor.core.entity.AvatarImage) File(java.io.File) SpannableStringBuilder(android.text.SpannableStringBuilder)

Example 92 with ForegroundColorSpan

use of android.text.style.ForegroundColorSpan in project actor-platform by actorapp.

the class ChatListProcessor method process.

@Nullable
@Override
public Object process(@NotNull List<Message> items, @Nullable Object previous) {
    // Init tools
    if (mobileInvitePattern == null) {
        mobileInvitePattern = Pattern.compile("(actor:\\\\/\\\\/)(invite\\\\?token=)([0-9-a-z]{1,64})");
    }
    if (invitePattern == null) {
        invitePattern = Pattern.compile("(https:\\/\\/)(quit\\.email\\/join\\/)([0-9-a-z]{1,64})");
    }
    if (peoplePattern == null) {
        peoplePattern = Pattern.compile("(people:\\\\/\\\\/)([0-9]{1,20})");
    }
    if (mentionPattern == null) {
        mentionPattern = Pattern.compile("(@)([0-9a-zA-Z_]{5,32})");
    }
    ArrayList<PreprocessedData> preprocessedDatas = new ArrayList<PreprocessedData>();
    for (Message msg : items) {
        // Preprocess message
        // Assume user is cached
        messenger().getUser(msg.getSenderId());
        // Process reactions
        boolean isImage = msg.getContent() instanceof PhotoContent || msg.getContent() instanceof VideoContent || msg.getContent() instanceof LocationContent;
        boolean hasReactions = msg.getReactions() != null && msg.getReactions().size() > 0;
        Spannable reactions = null;
        if (hasReactions) {
            SpannableStringBuilder builder = new SpannableStringBuilder();
            SpannableString s;
            boolean hasMyReaction = false;
            for (Reaction r : msg.getReactions()) {
                s = new SpannableString(Integer.toString(r.getUids().size()).concat(r.getCode()).concat("  "));
                for (Integer uid : r.getUids()) {
                    if (uid == myUid()) {
                        hasMyReaction = true;
                        break;
                    }
                }
                s.setSpan(new ReactionSpan(r.getCode(), hasMyReaction, peer, msg.getRid(), isImage ? Color.WHITE : ActorSDK.sharedActor().style.getConvTimeColor()), 0, s.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                reactions = builder.append(s);
            }
        }
        // Process Content
        if (msg.getContent() instanceof TextContent) {
            int updatedCounter = msg.getContent().getUpdatedCounter();
            if (!preprocessedTexts.containsKey(msg.getRid()) || (!updatedTexts.containsKey(msg.getRid()) || updatedTexts.get(msg.getRid()) != updatedCounter)) {
                TextContent text = (TextContent) msg.getContent();
                Spannable spannableString = new SpannableString(text.getText());
                boolean hasSpannable = false;
                // Wait Emoji to load
                emoji().waitForEmoji();
                // Process markdown
                Spannable markdown = AndroidMarkdown.processText(text.getText());
                if (markdown != null) {
                    spannableString = markdown;
                    hasSpannable = true;
                }
                // Process links
                if (Linkify.addLinks(spannableString, Linkify.EMAIL_ADDRESSES | Linkify.PHONE_NUMBERS | Linkify.WEB_URLS)) {
                    hasSpannable = true;
                }
                if (fixLinkifyCustomLinks(spannableString, mobileInvitePattern, false)) {
                    hasSpannable = true;
                }
                if (fixLinkifyCustomLinks(spannableString, invitePattern, false)) {
                    hasSpannable = true;
                }
                if (fixLinkifyCustomLinks(spannableString, peoplePattern, true)) {
                    hasSpannable = true;
                }
                if (fixLinkifyCustomLinks(spannableString, mentionPattern, true)) {
                    hasSpannable = true;
                }
                // Append Sender name for groups
                if (isGroup && msg.getSenderId() != myUid()) {
                    String name;
                    UserVM userModel = users().get(msg.getSenderId());
                    if (userModel != null) {
                        String userName = userModel.getName().get();
                        if (userName.equals("Bot")) {
                            name = group.getName().get();
                        } else {
                            name = userName;
                        }
                    } else {
                        name = "???";
                    }
                    SpannableStringBuilder builder = new SpannableStringBuilder();
                    builder.append(name);
                    builder.setSpan(new ForegroundColorSpan(colors[Math.abs(msg.getSenderId()) % colors.length]), 0, name.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
                    builder.append("\n");
                    spannableString = builder.append(spannableString);
                    hasSpannable = true;
                }
                // Process Emoji
                if (SmileProcessor.containsEmoji(spannableString)) {
                    spannableString = emoji().processEmojiCompatMutable(spannableString, SmileProcessor.CONFIGURATION_BUBBLES);
                    hasSpannable = true;
                }
                updatedTexts.put(msg.getRid(), updatedCounter);
                preprocessedTexts.put(msg.getRid(), new PreprocessedTextData(reactions, text.getText(), hasSpannable ? spannableString : null));
            } else {
                PreprocessedTextData text = preprocessedTexts.get(msg.getRid());
                preprocessedTexts.put(msg.getRid(), new PreprocessedTextData(reactions, text.getText(), text.getSpannableString()));
            }
            preprocessedDatas.add(preprocessedTexts.get(msg.getRid()));
        } else if (msg.getContent() instanceof ContactContent) {
            ContactContent contact = (ContactContent) msg.getContent();
            String text = "";
            for (String phone : contact.getPhones()) {
                text += "\n".concat(phone);
            }
            for (String email : contact.getEmails()) {
                text += "\n".concat(email);
            }
            Spannable spannableString = new SpannableString(text);
            SpannableStringBuilder builder = new SpannableStringBuilder();
            String name;
            name = contact.getName();
            builder.append(name);
            builder.setSpan(new ForegroundColorSpan(colors[Math.abs(msg.getSenderId()) % colors.length]), 0, name.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
            //builder.append("\n");
            spannableString = builder.append(spannableString);
            preprocessedTexts.put(msg.getRid(), new PreprocessedTextData(reactions, text, spannableString));
            preprocessedDatas.add(preprocessedTexts.get(msg.getRid()));
        } else {
            // Nothing to do yet
            preprocessedDatas.add(new PreprocessedData(reactions));
        }
    }
    return new PreprocessedList(preprocessedDatas.toArray(new PreprocessedData[preprocessedDatas.size()]));
}
Also used : LocationContent(im.actor.core.entity.content.LocationContent) VideoContent(im.actor.core.entity.content.VideoContent) Message(im.actor.core.entity.Message) ForegroundColorSpan(android.text.style.ForegroundColorSpan) ArrayList(java.util.ArrayList) SpannableString(android.text.SpannableString) Reaction(im.actor.core.entity.Reaction) ContactContent(im.actor.core.entity.content.ContactContent) SpannableString(android.text.SpannableString) ReactionSpan(im.actor.sdk.controllers.conversation.view.ReactionSpan) UserVM(im.actor.core.viewmodel.UserVM) TextContent(im.actor.core.entity.content.TextContent) Spannable(android.text.Spannable) SpannableStringBuilder(android.text.SpannableStringBuilder) PhotoContent(im.actor.core.entity.content.PhotoContent) Nullable(org.jetbrains.annotations.Nullable)

Example 93 with ForegroundColorSpan

use of android.text.style.ForegroundColorSpan in project actor-platform by actorapp.

the class SearchHighlight method highlightMentionsQuery.

public static Spannable highlightMentionsQuery(String src, String query, int color) {
    String matchString = src.toLowerCase();
    SpannableStringBuilder builder = new SpannableStringBuilder(src);
    int index = matchString.indexOf(" " + query);
    if (matchString.startsWith(query) || Strings.transliterate(matchString).startsWith(query)) {
        builder.setSpan(new ForegroundColorSpan(color), 0, query.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
    } else if (index >= 0) {
        builder.setSpan(new ForegroundColorSpan(color), index + 1, index + 1 + query.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
    } else if (query.length() == 2) {
        builder.setSpan(new ForegroundColorSpan(color), 0, 1, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
        int spaceIndex = matchString.indexOf(" ");
        builder.setSpan(new ForegroundColorSpan(color), spaceIndex + 1, spaceIndex + 2, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
    }
    return builder;
}
Also used : ForegroundColorSpan(android.text.style.ForegroundColorSpan) SpannableStringBuilder(android.text.SpannableStringBuilder)

Example 94 with ForegroundColorSpan

use of android.text.style.ForegroundColorSpan in project actor-platform by actorapp.

the class SearchHighlight method highlightQuery.

public static Spannable highlightQuery(String src, String query, int color) {
    String matchString = src.toLowerCase().replace("@", " ");
    SpannableStringBuilder builder = new SpannableStringBuilder(src);
    if (matchString.startsWith(query)) {
        builder.setSpan(new ForegroundColorSpan(color), 0, query.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
    } else {
        int index = matchString.indexOf(" " + query);
        if (index >= 0) {
            builder.setSpan(new ForegroundColorSpan(color), index + 1, index + 1 + query.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
        }
    }
    return builder;
}
Also used : ForegroundColorSpan(android.text.style.ForegroundColorSpan) SpannableStringBuilder(android.text.SpannableStringBuilder)

Example 95 with ForegroundColorSpan

use of android.text.style.ForegroundColorSpan in project Signal-Android by WhisperSystems.

the class ContactSelectionListAdapter method getSpannedHeaderString.

private CharSequence getSpannedHeaderString(int position) {
    final String headerString = getHeaderString(position);
    if (isPush(position)) {
        SpannableString spannable = new SpannableString(headerString);
        spannable.setSpan(new ForegroundColorSpan(getContext().getResources().getColor(R.color.signal_primary)), 0, headerString.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        return spannable;
    } else {
        return headerString;
    }
}
Also used : SpannableString(android.text.SpannableString) ForegroundColorSpan(android.text.style.ForegroundColorSpan) SpannableString(android.text.SpannableString)

Aggregations

ForegroundColorSpan (android.text.style.ForegroundColorSpan)157 SpannableStringBuilder (android.text.SpannableStringBuilder)57 SpannableString (android.text.SpannableString)50 StyleSpan (android.text.style.StyleSpan)25 TextView (android.widget.TextView)25 ImageSpan (android.text.style.ImageSpan)23 Spannable (android.text.Spannable)22 RelativeSizeSpan (android.text.style.RelativeSizeSpan)22 View (android.view.View)22 BackgroundColorSpan (android.text.style.BackgroundColorSpan)19 TypefaceSpan (android.text.style.TypefaceSpan)16 StrikethroughSpan (android.text.style.StrikethroughSpan)14 UnderlineSpan (android.text.style.UnderlineSpan)13 Drawable (android.graphics.drawable.Drawable)12 CharacterStyle (android.text.style.CharacterStyle)11 EditText (android.widget.EditText)11 AbsoluteSizeSpan (android.text.style.AbsoluteSizeSpan)10 SuperscriptSpan (android.text.style.SuperscriptSpan)8 LinearLayout (android.widget.LinearLayout)8 URLSpan (android.text.style.URLSpan)7