aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Schneppe <christian@pix-art.de>2016-05-27 20:44:02 +0200
committerChristian Schneppe <christian@pix-art.de>2016-05-27 20:44:02 +0200
commit25547747b37770b6ca8227c784488dd4deb5436f (patch)
tree04274e9063bd17c8d09b1d4663f035d0d8a2ae8f
parent5edcb7714985e24e0a068eb0970135170f9a17ed (diff)
parent25f6651848b67d225967cf1bb35e037c998a5682 (diff)
Merge remote-tracking branch 'refs/remotes/siacs/master'
-rw-r--r--src/main/java/eu/siacs/conversations/crypto/OtrService.java2
-rw-r--r--src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java4
-rw-r--r--src/main/java/eu/siacs/conversations/entities/Account.java5
-rw-r--r--src/main/java/eu/siacs/conversations/entities/Bookmark.java5
-rw-r--r--src/main/java/eu/siacs/conversations/entities/MucOptions.java11
-rw-r--r--src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java7
-rw-r--r--src/main/java/eu/siacs/conversations/generator/IqGenerator.java10
-rw-r--r--src/main/java/eu/siacs/conversations/generator/MessageGenerator.java14
-rw-r--r--src/main/java/eu/siacs/conversations/parser/MessageParser.java9
-rw-r--r--src/main/java/eu/siacs/conversations/parser/PresenceParser.java10
-rw-r--r--src/main/java/eu/siacs/conversations/services/AvatarService.java13
-rw-r--r--src/main/java/eu/siacs/conversations/services/XmppConnectionService.java39
-rw-r--r--src/main/java/eu/siacs/conversations/ui/ChooseContactActivity.java23
-rw-r--r--src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java15
-rw-r--r--src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java56
-rw-r--r--src/main/java/eu/siacs/conversations/ui/ConversationActivity.java2
-rw-r--r--src/main/java/eu/siacs/conversations/ui/ConversationFragment.java7
-rw-r--r--src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java17
-rw-r--r--src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java118
-rw-r--r--src/main/java/eu/siacs/conversations/ui/XmppActivity.java25
-rw-r--r--src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java21
-rw-r--r--src/main/res/layout/create_conference_dialog.xml42
-rw-r--r--src/main/res/menu/start_conversation.xml14
-rw-r--r--src/main/res/values-de/strings.xml25
-rw-r--r--src/main/res/values/strings.xml13
25 files changed, 410 insertions, 97 deletions
diff --git a/src/main/java/eu/siacs/conversations/crypto/OtrService.java b/src/main/java/eu/siacs/conversations/crypto/OtrService.java
index 1804704eb..af11756f6 100644
--- a/src/main/java/eu/siacs/conversations/crypto/OtrService.java
+++ b/src/main/java/eu/siacs/conversations/crypto/OtrService.java
@@ -122,7 +122,7 @@ public class OtrService extends OtrCryptoEngineImpl implements OtrEngineHost {
@Override
public String getFallbackMessage(SessionID arg0) {
- return "I would like to start a private (OTR encrypted) conversation but your client doesn’t seem to support that";
+ return MessageGenerator.OTR_FALLBACK_MESSAGE;
}
@Override
diff --git a/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java b/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java
index aac814433..9e54c0c7d 100644
--- a/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java
+++ b/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java
@@ -75,7 +75,9 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
@Override
public void onAdvancedStreamFeaturesAvailable(Account account) {
- if (account.getXmppConnection() != null && account.getXmppConnection().getFeatures().pep()) {
+ if (Config.supportOmemo()
+ && account.getXmppConnection() != null
+ && account.getXmppConnection().getFeatures().pep()) {
publishBundlesIfNeeded(true, false);
} else {
Log.d(Config.LOGTAG,account.getJid().toBareJid()+": skipping OMEMO initialization");
diff --git a/src/main/java/eu/siacs/conversations/entities/Account.java b/src/main/java/eu/siacs/conversations/entities/Account.java
index a708b0ce8..2f573c896 100644
--- a/src/main/java/eu/siacs/conversations/entities/Account.java
+++ b/src/main/java/eu/siacs/conversations/entities/Account.java
@@ -99,7 +99,8 @@ public class Account extends AbstractEntity {
INCOMPATIBLE_SERVER(true),
TOR_NOT_AVAILABLE(true),
BIND_FAILURE(true),
- HOST_UNKNOWN(true);
+ HOST_UNKNOWN(true),
+ REGISTRATION_PLEASE_WAIT(true);
private final boolean isError;
@@ -149,6 +150,8 @@ public class Account extends AbstractEntity {
return R.string.account_status_bind_failure;
case HOST_UNKNOWN:
return R.string.account_status_host_unknown;
+ case REGISTRATION_PLEASE_WAIT:
+ return R.string.registration_please_wait;
default:
return R.string.account_status_unknown;
}
diff --git a/src/main/java/eu/siacs/conversations/entities/Bookmark.java b/src/main/java/eu/siacs/conversations/entities/Bookmark.java
index fd6a5dab9..c5c4ff5dd 100644
--- a/src/main/java/eu/siacs/conversations/entities/Bookmark.java
+++ b/src/main/java/eu/siacs/conversations/entities/Bookmark.java
@@ -50,9 +50,8 @@ public class Bookmark extends Element implements ListItem {
@Override
public String getDisplayName() {
- if (this.mJoinedConversation != null
- && (this.mJoinedConversation.getMucOptions().getSubject() != null)) {
- return this.mJoinedConversation.getMucOptions().getSubject();
+ if (this.mJoinedConversation != null) {
+ return this.mJoinedConversation.getName();
} else if (getBookmarkName() != null) {
return getBookmarkName();
} else {
diff --git a/src/main/java/eu/siacs/conversations/entities/MucOptions.java b/src/main/java/eu/siacs/conversations/entities/MucOptions.java
index d4a15ea7a..5ec527ef2 100644
--- a/src/main/java/eu/siacs/conversations/entities/MucOptions.java
+++ b/src/main/java/eu/siacs/conversations/entities/MucOptions.java
@@ -18,6 +18,8 @@ import eu.siacs.conversations.xmpp.pep.Avatar;
@SuppressLint("DefaultLocale")
public class MucOptions {
+ private boolean mAutoPushConfiguration = true;
+
public Account getAccount() {
return this.conversation.getAccount();
}
@@ -39,6 +41,14 @@ public class MucOptions {
}
}
+ public void flagNoAutoPushConfiguration() {
+ mAutoPushConfiguration = false;
+ }
+
+ public boolean autoPushConfiguration() {
+ return mAutoPushConfiguration;
+ }
+
public enum Affiliation {
OWNER("owner", 4, R.string.owner),
ADMIN("admin", 3, R.string.admin),
@@ -118,6 +128,7 @@ public class MucOptions {
public static final String STATUS_CODE_ROOM_CONFIG_CHANGED = "104";
public static final String STATUS_CODE_SELF_PRESENCE = "110";
+ public static final String STATUS_CODE_ROOM_CREATED = "201";
public static final String STATUS_CODE_BANNED = "301";
public static final String STATUS_CODE_CHANGED_NICK = "303";
public static final String STATUS_CODE_KICKED = "307";
diff --git a/src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java b/src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java
index cc974e5fb..b80a0be19 100644
--- a/src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java
+++ b/src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java
@@ -12,6 +12,7 @@ import java.util.List;
import java.util.Locale;
import java.util.TimeZone;
+import eu.siacs.conversations.Config;
import eu.siacs.conversations.crypto.axolotl.AxolotlService;
import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.utils.PhoneHelper;
@@ -32,8 +33,7 @@ public abstract class AbstractGenerator {
"http://jabber.org/protocol/nick+notify",
"urn:xmpp:ping",
"jabber:iq:version",
- "http://jabber.org/protocol/chatstates",
- AxolotlService.PEP_DEVICE_LIST_NOTIFY};
+ "http://jabber.org/protocol/chatstates"};
private final String[] MESSAGE_CONFIRMATION_FEATURES = {
"urn:xmpp:chat-markers:0",
"urn:xmpp:receipts"
@@ -105,6 +105,9 @@ public abstract class AbstractGenerator {
if (mXmppConnectionService.allowMessageCorrection()) {
features.addAll(Arrays.asList(MESSAGE_CORRECTION_FEATURES));
}
+ if (Config.supportOmemo()) {
+ features.add(AxolotlService.PEP_DEVICE_LIST_NOTIFY);
+ }
Collections.sort(features);
return features;
}
diff --git a/src/main/java/eu/siacs/conversations/generator/IqGenerator.java b/src/main/java/eu/siacs/conversations/generator/IqGenerator.java
index 4962135e3..16af338c6 100644
--- a/src/main/java/eu/siacs/conversations/generator/IqGenerator.java
+++ b/src/main/java/eu/siacs/conversations/generator/IqGenerator.java
@@ -1,6 +1,7 @@
package eu.siacs.conversations.generator;
+import android.os.Bundle;
import android.util.Base64;
import android.util.Log;
@@ -344,4 +345,13 @@ public class IqGenerator extends AbstractGenerator {
packet.query("http://jabber.org/protocol/muc#admin").addChild("item").setAttribute("affiliation",affiliation);
return packet;
}
+
+ public static Bundle defaultRoomConfiguration() {
+ Bundle options = new Bundle();
+ options.putString("muc#roomconfig_persistentroom", "1");
+ options.putString("muc#roomconfig_membersonly", "1");
+ options.putString("muc#roomconfig_publicroom", "0");
+ options.putString("muc#roomconfig_whois", "anyone");
+ return options;
+ }
}
diff --git a/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java b/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java
index 0e7a8ce6e..823af397a 100644
--- a/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java
+++ b/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java
@@ -9,6 +9,7 @@ import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
+import eu.siacs.conversations.crypto.axolotl.AxolotlService;
import eu.siacs.conversations.crypto.axolotl.XmppAxolotlMessage;
import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.entities.Conversation;
@@ -20,6 +21,10 @@ import eu.siacs.conversations.xmpp.jid.Jid;
import eu.siacs.conversations.xmpp.stanzas.MessagePacket;
public class MessageGenerator extends AbstractGenerator {
+ public static final String OTR_FALLBACK_MESSAGE = "I would like to start a private (OTR encrypted) conversation but your client doesn’t seem to support that";
+ private static final String OMEMO_FALLBACK_MESSAGE = "I sent you an OMEMO encrypted message but your client doesn’t seem to support that. Find more information on https://conversations.im/omemo";
+ private static final String PGP_FALLBACK_MESSAGE = "I sent you a PGP encrypted message but your client doesn’t seem to support that.";
+
public MessageGenerator(XmppConnectionService service) {
super(service);
}
@@ -67,11 +72,18 @@ public class MessageGenerator extends AbstractGenerator {
if (axolotlMessage == null) {
return null;
}
+ if (!recipientSupportsOmemo(message)) {
+ packet.setBody(OMEMO_FALLBACK_MESSAGE);
+ }
packet.setAxolotlMessage(axolotlMessage.toElement());
packet.addChild("store", "urn:xmpp:hints");
return packet;
}
+ private static boolean recipientSupportsOmemo(Message message) {
+ return message.getContact().getPresences().allOrNonSupport(AxolotlService.PEP_DEVICE_LIST_NOTIFY);
+ }
+
public static void addMessageHints(MessagePacket packet) {
packet.addChild("private", "urn:xmpp:carbons:2");
packet.addChild("no-copy", "urn:xmpp:hints");
@@ -116,7 +128,7 @@ public class MessageGenerator extends AbstractGenerator {
public MessagePacket generatePgpChat(Message message) {
MessagePacket packet = preparePacket(message);
- packet.setBody("This is an XEP-0027 encrypted message");
+ packet.setBody(PGP_FALLBACK_MESSAGE);
if (message.getEncryption() == Message.ENCRYPTION_DECRYPTED) {
packet.addChild("x", "jabber:x:encrypted").setContent(message.getEncryptedBody());
} else if (message.getEncryption() == Message.ENCRYPTION_PGP) {
diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java
index aac8ee45a..d2f4bf9f5 100644
--- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java
+++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java
@@ -369,6 +369,7 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
if ((body != null || pgpEncrypted != null || axolotlEncrypted != null) && !isMucStatusMessage) {
Conversation conversation = mXmppConnectionService.findOrCreateConversation(account, counterpart.toBareJid(), isTypeGroupChat, query);
+ final boolean conversationMultiMode = conversation.getMode() == Conversation.MODE_MULTI;
if (isTypeGroupChat) {
if (counterpart.getResourcepart().equals(conversation.getMucOptions().getActualNick())) {
status = Message.STATUS_SEND_RECEIVED;
@@ -388,7 +389,7 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
}
Message message;
if (body != null && body.startsWith("?OTR") && Config.supportOtr()) {
- if (!isForwarded && !isTypeGroupChat && isProperlyAddressed) {
+ if (!isForwarded && !isTypeGroupChat && isProperlyAddressed && !conversationMultiMode) {
message = parseOtrChat(body, from, remoteMsgId, conversation);
if (message == null) {
return;
@@ -401,7 +402,7 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
message = new Message(conversation, pgpEncrypted, Message.ENCRYPTION_PGP, status);
} else if (axolotlEncrypted != null && Config.supportOmemo()) {
Jid origin;
- if (conversation.getMode() == Conversation.MODE_MULTI) {
+ if (conversationMultiMode) {
origin = conversation.getMucOptions().getTrueCounterpart(counterpart);
if (origin == null) {
Log.d(Config.LOGTAG,"axolotl message in non anonymous conference received");
@@ -429,7 +430,7 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
message.setTime(timestamp);
message.setOob(isOob);
message.markable = packet.hasChild("markable", "urn:xmpp:chat-markers:0");
- if (conversation.getMode() == Conversation.MODE_MULTI) {
+ if (conversationMultiMode) {
Jid trueCounterpart = conversation.getMucOptions().getTrueCounterpart(counterpart);
message.setTrueCounterpart(trueCounterpart);
if (trueCounterpart != null) {
@@ -452,7 +453,7 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
|| replacedMessage.getFingerprint().equals(message.getFingerprint());
final boolean trueCountersMatch = replacedMessage.getTrueCounterpart() != null
&& replacedMessage.getTrueCounterpart().equals(message.getTrueCounterpart());
- if (fingerprintsMatch && (trueCountersMatch || conversation.getMode() == Conversation.MODE_SINGLE)) {
+ if (fingerprintsMatch && (trueCountersMatch || !conversationMultiMode)) {
Log.d(Config.LOGTAG, "replaced message '" + replacedMessage.getBody() + "' with '" + message.getBody() + "'");
final String uuid = replacedMessage.getUuid();
replacedMessage.setUuid(UUID.randomUUID().toString());
diff --git a/src/main/java/eu/siacs/conversations/parser/PresenceParser.java b/src/main/java/eu/siacs/conversations/parser/PresenceParser.java
index ae5d576a6..8a2d444a7 100644
--- a/src/main/java/eu/siacs/conversations/parser/PresenceParser.java
+++ b/src/main/java/eu/siacs/conversations/parser/PresenceParser.java
@@ -14,6 +14,7 @@ import eu.siacs.conversations.entities.Conversation;
import eu.siacs.conversations.entities.Message;
import eu.siacs.conversations.entities.MucOptions;
import eu.siacs.conversations.entities.Presence;
+import eu.siacs.conversations.generator.IqGenerator;
import eu.siacs.conversations.generator.PresenceGenerator;
import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.xml.Element;
@@ -77,6 +78,15 @@ public class PresenceParser extends AbstractParser implements
} else {
mucOptions.addUser(user);
}
+ if (codes.contains(MucOptions.STATUS_CODE_ROOM_CREATED) && mucOptions.autoPushConfiguration()) {
+ Log.d(Config.LOGTAG,mucOptions.getAccount().getJid().toBareJid()
+ +": room '"
+ +mucOptions.getConversation().getJid().toBareJid()
+ +"' created. pushing default configuration");
+ mXmppConnectionService.pushConferenceConfiguration(mucOptions.getConversation(),
+ IqGenerator.defaultRoomConfiguration(),
+ null);
+ }
if (mXmppConnectionService.getPgpEngine() != null) {
Element signed = packet.findChild("x", "jabber:x:signed");
if (signed != null) {
diff --git a/src/main/java/eu/siacs/conversations/services/AvatarService.java b/src/main/java/eu/siacs/conversations/services/AvatarService.java
index 0ab0db2de..88071f500 100644
--- a/src/main/java/eu/siacs/conversations/services/AvatarService.java
+++ b/src/main/java/eu/siacs/conversations/services/AvatarService.java
@@ -64,7 +64,7 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded {
public Bitmap get(final MucOptions.User user, final int size, boolean cachedOnly) {
Contact c = user.getContact();
- if (c != null && (c.getProfilePhoto() != null || c.getAvatar() != null)) {
+ if (c != null && (c.getProfilePhoto() != null || c.getAvatar() != null || user.getAvatar() == null)) {
return get(c, size, cachedOnly);
} else {
return getImpl(user, size, cachedOnly);
@@ -380,7 +380,7 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded {
private boolean drawTile(Canvas canvas, String name, int left, int top, int right, int bottom) {
if (name != null) {
- final String letter = name.isEmpty() ? "X" : name.substring(0, 1);
+ final String letter = getFirstLetter(name);
final int color = UIHelper.getColorForName(name);
drawTile(canvas, letter, color, left, top, right, bottom);
return true;
@@ -388,6 +388,15 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded {
return false;
}
+ private static String getFirstLetter(String name) {
+ for(Character c : name.toCharArray()) {
+ if (Character.isLetterOrDigit(c)) {
+ return c.toString();
+ }
+ }
+ return "X";
+ }
+
private boolean drawTile(Canvas canvas, Uri uri, int left, int top, int right, int bottom) {
if (uri != null) {
Bitmap bitmap = mXmppConnectionService.getFileBackend()
diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java
index 67370e3ff..ad45d8e9a 100644
--- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java
+++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java
@@ -26,6 +26,7 @@ import android.os.SystemClock;
import android.preference.PreferenceManager;
import android.provider.ContactsContract;
import android.security.KeyChain;
+import android.util.Base64;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.LruCache;
@@ -1827,6 +1828,9 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
account.pendingConferenceLeaves.remove(conversation);
if (account.getStatus() == Account.State.ONLINE) {
conversation.resetMucOptions();
+ if (onConferenceJoined != null) {
+ conversation.getMucOptions().flagNoAutoPushConfiguration();
+ }
conversation.setHasMessagesLeftOnServer(false);
fetchConferenceConfiguration(conversation, new OnConferenceConfigurationFetched() {
@@ -2030,7 +2034,10 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
return null;
}
- public void createAdhocConference(final Account account, final Iterable<Jid> jids, final UiCallback<Conversation> callback) {
+ public void createAdhocConference(final Account account,
+ final String subject,
+ final Iterable<Jid> jids,
+ final UiCallback<Conversation> callback) {
Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": creating adhoc conference with " + jids.toString());
if (account.getStatus() == Account.State.ONLINE) {
try {
@@ -2041,26 +2048,24 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
}
return;
}
- String name = new BigInteger(75, getRNG()).toString(32);
- Jid jid = Jid.fromParts(name, server, null);
+ final Jid jid = Jid.fromParts(new BigInteger(64, getRNG()).toString(Character.MAX_RADIX), server, null);
final Conversation conversation = findOrCreateConversation(account, jid, true);
joinMuc(conversation, new OnConferenceJoined() {
@Override
public void onConferenceJoined(final Conversation conversation) {
- Bundle options = new Bundle();
- options.putString("muc#roomconfig_persistentroom", "1");
- options.putString("muc#roomconfig_membersonly", "1");
- options.putString("muc#roomconfig_publicroom", "0");
- options.putString("muc#roomconfig_whois", "anyone");
- pushConferenceConfiguration(conversation, options, new OnConferenceOptionsPushed() {
+ pushConferenceConfiguration(conversation, IqGenerator.defaultRoomConfiguration(), new OnConferenceOptionsPushed() {
@Override
public void onPushSucceeded() {
+ if (subject != null && !subject.trim().isEmpty()) {
+ pushSubjectToConference(conversation, subject.trim());
+ }
for (Jid invite : jids) {
invite(conversation, invite);
}
if (account.countPresences() > 1) {
directInvite(conversation, account.getJid().toBareJid());
}
+ saveConversationAsBookmark(conversation, subject);
if (callback != null) {
callback.success(conversation);
}
@@ -2068,6 +2073,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
@Override
public void onPushFailed() {
+ archiveConversation(conversation);
if (callback != null) {
callback.error(R.string.conference_creation_failed, conversation);
}
@@ -3301,6 +3307,21 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
return templates;
}
+ public void saveConversationAsBookmark(Conversation conversation, String name) {
+ Account account = conversation.getAccount();
+ Bookmark bookmark = new Bookmark(account, conversation.getJid().toBareJid());
+ if (!conversation.getJid().isBareJid()) {
+ bookmark.setNick(conversation.getJid().getResourcepart());
+ }
+ if (name != null && !name.trim().isEmpty()) {
+ bookmark.setBookmarkName(name.trim());
+ }
+ bookmark.setAutojoin(getPreferences().getBoolean("autojoin",true));
+ account.getBookmarks().add(bookmark);
+ pushBookmarks(account);
+ conversation.setBookmark(bookmark);
+ }
+
public interface OnMamPreferencesFetched {
void onPreferencesFetched(Element prefs);
void onPreferencesFetchFailed();
diff --git a/src/main/java/eu/siacs/conversations/ui/ChooseContactActivity.java b/src/main/java/eu/siacs/conversations/ui/ChooseContactActivity.java
index 1698343b0..5156fcca4 100644
--- a/src/main/java/eu/siacs/conversations/ui/ChooseContactActivity.java
+++ b/src/main/java/eu/siacs/conversations/ui/ChooseContactActivity.java
@@ -1,8 +1,10 @@
package eu.siacs.conversations.ui;
+import android.app.ActionBar;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
+import android.support.annotation.StringRes;
import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuInflater;
@@ -32,6 +34,7 @@ public class ChooseContactActivity extends AbstractSearchableListItemActivity {
private Set<Contact> selected;
private Set<String> filterContacts;
+ public static final String EXTRA_TITLE_RES_ID = "extra_title_res_id";
@Override
public void onCreate(final Bundle savedInstanceState) {
@@ -77,6 +80,8 @@ public class ChooseContactActivity extends AbstractSearchableListItemActivity {
String[] selection = getSelectedContactJids();
data.putExtra("contacts", selection);
data.putExtra("multiple", true);
+ data.putExtra(EXTRA_ACCOUNT,request.getStringExtra(EXTRA_ACCOUNT));
+ data.putExtra("subject", request.getStringExtra("subject"));
setResult(RESULT_OK, data);
finish();
return true;
@@ -121,6 +126,7 @@ public class ChooseContactActivity extends AbstractSearchableListItemActivity {
data.putExtra("conversation",
request.getStringExtra("conversation"));
data.putExtra("multiple", false);
+ data.putExtra("subject", request.getStringExtra("subject"));
setResult(RESULT_OK, data);
finish();
}
@@ -129,6 +135,22 @@ public class ChooseContactActivity extends AbstractSearchableListItemActivity {
}
@Override
+ public void onStart() {
+ super.onStart();
+ Intent intent = getIntent();
+ @StringRes
+ int res = intent != null ? intent.getIntExtra(EXTRA_TITLE_RES_ID,R.string.title_activity_choose_contact) : R.string.title_activity_choose_contact;
+ ActionBar bar = getActionBar();
+ if (bar != null) {
+ try {
+ bar.setTitle(res);
+ } catch (Exception e) {
+ bar.setTitle(R.string.title_activity_choose_contact);
+ }
+ }
+ }
+
+ @Override
public boolean onCreateOptionsMenu(final Menu menu) {
super.onCreateOptionsMenu(menu);
final Intent i = getIntent();
@@ -194,6 +216,7 @@ public class ChooseContactActivity extends AbstractSearchableListItemActivity {
data.putExtra("conversation",
request.getStringExtra("conversation"));
data.putExtra("multiple", false);
+ data.putExtra("subject", request.getStringExtra("subject"));
setResult(RESULT_OK, data);
finish();
diff --git a/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java b/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java
index 808f6e7f9..7e2e3297e 100644
--- a/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java
+++ b/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java
@@ -27,7 +27,6 @@ import org.openintents.openpgp.util.OpenPgpUtils;
import java.util.ArrayList;
import java.util.Collections;
-import java.util.Comparator;
import java.util.concurrent.atomic.AtomicInteger;
import eu.siacs.conversations.Config;
@@ -281,7 +280,7 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
case R.id.action_edit_subject:
if (mConversation != null) {
quickEdit(mConversation.getMucOptions().getSubject(),
- R.string.action_edit_subject,
+ R.string.edit_subject_hint,
this.onSubjectEdited);
}
break;
@@ -486,16 +485,8 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
}
protected void saveAsBookmark() {
- Account account = mConversation.getAccount();
- Bookmark bookmark = new Bookmark(account, mConversation.getJid().toBareJid());
- if (!mConversation.getJid().isBareJid()) {
- bookmark.setNick(mConversation.getJid().getResourcepart());
- }
- bookmark.setBookmarkName(mConversation.getMucOptions().getSubject());
- bookmark.setAutojoin(getPreferences().getBoolean("autojoin",true));
- account.getBookmarks().add(bookmark);
- xmppConnectionService.pushBookmarks(account);
- mConversation.setBookmark(bookmark);
+ xmppConnectionService.saveConversationAsBookmark(mConversation,
+ mConversation.getMucOptions().getSubject());
}
protected void deleteBookmark() {
diff --git a/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java b/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java
index 8fa0c6296..4f2f5e7b2 100644
--- a/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java
+++ b/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java
@@ -415,35 +415,39 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd
keys.removeAllViews();
boolean hasKeys = false;
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- for(final String otrFingerprint : contact.getOtrFingerprints()) {
- hasKeys = true;
- View view = inflater.inflate(R.layout.contact_key, keys, false);
- TextView key = (TextView) view.findViewById(R.id.key);
- TextView keyType = (TextView) view.findViewById(R.id.key_type);
- ImageButton removeButton = (ImageButton) view
- .findViewById(R.id.button_remove);
- removeButton.setVisibility(View.VISIBLE);
- keyType.setText("OTR Fingerprint");
- key.setText(CryptoHelper.prettifyFingerprint(otrFingerprint));
- keys.addView(view);
- removeButton.setOnClickListener(new OnClickListener() {
+ if (Config.supportOtr()) {
+ for (final String otrFingerprint : contact.getOtrFingerprints()) {
+ hasKeys = true;
+ View view = inflater.inflate(R.layout.contact_key, keys, false);
+ TextView key = (TextView) view.findViewById(R.id.key);
+ TextView keyType = (TextView) view.findViewById(R.id.key_type);
+ ImageButton removeButton = (ImageButton) view
+ .findViewById(R.id.button_remove);
+ removeButton.setVisibility(View.VISIBLE);
+ keyType.setText("OTR Fingerprint");
+ key.setText(CryptoHelper.prettifyFingerprint(otrFingerprint));
+ keys.addView(view);
+ removeButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- confirmToDeleteFingerprint(otrFingerprint);
- }
- });
+ @Override
+ public void onClick(View v) {
+ confirmToDeleteFingerprint(otrFingerprint);
+ }
+ });
+ }
}
- for (final String fingerprint : contact.getAccount().getAxolotlService().getFingerprintsForContact(contact)) {
- boolean highlight = fingerprint.equals(messageFingerprint);
- hasKeys |= addFingerprintRow(keys, contact.getAccount(), fingerprint, highlight, new OnClickListener() {
- @Override
- public void onClick(View v) {
- onOmemoKeyClicked(contact.getAccount(), fingerprint);
- }
- });
+ if (Config.supportOmemo()) {
+ for (final String fingerprint : contact.getAccount().getAxolotlService().getFingerprintsForContact(contact)) {
+ boolean highlight = fingerprint.equals(messageFingerprint);
+ hasKeys |= addFingerprintRow(keys, contact.getAccount(), fingerprint, highlight, new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ onOmemoKeyClicked(contact.getAccount(), fingerprint);
+ }
+ });
+ }
}
- if (contact.getPgpKeyId() != 0) {
+ if (Config.supportOpenPgp() && contact.getPgpKeyId() != 0) {
hasKeys = true;
View view = inflater.inflate(R.layout.contact_key, keys, false);
TextView key = (TextView) view.findViewById(R.id.key);
diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java
index 9e8c7f6f6..2db0e7c38 100644
--- a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java
+++ b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java
@@ -1316,6 +1316,8 @@ public class ConversationActivity extends XmppActivity
if (mPendingConferenceInvite != null) {
mPendingConferenceInvite.execute(this);
+ mToast = Toast.makeText(this, R.string.creating_conference,Toast.LENGTH_LONG);
+ mToast.show();
mPendingConferenceInvite = null;
}
diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java
index 014fedd39..3ec484087 100644
--- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java
+++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java
@@ -400,8 +400,11 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
} else {
switch (conversation.getNextEncryption()) {
case Message.ENCRYPTION_NONE:
- mEditMessage
- .setHint(getString(R.string.send_unencrypted_message));
+ if (Config.multipleEncryptionChoices()) {
+ mEditMessage.setHint(getString(R.string.send_unencrypted_message));
+ } else {
+ mEditMessage.setHint(getString(R.string.send_message_to_x,conversation.getName()));
+ }
break;
case Message.ENCRYPTION_OTR:
mEditMessage.setHint(getString(R.string.send_otr_message));
diff --git a/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java b/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java
index 15701c950..af6b305c0 100644
--- a/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java
+++ b/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java
@@ -523,7 +523,7 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate
}
mamPrefs.setVisible(mAccount.getXmppConnection().getFeatures().mam());
Set<Integer> otherDevices = mAccount.getAxolotlService().getOwnDeviceIds();
- if (otherDevices == null || otherDevices.isEmpty()) {
+ if (otherDevices == null || otherDevices.isEmpty() || Config.supportOmemo()) {
clearDevices.setVisible(false);
}
changePresence.setVisible(manuallyChangePresence());
@@ -785,7 +785,7 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate
this.mServerInfoPush.setText(R.string.server_info_unavailable);
}
final String otrFingerprint = this.mAccount.getOtrFingerprint();
- if (otrFingerprint != null) {
+ if (otrFingerprint != null && Config.supportOtr()) {
this.mOtrFingerprintBox.setVisibility(View.VISIBLE);
this.mOtrFingerprint.setText(CryptoHelper.prettifyFingerprint(otrFingerprint));
this.mOtrFingerprintToClipboardButton
@@ -807,10 +807,10 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate
} else {
this.mOtrFingerprintBox.setVisibility(View.GONE);
}
- final String axolotlFingerprint = this.mAccount.getAxolotlService().getOwnFingerprint();
- if (axolotlFingerprint != null) {
+ final String ownAxolotlFingerprint = this.mAccount.getAxolotlService().getOwnFingerprint();
+ if (ownAxolotlFingerprint != null && Config.supportOmemo()) {
this.mAxolotlFingerprintBox.setVisibility(View.VISIBLE);
- this.mAxolotlFingerprint.setText(CryptoHelper.prettifyFingerprint(axolotlFingerprint.substring(2)));
+ this.mAxolotlFingerprint.setText(CryptoHelper.prettifyFingerprint(ownAxolotlFingerprint.substring(2)));
this.mAxolotlFingerprintToClipboardButton
.setVisibility(View.VISIBLE);
this.mAxolotlFingerprintToClipboardButton
@@ -819,7 +819,7 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate
@Override
public void onClick(final View v) {
- if (copyTextToClipboard(axolotlFingerprint.substring(2), R.string.omemo_fingerprint)) {
+ if (copyTextToClipboard(ownAxolotlFingerprint.substring(2), R.string.omemo_fingerprint)) {
Toast.makeText(
EditAccountActivity.this,
R.string.toast_message_omemo_fingerprint,
@@ -842,17 +842,16 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate
} else {
this.mAxolotlFingerprintBox.setVisibility(View.GONE);
}
- final String ownFingerprint = mAccount.getAxolotlService().getOwnFingerprint();
boolean hasKeys = false;
keys.removeAllViews();
for (final String fingerprint : mAccount.getAxolotlService().getFingerprintsForOwnSessions()) {
- if (ownFingerprint.equals(fingerprint)) {
+ if (ownAxolotlFingerprint.equals(fingerprint)) {
continue;
}
boolean highlight = fingerprint.equals(messageFingerprint);
hasKeys |= addFingerprintRow(keys, mAccount, fingerprint, highlight, null);
}
- if (hasKeys) {
+ if (hasKeys && Config.supportOmemo()) {
keysCard.setVisibility(View.VISIBLE);
} else {
keysCard.setVisibility(View.GONE);
diff --git a/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java
index 3ab6d1d2e..9af83edd8 100644
--- a/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java
+++ b/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java
@@ -10,6 +10,7 @@ import android.app.AlertDialog;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.app.ListFragment;
+import android.app.PendingIntent;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
@@ -27,6 +28,7 @@ import android.support.v4.view.ViewPager;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
+import android.util.Pair;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.KeyEvent;
@@ -54,6 +56,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
+import java.util.concurrent.RunnableFuture;
import java.util.concurrent.atomic.AtomicBoolean;
import eu.siacs.conversations.Config;
@@ -94,6 +97,7 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
private EditText mSearchEditText;
private AtomicBoolean mRequestedContactsPermission = new AtomicBoolean(false);
private final int REQUEST_SYNC_CONTACTS = 0x3b28cf;
+ private final int REQUEST_CREATE_CONFERENCE = 0x3b39da;
private MenuItem.OnActionExpandListener mOnActionExpandListener = new MenuItem.OnActionExpandListener() {
@@ -201,6 +205,47 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
}
};
private String mInitialJid;
+ private Pair<Integer, Intent> mPostponedActivityResult;
+ private UiCallback<Conversation> mAdhocConferenceCallback = new UiCallback<Conversation>() {
+ @Override
+ public void success(final Conversation conversation) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ hideToast();
+ switchToConversation(conversation);
+ }
+ });
+ }
+
+ @Override
+ public void error(final int errorCode, Conversation object) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ replaceToast(getString(errorCode));
+ }
+ });
+ }
+
+ @Override
+ public void userInputRequried(PendingIntent pi, Conversation object) {
+
+ }
+ };
+ private Toast mToast;
+
+ protected void hideToast() {
+ if (mToast != null) {
+ mToast.cancel();
+ }
+ }
+
+ protected void replaceToast(String msg) {
+ hideToast();
+ mToast = Toast.makeText(this, msg ,Toast.LENGTH_LONG);
+ mToast.show();
+ }
@Override
public void onRosterUpdate() {
@@ -488,6 +533,37 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
});
}
+ private void showCreateConferenceDialog() {
+ final AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ builder.setTitle(R.string.create_conference);
+ final View dialogView = getLayoutInflater().inflate(R.layout.create_conference_dialog, null);
+ final Spinner spinner = (Spinner) dialogView.findViewById(R.id.account);
+ final EditText subject = (EditText) dialogView.findViewById(R.id.subject);
+ populateAccountSpinner(this, mActivatedAccounts, spinner);
+ builder.setView(dialogView);
+ builder.setPositiveButton(R.string.choose_participants, new OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ if (!xmppConnectionServiceBound) {
+ return;
+ }
+ final Account account = getSelectedAccount(spinner);
+ if (account == null) {
+ return;
+ }
+ Intent intent = new Intent(getApplicationContext(), ChooseContactActivity.class);
+ intent.putExtra("multiple", true);
+ intent.putExtra("show_enter_jid", true);
+ intent.putExtra("subject", subject.getText().toString());
+ intent.putExtra(EXTRA_ACCOUNT, account.getJid().toBareJid().toString());
+ intent.putExtra(ChooseContactActivity.EXTRA_TITLE_RES_ID,R.string.choose_participants);
+ startActivityForResult(intent, REQUEST_CREATE_CONFERENCE);
+ }
+ });
+ builder.setNegativeButton(R.string.cancel, null);
+ builder.create().show();
+ }
+
private Account getSelectedAccount(Spinner spinner) {
if (!spinner.isEnabled()) {
return null;
@@ -532,7 +608,7 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.start_conversation, menu);
MenuItem menuCreateContact = menu.findItem(R.id.action_create_contact);
- MenuItem menuCreateConference = menu.findItem(R.id.action_join_conference);
+ MenuItem menuCreateConference = menu.findItem(R.id.action_conference);
MenuItem menuHideOffline = menu.findItem(R.id.action_hide_offline);
menuHideOffline.setChecked(this.mHideOfflineContacts);
mMenuSearchView = menu.findItem(R.id.action_search);
@@ -564,6 +640,9 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
case R.id.action_join_conference:
showJoinConferenceDialog(null);
return true;
+ case R.id.action_create_conference:
+ showCreateConferenceDialog();
+ return true;
case R.id.action_scan_qr_code:
new IntentIntegrator(this).initiateScan();
return true;
@@ -616,6 +695,39 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
this.mPendingInvite = null;
}
}
+ } else if (resultCode == RESULT_OK) {
+ if (xmppConnectionServiceBound) {
+ this.mPostponedActivityResult = null;
+ if (requestCode == REQUEST_CREATE_CONFERENCE) {
+ Log.d(Config.LOGTAG,"account jid: "+ intent.getStringExtra(EXTRA_ACCOUNT));
+ Account account = extractAccount(intent);
+ final String subject = intent.getStringExtra("subject");
+ List<Jid> jids = new ArrayList<>();
+ if (intent.getBooleanExtra("multiple", false)) {
+ String[] toAdd = intent.getStringArrayExtra("contacts");
+ for (String item : toAdd) {
+ try {
+ jids.add(Jid.fromString(item));
+ } catch (InvalidJidException e) {
+ //ignored
+ }
+ }
+ } else {
+ try {
+ jids.add(Jid.fromString(intent.getStringExtra("contact")));
+ } catch (Exception e) {
+ //ignored
+ }
+ }
+ if (account != null && jids.size() > 1) {
+ xmppConnectionService.createAdhocConference(account, subject, jids, mAdhocConferenceCallback);
+ mToast = Toast.makeText(this, R.string.creating_conference,Toast.LENGTH_LONG);
+ mToast.show();
+ }
+ }
+ } else {
+ this.mPostponedActivityResult = new Pair<>(requestCode, intent);
+ }
}
super.onActivityResult(requestCode, requestCode, intent);
}
@@ -657,6 +769,10 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
@Override
protected void onBackendConnected() {
+ if (mPostponedActivityResult != null) {
+ onActivityResult(mPostponedActivityResult.first, RESULT_OK, mPostponedActivityResult.second);
+ this.mPostponedActivityResult = null;
+ }
this.mActivatedAccounts.clear();
for (Account account : xmppConnectionService.getAccounts()) {
if (account.getStatus() != Account.State.DISABLED) {
diff --git a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java
index 2a6dbf589..faa314752 100644
--- a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java
+++ b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java
@@ -118,6 +118,20 @@ public abstract class XmppActivity extends Activity {
protected int mTheme;
protected boolean mUsingEnterKey = false;
+ protected Toast mToast;
+
+ protected void hideToast() {
+ if (mToast != null) {
+ mToast.cancel();
+ }
+ }
+
+ protected void replaceToast(String msg) {
+ hideToast();
+ mToast = Toast.makeText(this, msg ,Toast.LENGTH_LONG);
+ mToast.show();
+ }
+
protected Runnable onOpenPGPKeyPublished = new Runnable() {
@Override
public void run() {
@@ -948,19 +962,22 @@ public abstract class XmppActivity extends Activity {
mPendingConferenceInvite = ConferenceInvite.parse(data);
if (xmppConnectionServiceBound && mPendingConferenceInvite != null) {
mPendingConferenceInvite.execute(this);
+ mToast = Toast.makeText(this, R.string.creating_conference,Toast.LENGTH_LONG);
+ mToast.show();
mPendingConferenceInvite = null;
}
}
}
+
private UiCallback<Conversation> adhocCallback = new UiCallback<Conversation>() {
@Override
public void success(final Conversation conversation) {
- switchToConversation(conversation);
runOnUiThread(new Runnable() {
@Override
public void run() {
- Toast.makeText(XmppActivity.this,R.string.conference_created,Toast.LENGTH_LONG).show();
+ switchToConversation(conversation);
+ hideToast();
}
});
}
@@ -970,7 +987,7 @@ public abstract class XmppActivity extends Activity {
runOnUiThread(new Runnable() {
@Override
public void run() {
- Toast.makeText(XmppActivity.this,errorCode,Toast.LENGTH_LONG).show();
+ replaceToast(getString(errorCode));
}
});
}
@@ -1167,7 +1184,7 @@ public abstract class XmppActivity extends Activity {
}
} else {
jids.add(conversation.getJid().toBareJid());
- service.createAdhocConference(conversation.getAccount(), jids, activity.adhocCallback);
+ service.createAdhocConference(conversation.getAccount(), null, jids, activity.adhocCallback);
}
}
}
diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java
index b42be17b9..a07267e71 100644
--- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java
+++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java
@@ -184,14 +184,21 @@ public class XmppConnection implements Runnable {
account.setOption(Account.OPTION_REGISTER, false);
forceCloseSocket();
changeStatus(Account.State.REGISTRATION_SUCCESSFUL);
- } else if (packet.hasChild("error")
- && (packet.findChild("error").hasChild("conflict"))) {
- forceCloseSocket();
- changeStatus(Account.State.REGISTRATION_CONFLICT);
} else {
- forceCloseSocket();
- changeStatus(Account.State.REGISTRATION_FAILED);
- Log.d(Config.LOGTAG, packet.toString());
+ Element error = packet.findChild("error");
+ if (error != null && error.hasChild("conflict")) {
+ forceCloseSocket();
+ changeStatus(Account.State.REGISTRATION_CONFLICT);
+ } else if (error != null
+ && "wait".equals(error.getAttribute("type"))
+ && error.hasChild("resource-constraint")) {
+ forceCloseSocket();
+ changeStatus(Account.State.REGISTRATION_PLEASE_WAIT);
+ } else {
+ forceCloseSocket();
+ changeStatus(Account.State.REGISTRATION_FAILED);
+ Log.d(Config.LOGTAG, packet.toString());
+ }
}
}
};
diff --git a/src/main/res/layout/create_conference_dialog.xml b/src/main/res/layout/create_conference_dialog.xml
new file mode 100644
index 000000000..cab2ac578
--- /dev/null
+++ b/src/main/res/layout/create_conference_dialog.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:paddingBottom="8dp"
+ android:paddingLeft="24dp"
+ android:paddingRight="24dp"
+ android:paddingTop="16dp">
+
+ <TextView
+ android:id="@+id/your_account"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/your_account"
+ android:textColor="@color/black87"
+ android:textSize="?attr/TextSizeBody" />
+
+ <Spinner
+ android:id="@+id/account"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content" />
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="8dp"
+ android:text="@string/conference_subject"
+ android:textColor="@color/black87"
+ android:textSize="?attr/TextSizeBody" />
+
+ <EditText
+ android:id="@+id/subject"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:hint="@string/edit_subject_hint"
+ android:inputType="textAutoComplete"
+ android:textColor="@color/black87"
+ android:textColorHint="@color/black54"
+ android:textSize="?attr/TextSizeBody"/>
+
+</LinearLayout> \ No newline at end of file
diff --git a/src/main/res/menu/start_conversation.xml b/src/main/res/menu/start_conversation.xml
index b0472af05..305ffd223 100644
--- a/src/main/res/menu/start_conversation.xml
+++ b/src/main/res/menu/start_conversation.xml
@@ -13,10 +13,20 @@
android:showAsAction="always"
android:title="@string/create_contact" />
<item
- android:id="@+id/action_join_conference"
+ android:id="@+id/action_conference"
android:icon="?attr/icon_add_group"
android:showAsAction="always"
- android:title="@string/join_conference" />
+ android:title="@string/join_or_create_conference">
+ <menu>
+ <item
+ android:id="@+id/action_join_conference"
+ android:title="@string/join_conference"/>
+ <item
+ android:id="@+id/action_create_conference"
+ android:title="@string/create_conference"/>
+
+ </menu>
+ </item>
<item
android:id="@+id/action_scan_qr_code"
android:showAsAction="never"
diff --git a/src/main/res/values-de/strings.xml b/src/main/res/values-de/strings.xml
index 4ff75a9be..83f04e9d8 100644
--- a/src/main/res/values-de/strings.xml
+++ b/src/main/res/values-de/strings.xml
@@ -155,9 +155,8 @@
<string name="mgmt_account_delete">Löschen</string>
<string name="mgmt_account_publish_avatar">Profilbild veröffentlichen</string>
<string name="mgmt_account_publish_pgp">Öffentlichen OpenPGP-Schlüssel veröffentlichen</string>
- <string name="openpgp_has_been_published">Öffentlicher OpenPGP Schlüssel wurde veröffentlicht.</string>
- <string name="republish_pgp_keys">Deine öffentliche OpenPGP Schlüssel müssen veröffentlicht werden!</string>
- <string name="mgmt_account_enable">Konto aktivieren </string>
+ <string name="openpgp_has_been_published">Öffentlicher OpenPGP-Schlüssel wurde veröffentlicht.</string>
+ <string name="republish_pgp_keys">Deine öffentliche OpenPGP-Schlüssel müssen veröffentlicht werden!</string>
<string name="mgmt_account_are_you_sure">Bist du dir sicher?</string>
<string name="mgmt_account_delete_confirm_text">Wenn du dein Profil löschst, gehen alle Gesprächsverläufe verloren</string>
<string name="attach_record_voice">Sprache aufzeichnen</string>
@@ -225,7 +224,7 @@
<string name="delete_bookmark">Von Kontaktliste entfernen</string>
<string name="bookmark_already_exists">Die Konferenz befindet sich bereits auf deiner Kontaktliste</string>
<string name="action_edit_subject">Konferenz-Thema bearbeiten</string>
- <string name="joining_conference">Konferenz wird betreten…</string>
+ <string name="joining_conference">Konferenz wird beigetreten…</string>
<string name="leave">Verlassen</string>
<string name="contact_added_you">Der Kontakt hat dich zur Kontaktliste hinzugefügt</string>
<string name="add_back">Auch hinzufügen</string>
@@ -339,8 +338,9 @@
<string name="enable_notifications">Benachrichtigungen aktivieren</string>
<string name="no_conference_server_found">Kein Konferenz-Server gefunden</string>
<string name="conference_creation_failed">Erstellen der Konferenz fehlgeschlagen!</string>
- <string name="conference_created">Konferenz erstellt!</string>
<string name="account_image_description">Profilbild</string>
+ <string name="secret_accepted">Schlüssel akzeptiert!</string>
+ <string name="reset">Zurücksetzen</string>
<string name="copy_otr_clipboard_description">OTR-Fingerabdruck in Zwischenablage kopieren</string>
<string name="copy_omemo_clipboard_description">OMEMO-Fingerabdruck in Zwischenablage kopieren</string>
<string name="regenerate_omemo_key">OMEMO-Schlüssel erneuern</string>
@@ -448,7 +448,7 @@
<string name="pref_quick_action">Schnell-Tasten</string>
<string name="none">keine</string>
<string name="recently_used">zuletzt verwendet</string>
- <string name="choose_quick_action">wähle Schnell-Taste</string>
+ <string name="choose_quick_action">Schnell-Taste auswähle</string>
<string name="search_for_contacts_or_groups">Nach Kontakten oder Konferenzen suchen</string>
<string name="elv_undo">Rückgängig</string>
<string name="send_private_message">Private Nachricht senden</string>
@@ -490,7 +490,7 @@
<string name="fetching_mam_prefs">Archivierungseinstellungen werden abgerufen. Bitte warten …</string>
<string name="unable_to_fetch_mam_prefs">Archivierungseinstellungen konnten nicht abgerufen werden</string>
<string name="captcha_required">Captcha erforderlich</string>
- <string name="captcha_hint">Gib den Text vom obigen Bild ein</string>
+ <string name="captcha_hint">Gib den Text von obigem Bild ein</string>
<string name="certificate_chain_is_not_trusted">Zertifikat wird nicht vertraut</string>
<string name="jid_does_not_match_certificate">Jabber-ID stimmt nicht dem Zertifikat überein</string>
<string name="action_renew_certificate">Zertifikat erneuern</string>
@@ -589,7 +589,7 @@
<string name="presence_xa">Nicht verfügbar</string>
<string name="presence_dnd">Beschäftigt</string>
<string name="secure_password_generated">Ein sicheres Passwort wurde erstellt</string>
- <string name="device_does_not_support_battery_op">Dein Gerät unterstützt keine Batterieoptimierungen</string>
+ <string name="device_does_not_support_battery_op">Dein Gerät unterstützt kein Ausschalten der Batterieoptimierung</string>
<string name="locating">Lokalisiere…</string>
<string name="location_sharing_disabled">GPS ist in den Android-Einstellungen deaktiviert</string>
<string name="share">Teilen</string>
@@ -600,4 +600,13 @@
<string name="default_resource"></string>
<string name="leave_conference_warning">Willst du die Konferenz wirklich verlassen? Du wirst keine neuen Nachrichten mehr bekommen, bis du der Konferenz erneut beitrittst.</string>
<string name="show_password">Passwort anzeigen</string>
+ <string name="choose_participants">Mitglieder auswählen</string>
+ <string name="conference_subject">Titel</string>
+ <string name="create_conference">Konferenz erstellen</string>
+ <string name="creating_conference">Erstelle Konferenz…</string>
+ <string name="edit_subject_hint">Der Titel dieser Konferenz</string>
+ <string name="join_or_create_conference">Konferenz beitreten oder erstellen</string>
+ <string name="mgmt_account_enable"></string>
+ <string name="registration_please_wait">Registrierung fehlgeschlagen: Bitte später versuchen</string>
+ <string name="send_message_to_x">Nachricht an %s senden</string>
</resources>
diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml
index 5185f37aa..f25918008 100644
--- a/src/main/res/values/strings.xml
+++ b/src/main/res/values/strings.xml
@@ -79,6 +79,7 @@
<string name="also_end_conversation">End this conversation afterwards</string>
<string name="choose_presence">Choose presence to contact</string>
<string name="send_unencrypted_message">Send unencrypted message</string>
+ <string name="send_message_to_x">Send message to %s</string>
<string name="send_otr_message">Send OTR encrypted message</string>
<string name="send_omemo_message">Send OMEMO encrypted message</string>
<string name="send_omemo_x509_message">Send v\\OMEMO encrypted message</string>
@@ -230,6 +231,7 @@
<string name="delete_bookmark">Delete bookmark</string>
<string name="bookmark_already_exists">This bookmark already exists</string>
<string name="action_edit_subject">Edit conference subject</string>
+ <string name="edit_subject_hint">The subject of this conference</string>
<string name="joining_conference">Joining conference…</string>
<string name="leave">Leave</string>
<string name="contact_added_you">Contact added you to contact list</string>
@@ -387,8 +389,9 @@
<string name="pref_show_dynamic_tags_summary">Display read-only tags underneath contacts</string>
<string name="enable_notifications">Enable notifications</string>
<string name="no_conference_server_found">No conference server found</string>
- <string name="conference_creation_failed">Conference creation failed!</string>
- <string name="conference_created">Conference created!</string>
+ <string name="conference_creation_failed">Conference creation failed!</string>s
+ <string name="secret_accepted">Secret accepted!</string>
+ <string name="reset">Reset</string>
<string name="account_image_description">Account avatar</string>
<string name="copy_otr_clipboard_description">Copy OTR fingerprint to clipboard</string>
<string name="copy_omemo_clipboard_description">Copy OMEMO fingerprint to clipboard</string>
@@ -633,5 +636,11 @@
<string name="action_end_conversation_muc">Leave conference</string>
<string name="leave_conference_warning">Do you really want to leave this conference? You will no longer be notified of new messages until joining the conference again.</string>
<string name="show_password">Show password</string>
+ <string name="registration_please_wait">Registration failed: Try again later</string>
+ <string name="create_conference">Create conference</string>
+ <string name="join_or_create_conference">Join or create conference</string>
+ <string name="conference_subject">Subject</string>
+ <string name="choose_participants">Choose participants</string>
+ <string name="creating_conference">Creating conference…</string>
</resources>