Search in sources :

Example 36 with Conversation

use of eu.siacs.conversations.entities.Conversation in project Conversations by siacs.

the class MessageAdapter method displayTextMessage.

private void displayTextMessage(final ViewHolder viewHolder, final Message message, boolean darkBackground, int type) {
    viewHolder.download_button.setVisibility(View.GONE);
    viewHolder.image.setVisibility(View.GONE);
    viewHolder.audioPlayer.setVisibility(View.GONE);
    viewHolder.messageBody.setVisibility(View.VISIBLE);
    if (darkBackground) {
        viewHolder.messageBody.setTextAppearance(getContext(), R.style.TextAppearance_Conversations_Body1_OnDark);
    } else {
        viewHolder.messageBody.setTextAppearance(getContext(), R.style.TextAppearance_Conversations_Body1);
    }
    viewHolder.messageBody.setHighlightColor(ContextCompat.getColor(activity, darkBackground ? (type == SENT || !mUseGreenBackground ? R.color.black26 : R.color.grey800) : R.color.grey500));
    viewHolder.messageBody.setTypeface(null, Typeface.NORMAL);
    if (message.getBody() != null) {
        final String nick = UIHelper.getMessageDisplayName(message);
        SpannableStringBuilder body = message.getMergedBody();
        boolean hasMeCommand = message.hasMeCommand();
        if (hasMeCommand) {
            body = body.replace(0, Message.ME_COMMAND.length(), nick + " ");
        }
        if (body.length() > Config.MAX_DISPLAY_MESSAGE_CHARS) {
            body = new SpannableStringBuilder(body, 0, Config.MAX_DISPLAY_MESSAGE_CHARS);
            body.append("\u2026");
        }
        Message.MergeSeparator[] mergeSeparators = body.getSpans(0, body.length(), Message.MergeSeparator.class);
        for (Message.MergeSeparator mergeSeparator : mergeSeparators) {
            int start = body.getSpanStart(mergeSeparator);
            int end = body.getSpanEnd(mergeSeparator);
            body.setSpan(new DividerSpan(true), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        }
        boolean startsWithQuote = handleTextQuotes(body, darkBackground);
        if (!message.isPrivateMessage()) {
            if (hasMeCommand) {
                body.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), 0, nick.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            }
        } else {
            String privateMarker;
            if (message.getStatus() <= Message.STATUS_RECEIVED) {
                privateMarker = activity.getString(R.string.private_message);
            } else {
                Jid cp = message.getCounterpart();
                privateMarker = activity.getString(R.string.private_message_to, Strings.nullToEmpty(cp == null ? null : cp.getResource()));
            }
            body.insert(0, privateMarker);
            int privateMarkerIndex = privateMarker.length();
            if (startsWithQuote) {
                body.insert(privateMarkerIndex, "\n\n");
                body.setSpan(new DividerSpan(false), privateMarkerIndex, privateMarkerIndex + 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            } else {
                body.insert(privateMarkerIndex, " ");
            }
            body.setSpan(new ForegroundColorSpan(getMessageTextColor(darkBackground, false)), 0, privateMarkerIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            body.setSpan(new StyleSpan(Typeface.BOLD), 0, privateMarkerIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            if (hasMeCommand) {
                body.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), privateMarkerIndex + 1, privateMarkerIndex + 1 + nick.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            }
        }
        if (message.getConversation().getMode() == Conversation.MODE_MULTI && message.getStatus() == Message.STATUS_RECEIVED) {
            if (message.getConversation() instanceof Conversation) {
                final Conversation conversation = (Conversation) message.getConversation();
                Pattern pattern = NotificationService.generateNickHighlightPattern(conversation.getMucOptions().getActualNick());
                Matcher matcher = pattern.matcher(body);
                while (matcher.find()) {
                    body.setSpan(new StyleSpan(Typeface.BOLD), matcher.start(), matcher.end(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                }
            }
        }
        Matcher matcher = Emoticons.getEmojiPattern(body).matcher(body);
        while (matcher.find()) {
            if (matcher.start() < matcher.end()) {
                body.setSpan(new RelativeSizeSpan(1.2f), matcher.start(), matcher.end(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            }
        }
        StylingHelper.format(body, viewHolder.messageBody.getCurrentTextColor());
        if (highlightedTerm != null) {
            StylingHelper.highlight(activity, body, highlightedTerm, StylingHelper.isDarkText(viewHolder.messageBody));
        }
        MyLinkify.addLinks(body, true);
        viewHolder.messageBody.setAutoLinkMask(0);
        viewHolder.messageBody.setText(EmojiWrapper.transform(body));
        viewHolder.messageBody.setMovementMethod(ClickableMovementMethod.getInstance());
    } else {
        viewHolder.messageBody.setText("");
        viewHolder.messageBody.setTextIsSelectable(false);
    }
}
Also used : Pattern(java.util.regex.Pattern) Message(eu.siacs.conversations.entities.Message) Jid(eu.siacs.conversations.xmpp.Jid) ForegroundColorSpan(android.text.style.ForegroundColorSpan) Matcher(java.util.regex.Matcher) Conversation(eu.siacs.conversations.entities.Conversation) SpannableString(android.text.SpannableString) RelativeSizeSpan(android.text.style.RelativeSizeSpan) StyleSpan(android.text.style.StyleSpan) DividerSpan(eu.siacs.conversations.ui.text.DividerSpan) SpannableStringBuilder(android.text.SpannableStringBuilder)

Example 37 with Conversation

use of eu.siacs.conversations.entities.Conversation in project Conversations by siacs.

the class MessageParser method handleErrorMessage.

private boolean handleErrorMessage(final Account account, final MessagePacket packet) {
    if (packet.getType() == MessagePacket.TYPE_ERROR) {
        if (packet.fromServer(account)) {
            final Pair<MessagePacket, Long> forwarded = packet.getForwardedMessagePacket("received", "urn:xmpp:carbons:2");
            if (forwarded != null) {
                return handleErrorMessage(account, forwarded.first);
            }
        }
        final Jid from = packet.getFrom();
        final String id = packet.getId();
        if (from != null && id != null) {
            if (id.startsWith(JingleRtpConnection.JINGLE_MESSAGE_PROPOSE_ID_PREFIX)) {
                final String sessionId = id.substring(JingleRtpConnection.JINGLE_MESSAGE_PROPOSE_ID_PREFIX.length());
                mXmppConnectionService.getJingleConnectionManager().updateProposedSessionDiscovered(account, from, sessionId, JingleConnectionManager.DeviceDiscoveryState.FAILED);
                return true;
            }
            if (id.startsWith(JingleRtpConnection.JINGLE_MESSAGE_PROCEED_ID_PREFIX)) {
                final String sessionId = id.substring(JingleRtpConnection.JINGLE_MESSAGE_PROCEED_ID_PREFIX.length());
                mXmppConnectionService.getJingleConnectionManager().failProceed(account, from, sessionId);
                return true;
            }
            mXmppConnectionService.markMessage(account, from.asBareJid(), id, Message.STATUS_SEND_FAILED, extractErrorMessage(packet));
            final Element error = packet.findChild("error");
            final boolean pingWorthyError = error != null && (error.hasChild("not-acceptable") || error.hasChild("remote-server-timeout") || error.hasChild("remote-server-not-found"));
            if (pingWorthyError) {
                Conversation conversation = mXmppConnectionService.find(account, from);
                if (conversation != null && conversation.getMode() == Conversational.MODE_MULTI) {
                    if (conversation.getMucOptions().online()) {
                        Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": received ping worthy error for seemingly online muc at " + from);
                        mXmppConnectionService.mucSelfPingAndRejoin(conversation);
                    }
                }
            }
        }
        return true;
    }
    return false;
}
Also used : MessagePacket(eu.siacs.conversations.xmpp.stanzas.MessagePacket) InvalidJid(eu.siacs.conversations.xmpp.InvalidJid) Jid(eu.siacs.conversations.xmpp.Jid) Element(eu.siacs.conversations.xml.Element) Conversation(eu.siacs.conversations.entities.Conversation)

Example 38 with Conversation

use of eu.siacs.conversations.entities.Conversation in project Conversations by siacs.

the class PresenceParser method parseConferencePresence.

public void parseConferencePresence(PresencePacket packet, Account account) {
    final Conversation conversation = packet.getFrom() == null ? null : mXmppConnectionService.find(account, packet.getFrom().asBareJid());
    if (conversation != null) {
        final MucOptions mucOptions = conversation.getMucOptions();
        boolean before = mucOptions.online();
        int count = mucOptions.getUserCount();
        final List<MucOptions.User> tileUserBefore = mucOptions.getUsers(5);
        processConferencePresence(packet, conversation);
        final List<MucOptions.User> tileUserAfter = mucOptions.getUsers(5);
        if (!tileUserAfter.equals(tileUserBefore)) {
            mXmppConnectionService.getAvatarService().clear(mucOptions);
        }
        if (before != mucOptions.online() || (mucOptions.online() && count != mucOptions.getUserCount())) {
            mXmppConnectionService.updateConversationUi();
        } else if (mucOptions.online()) {
            mXmppConnectionService.updateMucRosterUi();
        }
    }
}
Also used : MucOptions(eu.siacs.conversations.entities.MucOptions) Conversation(eu.siacs.conversations.entities.Conversation)

Example 39 with Conversation

use of eu.siacs.conversations.entities.Conversation in project Conversations by siacs.

the class DatabaseBackend method getConversations.

public CopyOnWriteArrayList<Conversation> getConversations(int status) {
    CopyOnWriteArrayList<Conversation> list = new CopyOnWriteArrayList<>();
    SQLiteDatabase db = this.getReadableDatabase();
    String[] selectionArgs = { Integer.toString(status) };
    Cursor cursor = db.rawQuery("select * from " + Conversation.TABLENAME + " where " + Conversation.STATUS + " = ? and " + Conversation.CONTACTJID + " is not null order by " + Conversation.CREATED + " desc", selectionArgs);
    while (cursor.moveToNext()) {
        final Conversation conversation = Conversation.fromCursor(cursor);
        if (conversation.getJid() instanceof InvalidJid) {
            continue;
        }
        list.add(conversation);
    }
    cursor.close();
    return list;
}
Also used : SQLiteDatabase(android.database.sqlite.SQLiteDatabase) Conversation(eu.siacs.conversations.entities.Conversation) Cursor(android.database.Cursor) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) InvalidJid(eu.siacs.conversations.xmpp.InvalidJid)

Example 40 with Conversation

use of eu.siacs.conversations.entities.Conversation in project Conversations by siacs.

the class MucDetailsContextMenuHelper method onContextItemSelected.

public static boolean onContextItemSelected(MenuItem item, User user, XmppActivity activity, final String fingerprint) {
    final Conversation conversation = user.getConversation();
    final XmppConnectionService.OnAffiliationChanged onAffiliationChanged = activity instanceof XmppConnectionService.OnAffiliationChanged ? (XmppConnectionService.OnAffiliationChanged) activity : null;
    Jid jid = user.getRealJid();
    switch(item.getItemId()) {
        case R.id.action_contact_details:
            final Jid realJid = user.getRealJid();
            final Account account = conversation.getAccount();
            final Contact contact = realJid == null ? null : account.getRoster().getContact(realJid);
            if (contact != null) {
                activity.switchToContactDetails(contact, fingerprint);
            }
            return true;
        case R.id.start_conversation:
            startConversation(user, activity);
            return true;
        case R.id.give_admin_privileges:
            activity.xmppConnectionService.changeAffiliationInConference(conversation, jid, MucOptions.Affiliation.ADMIN, onAffiliationChanged);
            return true;
        case R.id.give_membership:
        case R.id.remove_admin_privileges:
        case R.id.revoke_owner_privileges:
            activity.xmppConnectionService.changeAffiliationInConference(conversation, jid, MucOptions.Affiliation.MEMBER, onAffiliationChanged);
            return true;
        case R.id.give_owner_privileges:
            activity.xmppConnectionService.changeAffiliationInConference(conversation, jid, MucOptions.Affiliation.OWNER, onAffiliationChanged);
            return true;
        case R.id.remove_membership:
            activity.xmppConnectionService.changeAffiliationInConference(conversation, jid, MucOptions.Affiliation.NONE, onAffiliationChanged);
            return true;
        case R.id.remove_from_room:
            removeFromRoom(user, activity, onAffiliationChanged);
            return true;
        case R.id.ban_from_conference:
            activity.xmppConnectionService.changeAffiliationInConference(conversation, jid, MucOptions.Affiliation.OUTCAST, onAffiliationChanged);
            if (user.getRole() != MucOptions.Role.NONE) {
                activity.xmppConnectionService.changeRoleInConference(conversation, user.getName(), MucOptions.Role.NONE);
            }
            return true;
        case R.id.send_private_message:
            if (activity instanceof ConversationsActivity) {
                ConversationFragment conversationFragment = ConversationFragment.get(activity);
                if (conversationFragment != null) {
                    conversationFragment.privateMessageWith(user.getFullJid());
                    return true;
                }
            }
            activity.privateMsgInMuc(conversation, user.getName());
            return true;
        case R.id.invite:
            if (user.getAffiliation().ranks(MucOptions.Affiliation.MEMBER)) {
                activity.xmppConnectionService.directInvite(conversation, jid.asBareJid());
            } else {
                activity.xmppConnectionService.invite(conversation, jid);
            }
            return true;
        default:
            return false;
    }
}
Also used : Account(eu.siacs.conversations.entities.Account) XmppConnectionService(eu.siacs.conversations.services.XmppConnectionService) Jid(eu.siacs.conversations.xmpp.Jid) Conversation(eu.siacs.conversations.entities.Conversation) ConversationFragment(eu.siacs.conversations.ui.ConversationFragment) ConversationsActivity(eu.siacs.conversations.ui.ConversationsActivity) Contact(eu.siacs.conversations.entities.Contact)

Aggregations

Conversation (eu.siacs.conversations.entities.Conversation)110 Account (eu.siacs.conversations.entities.Account)27 Message (eu.siacs.conversations.entities.Message)24 Jid (eu.siacs.conversations.xmpp.Jid)22 Contact (eu.siacs.conversations.entities.Contact)17 MucOptions (eu.siacs.conversations.entities.MucOptions)10 Intent (android.content.Intent)9 Element (eu.siacs.conversations.xml.Element)9 PendingIntent (android.app.PendingIntent)8 XmppAxolotlMessage (eu.siacs.conversations.crypto.axolotl.XmppAxolotlMessage)8 MessagePacket (eu.siacs.conversations.xmpp.stanzas.MessagePacket)8 Uri (android.net.Uri)7 Conversational (eu.siacs.conversations.entities.Conversational)7 InvalidJidException (eu.siacs.conversations.xmpp.jid.InvalidJidException)7 SuppressLint (android.annotation.SuppressLint)6 SpannableString (android.text.SpannableString)6 XmppConnection (eu.siacs.conversations.xmpp.XmppConnection)6 Jid (eu.siacs.conversations.xmpp.jid.Jid)6 ArrayList (java.util.ArrayList)6 Fragment (android.app.Fragment)4