otr conversations implementation
This commit is contained in:
parent
389074e802
commit
973a48ef62
|
@ -188,6 +188,7 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
|
||||||
private int mode;
|
private int mode;
|
||||||
private JSONObject attributes;
|
private JSONObject attributes;
|
||||||
private Jid nextCounterpart;
|
private Jid nextCounterpart;
|
||||||
|
private boolean hasPermanentCounterpart;
|
||||||
private transient SessionImpl otrSession;
|
private transient SessionImpl otrSession;
|
||||||
private transient String otrFingerprint = null;
|
private transient String otrFingerprint = null;
|
||||||
private Smp mSmp = new Smp();
|
private Smp mSmp = new Smp();
|
||||||
|
@ -229,6 +230,9 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
|
||||||
this.attributes = new JSONObject();
|
this.attributes = new JSONObject();
|
||||||
}
|
}
|
||||||
this.nextCounterpart = nextCounterpart;
|
this.nextCounterpart = nextCounterpart;
|
||||||
|
if (nextCounterpart != null) {
|
||||||
|
hasPermanentCounterpart = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getContactUuid() {
|
public String getContactUuid() {
|
||||||
|
@ -937,7 +941,7 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
|
||||||
values.put(STATUS, status);
|
values.put(STATUS, status);
|
||||||
values.put(MODE, mode);
|
values.put(MODE, mode);
|
||||||
|
|
||||||
if (nextCounterpart != null) {
|
if (nextCounterpart != null && hasPermanentCounterpart) {
|
||||||
values.put(NEXT_COUNTERPART, nextCounterpart.toString());
|
values.put(NEXT_COUNTERPART, nextCounterpart.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -963,6 +967,7 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
|
||||||
presence,
|
presence,
|
||||||
"xmpp");
|
"xmpp");
|
||||||
this.otrSession = new SessionImpl(sessionId, getAccount().getOtrService());
|
this.otrSession = new SessionImpl(sessionId, getAccount().getOtrService());
|
||||||
|
android.util.Log.e("41fd", "new session " + System.identityHashCode(this), new RuntimeException());
|
||||||
try {
|
try {
|
||||||
if (sendStart) {
|
if (sendStart) {
|
||||||
this.otrSession.startSession();
|
this.otrSession.startSession();
|
||||||
|
@ -981,6 +986,7 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
|
||||||
}
|
}
|
||||||
|
|
||||||
public void resetOtrSession() {
|
public void resetOtrSession() {
|
||||||
|
android.util.Log.e("41fd", "reset " + System.identityHashCode(this), new RuntimeException());
|
||||||
this.otrFingerprint = null;
|
this.otrFingerprint = null;
|
||||||
this.otrSession = null;
|
this.otrSession = null;
|
||||||
this.mSmp.hint = null;
|
this.mSmp.hint = null;
|
||||||
|
@ -1109,6 +1115,10 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
|
||||||
return this.nextCounterpart;
|
return this.nextCounterpart;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasPermanentCounterpart() {
|
||||||
|
return hasPermanentCounterpart;
|
||||||
|
}
|
||||||
|
|
||||||
public void setNextCounterpart(Jid jid) {
|
public void setNextCounterpart(Jid jid) {
|
||||||
this.nextCounterpart = jid;
|
this.nextCounterpart = jid;
|
||||||
}
|
}
|
||||||
|
@ -1117,6 +1127,11 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
|
||||||
if (!Config.supportOmemo() && !Config.supportOpenPgp() && !Config.supportOtr()) {
|
if (!Config.supportOmemo() && !Config.supportOpenPgp() && !Config.supportOtr()) {
|
||||||
return Message.ENCRYPTION_NONE;
|
return Message.ENCRYPTION_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Config.supportOtr() && nextCounterpart != null && getMode() == MODE_SINGLE && hasPermanentCounterpart) {
|
||||||
|
return Message.ENCRYPTION_OTR;
|
||||||
|
}
|
||||||
|
|
||||||
if (OmemoSetting.isAlways()) {
|
if (OmemoSetting.isAlways()) {
|
||||||
return suitableForOmemoByDefault(this) ? Message.ENCRYPTION_AXOLOTL : Message.ENCRYPTION_NONE;
|
return suitableForOmemoByDefault(this) ? Message.ENCRYPTION_AXOLOTL : Message.ENCRYPTION_NONE;
|
||||||
}
|
}
|
||||||
|
@ -1127,7 +1142,7 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
|
||||||
defaultEncryption = Message.ENCRYPTION_NONE;
|
defaultEncryption = Message.ENCRYPTION_NONE;
|
||||||
}
|
}
|
||||||
int encryption = this.getIntAttribute(ATTRIBUTE_NEXT_ENCRYPTION, defaultEncryption);
|
int encryption = this.getIntAttribute(ATTRIBUTE_NEXT_ENCRYPTION, defaultEncryption);
|
||||||
if (encryption == Message.ENCRYPTION_OTR || encryption < 0) {
|
if (encryption < 0) {
|
||||||
return defaultEncryption;
|
return defaultEncryption;
|
||||||
} else {
|
} else {
|
||||||
return encryption;
|
return encryption;
|
||||||
|
@ -1393,14 +1408,14 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
|
||||||
String res2 = nextCounterpart == null ? null : nextCounterpart.getResource();
|
String res2 = nextCounterpart == null ? null : nextCounterpart.getResource();
|
||||||
|
|
||||||
if (nextCounterpart == null) {
|
if (nextCounterpart == null) {
|
||||||
if (!message.isPrivateMessage()) {
|
if (!message.isPrivateMessage() && message.encryption != Message.ENCRYPTION_OTR) {
|
||||||
synchronized (this.messages) {
|
synchronized (this.messages) {
|
||||||
this.messages.add(message);
|
this.messages.add(message);
|
||||||
actualizeReplyMessages(this.messages, List.of(message));
|
actualizeReplyMessages(this.messages, List.of(message));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (message.isPrivateMessage() && Objects.equals(res1, res2)) {
|
if ((message.isPrivateMessage() || message.encryption == Message.ENCRYPTION_OTR) && Objects.equals(res1, res2)) {
|
||||||
synchronized (this.messages) {
|
synchronized (this.messages) {
|
||||||
this.messages.add(message);
|
this.messages.add(message);
|
||||||
actualizeReplyMessages(this.messages, List.of(message));
|
actualizeReplyMessages(this.messages, List.of(message));
|
||||||
|
@ -1422,14 +1437,14 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nextCounterpart == null) {
|
if (nextCounterpart == null) {
|
||||||
if (!message.isPrivateMessage()) {
|
if (!message.isPrivateMessage() && message.encryption != Message.ENCRYPTION_OTR) {
|
||||||
synchronized (this.messages) {
|
synchronized (this.messages) {
|
||||||
properListToAdd.add(Math.min(offset, properListToAdd.size()), message);
|
properListToAdd.add(Math.min(offset, properListToAdd.size()), message);
|
||||||
actualizeReplyMessages(properListToAdd, List.of(message));
|
actualizeReplyMessages(properListToAdd, List.of(message));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (message.isPrivateMessage() && Objects.equals(res1, res2)) {
|
if ((message.isPrivateMessage() || message.encryption == Message.ENCRYPTION_OTR) && Objects.equals(res1, res2)) {
|
||||||
synchronized (this.messages) {
|
synchronized (this.messages) {
|
||||||
properListToAdd.add(Math.min(offset, properListToAdd.size()), message);
|
properListToAdd.add(Math.min(offset, properListToAdd.size()), message);
|
||||||
actualizeReplyMessages(properListToAdd, List.of(message));
|
actualizeReplyMessages(properListToAdd, List.of(message));
|
||||||
|
@ -1453,7 +1468,7 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
|
||||||
|
|
||||||
if (nextCounterpart == null) {
|
if (nextCounterpart == null) {
|
||||||
for(Message m : messages) {
|
for(Message m : messages) {
|
||||||
if (!m.isPrivateMessage()) {
|
if (!m.isPrivateMessage() && m.encryption != Message.ENCRYPTION_OTR) {
|
||||||
newM.add(m);
|
newM.add(m);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1464,7 +1479,7 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
|
||||||
String res2 = nextCounterpart == null ? null : nextCounterpart.getResource();
|
String res2 = nextCounterpart == null ? null : nextCounterpart.getResource();
|
||||||
|
|
||||||
|
|
||||||
if (m.isPrivateMessage() && Objects.equals(res1, res2)) {
|
if ((m.isPrivateMessage() || m.encryption == Message.ENCRYPTION_OTR) && Objects.equals(res1, res2)) {
|
||||||
newM.add(m);
|
newM.add(m);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,8 @@ import android.text.Html;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
|
|
||||||
|
import com.google.common.base.Strings;
|
||||||
|
|
||||||
import net.java.otr4j.session.Session;
|
import net.java.otr4j.session.Session;
|
||||||
import net.java.otr4j.session.SessionStatus;
|
import net.java.otr4j.session.SessionStatus;
|
||||||
|
|
||||||
|
@ -594,7 +596,9 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
|
||||||
|
|
||||||
final boolean conversationIsProbablyMuc = isTypeGroupChat || mucUserElement != null || account.getXmppConnection().getMucServersWithholdAccount().contains(counterpart.getDomain().toEscapedString());
|
final boolean conversationIsProbablyMuc = isTypeGroupChat || mucUserElement != null || account.getXmppConnection().getMucServersWithholdAccount().contains(counterpart.getDomain().toEscapedString());
|
||||||
|
|
||||||
if (conversationIsProbablyMuc && !isTypeGroupChat) {
|
final boolean isOTR = body != null && body.content.startsWith("?OTR") && Config.supportOtr();
|
||||||
|
|
||||||
|
if ((conversationIsProbablyMuc && !isTypeGroupChat) || (!Strings.isNullOrEmpty(counterpart.getResource()) && isOTR)) {
|
||||||
nextCounterpart = counterpart;
|
nextCounterpart = counterpart;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -658,7 +662,7 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final Message message;
|
final Message message;
|
||||||
if (body != null && body.content.startsWith("?OTR") && Config.supportOtr()) {
|
if (isOTR) {
|
||||||
if (!isForwarded && !isTypeGroupChat && isProperlyAddressed && !conversationMultiMode) {
|
if (!isForwarded && !isTypeGroupChat && isProperlyAddressed && !conversationMultiMode) {
|
||||||
message = parseOtrChat(body.content, from, remoteMsgId, conversation);
|
message = parseOtrChat(body.content, from, remoteMsgId, conversation);
|
||||||
if (message == null) {
|
if (message == null) {
|
||||||
|
|
|
@ -50,6 +50,7 @@ import eu.siacs.conversations.crypto.axolotl.SQLiteAxolotlStore;
|
||||||
import eu.siacs.conversations.entities.Account;
|
import eu.siacs.conversations.entities.Account;
|
||||||
import eu.siacs.conversations.entities.Contact;
|
import eu.siacs.conversations.entities.Contact;
|
||||||
import eu.siacs.conversations.entities.Conversation;
|
import eu.siacs.conversations.entities.Conversation;
|
||||||
|
import eu.siacs.conversations.entities.Conversational;
|
||||||
import eu.siacs.conversations.entities.Message;
|
import eu.siacs.conversations.entities.Message;
|
||||||
import eu.siacs.conversations.entities.PresenceTemplate;
|
import eu.siacs.conversations.entities.PresenceTemplate;
|
||||||
import eu.siacs.conversations.entities.Roster;
|
import eu.siacs.conversations.entities.Roster;
|
||||||
|
@ -887,30 +888,40 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
||||||
String comparsionOperation = isForward ? ">?" : "<?";
|
String comparsionOperation = isForward ? ">?" : "<?";
|
||||||
String sorting = isForward ? " ASC" : " DESC";
|
String sorting = isForward ? " ASC" : " DESC";
|
||||||
if (timestamp == -1) {
|
if (timestamp == -1) {
|
||||||
if (conversation.getNextCounterpart() == null) {
|
if (conversation.getNextCounterpart() != null && conversation.hasPermanentCounterpart() && conversation.getMode() == Conversational.MODE_MULTI) {
|
||||||
String[] selectionArgs = {conversation.getUuid()};
|
|
||||||
cursor = db.query(Message.TABLENAME, null, Message.CONVERSATION
|
|
||||||
+ "=?", selectionArgs, null, null, Message.TIME_SENT
|
|
||||||
+ sorting, String.valueOf(limit));
|
|
||||||
} else {
|
|
||||||
String[] selectionArgs = {conversation.getUuid(), String.valueOf(Message.TYPE_PRIVATE), String.valueOf(Message.TYPE_PRIVATE_FILE), conversation.getNextCounterpart().toString()};
|
String[] selectionArgs = {conversation.getUuid(), String.valueOf(Message.TYPE_PRIVATE), String.valueOf(Message.TYPE_PRIVATE_FILE), conversation.getNextCounterpart().toString()};
|
||||||
cursor = db.query(Message.TABLENAME, null, Message.CONVERSATION
|
cursor = db.query(Message.TABLENAME, null, Message.CONVERSATION
|
||||||
+ "=? and (" + Message.TYPE + "=? or " + Message.TYPE + "=?) and " + Message.COUNTERPART + "=?" , selectionArgs, null, null, Message.TIME_SENT
|
+ "=? and (" + Message.TYPE + "=? or " + Message.TYPE + "=?) and " + Message.COUNTERPART + "=?" , selectionArgs, null, null, Message.TIME_SENT
|
||||||
+ sorting, String.valueOf(limit));
|
+ sorting, String.valueOf(limit));
|
||||||
|
} else if (conversation.getNextCounterpart() != null && conversation.hasPermanentCounterpart()) {
|
||||||
|
String[] selectionArgs = {conversation.getUuid(), String.valueOf(Message.ENCRYPTION_OTR), conversation.getNextCounterpart().toString()};
|
||||||
|
cursor = db.query(Message.TABLENAME, null, Message.CONVERSATION
|
||||||
|
+ "=? and " + Message.ENCRYPTION + "=? and " + Message.COUNTERPART + "=?" , selectionArgs, null, null, Message.TIME_SENT
|
||||||
|
+ sorting, String.valueOf(limit));
|
||||||
|
} else {
|
||||||
|
String[] selectionArgs = {conversation.getUuid()};
|
||||||
|
cursor = db.query(Message.TABLENAME, null, Message.CONVERSATION
|
||||||
|
+ "=?", selectionArgs, null, null, Message.TIME_SENT
|
||||||
|
+ sorting, String.valueOf(limit));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (conversation.getNextCounterpart() == null) {
|
if (conversation.getNextCounterpart() != null && conversation.hasPermanentCounterpart() && conversation.getMode() == Conversational.MODE_MULTI) {
|
||||||
|
String[] selectionArgs = {conversation.getUuid(), String.valueOf(Message.TYPE_PRIVATE), String.valueOf(Message.TYPE_PRIVATE_FILE), conversation.getNextCounterpart().toString(), Long.toString(timestamp)};
|
||||||
|
cursor = db.query(Message.TABLENAME, null, Message.CONVERSATION
|
||||||
|
+ "=? and (" + Message.TYPE + "=? or " + Message.TYPE + "=?) and " + Message.COUNTERPART + "=? and " + Message.TIME_SENT + comparsionOperation, selectionArgs, null, null, Message.TIME_SENT
|
||||||
|
+ sorting, String.valueOf(limit));
|
||||||
|
} else if (conversation.getNextCounterpart() != null && conversation.hasPermanentCounterpart()) {
|
||||||
|
String[] selectionArgs = {conversation.getUuid(), String.valueOf(Message.ENCRYPTION_OTR), conversation.getNextCounterpart().toString(), Long.toString(timestamp)};
|
||||||
|
cursor = db.query(Message.TABLENAME, null, Message.CONVERSATION
|
||||||
|
+ "=? and " + Message.ENCRYPTION + "=? and " + Message.COUNTERPART + "=? and " + Message.TIME_SENT + comparsionOperation, selectionArgs, null, null, Message.TIME_SENT
|
||||||
|
+ sorting, String.valueOf(limit));
|
||||||
|
} else {
|
||||||
String[] selectionArgs = {conversation.getUuid(),
|
String[] selectionArgs = {conversation.getUuid(),
|
||||||
Long.toString(timestamp)};
|
Long.toString(timestamp)};
|
||||||
cursor = db.query(Message.TABLENAME, null, Message.CONVERSATION
|
cursor = db.query(Message.TABLENAME, null, Message.CONVERSATION
|
||||||
+ "=? and " + Message.TIME_SENT + comparsionOperation, selectionArgs,
|
+ "=? and " + Message.TIME_SENT + comparsionOperation, selectionArgs,
|
||||||
null, null, Message.TIME_SENT + sorting,
|
null, null, Message.TIME_SENT + sorting,
|
||||||
String.valueOf(limit));
|
String.valueOf(limit));
|
||||||
} else {
|
|
||||||
String[] selectionArgs = {conversation.getUuid(), String.valueOf(Message.TYPE_PRIVATE), String.valueOf(Message.TYPE_PRIVATE_FILE), conversation.getNextCounterpart().toString(), Long.toString(timestamp)};
|
|
||||||
cursor = db.query(Message.TABLENAME, null, Message.CONVERSATION
|
|
||||||
+ "=? and (" + Message.TYPE + "=? or " + Message.TYPE + "=?) and " + Message.COUNTERPART + "=? and " + Message.TIME_SENT + comparsionOperation, selectionArgs, null, null, Message.TIME_SENT
|
|
||||||
+ sorting, String.valueOf(limit));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CursorUtils.upgradeCursorWindowSize(cursor);
|
CursorUtils.upgradeCursorWindowSize(cursor);
|
||||||
|
|
|
@ -2550,6 +2550,7 @@ public class XmppConnectionService extends Service {
|
||||||
if ((account == null || conversation.getAccount() == account)
|
if ((account == null || conversation.getAccount() == account)
|
||||||
&& (conversation.getJid().asBareJid().equals(jid.asBareJid()))
|
&& (conversation.getJid().asBareJid().equals(jid.asBareJid()))
|
||||||
&& Objects.equal(conversation.getNextCounterpart(), counterpart)
|
&& Objects.equal(conversation.getNextCounterpart(), counterpart)
|
||||||
|
&& conversation.hasPermanentCounterpart()
|
||||||
) {
|
) {
|
||||||
return conversation;
|
return conversation;
|
||||||
}
|
}
|
||||||
|
@ -2558,7 +2559,7 @@ public class XmppConnectionService extends Service {
|
||||||
for (final Conversation conversation : haystack) {
|
for (final Conversation conversation : haystack) {
|
||||||
if ((account == null || conversation.getAccount() == account)
|
if ((account == null || conversation.getAccount() == account)
|
||||||
&& (conversation.getJid().asBareJid().equals(jid.asBareJid()))
|
&& (conversation.getJid().asBareJid().equals(jid.asBareJid()))
|
||||||
&& conversation.getNextCounterpart() == null
|
&& (conversation.getNextCounterpart() == null || !conversation.hasPermanentCounterpart())
|
||||||
) {
|
) {
|
||||||
return conversation;
|
return conversation;
|
||||||
}
|
}
|
||||||
|
@ -2616,10 +2617,15 @@ public class XmppConnectionService extends Service {
|
||||||
|
|
||||||
public Conversation findOrCreateConversation(final Account account, final Jid jid, final MessageArchiveService.Query query, final boolean muc, final boolean joinAfterCreate, final boolean async, Jid counterpart) {
|
public Conversation findOrCreateConversation(final Account account, final Jid jid, final MessageArchiveService.Query query, final boolean muc, final boolean joinAfterCreate, final boolean async, Jid counterpart) {
|
||||||
synchronized (this.conversations) {
|
synchronized (this.conversations) {
|
||||||
|
android.util.Log.e("41fd", jid.toString() + " " + counterpart);
|
||||||
|
|
||||||
Conversation conversation = find(account, jid, counterpart);
|
Conversation conversation = find(account, jid, counterpart);
|
||||||
if (conversation != null) {
|
if (conversation != null) {
|
||||||
return conversation;
|
return conversation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
android.util.Log.e("41fd 1 not find", jid.toString() + " " + counterpart);
|
||||||
|
|
||||||
conversation = databaseBackend.findConversation(account, jid, counterpart);
|
conversation = databaseBackend.findConversation(account, jid, counterpart);
|
||||||
final boolean loadMessagesFromDb;
|
final boolean loadMessagesFromDb;
|
||||||
if (conversation != null) {
|
if (conversation != null) {
|
||||||
|
@ -2651,6 +2657,8 @@ public class XmppConnectionService extends Service {
|
||||||
Conversation.MODE_SINGLE, counterpart);
|
Conversation.MODE_SINGLE, counterpart);
|
||||||
}
|
}
|
||||||
this.databaseBackend.createConversation(conversation);
|
this.databaseBackend.createConversation(conversation);
|
||||||
|
android.util.Log.e("41fd 2 not find", jid.toString() + " " + counterpart);
|
||||||
|
|
||||||
loadMessagesFromDb = false;
|
loadMessagesFromDb = false;
|
||||||
}
|
}
|
||||||
final Conversation c = conversation;
|
final Conversation c = conversation;
|
||||||
|
|
|
@ -1090,6 +1090,7 @@ public class ConversationFragment extends XmppFragment
|
||||||
switch (conversation.getNextEncryption()) {
|
switch (conversation.getNextEncryption()) {
|
||||||
case Message.ENCRYPTION_OTR:
|
case Message.ENCRYPTION_OTR:
|
||||||
sendOtrMessage(message);
|
sendOtrMessage(message);
|
||||||
|
break;
|
||||||
case Message.ENCRYPTION_PGP:
|
case Message.ENCRYPTION_PGP:
|
||||||
sendPgpMessage(message);
|
sendPgpMessage(message);
|
||||||
break;
|
break;
|
||||||
|
@ -1406,6 +1407,11 @@ public class ConversationFragment extends XmppFragment
|
||||||
final MenuItem menuVideoCall = menu.findItem(R.id.action_video_call);
|
final MenuItem menuVideoCall = menu.findItem(R.id.action_video_call);
|
||||||
final MenuItem menuTogglePinned = menu.findItem(R.id.action_toggle_pinned);
|
final MenuItem menuTogglePinned = menu.findItem(R.id.action_toggle_pinned);
|
||||||
final MenuItem deleteCustomBg = menu.findItem(R.id.action_delete_custom_bg);
|
final MenuItem deleteCustomBg = menu.findItem(R.id.action_delete_custom_bg);
|
||||||
|
final MenuItem startSecretChat = menu.findItem(R.id.action_start_secret_chat);
|
||||||
|
final MenuItem encryption = menu.findItem(R.id.action_security);
|
||||||
|
|
||||||
|
boolean considerAsSecretChat = conversation.getMode() == Conversational.MODE_SINGLE &&
|
||||||
|
conversation.getNextCounterpart() != null && conversation.hasPermanentCounterpart();
|
||||||
|
|
||||||
if (conversation != null) {
|
if (conversation != null) {
|
||||||
if (conversation.getMode() == Conversation.MODE_MULTI) {
|
if (conversation.getMode() == Conversation.MODE_MULTI) {
|
||||||
|
@ -1417,6 +1423,7 @@ public class ConversationFragment extends XmppFragment
|
||||||
: R.string.channel_details);
|
: R.string.channel_details);
|
||||||
menuCall.setVisible(false);
|
menuCall.setVisible(false);
|
||||||
menuOngoingCall.setVisible(false);
|
menuOngoingCall.setVisible(false);
|
||||||
|
startSecretChat.setVisible(false);
|
||||||
} else {
|
} else {
|
||||||
menuMucParticipants.setVisible(false);
|
menuMucParticipants.setVisible(false);
|
||||||
final XmppConnectionService service =
|
final XmppConnectionService service =
|
||||||
|
@ -1458,6 +1465,10 @@ public class ConversationFragment extends XmppFragment
|
||||||
menuTogglePinned.setTitle(R.string.add_to_favorites);
|
menuTogglePinned.setTitle(R.string.add_to_favorites);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (considerAsSecretChat) {
|
||||||
|
encryption.setVisible(false);
|
||||||
|
}
|
||||||
|
|
||||||
deleteCustomBg.setVisible(ChatBackgroundHelper.getBgFile(activity, conversation.getUuid()).exists());
|
deleteCustomBg.setVisible(ChatBackgroundHelper.getBgFile(activity, conversation.getUuid()).exists());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2048,6 +2059,9 @@ public class ConversationFragment extends XmppFragment
|
||||||
case R.id.action_archive:
|
case R.id.action_archive:
|
||||||
activity.xmppConnectionService.archiveConversation(conversation);
|
activity.xmppConnectionService.archiveConversation(conversation);
|
||||||
break;
|
break;
|
||||||
|
case R.id.action_start_secret_chat:
|
||||||
|
startOtrChat();
|
||||||
|
break;
|
||||||
case R.id.action_contact_details:
|
case R.id.action_contact_details:
|
||||||
activity.switchToContactDetails(conversation.getContact());
|
activity.switchToContactDetails(conversation.getContact());
|
||||||
break;
|
break;
|
||||||
|
@ -3979,11 +3993,20 @@ public class ConversationFragment extends XmppFragment
|
||||||
protected void sendOtrMessage(final Message message) {
|
protected void sendOtrMessage(final Message message) {
|
||||||
final ConversationsActivity activity = (ConversationsActivity) getActivity();
|
final ConversationsActivity activity = (ConversationsActivity) getActivity();
|
||||||
final XmppConnectionService xmppService = activity.xmppConnectionService;
|
final XmppConnectionService xmppService = activity.xmppConnectionService;
|
||||||
|
message.setCounterpart(conversation.getNextCounterpart());
|
||||||
|
xmppService.sendMessage(message);
|
||||||
|
messageSent();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void startOtrChat() {
|
||||||
|
final ConversationsActivity activity = (ConversationsActivity) getActivity();
|
||||||
activity.selectPresence(conversation,
|
activity.selectPresence(conversation,
|
||||||
() -> {
|
() -> {
|
||||||
message.setCounterpart(conversation.getNextCounterpart());
|
Conversation c = activity.xmppConnectionService.findOrCreateConversation(conversation.getAccount(), conversation.getJid(), null, false, false, false, conversation.getNextCounterpart());
|
||||||
xmppService.sendMessage(message);
|
conversation.setNextCounterpart(null);
|
||||||
messageSent();
|
if (c != conversation) {
|
||||||
|
activity.switchToConversation(c);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -757,8 +757,12 @@ public class ConversationsActivity extends XmppActivity implements OnConversatio
|
||||||
if (mainFragment instanceof ConversationFragment) {
|
if (mainFragment instanceof ConversationFragment) {
|
||||||
final Conversation conversation = ((ConversationFragment) mainFragment).getConversation();
|
final Conversation conversation = ((ConversationFragment) mainFragment).getConversation();
|
||||||
if (conversation != null) {
|
if (conversation != null) {
|
||||||
if (conversation.getNextCounterpart() != null) {
|
if (conversation.getNextCounterpart() != null && conversation.hasPermanentCounterpart()) {
|
||||||
actionBar.setTitle(getString(R.string.muc_private_conversation_title, conversation.getNextCounterpart().getResource(), conversation.getName()));
|
if (conversation.getMode() == Conversational.MODE_MULTI) {
|
||||||
|
actionBar.setTitle(getString(R.string.muc_private_conversation_title, conversation.getNextCounterpart().getResource(), conversation.getName()));
|
||||||
|
} else {
|
||||||
|
actionBar.setTitle(getString(R.string.secret_chat_title, conversation.getName(), ""));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
actionBar.setTitle(conversation.getName());
|
actionBar.setTitle(conversation.getName());
|
||||||
}
|
}
|
||||||
|
@ -780,7 +784,9 @@ public class ConversationsActivity extends XmppActivity implements OnConversatio
|
||||||
} else if (conversation.getMode() == Conversation.MODE_SINGLE) {
|
} else if (conversation.getMode() == Conversation.MODE_SINGLE) {
|
||||||
Contact contact = conversation.getContact();
|
Contact contact = conversation.getContact();
|
||||||
List<String> statuses = contact.getPresences().getStatusMessages();
|
List<String> statuses = contact.getPresences().getStatusMessages();
|
||||||
if (!statuses.isEmpty() && !statuses.get(0).isBlank()) {
|
if (conversation.getNextCounterpart() != null && conversation.hasPermanentCounterpart()) {
|
||||||
|
actionBar.setSubtitle(conversation.getNextCounterpart().getResource());
|
||||||
|
} else if (!statuses.isEmpty() && !statuses.get(0).isBlank()) {
|
||||||
actionBar.setSubtitle(statuses.get(0));
|
actionBar.setSubtitle(statuses.get(0));
|
||||||
handler.postDelayed(refreshTitleRunnable, 5000L);
|
handler.postDelayed(refreshTitleRunnable, 5000L);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -338,8 +338,12 @@ public class ConversationAdapter
|
||||||
}
|
}
|
||||||
|
|
||||||
CharSequence name = conversation.getName();
|
CharSequence name = conversation.getName();
|
||||||
if (conversation.getNextCounterpart() != null) {
|
if (conversation.getNextCounterpart() != null && conversation.hasPermanentCounterpart()) {
|
||||||
name = viewHolder.binding.getRoot().getResources().getString(R.string.muc_private_conversation_title, conversation.getNextCounterpart().getResource(), conversation.getName());
|
if (conversation.getMode() == Conversational.MODE_MULTI) {
|
||||||
|
name = viewHolder.binding.getRoot().getResources().getString(R.string.muc_private_conversation_title, conversation.getNextCounterpart().getResource(), conversation.getName());
|
||||||
|
} else {
|
||||||
|
name = viewHolder.binding.getRoot().getResources().getString(R.string.secret_chat_title, conversation.getName(), conversation.getNextCounterpart().getResource());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conversation.withSelf()) {
|
if (conversation.withSelf()) {
|
||||||
|
|
|
@ -121,6 +121,11 @@
|
||||||
android:orderInCategory="60"
|
android:orderInCategory="60"
|
||||||
android:title="@string/action_end_conversation"
|
android:title="@string/action_end_conversation"
|
||||||
app:showAsAction="never" />
|
app:showAsAction="never" />
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_start_secret_chat"
|
||||||
|
android:orderInCategory="65"
|
||||||
|
android:title="@string/action_start_secret_chat"
|
||||||
|
app:showAsAction="never" />
|
||||||
<item
|
<item
|
||||||
android:orderInCategory="70"
|
android:orderInCategory="70"
|
||||||
android:title="@string/more_options">
|
android:title="@string/more_options">
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
<string name="action_accounts">Manage accounts</string>
|
<string name="action_accounts">Manage accounts</string>
|
||||||
<string name="action_account">Manage account</string>
|
<string name="action_account">Manage account</string>
|
||||||
<string name="action_end_conversation">Close conversation</string>
|
<string name="action_end_conversation">Close conversation</string>
|
||||||
|
<string name="action_start_secret_chat">Start secret chat</string>
|
||||||
<string name="action_contact_details">Contact details</string>
|
<string name="action_contact_details">Contact details</string>
|
||||||
<string name="action_muc_details">Group chat details</string>
|
<string name="action_muc_details">Group chat details</string>
|
||||||
<string name="channel_details">Channel details</string>
|
<string name="channel_details">Channel details</string>
|
||||||
|
@ -1089,6 +1090,7 @@
|
||||||
<string name="resize">resize</string>
|
<string name="resize">resize</string>
|
||||||
<string name="filter">filter</string>
|
<string name="filter">filter</string>
|
||||||
<string name="could_not_create_file">could_not_create_file</string>
|
<string name="could_not_create_file">could_not_create_file</string>
|
||||||
|
<string name="secret_chat_title">%1$s (Secret Chat / %2$s)</string>
|
||||||
<string name="muc_private_conversation_title">%1$s (%2$s)</string>
|
<string name="muc_private_conversation_title">%1$s (%2$s)</string>
|
||||||
<string name="note_to_self_conversation_title">Note to self (%1$s)</string>
|
<string name="note_to_self_conversation_title">Note to self (%1$s)</string>
|
||||||
<string name="muc_private_conversation_info_title">Private conversation with:</string>
|
<string name="muc_private_conversation_info_title">Private conversation with:</string>
|
||||||
|
|
Loading…
Reference in a new issue