aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/eu/siacs/conversations/crypto/OtrEngine.java38
-rw-r--r--src/main/java/eu/siacs/conversations/entities/Account.java14
-rw-r--r--src/main/java/eu/siacs/conversations/entities/Message.java28
-rw-r--r--src/main/java/eu/siacs/conversations/generator/MessageGenerator.java4
-rw-r--r--src/main/java/eu/siacs/conversations/generator/PresenceGenerator.java7
-rw-r--r--src/main/java/eu/siacs/conversations/services/XmppConnectionService.java6
-rw-r--r--src/main/java/eu/siacs/conversations/ui/ConversationActivity.java213
-rw-r--r--src/main/java/eu/siacs/conversations/ui/ConversationFragment.java1
-rw-r--r--src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java14
-rw-r--r--src/main/java/eu/siacs/conversations/ui/ManageAccountActivity.java8
-rw-r--r--src/main/java/eu/siacs/conversations/ui/SettingsActivity.java12
-rw-r--r--src/main/java/eu/siacs/conversations/ui/ShareWithActivity.java54
-rw-r--r--src/main/java/eu/siacs/conversations/ui/XmppActivity.java8
-rw-r--r--src/main/java/eu/siacs/conversations/ui/adapter/AccountAdapter.java46
-rw-r--r--src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java15
-rw-r--r--src/main/java/eu/siacs/conversations/utils/GeoHelper.java2
-rw-r--r--src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java4
17 files changed, 336 insertions, 138 deletions
diff --git a/src/main/java/eu/siacs/conversations/crypto/OtrEngine.java b/src/main/java/eu/siacs/conversations/crypto/OtrEngine.java
index 20427d7b..263f6089 100644
--- a/src/main/java/eu/siacs/conversations/crypto/OtrEngine.java
+++ b/src/main/java/eu/siacs/conversations/crypto/OtrEngine.java
@@ -202,20 +202,7 @@ public class OtrEngine extends OtrCryptoEngineImpl implements OtrEngineHost {
@Override
public void messageFromAnotherInstanceReceived(SessionID session) {
- try {
- Jid jid = Jid.fromSessionID(session);
- Conversation conversation = mXmppConnectionService.find(account, jid);
- String id = conversation == null ? null : conversation.getLastReceivedOtrMessageId();
- if (id != null) {
- MessagePacket packet = mXmppConnectionService.getMessageGenerator().generateOtrError(jid,id);
- packet.setFrom(account.getJid());
- mXmppConnectionService.sendMessagePacket(account,packet);
- Log.d(Config.LOGTAG,packet.toString());
- Log.d(Config.LOGTAG,account.getJid().toBareJid().toString()+": unreadable OTR message in "+conversation.getName());
- }
- } catch (InvalidJidException e) {
- return;
- }
+ sendOtrErrorMessage(session, "Message from another OTR-instance received");
}
@Override
@@ -267,9 +254,28 @@ public class OtrEngine extends OtrCryptoEngineImpl implements OtrEngineHost {
}
@Override
- public void unreadableMessageReceived(SessionID arg0) throws OtrException {
+ public void unreadableMessageReceived(SessionID session) throws OtrException {
Log.d(Config.LOGTAG,"unreadable message received");
- throw new OtrException(new Exception("unreadable message received"));
+ sendOtrErrorMessage(session, "You sent me an unreadable OTR-encrypted message");
+ }
+
+ public void sendOtrErrorMessage(SessionID session, String errorText) {
+ try {
+ Jid jid = Jid.fromSessionID(session);
+ Conversation conversation = mXmppConnectionService.find(account, jid);
+ String id = conversation == null ? null : conversation.getLastReceivedOtrMessageId();
+ if (id != null) {
+ MessagePacket packet = mXmppConnectionService.getMessageGenerator()
+ .generateOtrError(jid, id, errorText);
+ packet.setFrom(account.getJid());
+ mXmppConnectionService.sendMessagePacket(account,packet);
+ Log.d(Config.LOGTAG,packet.toString());
+ Log.d(Config.LOGTAG,account.getJid().toBareJid().toString()
+ +": unreadable OTR message in "+conversation.getName());
+ }
+ } catch (InvalidJidException e) {
+ return;
+ }
}
@Override
diff --git a/src/main/java/eu/siacs/conversations/entities/Account.java b/src/main/java/eu/siacs/conversations/entities/Account.java
index 2bc2c954..fe103094 100644
--- a/src/main/java/eu/siacs/conversations/entities/Account.java
+++ b/src/main/java/eu/siacs/conversations/entities/Account.java
@@ -229,11 +229,17 @@ public class Account extends AbstractEntity {
return jid.getResourcepart();
}
- public void setResource(final String resource) {
- try {
- jid = Jid.fromParts(jid.getLocalpart(), jid.getDomainpart(), resource);
- } catch (final InvalidJidException ignored) {
+ public boolean setResource(final String resource) {
+ final String oldResource = jid.getResourcepart();
+ if (oldResource == null || !oldResource.equals(resource)) {
+ try {
+ jid = Jid.fromParts(jid.getLocalpart(), jid.getDomainpart(), resource);
+ return true;
+ } catch (final InvalidJidException ignored) {
+ return true;
+ }
}
+ return false;
}
public Jid getJid() {
diff --git a/src/main/java/eu/siacs/conversations/entities/Message.java b/src/main/java/eu/siacs/conversations/entities/Message.java
index 8015eead..7ea3d60b 100644
--- a/src/main/java/eu/siacs/conversations/entities/Message.java
+++ b/src/main/java/eu/siacs/conversations/entities/Message.java
@@ -430,23 +430,31 @@ public class Message extends AbstractEntity {
}
public boolean bodyContainsDownloadable() {
+ /**
+ * there are a few cases where spaces result in an unwanted behavior, e.g.
+ * "http://example.com/image.jpg text that will not be shown /abc.png"
+ * or more than one image link in one message.
+ */
+ if (body.contains(" ")) {
+ return false;
+ }
try {
- URL url = new URL(this.getBody());
+ URL url = new URL(body);
if (!url.getProtocol().equalsIgnoreCase("http")
&& !url.getProtocol().equalsIgnoreCase("https")) {
return false;
}
- if (url.getPath() == null) {
- return false;
- }
- String[] pathParts = url.getPath().split("/");
- String filename;
- if (pathParts.length > 0) {
- filename = pathParts[pathParts.length - 1].toLowerCase();
- } else {
+
+ String sUrlPath = url.getPath();
+ if (sUrlPath == null || sUrlPath.isEmpty()) {
return false;
}
- String[] extensionParts = filename.split("\\.");
+
+ int iSlashIndex = sUrlPath.lastIndexOf('/') + 1;
+
+ String sLastUrlPath = sUrlPath.substring(iSlashIndex).toLowerCase();
+
+ String[] extensionParts = sLastUrlPath.split("\\.");
if (extensionParts.length == 2
&& Arrays.asList(Downloadable.VALID_IMAGE_EXTENSIONS).contains(
extensionParts[extensionParts.length - 1])) {
diff --git a/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java b/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java
index 8f6a90b9..a60c5613 100644
--- a/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java
+++ b/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java
@@ -172,7 +172,7 @@ public class MessageGenerator extends AbstractGenerator {
return receivedPacket;
}
- public MessagePacket generateOtrError(Jid to, String id) {
+ public MessagePacket generateOtrError(Jid to, String id, String errorText) {
MessagePacket packet = new MessagePacket();
packet.setType(MessagePacket.TYPE_ERROR);
packet.setAttribute("id",id);
@@ -181,7 +181,7 @@ public class MessageGenerator extends AbstractGenerator {
error.setAttribute("code","406");
error.setAttribute("type","modify");
error.addChild("not-acceptable","urn:ietf:params:xml:ns:xmpp-stanzas");
- error.addChild("text").setContent("unreadable OTR message received");
+ error.addChild("text").setContent("?OTR Error:" + errorText);
return packet;
}
}
diff --git a/src/main/java/eu/siacs/conversations/generator/PresenceGenerator.java b/src/main/java/eu/siacs/conversations/generator/PresenceGenerator.java
index 1e896724..526005f3 100644
--- a/src/main/java/eu/siacs/conversations/generator/PresenceGenerator.java
+++ b/src/main/java/eu/siacs/conversations/generator/PresenceGenerator.java
@@ -54,4 +54,11 @@ public class PresenceGenerator extends AbstractGenerator {
}
return packet;
}
+
+ public PresencePacket sendOfflinePresence(Account account) {
+ PresencePacket packet = new PresencePacket();
+ packet.setFrom(account.getJid());
+ packet.setAttribute("type","unavailable");
+ return packet;
+ }
} \ No newline at end of file
diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java
index f94e715e..3e8ce65f 100644
--- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java
+++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java
@@ -1127,6 +1127,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
}
public void archiveConversation(Conversation conversation) {
+ getNotificationService().clear(conversation);
conversation.setStatus(Conversation.STATUS_ARCHIVED);
conversation.setNextEncryption(-1);
synchronized (this.conversations) {
@@ -1698,6 +1699,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
}
}
}
+ sendOfflinePresence(account);
}
account.getXmppConnection().disconnect(force);
}
@@ -2273,6 +2275,10 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
sendPresencePacket(account, mPresenceGenerator.sendPresence(account));
}
+ public void sendOfflinePresence(final Account account) {
+ sendPresencePacket(account, mPresenceGenerator.sendOfflinePresence(account));
+ }
+
public MessageGenerator getMessageGenerator() {
return this.mMessageGenerator;
}
diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java
index 82afda07..c8a1e6df 100644
--- a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java
+++ b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java
@@ -5,6 +5,7 @@ import android.app.ActionBar;
import android.app.AlertDialog;
import android.app.FragmentTransaction;
import android.app.PendingIntent;
+import android.content.ClipData;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
@@ -22,14 +23,15 @@ import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
-import android.widget.ListView;
import android.widget.PopupMenu;
import android.widget.PopupMenu.OnMenuItemClickListener;
import android.widget.Toast;
import net.java.otr4j.session.SessionStatus;
+import de.timroes.android.listview.EnhancedListView;
import java.util.ArrayList;
+import java.util.Iterator;
import java.util.List;
import eu.siacs.conversations.R;
@@ -69,15 +71,16 @@ public class ConversationActivity extends XmppActivity
private String mOpenConverstaion = null;
private boolean mPanelOpen = true;
- private Uri mPendingImageUri = null;
- private Uri mPendingFileUri = null;
+ final private List<Uri> mPendingImageUris = new ArrayList<>();
+ final private List<Uri> mPendingFileUris = new ArrayList<>();
private Uri mPendingGeoUri = null;
private View mContentView;
private List<Conversation> conversationList = new ArrayList<>();
+ private Conversation swipedConversation = null;
private Conversation mSelectedConversation = null;
- private ListView listView;
+ private EnhancedListView listView;
private ConversationFragment mConversationFragment;
private ArrayAdapter<Conversation> listAdapter;
@@ -140,13 +143,14 @@ public class ConversationActivity extends XmppActivity
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- if (savedInstanceState != null) {mOpenConverstaion = savedInstanceState.getString(
- STATE_OPEN_CONVERSATION, null);
- mPanelOpen = savedInstanceState.getBoolean(STATE_PANEL_OPEN, true);
- String pending = savedInstanceState.getString(STATE_PENDING_URI, null);
- if (pending != null) {
- mPendingImageUri = Uri.parse(pending);
- }
+ if (savedInstanceState != null) {
+ mOpenConverstaion = savedInstanceState.getString(STATE_OPEN_CONVERSATION, null);
+ mPanelOpen = savedInstanceState.getBoolean(STATE_PANEL_OPEN, true);
+ String pending = savedInstanceState.getString(STATE_PENDING_URI, null);
+ if (pending != null) {
+ mPendingImageUris.clear();
+ mPendingImageUris.add(Uri.parse(pending));
+ }
}
setContentView(R.layout.fragment_conversations_overview);
@@ -156,7 +160,7 @@ public class ConversationActivity extends XmppActivity
transaction.replace(R.id.selected_conversation, this.mConversationFragment, "conversation");
transaction.commit();
- listView = (ListView) findViewById(R.id.list);
+ listView = (EnhancedListView) findViewById(R.id.list);
this.listAdapter = new ConversationAdapter(this, conversationList);
listView.setAdapter(this.listAdapter);
@@ -178,6 +182,73 @@ public class ConversationActivity extends XmppActivity
openConversation();
}
});
+
+ listView.setDismissCallback(new EnhancedListView.OnDismissCallback() {
+
+ @Override
+ public EnhancedListView.Undoable onDismiss(final EnhancedListView enhancedListView, final int position) {
+
+ final int index = listView.getFirstVisiblePosition();
+ View v = listView.getChildAt(0);
+ final int top = (v == null) ? 0 : (v.getTop() - listView.getPaddingTop());
+
+ swipedConversation = listAdapter.getItem(position);
+ listAdapter.remove(swipedConversation);
+ swipedConversation.markRead();
+ xmppConnectionService.getNotificationService().clear(swipedConversation);
+
+ final boolean formerlySelected = (getSelectedConversation() == swipedConversation);
+ if (position == 0 && listAdapter.getCount() == 0) {
+ endConversation(swipedConversation, false, true);
+ return null;
+ } else if (formerlySelected) {
+ setSelectedConversation(listAdapter.getItem(0));
+ ConversationActivity.this.mConversationFragment
+ .reInit(getSelectedConversation());
+ }
+
+ return new EnhancedListView.Undoable() {
+
+ @Override
+ public void undo() {
+ listAdapter.insert(swipedConversation, position);
+ if (formerlySelected) {
+ setSelectedConversation(swipedConversation);
+ ConversationActivity.this.mConversationFragment
+ .reInit(getSelectedConversation());
+ }
+ swipedConversation = null;
+ listView.setSelectionFromTop(index + (listView.getChildCount() < position ? 1 : 0), top);
+ }
+
+ @Override
+ public void discard() {
+ if (!swipedConversation.isRead()
+ && swipedConversation.getMode() == Conversation.MODE_SINGLE) {
+ swipedConversation = null;
+ return;
+ }
+ endConversation(swipedConversation, false, false);
+ swipedConversation = null;
+ }
+
+ @Override
+ public String getTitle() {
+ if (swipedConversation.getMode() == Conversation.MODE_MULTI) {
+ return getResources().getString(R.string.title_undo_swipe_out_muc);
+ } else {
+ return getResources().getString(R.string.title_undo_swipe_out_conversation);
+ }
+ }
+ };
+ }
+ });
+ listView.enableSwipeToDismiss();
+ listView.setSwipingLayout(R.id.swipeable_item);
+ listView.setUndoStyle(EnhancedListView.UndoStyle.SINGLE_POPUP);
+ listView.setUndoHideDelay(3000);
+ listView.setRequireTouchBeforeDismiss(false);
+
mContentView = findViewById(R.id.content_view_spl);
if (mContentView == null) {
mContentView = findViewById(R.id.content_view_ll);
@@ -204,6 +275,7 @@ public class ConversationActivity extends XmppActivity
@Override
public void onPanelClosed(View arg0) {
+ listView.discardUndo();
openConversation();
}
@@ -340,13 +412,18 @@ public class ConversationActivity extends XmppActivity
switch (attachmentChoice) {
case ATTACHMENT_CHOICE_CHOOSE_IMAGE:
intent.setAction(Intent.ACTION_GET_CONTENT);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
+ intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE,true);
+ }
intent.setType("image/*");
chooser = true;
break;
case ATTACHMENT_CHOICE_TAKE_PHOTO:
- mPendingImageUri = xmppConnectionService.getFileBackend().getTakePhotoUri();
+ Uri uri = xmppConnectionService.getFileBackend().getTakePhotoUri();
intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
- intent.putExtra(MediaStore.EXTRA_OUTPUT, mPendingImageUri);
+ intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
+ mPendingImageUris.clear();
+ mPendingImageUris.add(uri);
break;
case ATTACHMENT_CHOICE_CHOOSE_FILE:
chooser = true;
@@ -485,13 +562,21 @@ public class ConversationActivity extends XmppActivity
}
public void endConversation(Conversation conversation) {
- showConversationsOverview();
+ endConversation(conversation, true, true);
+ }
+
+ public void endConversation(Conversation conversation, boolean showOverview, boolean reinit) {
+ if (showOverview) {
+ showConversationsOverview();
+ }
xmppConnectionService.archiveConversation(conversation);
- if (conversationList.size() > 0) {
- setSelectedConversation(conversationList.get(0));
- this.mConversationFragment.reInit(getSelectedConversation());
- } else {
- setSelectedConversation(null);
+ if (reinit) {
+ if (conversationList.size() > 0) {
+ setSelectedConversation(conversationList.get(0));
+ this.mConversationFragment.reInit(getSelectedConversation());
+ } else {
+ setSelectedConversation(null);
+ }
}
}
@@ -744,6 +829,7 @@ public class ConversationActivity extends XmppActivity
@Override
public void onPause() {
+ listView.discardUndo();
super.onPause();
this.mActivityPaused = true;
if (this.xmppConnectionServiceBound) {
@@ -779,8 +865,8 @@ public class ConversationActivity extends XmppActivity
}
savedInstanceState.putBoolean(STATE_PANEL_OPEN,
isConversationsOverviewVisable());
- if (this.mPendingImageUri != null) {
- savedInstanceState.putString(STATE_PENDING_URI, this.mPendingImageUri.toString());
+ if (this.mPendingImageUris.size() >= 1) {
+ savedInstanceState.putString(STATE_PENDING_URI, this.mPendingImageUris.get(0).toString());
}
super.onSaveInstanceState(savedInstanceState);
}
@@ -819,21 +905,23 @@ public class ConversationActivity extends XmppActivity
this.mConversationFragment.reInit(getSelectedConversation());
} else {
showConversationsOverview();
- mPendingImageUri = null;
- mPendingFileUri = null;
+ mPendingImageUris.clear();
+ mPendingFileUris.clear();
mPendingGeoUri = null;
setSelectedConversation(conversationList.get(0));
this.mConversationFragment.reInit(getSelectedConversation());
}
- if (mPendingImageUri != null) {
- attachImageToConversation(getSelectedConversation(),mPendingImageUri);
- mPendingImageUri = null;
- } else if (mPendingFileUri != null) {
- attachFileToConversation(getSelectedConversation(),mPendingFileUri);
- mPendingFileUri = null;
- } else if (mPendingGeoUri != null) {
- attachLocationToConversation(getSelectedConversation(),mPendingGeoUri);
+ for(Iterator<Uri> i = mPendingImageUris.iterator(); i.hasNext(); i.remove()) {
+ attachImageToConversation(getSelectedConversation(),i.next());
+ }
+
+ for(Iterator<Uri> i = mPendingFileUris.iterator(); i.hasNext(); i.remove()) {
+ attachFileToConversation(getSelectedConversation(),i.next());
+ }
+
+ if (mPendingGeoUri != null) {
+ attachLocationToConversation(getSelectedConversation(), mPendingGeoUri);
mPendingGeoUri = null;
}
ExceptionHelper.checkForCrash(this, this.xmppConnectionService);
@@ -885,6 +973,21 @@ public class ConversationActivity extends XmppActivity
xmppConnectionService.getNotificationService().setOpenConversation(null);
}
+ @SuppressLint("NewApi")
+ private static List<Uri> extractUriFromIntent(final Intent intent) {
+ List<Uri> uris = new ArrayList<>();
+ Uri uri = intent.getData();
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2 && uri == null) {
+ ClipData clipData = intent.getClipData();
+ for(int i = 0; i < clipData.getItemCount(); ++i) {
+ uris.add(clipData.getItemAt(i).getUri());
+ }
+ } else {
+ uris.add(uri);
+ }
+ return uris;
+ }
+
@Override
protected void onActivityResult(int requestCode, int resultCode,
final Intent data) {
@@ -894,25 +997,34 @@ public class ConversationActivity extends XmppActivity
mConversationFragment.hideSnackbar();
mConversationFragment.updateMessages();
} else if (requestCode == ATTACHMENT_CHOICE_CHOOSE_IMAGE) {
- mPendingImageUri = data.getData();
+ mPendingImageUris.clear();
+ mPendingImageUris.addAll(extractUriFromIntent(data));
if (xmppConnectionServiceBound) {
- attachImageToConversation(getSelectedConversation(),mPendingImageUri);
- mPendingImageUri = null;
+ for(Iterator<Uri> i = mPendingImageUris.iterator(); i.hasNext(); i.remove()) {
+ attachImageToConversation(getSelectedConversation(),i.next());
+ }
}
} else if (requestCode == ATTACHMENT_CHOICE_CHOOSE_FILE || requestCode == ATTACHMENT_CHOICE_RECORD_VOICE) {
- mPendingFileUri = data.getData();
+ mPendingFileUris.clear();
+ mPendingFileUris.addAll(extractUriFromIntent(data));
if (xmppConnectionServiceBound) {
- attachFileToConversation(getSelectedConversation(),mPendingFileUri);
- mPendingFileUri = null;
+ for(Iterator<Uri> i = mPendingImageUris.iterator(); i.hasNext(); i.remove()) {
+ attachFileToConversation(getSelectedConversation(), i.next());
+ }
}
- } else if (requestCode == ATTACHMENT_CHOICE_TAKE_PHOTO && mPendingImageUri != null) {
- if (xmppConnectionServiceBound) {
- attachImageToConversation(getSelectedConversation(),mPendingImageUri);
- mPendingImageUri = null;
+ } else if (requestCode == ATTACHMENT_CHOICE_TAKE_PHOTO) {
+ if (mPendingImageUris.size() == 1) {
+ Uri uri = mPendingImageUris.get(0);
+ if (xmppConnectionServiceBound) {
+ attachImageToConversation(getSelectedConversation(), uri);
+ mPendingImageUris.clear();
+ }
+ Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
+ intent.setData(uri);
+ sendBroadcast(intent);
+ } else {
+ mPendingImageUris.clear();
}
- Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
- intent.setData(mPendingImageUri);
- sendBroadcast(intent);
} else if (requestCode == ATTACHMENT_CHOICE_LOCATION) {
double latitude = data.getDoubleExtra("latitude",0);
double longitude = data.getDoubleExtra("longitude",0);
@@ -922,10 +1034,6 @@ public class ConversationActivity extends XmppActivity
this.mPendingGeoUri = null;
}
}
- } else {
- if (requestCode == ATTACHMENT_CHOICE_TAKE_PHOTO) {
- mPendingImageUri = null;
- }
}
}
@@ -1013,6 +1121,13 @@ public class ConversationActivity extends XmppActivity
public void updateConversationList() {
xmppConnectionService
.populateWithOrderedConversations(conversationList);
+ if (swipedConversation != null) {
+ if (swipedConversation.isRead()) {
+ conversationList.remove(swipedConversation);
+ } else {
+ listView.discardUndo();
+ }
+ }
listAdapter.notifyDataSetChanged();
}
diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java
index d5f20e41..a3a02b27 100644
--- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java
+++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java
@@ -268,7 +268,6 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
if (conversation.getNextCounterpart() != null) {
message.setCounterpart(conversation.getNextCounterpart());
message.setType(Message.TYPE_PRIVATE);
- conversation.setNextCounterpart(null);
}
}
if (conversation.getNextEncryption(activity.forceEncryption()) == Message.ENCRYPTION_OTR) {
diff --git a/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java b/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java
index 27dfc492..dbad9e00 100644
--- a/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java
+++ b/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java
@@ -67,7 +67,7 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate
@Override
public void onClick(final View v) {
- if (mAccount != null && mAccount.getStatus() == Account.State.DISABLED) {
+ if (mAccount != null && mAccount.getStatus() == Account.State.DISABLED && !accountInfoEdited()) {
mAccount.setOption(Account.OPTION_DISABLED, false);
xmppConnectionService.updateAccount(mAccount);
return;
@@ -237,7 +237,11 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate
}
protected void updateSaveButton() {
- if (mAccount != null && (mAccount.getStatus() == Account.State.CONNECTING || mFetchingAvatar)) {
+ if (accountInfoEdited() && jidToEdit != null) {
+ this.mSaveButton.setText(R.string.save);
+ this.mSaveButton.setEnabled(true);
+ this.mSaveButton.setTextColor(getPrimaryTextColor());
+ } else if (mAccount != null && (mAccount.getStatus() == Account.State.CONNECTING || mFetchingAvatar)) {
this.mSaveButton.setEnabled(false);
this.mSaveButton.setTextColor(getSecondaryTextColor());
this.mSaveButton.setText(R.string.account_status_connecting);
@@ -265,9 +269,9 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate
}
protected boolean accountInfoEdited() {
- return (!this.mAccount.getJid().toBareJid().toString().equals(
- this.mAccountJid.getText().toString()))
- || (!this.mAccount.getPassword().equals(
+ return this.mAccount != null && (!this.mAccount.getJid().toBareJid().toString().equals(
+ this.mAccountJid.getText().toString())
+ || !this.mAccount.getPassword().equals(
this.mPassword.getText().toString()));
}
diff --git a/src/main/java/eu/siacs/conversations/ui/ManageAccountActivity.java b/src/main/java/eu/siacs/conversations/ui/ManageAccountActivity.java
index b2d5ddfd..56dbc55e 100644
--- a/src/main/java/eu/siacs/conversations/ui/ManageAccountActivity.java
+++ b/src/main/java/eu/siacs/conversations/ui/ManageAccountActivity.java
@@ -168,6 +168,14 @@ public class ManageAccountActivity extends XmppActivity implements OnAccountUpda
}
}
+ public void onClickTglAccountState(Account account, boolean enable) {
+ if (enable) {
+ enableAccount(account);
+ } else {
+ disableAccount(account);
+ }
+ }
+
private void publishAvatar(Account account) {
Intent intent = new Intent(getApplicationContext(),
PublishProfilePictureActivity.class);
diff --git a/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java b/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java
index 1bc59b13..d24cb52b 100644
--- a/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java
+++ b/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java
@@ -5,6 +5,7 @@ import java.util.Arrays;
import java.util.Locale;
import eu.siacs.conversations.entities.Account;
+import eu.siacs.conversations.xmpp.XmppConnection;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
@@ -63,9 +64,14 @@ public class SettingsActivity extends XmppActivity implements
.toLowerCase(Locale.US);
if (xmppConnectionServiceBound) {
for (Account account : xmppConnectionService.getAccounts()) {
- account.setResource(resource);
- if (!account.isOptionSet(Account.OPTION_DISABLED)) {
- xmppConnectionService.reconnectAccountInBackground(account);
+ if (account.setResource(resource)) {
+ if (!account.isOptionSet(Account.OPTION_DISABLED)) {
+ XmppConnection connection = account.getXmppConnection();
+ if (connection != null) {
+ connection.resetStreamId();
+ }
+ xmppConnectionService.reconnectAccountInBackground(account);
+ }
}
}
}
diff --git a/src/main/java/eu/siacs/conversations/ui/ShareWithActivity.java b/src/main/java/eu/siacs/conversations/ui/ShareWithActivity.java
index 6be238dc..200a577e 100644
--- a/src/main/java/eu/siacs/conversations/ui/ShareWithActivity.java
+++ b/src/main/java/eu/siacs/conversations/ui/ShareWithActivity.java
@@ -18,6 +18,7 @@ import java.net.URLConnection;
import java.net.URLDecoder;
import java.nio.charset.UnsupportedCharsetException;
import java.util.ArrayList;
+import java.util.Iterator;
import java.util.List;
import eu.siacs.conversations.Config;
@@ -32,7 +33,7 @@ import eu.siacs.conversations.xmpp.jid.Jid;
public class ShareWithActivity extends XmppActivity {
private class Share {
- public Uri uri;
+ public List<Uri> uris = new ArrayList<>();
public boolean image;
public String account;
public String contact;
@@ -104,7 +105,7 @@ public class ShareWithActivity extends XmppActivity {
int position, long arg3) {
Conversation conversation = mConversations.get(position);
if (conversation.getMode() == Conversation.MODE_SINGLE
- || share.uri == null) {
+ || share.uris.size() == 0) {
share(mConversations.get(position));
}
}
@@ -133,18 +134,32 @@ public class ShareWithActivity extends XmppActivity {
@Override
public void onStart() {
- final String type = getIntent().getType();
- final Uri uri = getIntent().getParcelableExtra(Intent.EXTRA_STREAM);
- if (type != null && uri != null && !type.equalsIgnoreCase("text/plain")) {
- this.share.uri = uri;
- this.share.image = type.startsWith("image/") || isImage(uri);
- } else {
- this.share.text = getIntent().getStringExtra(Intent.EXTRA_TEXT);
+ super.onStart();
+ Intent intent = getIntent();
+ if (intent == null) {
+ return;
+ }
+ final String type = intent.getType();
+ if (Intent.ACTION_SEND.equals(intent.getAction())) {
+ final Uri uri = getIntent().getParcelableExtra(Intent.EXTRA_STREAM);
+ if (type != null && uri != null && !type.equalsIgnoreCase("text/plain")) {
+ this.share.uris.add(uri);
+ this.share.image = type.startsWith("image/") || isImage(uri);
+ } else {
+ this.share.text = getIntent().getStringExtra(Intent.EXTRA_TEXT);
+ }
+ } else if (Intent.ACTION_SEND_MULTIPLE.equals(intent.getAction())) {
+ this.share.image = type != null && type.startsWith("image/");
+ if (!this.share.image) {
+ return;
+ }
+
+ this.share.uris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
}
if (xmppConnectionServiceBound) {
- xmppConnectionService.populateWithOrderedConversations(mConversations, this.share.uri == null);
+ xmppConnectionService.populateWithOrderedConversations(mConversations, this.share.image);
}
- super.onStart();
+
}
protected boolean isImage(Uri uri) {
@@ -164,7 +179,7 @@ public class ShareWithActivity extends XmppActivity {
return;
}
xmppConnectionService.populateWithOrderedConversations(mConversations,
- this.share != null && this.share.uri == null);
+ this.share != null && this.share.uris.size() == 0);
}
private void share() {
@@ -188,7 +203,7 @@ public class ShareWithActivity extends XmppActivity {
}
private void share(final Conversation conversation) {
- if (share.uri != null) {
+ if (share.uris.size() != 0) {
selectPresence(conversation, new OnPresenceSelected() {
@Override
public void onPresenceSelected() {
@@ -196,22 +211,23 @@ public class ShareWithActivity extends XmppActivity {
Toast.makeText(getApplicationContext(),
getText(R.string.preparing_image),
Toast.LENGTH_LONG).show();
- ShareWithActivity.this.xmppConnectionService
- .attachImageToConversation(conversation, share.uri,
- attachFileCallback);
+ for (Iterator<Uri> i = share.uris.iterator(); i.hasNext(); i.remove()) {
+ ShareWithActivity.this.xmppConnectionService
+ .attachImageToConversation(conversation, i.next(),
+ attachFileCallback);
+ }
} else {
Toast.makeText(getApplicationContext(),
getText(R.string.preparing_file),
Toast.LENGTH_LONG).show();
ShareWithActivity.this.xmppConnectionService
- .attachFileToConversation(conversation, share.uri,
- attachFileCallback);
+ .attachFileToConversation(conversation, share.uris.get(0),
+ attachFileCallback);
}
switchToConversation(conversation, null, true);
finish();
}
});
-
} else {
switchToConversation(conversation, this.share.text, true);
finish();
diff --git a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java
index 7eaec10c..392e57a7 100644
--- a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java
+++ b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java
@@ -90,6 +90,7 @@ public abstract class XmppActivity extends Activity {
protected int mPrimaryTextColor;
protected int mSecondaryTextColor;
+ protected int mPrimaryBackgroundColor;
protected int mSecondaryBackgroundColor;
protected int mColorRed;
protected int mColorOrange;
@@ -331,6 +332,7 @@ public abstract class XmppActivity extends Activity {
mColorOrange = getResources().getColor(R.color.orange);
mColorGreen = getResources().getColor(R.color.green);
mPrimaryColor = getResources().getColor(R.color.primary);
+ mPrimaryBackgroundColor = getResources().getColor(R.color.primarybackground);
mSecondaryBackgroundColor = getResources().getColor(R.color.secondarybackground);
this.mTheme = findTheme();
setTheme(this.mTheme);
@@ -740,7 +742,11 @@ public abstract class XmppActivity extends Activity {
public int getOnlineColor() {
return this.mColorGreen;
}
-
+
+ public int getPrimaryBackgroundColor() {
+ return this.mPrimaryBackgroundColor;
+ }
+
public int getSecondaryBackgroundColor() {
return this.mSecondaryBackgroundColor;
}
diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/AccountAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/AccountAdapter.java
index 29730914..95c0524d 100644
--- a/src/main/java/eu/siacs/conversations/ui/adapter/AccountAdapter.java
+++ b/src/main/java/eu/siacs/conversations/ui/adapter/AccountAdapter.java
@@ -5,13 +5,16 @@ import java.util.List;
import eu.siacs.conversations.R;
import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.ui.XmppActivity;
+import eu.siacs.conversations.ui.ManageAccountActivity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
+import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.TextView;
+import android.widget.Switch;
public class AccountAdapter extends ArrayAdapter<Account> {
@@ -24,7 +27,7 @@ public class AccountAdapter extends ArrayAdapter<Account> {
@Override
public View getView(int position, View view, ViewGroup parent) {
- Account account = getItem(position);
+ final Account account = getItem(position);
if (view == null) {
LayoutInflater inflater = (LayoutInflater) getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
@@ -34,21 +37,32 @@ public class AccountAdapter extends ArrayAdapter<Account> {
jid.setText(account.getJid().toBareJid().toString());
TextView statusView = (TextView) view.findViewById(R.id.account_status);
ImageView imageView = (ImageView) view.findViewById(R.id.account_image);
- imageView.setImageBitmap(activity.avatarService().get(account,
- activity.getPixel(48)));
- statusView.setText(getContext().getString(account.getStatus().getReadableId()));
- switch (account.getStatus()) {
- case ONLINE:
- statusView.setTextColor(activity.getOnlineColor());
- break;
- case DISABLED:
- case CONNECTING:
- statusView.setTextColor(activity.getSecondaryTextColor());
- break;
- default:
- statusView.setTextColor(activity.getWarningTextColor());
- break;
- }
+ imageView.setImageBitmap(activity.avatarService().get(account, activity.getPixel(48)));
+ statusView.setText(getContext().getString(account.getStatus().getReadableId()));
+ switch (account.getStatus()) {
+ case ONLINE:
+ statusView.setTextColor(activity.getOnlineColor());
+ break;
+ case DISABLED:
+ case CONNECTING:
+ statusView.setTextColor(activity.getSecondaryTextColor());
+ break;
+ default:
+ statusView.setTextColor(activity.getWarningTextColor());
+ break;
+ }
+ final Switch tglAccountState = (Switch) view.findViewById(R.id.tgl_account_status);
+ final boolean isDisabled = (account.getStatus() == Account.State.DISABLED) ? true : false;
+ tglAccountState.setOnCheckedChangeListener(null);
+ tglAccountState.setChecked(!isDisabled);
+ tglAccountState.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
+ if (b == isDisabled && activity instanceof ManageAccountActivity) {
+ ((ManageAccountActivity) activity).onClickTglAccountState(account,b);
+ }
+ }
+ });
return view;
}
}
diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java
index a48f6ae4..d5b7e4c0 100644
--- a/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java
+++ b/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java
@@ -46,17 +46,10 @@ public class ConversationAdapter extends ArrayAdapter<Conversation> {
}
Conversation conversation = getItem(position);
if (this.activity instanceof ConversationActivity) {
- ConversationActivity activity = (ConversationActivity) this.activity;
- if (!activity.isConversationsOverviewHideable()) {
- if (conversation == activity.getSelectedConversation()) {
- view.setBackgroundColor(activity
- .getSecondaryBackgroundColor());
- } else {
- view.setBackgroundColor(Color.TRANSPARENT);
- }
- } else {
- view.setBackgroundColor(Color.TRANSPARENT);
- }
+ View swipeableItem = view.findViewById(R.id.swipeable_item);
+ ConversationActivity a = (ConversationActivity) this.activity;
+ int c = !a.isConversationsOverviewHideable() && conversation == a.getSelectedConversation() ? a.getSecondaryBackgroundColor() : a.getPrimaryBackgroundColor();
+ swipeableItem.setBackgroundColor(c);
}
TextView convName = (TextView) view.findViewById(R.id.conversation_name);
if (conversation.getMode() == Conversation.MODE_SINGLE || activity.useSubjectToIdentifyConference()) {
diff --git a/src/main/java/eu/siacs/conversations/utils/GeoHelper.java b/src/main/java/eu/siacs/conversations/utils/GeoHelper.java
index f7dda936..b31b9018 100644
--- a/src/main/java/eu/siacs/conversations/utils/GeoHelper.java
+++ b/src/main/java/eu/siacs/conversations/utils/GeoHelper.java
@@ -20,7 +20,7 @@ public class GeoHelper {
}
public static ArrayList<Intent> createGeoIntentsFromMessage(Message message) {
- final ArrayList<Intent> intents = new ArrayList();
+ final ArrayList<Intent> intents = new ArrayList<>();
Matcher matcher = GEO_URI.matcher(message.getBody());
if (!matcher.matches()) {
return intents;
diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java
index 48dc2150..25db8ecc 100644
--- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java
+++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java
@@ -981,6 +981,10 @@ public class XmppConnection implements Runnable {
}
}
+ public void resetStreamId() {
+ this.streamId = null;
+ }
+
public List<String> findDiscoItemsByFeature(final String feature) {
final List<String> items = new ArrayList<>();
for (final Entry<String, List<String>> cursor : disco.entrySet()) {