Search in sources :

Example 26 with Message

use of im.actor.core.entity.Message in project actor-platform by actorapp.

the class MessagesFragment method recalculateUnreadMessageIfNeeded.

// 
// Unread Messages
// 
private void recalculateUnreadMessageIfNeeded() {
    Log.d("READ_DEBUG", "trying to scroll to unread");
    // Scroll to unread only in primary mode
    if (!isPrimaryMode) {
        return;
    }
    BindedDisplayList<Message> list = getDisplayList();
    if (firstUnread == -1) {
        firstUnread = conversationVM.getLastReadMessageDate();
    }
    // Do not scroll to unread twice
    if (isUnreadLoaded) {
        return;
    }
    // Ignore if list is not loaded
    if (list.getSize() == 0) {
        return;
    }
    // refresh list if top message is too old
    if (getLastMessage(getDisplayList()).getSortDate() < firstUnread && !reloaded) {
        reloaded = true;
        getDisplayList().initCenter(firstUnread, true);
        return;
    }
    // If List is not empty: mark as loaded
    isUnreadLoaded = true;
    // If don't have unread message date: nothing to do
    if (firstUnread <= 0) {
        return;
    }
    // Searching for first unread message
    int index = -1;
    long unread = -1;
    for (int i = list.getSize() - 1; i >= 0; i--) {
        Message message = list.getItem(i);
        if (message.getSenderId() == messenger().myUid()) {
            continue;
        }
        if (message.getSortDate() > firstUnread) {
            index = i;
            unread = message.getRid();
            break;
        }
    }
    // If have some unread messages: scroll to it
    if (index >= 0) {
        scrollToUnread(unread, index);
    } else {
        scrollToUnread(0, 0);
    }
}
Also used : Message(im.actor.core.entity.Message)

Example 27 with Message

use of im.actor.core.entity.Message in project actor-platform by actorapp.

the class MessagesFragment method onCreateView.

// 
// View
// 
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    // 
    try {
        peer = Peer.fromBytes(getArguments().getByteArray("EXTRA_PEER"));
        conversationVM = messenger().getConversationVM(peer);
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
    // 
    // Display List
    // 
    BindedDisplayList<Message> displayList = onCreateDisplayList();
    if (isPrimaryMode) {
        displayList.setLinearLayoutCallback(b -> {
            if (layoutManager != null) {
                layoutManager.setStackFromEnd(b);
            }
        });
    }
    // 
    // Main View
    // 
    View res = inflate(inflater, container, R.layout.fragment_messages, displayList);
    progressView = (CircularProgressBar) res.findViewById(R.id.loadingProgress);
    progressView.setIndeterminate(true);
    progressView.setVisibility(View.INVISIBLE);
    // 
    // Loading background
    // 
    Drawable background;
    int[] backgrounds = ActorSDK.sharedActor().style.getDefaultBackgrouds();
    String selectedWallpaper = messenger().getSelectedWallpaper();
    if (selectedWallpaper != null) {
        background = getResources().getDrawable(backgrounds[0]);
        if (selectedWallpaper.startsWith("local:")) {
            for (int i = 1; i < backgrounds.length; i++) {
                if (getResources().getResourceEntryName(backgrounds[i]).equals(selectedWallpaper.replaceAll("local:", ""))) {
                    background = getResources().getDrawable(backgrounds[i]);
                }
            }
        } else {
            background = Drawable.createFromPath(BaseActorSettingsFragment.getWallpaperFile());
        }
    } else {
        background = getResources().getDrawable(backgrounds[0]);
    }
    ((ImageView) res.findViewById(R.id.chatBackgroundView)).setImageDrawable(background);
    // 
    // List Padding
    // 
    View footer = new View(getActivity());
    footer.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, Screen.dp(8)));
    // Add Footer as Header because of reverse layout
    addHeaderView(footer);
    View header = new View(getActivity());
    header.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, Screen.dp(64)));
    // Add Header as Footer because of reverse layout
    addFooterView(header);
    // 
    // Init unread message index if available
    // 
    recalculateUnreadMessageIfNeeded();
    return res;
}
Also used : Message(im.actor.core.entity.Message) FrameLayout(android.widget.FrameLayout) Drawable(android.graphics.drawable.Drawable) IOException(java.io.IOException) ImageView(android.widget.ImageView) ImageView(android.widget.ImageView) View(android.view.View) RecyclerView(android.support.v7.widget.RecyclerView)

Example 28 with Message

use of im.actor.core.entity.Message 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)

Aggregations

Message (im.actor.core.entity.Message)28 ApiMessage (im.actor.core.api.ApiMessage)13 ApiTextMessage (im.actor.core.api.ApiTextMessage)12 ApiDocumentMessage (im.actor.core.api.ApiDocumentMessage)11 ApiJsonMessage (im.actor.core.api.ApiJsonMessage)11 RequestSendMessage (im.actor.core.api.rpc.RequestSendMessage)11 PendingMessage (im.actor.core.modules.messaging.actions.entity.PendingMessage)11 UpdateMessage (im.actor.core.api.updates.UpdateMessage)7 TextContent (im.actor.core.entity.content.TextContent)6 RouterOutgoingMessage (im.actor.core.modules.messaging.router.entity.RouterOutgoingMessage)6 ArrayList (java.util.ArrayList)6 ConversationState (im.actor.core.entity.ConversationState)5 Peer (im.actor.core.entity.Peer)5 AbsContent (im.actor.core.entity.content.AbsContent)5 Reaction (im.actor.core.entity.Reaction)3 UserVM (im.actor.core.viewmodel.UserVM)3 Void (im.actor.runtime.actors.messages.Void)3 ApiPeer (im.actor.core.api.ApiPeer)2 Dialog (im.actor.core.entity.Dialog)2 Sticker (im.actor.core.entity.Sticker)2