aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/services/filetransfer/http/delete/DeleteRemoteFileService.java16
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/services/filetransfer/http/delete/DeleteTokenReceived.java11
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/services/filetransfer/http/upload/HttpUploadFileTransferService.java26
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/utils/AccountUtil.java34
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/utils/ui/ConversationsPlusToast.java102
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/utils/ui/TextViewUtil.java4
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/utils/ui/ViewUtil.java39
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/utils/ErrorIqPacketExceptionHelper.java29
-rw-r--r--src/main/java/eu/siacs/conversations/entities/Account.java8
-rw-r--r--src/main/java/eu/siacs/conversations/services/XmppConnectionService.java8
-rw-r--r--src/main/java/eu/siacs/conversations/ui/ConversationActivity.java9
-rw-r--r--src/main/java/eu/siacs/conversations/ui/ConversationFragment.java5
-rw-r--r--src/main/java/eu/siacs/conversations/ui/ShareWithActivity.java5
-rw-r--r--src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java20
-rw-r--r--src/main/java/eu/siacs/conversations/utils/Xmlns.java3
-rw-r--r--src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java73
-rw-r--r--src/main/res/drawable-hdpi/ic_toast.pngbin0 -> 1708 bytes
-rw-r--r--src/main/res/drawable-hdpi/ic_toast_error.pngbin0 -> 1764 bytes
-rw-r--r--src/main/res/layout/cplus_toast_container.xml22
-rw-r--r--src/main/res/layout/message_sent.xml2
-rw-r--r--src/main/res/values/strings.xml2
21 files changed, 333 insertions, 85 deletions
diff --git a/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/http/delete/DeleteRemoteFileService.java b/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/http/delete/DeleteRemoteFileService.java
index f60efb56..038369ca 100644
--- a/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/http/delete/DeleteRemoteFileService.java
+++ b/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/http/delete/DeleteRemoteFileService.java
@@ -29,12 +29,16 @@ public class DeleteRemoteFileService implements SimpleUserDecisionCallback {
path = this.message.getFileParams().getUrl();
}
- DeleteRemoteFile remoteFile = new DeleteRemoteFile(path, this.message);
- Account account = this.message.getConversation().getAccount();
- Jid host = account.getXmppConnection().findDiscoItemByFeature(FileTransferHttp.NAMESPACE);
- IqPacket request = FileTransferHttpDeleteSlotRequestPacketGenerator.generate(host, path);
- MessageUtil.setAndSaveFileStatus(this.message, FileStatus.DELETING);
- XmppSendUtil.sendIqPacket(account, request, new DeleteTokenReceived(remoteFile));
+ if (null != path) {
+ DeleteRemoteFile remoteFile = new DeleteRemoteFile(path, this.message);
+ Account account = this.message.getConversation().getAccount();
+ Jid host = account.getXmppConnection().findDiscoItemByFeature(FileTransferHttp.NAMESPACE);
+ if (null != host) {
+ IqPacket request = FileTransferHttpDeleteSlotRequestPacketGenerator.generate(host, path);
+ MessageUtil.setAndSaveFileStatus(this.message, FileStatus.DELETING);
+ XmppSendUtil.sendIqPacket(account, request, new DeleteTokenReceived(remoteFile));
+ }
+ }
}
}
diff --git a/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/http/delete/DeleteTokenReceived.java b/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/http/delete/DeleteTokenReceived.java
index 3151ca30..ef0032e3 100644
--- a/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/http/delete/DeleteTokenReceived.java
+++ b/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/http/delete/DeleteTokenReceived.java
@@ -1,17 +1,23 @@
package de.thedevstack.conversationsplus.services.filetransfer.http.delete;
+import android.widget.Toast;
+
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import de.thedevstack.android.logcat.Logging;
+
import de.thedevstack.conversationsplus.enums.FileStatus;
import de.thedevstack.conversationsplus.http.HttpClient;
import de.thedevstack.conversationsplus.utils.MessageUtil;
+import de.thedevstack.conversationsplus.utils.ui.ConversationsPlusToast;
+import de.thedevstack.conversationsplus.xmpp.exceptions.ServiceUnavailableException;
import de.thedevstack.conversationsplus.xmpp.exceptions.XmppException;
import de.thedevstack.conversationsplus.xmpp.filetransfer.http.delete.DeleteSlotPacketParser;
+import eu.siacs.conversations.R;
import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.xmpp.stanzas.IqPacket;
import eu.siacs.conversations.xmpp.OnIqPacketReceived;
@@ -83,6 +89,11 @@ public class DeleteTokenReceived implements OnIqPacketReceived {
} catch (XmppException e) {
Logging.e("filetransfer.http.delete", "Error while trying to get the delete token: " + e.getMessage());
+ int messageResId = R.string.cplus_remote_file_delete_failed;
+ if (e instanceof ServiceUnavailableException) {
+ messageResId = R.string.cplus_remote_file_delete_service_unavailable;
+ }
+ ConversationsPlusToast.makeErrorToast(messageResId, Toast.LENGTH_LONG);
MessageUtil.setAndSaveFileStatus(remoteFile.getMessage(), FileStatus.DELETE_FAILED);
}
}
diff --git a/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/http/upload/HttpUploadFileTransferService.java b/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/http/upload/HttpUploadFileTransferService.java
index 7fe12dc6..0ab6a8ec 100644
--- a/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/http/upload/HttpUploadFileTransferService.java
+++ b/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/http/upload/HttpUploadFileTransferService.java
@@ -9,8 +9,10 @@ import de.thedevstack.android.logcat.Logging;
import eu.siacs.conversations.services.AbstractConnectionManager;
import de.thedevstack.conversationsplus.services.FileTransferService;
import de.thedevstack.conversationsplus.services.filetransfer.AbstractFileTransferService;
+import de.thedevstack.conversationsplus.utils.AccountUtil;
import de.thedevstack.conversationsplus.utils.MessageUtil;
import de.thedevstack.conversationsplus.utils.XmppSendUtil;
+import de.thedevstack.conversationsplus.xmpp.filetransfer.http.FileTransferHttp;
import de.thedevstack.conversationsplus.xmpp.filetransfer.http.upload.HttpUpload;
import de.thedevstack.conversationsplus.xmpp.filetransfer.http.upload.HttpUploadRequestSlotPacketGenerator;
@@ -62,19 +64,29 @@ public class HttpUploadFileTransferService extends AbstractFileTransferService i
file.setExpectedSize(inputStreamAndExpectedSize.second);
Logging.d("httpupload", "Requesting upload slot for file upload");
- Jid host = account.getXmppConnection().findDiscoItemByFeature(HttpUpload.NAMESPACE);
- IqPacket request = HttpUploadRequestSlotPacketGenerator.generate(host, file.getName(), file.getSize(), file.getMimeType());
- XmppSendUtil.sendIqPacket(account, request, new HttpUploadSlotRequestReceived(entity));
- MessageUtil.markMessage(message, Message.STATUS_UNSEND);
+ Jid host = this.getHost(account);
+ if (null != host) {
+ IqPacket request = HttpUploadRequestSlotPacketGenerator.generate(host, file.getName(), file.getSize(), file.getMimeType());
+ XmppSendUtil.sendIqPacket(account, request, new HttpUploadSlotRequestReceived(entity));
+ MessageUtil.markMessage(message, Message.STATUS_UNSEND);
- Logging.d("httpupload", "Upload slot for file upload requested");
- started = true;
+ Logging.d("httpupload", "Upload slot for file upload requested");
+ started = true;
+ }
} catch (FileNotFoundException e) {
Logging.e("httpupload", "Could not find file, exception message: " + e.getMessage());
}
return started;
}
+ private Jid getHost(Account account) {
+ Jid host = account.getXmppConnection().findDiscoItemByFeature(FileTransferHttp.NAMESPACE);
+ if (null == host) {
+ host = account.getXmppConnection().findDiscoItemByFeature(HttpUpload.NAMESPACE);
+ }
+ return host;
+ }
+
/**
* Checks whether a message can be sent using this service or not.
*
@@ -87,6 +99,6 @@ public class HttpUploadFileTransferService extends AbstractFileTransferService i
&& null != message.getConversation()
&& null != message.getConversation().getAccount()
&& null != message.getFileParams()
- && message.getConversation().getAccount().httpUploadAvailable(message.getFileParams().getSize());
+ && AccountUtil.isHttpUploadAvailable(message.getConversation().getAccount(), message.getFileParams().getSize());
}
}
diff --git a/src/main/java/de/thedevstack/conversationsplus/utils/AccountUtil.java b/src/main/java/de/thedevstack/conversationsplus/utils/AccountUtil.java
new file mode 100644
index 00000000..06c6b6ab
--- /dev/null
+++ b/src/main/java/de/thedevstack/conversationsplus/utils/AccountUtil.java
@@ -0,0 +1,34 @@
+package de.thedevstack.conversationsplus.utils;
+
+import eu.siacs.conversations.entities.Account;
+
+/**
+ * Utility class to work with accounts.
+ */
+public final class AccountUtil {
+
+ public static boolean isHttpUploadAvailable(Account account, long filesize) {
+ return null != account
+ && null != account.getXmppConnection()
+ && null != account.getXmppConnection().getFeatures()
+ && account.getXmppConnection().getFeatures().httpUpload(filesize);
+ }
+
+ public static boolean isHttpUploadAvailable(Account account) {
+ return null != account
+ && null != account.getXmppConnection()
+ && null != account.getXmppConnection().getFeatures()
+ && account.getXmppConnection().getFeatures().httpUpload(0);
+ }
+
+ public static boolean isFileTransferHttpAvailable(Account account) {
+ return null != account
+ && null != account.getXmppConnection()
+ && null != account.getXmppConnection().getFeatures()
+ && account.getXmppConnection().getFeatures().hasFeatureFileTransferHttp(0);
+ }
+
+ private AccountUtil() {
+ // avoid instantiation of utility class
+ }
+}
diff --git a/src/main/java/de/thedevstack/conversationsplus/utils/ui/ConversationsPlusToast.java b/src/main/java/de/thedevstack/conversationsplus/utils/ui/ConversationsPlusToast.java
new file mode 100644
index 00000000..3ebb8602
--- /dev/null
+++ b/src/main/java/de/thedevstack/conversationsplus/utils/ui/ConversationsPlusToast.java
@@ -0,0 +1,102 @@
+package de.thedevstack.conversationsplus.utils.ui;
+
+import android.content.Context;
+import android.os.Handler;
+import android.os.Looper;
+import android.support.annotation.StringRes;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.Toast;
+
+import de.thedevstack.conversationsplus.ConversationsPlusApplication;
+
+import eu.siacs.conversations.R;
+
+/**
+ * Wrapper for custom styled Toasts for Conversations+.
+ */
+public final class ConversationsPlusToast {
+
+ /**
+ * Creates an error toast with text and duration
+ * @param text
+ * @param duration
+ */
+ public static void makeErrorToast(final CharSequence text, final int duration) {
+ Handler toastHandler = new Handler(Looper.getMainLooper());
+ toastHandler.post(new ConversationsPlusToast.ToastRunnable(text, duration, true));
+ }
+
+ /**
+ * Creates an error toast with text from resource and duration
+ * @param resId
+ * @param duration
+ */
+ public static void makeErrorToast(@StringRes int resId, int duration) {
+ makeErrorToast(ConversationsPlusApplication.getAppContext().getString(resId), duration);
+ }
+
+ /**
+ * Creates an toast with text and duration
+ * @param text
+ * @param duration
+ */
+ public static void makeToast(final CharSequence text, final int duration) {
+ Handler toastHandler = new Handler(Looper.getMainLooper());
+ toastHandler.post(new ConversationsPlusToast.ToastRunnable(text, duration));
+ }
+
+ /**
+ * Creates an toast with text from resource and duration
+ * @param resId
+ * @param duration
+ */
+ public static void makeToast(@StringRes int resId, int duration) {
+ makeToast(ConversationsPlusApplication.getAppContext().getString(resId), duration);
+ }
+
+ private ConversationsPlusToast() {
+ // avoid instantiation - helper class
+ }
+
+ /**
+ * Runnable to show the toast in an UI thread.
+ */
+ static class ToastRunnable implements Runnable {
+ private boolean showErrorToast = false;
+ private CharSequence text;
+ private int duration;
+
+ public ToastRunnable(CharSequence text, int duration, boolean isError) {
+ this.showErrorToast = isError;
+ this.text = text;
+ this.duration = duration;
+ }
+
+ public ToastRunnable(CharSequence text, int duration) {
+ this.text = text;
+ this.duration = duration;
+ }
+
+ @Override
+ public void run() {
+ Context applicationContext = ConversationsPlusApplication.getAppContext();
+ LayoutInflater inflater = LayoutInflater.from(applicationContext);
+ View layout = inflater.inflate(R.layout.cplus_toast_container, null);
+
+ TextViewUtil.setText(layout, R.id.cplus_toast_txt, text);
+
+ if (this.showErrorToast) {
+ // Set image view to error icon
+ ImageView iv = (ImageView) layout.findViewById(R.id.cplus_toast_icon);
+ iv.setImageResource(R.drawable.ic_toast_error);
+ }
+
+ Toast toast = new Toast(applicationContext);
+ toast.setDuration(duration);
+ toast.setView(layout);
+ toast.show();
+ }
+ }
+}
diff --git a/src/main/java/de/thedevstack/conversationsplus/utils/ui/TextViewUtil.java b/src/main/java/de/thedevstack/conversationsplus/utils/ui/TextViewUtil.java
index a775dad6..27a269f2 100644
--- a/src/main/java/de/thedevstack/conversationsplus/utils/ui/TextViewUtil.java
+++ b/src/main/java/de/thedevstack/conversationsplus/utils/ui/TextViewUtil.java
@@ -5,9 +5,9 @@ import android.view.View;
import android.widget.TextView;
/**
- * Created by steckbrief on 29.03.2016.
+ *
*/
-public final class TextViewUtil {
+public final class TextViewUtil extends ViewUtil {
public static void setText(View parentView, int textViewId, CharSequence text) {
TextView tv = (TextView) parentView.findViewById(textViewId);
diff --git a/src/main/java/de/thedevstack/conversationsplus/utils/ui/ViewUtil.java b/src/main/java/de/thedevstack/conversationsplus/utils/ui/ViewUtil.java
new file mode 100644
index 00000000..77422587
--- /dev/null
+++ b/src/main/java/de/thedevstack/conversationsplus/utils/ui/ViewUtil.java
@@ -0,0 +1,39 @@
+package de.thedevstack.conversationsplus.utils.ui;
+
+import android.support.annotation.IdRes;
+import android.view.View;
+
+/**
+ * Created by steckbrief on 11.01.2017.
+ */
+
+public class ViewUtil {
+
+ public static <T extends View> T visible(View parentView, @IdRes int textViewId) {
+ T tv = (T) parentView.findViewById(textViewId);
+ if (null != tv) {
+ tv.setVisibility(View.VISIBLE);
+ }
+
+ return tv;
+ }
+
+ public static <T extends View> T invisible(View parentView, @IdRes int textViewId) {
+ T tv = (T) parentView.findViewById(textViewId);
+ if (null != tv) {
+ tv.setVisibility(View.INVISIBLE);
+ }
+
+ return tv;
+ }
+
+ public static <T extends View> T gone(View parentView, @IdRes int textViewId) {
+ T tv = (T) parentView.findViewById(textViewId);
+ if (null != tv) {
+ tv.setVisibility(View.GONE);
+ }
+
+ return tv;
+ }
+
+}
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/utils/ErrorIqPacketExceptionHelper.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/utils/ErrorIqPacketExceptionHelper.java
index 15771248..93e525a8 100644
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/utils/ErrorIqPacketExceptionHelper.java
+++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/utils/ErrorIqPacketExceptionHelper.java
@@ -15,20 +15,23 @@ import eu.siacs.conversations.xml.Element;
public final class ErrorIqPacketExceptionHelper {
private final static String ERROR_NAMESPACE = "urn:ietf:params:xml:ns:xmpp-stanzas";
- public static void throwIqErrorException(Element packet) throws IqPacketErrorException {
- if (hasErrorElement(packet, "bad-request")) {
- throw new BadRequestIqErrorException(packet, getErrorText(packet));
+ public static void throwIqErrorException(Element errorIqPacket) throws IqPacketErrorException {
+ Element packet = IqPacketParser.findChild(errorIqPacket, "error", "jabber:client");
+ if (null != packet) {
+ if (hasErrorElement(packet, "bad-request")) {
+ throw new BadRequestIqErrorException(errorIqPacket, getErrorText(packet));
+ }
+ if (hasErrorElement(packet, "service-unavailable")) {
+ throw new ServiceUnavailableException(errorIqPacket, getErrorText(packet));
+ }
+ if (hasErrorElement(packet, "internal-server-error")) {
+ throw new InternalServerErrorException(errorIqPacket, getErrorText(packet));
+ }
+ if (hasErrorElement(packet, "undefined-condition")) {
+ throw new UndefinedConditionException(errorIqPacket, getErrorText(packet));
+ }
}
- if (hasErrorElement(packet, "service-unavailable")) {
- throw new ServiceUnavailableException(packet, getErrorText(packet));
- }
- if (hasErrorElement(packet, "internal-server-error")) {
- throw new InternalServerErrorException(packet, getErrorText(packet));
- }
- if (hasErrorElement(packet, "undefined-condition")) {
- throw new UndefinedConditionException(packet, getErrorText(packet));
- }
- throw new IqPacketErrorException(packet, "Unknown error packet.");
+ throw new IqPacketErrorException(errorIqPacket, "Unknown error packet.");
}
private static boolean hasErrorElement(Element packet, String elementName) {
diff --git a/src/main/java/eu/siacs/conversations/entities/Account.java b/src/main/java/eu/siacs/conversations/entities/Account.java
index 9b4198c8..9316706d 100644
--- a/src/main/java/eu/siacs/conversations/entities/Account.java
+++ b/src/main/java/eu/siacs/conversations/entities/Account.java
@@ -57,14 +57,6 @@ public class Account extends AbstractEntity {
public static final int OPTION_USECOMPRESSION = 3;
public final HashSet<Pair<String, String>> inProgressDiscoFetches = new HashSet<>();
- public boolean httpUploadAvailable(long filesize) {
- return xmppConnection != null && xmppConnection.getFeatures().httpUpload(filesize);
- }
-
- public boolean httpUploadAvailable() {
- return httpUploadAvailable(0);
- }
-
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java
index 90f9027a..cba9f25b 100644
--- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java
+++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java
@@ -38,7 +38,6 @@ import org.openintents.openpgp.util.OpenPgpApi;
import org.openintents.openpgp.util.OpenPgpServiceConnection;
import java.math.BigInteger;
-import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
@@ -53,11 +52,11 @@ import java.util.Locale;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
-import de.duenndns.ssl.MemorizingTrustManager;
import de.thedevstack.android.logcat.Logging;
import de.thedevstack.conversationsplus.ConversationsPlusApplication;
import de.thedevstack.conversationsplus.ConversationsPlusPreferences;
import de.thedevstack.conversationsplus.services.filetransfer.FileTransferManager;
+import de.thedevstack.conversationsplus.utils.AccountUtil;
import de.thedevstack.conversationsplus.utils.ImageUtil;
import de.thedevstack.conversationsplus.utils.MessageUtil;
import de.thedevstack.conversationsplus.utils.UiUpdateHelper;
@@ -66,6 +65,7 @@ import de.thedevstack.conversationsplus.utils.XmppSendUtil;
import de.tzur.conversations.Settings;
import eu.siacs.conversations.Config;
+
import eu.siacs.conversations.R;
import eu.siacs.conversations.crypto.PgpEngine;
import eu.siacs.conversations.crypto.axolotl.AxolotlService;
@@ -86,7 +86,6 @@ import eu.siacs.conversations.entities.TransferablePlaceholder;
import eu.siacs.conversations.generator.IqGenerator;
import eu.siacs.conversations.generator.MessageGenerator;
import eu.siacs.conversations.generator.PresenceGenerator;
-import eu.siacs.conversations.http.HttpConnectionManager;
import eu.siacs.conversations.parser.IqParser;
import eu.siacs.conversations.parser.MessageParser;
import eu.siacs.conversations.parser.PresenceParser;
@@ -95,7 +94,6 @@ import eu.siacs.conversations.persistance.FileBackend;
import eu.siacs.conversations.ui.UiCallback;
import eu.siacs.conversations.utils.CryptoHelper;
import eu.siacs.conversations.utils.ExceptionHelper;
-import eu.siacs.conversations.utils.FileUtils;
import eu.siacs.conversations.utils.OnPhoneContactsLoadedListener;
import eu.siacs.conversations.utils.PhoneHelper;
import eu.siacs.conversations.utils.Xmlns;
@@ -1083,7 +1081,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
} else {
for (Conversation conversation : getConversations()) {
if (conversation.getMode() == Conversation.MODE_SINGLE
- || conversation.getAccount().httpUploadAvailable()) {
+ || AccountUtil.isHttpUploadAvailable(conversation.getAccount())) {
list.add(conversation);
}
}
diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java
index 4466dd22..1b725f1a 100644
--- a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java
+++ b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java
@@ -43,12 +43,15 @@ import java.util.Iterator;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
+import de.timroes.android.listview.EnhancedListView;
+
import de.thedevstack.android.logcat.Logging;
+
import de.thedevstack.conversationsplus.ConversationsPlusPreferences;
import de.thedevstack.conversationsplus.ui.dialogs.UserDecisionDialog;
import de.thedevstack.conversationsplus.ui.listeners.ResizePictureUserDecisionListener;
+import de.thedevstack.conversationsplus.utils.AccountUtil;
import de.thedevstack.conversationsplus.utils.ConversationUtil;
-import de.timroes.android.listview.EnhancedListView;
import eu.siacs.conversations.Config;
import eu.siacs.conversations.R;
@@ -422,7 +425,7 @@ public class ConversationActivity extends XmppActivity
}
if (this.getSelectedConversation().getMode() == Conversation.MODE_MULTI) {
menuContactDetails.setVisible(false);
- menuAttach.setVisible(getSelectedConversation().getAccount().httpUploadAvailable() && getSelectedConversation().getMucOptions().participating());
+ menuAttach.setVisible(AccountUtil.isHttpUploadAvailable(getSelectedConversation().getAccount()) && getSelectedConversation().getMucOptions().participating());
menuInviteContact.setVisible(getSelectedConversation().getMucOptions().canInvite());
menuSecure.setVisible((Config.supportOpenPgp() || Config.supportOmemo()) && Config.multipleEncryptionChoices()); //only if pgp is supported we have a choice
} else {
@@ -493,7 +496,7 @@ public class ConversationActivity extends XmppActivity
}
}
};
- if ((account.httpUploadAvailable() || attachmentChoice == ATTACHMENT_CHOICE_LOCATION) && encryption != Message.ENCRYPTION_OTR) {
+ if ((AccountUtil.isHttpUploadAvailable(account) || attachmentChoice == ATTACHMENT_CHOICE_LOCATION) && encryption != Message.ENCRYPTION_OTR) {
conversation.setNextCounterpart(null);
callback.onPresenceSelected();
} else {
diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java
index 08f49551..944299e1 100644
--- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java
+++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java
@@ -52,6 +52,7 @@ import de.thedevstack.conversationsplus.ui.dialogs.MessageDetailsDialog;
import de.thedevstack.conversationsplus.ui.listeners.DeleteFileCallback;
import de.thedevstack.conversationsplus.ui.listeners.SimpleUserDecisionCallback;
import de.thedevstack.conversationsplus.ui.listeners.UserDecisionListener;
+import de.thedevstack.conversationsplus.utils.AccountUtil;
import de.thedevstack.conversationsplus.utils.MessageUtil;
import eu.siacs.conversations.Config;
@@ -583,7 +584,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
deleteFile.setVisible(true);
deleteFile.setTitle(activity.getString(R.string.delete_x_file,UIHelper.getFileDescriptionString(activity, m)));
}
- if (m.isHttpUploaded() && MessageUtil.isMessageSent(m)) {
+ if (m.isHttpUploaded() && MessageUtil.isMessageSent(m) && AccountUtil.isFileTransferHttpAvailable(m.getConversation().getAccount())) {
MenuItem deleteRemoteFile = menu.findItem(R.id.msg_ctx_menu_delete_remote_file);
deleteRemoteFile.setVisible(true);
}
@@ -1043,7 +1044,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
final String text = this.mEditMessage == null ? "" : this.mEditMessage.getText().toString();
final boolean empty = text.length() == 0;
final boolean conference = c.getMode() == Conversation.MODE_MULTI;
- if (conference && !c.getAccount().httpUploadAvailable()) {
+ if (conference && !AccountUtil.isHttpUploadAvailable(c.getAccount())) {
if (empty && c.getNextCounterpart() != null) {
action = SendButtonAction.CANCEL;
} else {
diff --git a/src/main/java/eu/siacs/conversations/ui/ShareWithActivity.java b/src/main/java/eu/siacs/conversations/ui/ShareWithActivity.java
index 7fcd6b33..ebe622d0 100644
--- a/src/main/java/eu/siacs/conversations/ui/ShareWithActivity.java
+++ b/src/main/java/eu/siacs/conversations/ui/ShareWithActivity.java
@@ -15,7 +15,6 @@ import android.widget.Toast;
import java.net.URLConnection;
import java.util.ArrayList;
-import java.util.Iterator;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
@@ -23,6 +22,7 @@ import de.thedevstack.conversationsplus.ConversationsPlusPreferences;
import de.thedevstack.conversationsplus.ui.dialogs.UserDecisionDialog;
import de.thedevstack.conversationsplus.ui.listeners.ResizePictureUserDecisionListener;
import de.thedevstack.conversationsplus.ui.listeners.ShareWithResizePictureUserDecisionListener;
+import de.thedevstack.conversationsplus.utils.AccountUtil;
import de.thedevstack.conversationsplus.utils.ConversationUtil;
import eu.siacs.conversations.Config;
@@ -30,7 +30,6 @@ import eu.siacs.conversations.R;
import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.entities.Conversation;
import eu.siacs.conversations.entities.Message;
-import eu.siacs.conversations.persistance.FileBackend;
import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.ui.adapter.ConversationAdapter;
import eu.siacs.conversations.utils.FileUtils;
@@ -308,7 +307,7 @@ public class ShareWithActivity extends XmppActivity implements XmppConnectionSer
}
};
}
- if (account.httpUploadAvailable()
+ if (AccountUtil.isHttpUploadAvailable(account)
&& (conversation.getMode() == Conversation.MODE_MULTI
|| FileUtils.allFilesUnderSize(this, share.uris, max))
&& conversation.getNextEncryption() != Message.ENCRYPTION_OTR) {
diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java
index 10450b8d..d413d059 100644
--- a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java
+++ b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java
@@ -42,7 +42,8 @@ import de.thedevstack.conversationsplus.ConversationsPlusPreferences;
import de.thedevstack.conversationsplus.entities.FileParams;
import de.thedevstack.conversationsplus.enums.FileStatus;
import de.thedevstack.conversationsplus.utils.MessageUtil;
-
+import de.thedevstack.conversationsplus.utils.ui.TextViewUtil;
+import de.thedevstack.conversationsplus.utils.ui.ViewUtil;
import eu.siacs.conversations.R;
import eu.siacs.conversations.crypto.axolotl.XmppAxolotlSession;
import eu.siacs.conversations.entities.Account;
@@ -237,9 +238,9 @@ public class MessageAdapter extends ArrayAdapter<Message> {
FileStatus fileStatus = message.getFileParams().getFileStatus();
if (fileStatus == FileStatus.DELETE_FAILED || fileStatus == FileStatus.DELETED || fileStatus == FileStatus.DELETING) {
viewHolder.remoteFileStatus.setVisibility(View.VISIBLE);
- viewHolder.remoteFileStatus.setTypeface(null, Typeface.ITALIC);
switch (fileStatus) {
case DELETE_FAILED:
+ TextViewUtil.setColor(viewHolder.remoteFileStatus, R.color.error);
viewHolder.remoteFileStatus.setText(R.string.remote_filestatus_delete_failed);
break;
case DELETED:
@@ -606,8 +607,7 @@ public class MessageAdapter extends ArrayAdapter<Message> {
ViewHolder viewHolder = new ViewHolder(view);
if (SENT == type
|| RECEIVED == type) {
- viewHolder.message_box = (LinearLayout) view.findViewById(R.id.message_box);
- viewHolder.message_box.setVisibility(View.VISIBLE);
+ viewHolder.message_box = ViewUtil.visible(view, R.id.message_box);
viewHolder.indicator = (ImageView) view.findViewById(R.id.security_indicator);
viewHolder.messageBody = (TextView) view.findViewById(R.id.message_body);
viewHolder.time = (TextView) view.findViewById(R.id.message_time);
@@ -619,17 +619,17 @@ public class MessageAdapter extends ArrayAdapter<Message> {
viewHolder.image = (ImageView) view.findViewById(R.id.message_image);
}
if (RECEIVED == type) { // Extra block as preparation for new /me representation
- viewHolder.contact_picture = (ImageView) view.findViewById(R.id.message_photo);
- viewHolder.contact_picture.setVisibility(View.VISIBLE);
+ viewHolder.contact_picture = ViewUtil.visible(view, R.id.message_photo);
}
if (RECEIVED == type) {
viewHolder.encryption = (TextView) view.findViewById(R.id.message_encryption);
}
if (STATUS == type) {
- viewHolder.contact_picture = (ImageView) view.findViewById(R.id.message_photo);
- viewHolder.contact_picture.setVisibility(View.VISIBLE);
- viewHolder.status_message = (TextView) view.findViewById(R.id.status_message);
- viewHolder.status_message.setVisibility(View.VISIBLE);
+ viewHolder.contact_picture = ViewUtil.visible(view, R.id.message_photo);
+ viewHolder.status_message = TextViewUtil.visible(view, R.id.status_message);
+ }
+ if (SENT == type) {
+ viewHolder.remoteFileStatus = TextViewUtil.gone(view, R.id.remote_file_status);
}
view.setTag(viewHolder);
diff --git a/src/main/java/eu/siacs/conversations/utils/Xmlns.java b/src/main/java/eu/siacs/conversations/utils/Xmlns.java
index ad30b3e6..17fd2d26 100644
--- a/src/main/java/eu/siacs/conversations/utils/Xmlns.java
+++ b/src/main/java/eu/siacs/conversations/utils/Xmlns.java
@@ -1,11 +1,8 @@
package eu.siacs.conversations.utils;
-import eu.siacs.conversations.Config;
-
public final class Xmlns {
public static final String BLOCKING = "urn:xmpp:blocking";
public static final String ROSTER = "jabber:iq:roster";
public static final String REGISTER = "jabber:iq:register";
public static final String BYTE_STREAMS = "http://jabber.org/protocol/bytestreams";
- public static final String HTTP_UPLOAD = "urn:xmpp:http:upload";
}
diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java
index a5d0321d..139e207a 100644
--- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java
+++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java
@@ -53,6 +53,9 @@ import de.thedevstack.android.logcat.Logging;
import de.thedevstack.conversationsplus.ConversationsPlusApplication;
import de.thedevstack.conversationsplus.ConversationsPlusPreferences;
import de.thedevstack.conversationsplus.dto.SrvRecord;
+import de.thedevstack.conversationsplus.xmpp.filetransfer.http.FileTransferHttp;
+import de.thedevstack.conversationsplus.xmpp.filetransfer.http.upload.HttpUpload;
+
import eu.siacs.conversations.Config;
import eu.siacs.conversations.crypto.XmppDomainVerifier;
import eu.siacs.conversations.crypto.sasl.DigestMd5;
@@ -67,7 +70,6 @@ import eu.siacs.conversations.generator.IqGenerator;
import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.utils.DNSHelper;
import eu.siacs.conversations.utils.SSLSocketHelper;
-import eu.siacs.conversations.utils.SocksSocketFactory;
import eu.siacs.conversations.utils.Xmlns;
import eu.siacs.conversations.xml.Element;
import eu.siacs.conversations.xml.Tag;
@@ -1536,35 +1538,62 @@ public class XmppConnection implements Runnable {
this.blockListRequested = value;
}
+ public boolean hasFeatureFileTransferHttp(long filesize) {
+ if (Config.DISABLE_HTTP_UPLOAD) {
+ return false;
+ } else {
+ List<Entry<Jid, ServiceDiscoveryResult>> items = findDiscoItemsByFeature(FileTransferHttp.NAMESPACE);
+ if (items.size() > 0) {
+ long maxsize = this.parseMaxHttpUploadSize(items.get(0), FileTransferHttp.NAMESPACE);
+ return filesize <= maxsize;
+ } else {
+ return false;
+ }
+ }
+ }
+
public boolean httpUpload(long filesize) {
if (Config.DISABLE_HTTP_UPLOAD) {
return false;
} else {
- List<Entry<Jid, ServiceDiscoveryResult>> items = findDiscoItemsByFeature(Xmlns.HTTP_UPLOAD);
- if (items.size() > 0) {
- try {
- long maxsize = Long.parseLong(items.get(0).getValue().getExtendedDiscoInformation(Xmlns.HTTP_UPLOAD, "max-file-size"));
- return filesize <= maxsize;
- } catch (Exception e) {
- return true;
- }
- } else {
- return false;
- }
+ if (hasFeatureFileTransferHttp(filesize)) {
+ return true;
+ } else {
+ List<Entry<Jid, ServiceDiscoveryResult>> items = findDiscoItemsByFeature(HttpUpload.NAMESPACE);
+ if (items.size() > 0) {
+ long maxsize = this.parseMaxHttpUploadSize(items.get(0), HttpUpload.NAMESPACE);
+ return filesize <= maxsize;
+ } else {
+ return false;
+ }
+ }
}
}
+ private long parseMaxHttpUploadSize(Entry<Jid, ServiceDiscoveryResult> item, String namespace) {
+ long maxsize = Long.MAX_VALUE;
+ if (null != item && null != namespace) {
+ try {
+ maxsize = Long.parseLong(item.getValue().getExtendedDiscoInformation(namespace, "max-file-size"));
+ } catch (Exception e) {
+ // Suppress exception
+ }
+ }
+ return maxsize;
+ }
+
public long getMaxHttpUploadSize() {
- List<Entry<Jid, ServiceDiscoveryResult>> items = findDiscoItemsByFeature(Xmlns.HTTP_UPLOAD);
- if (items.size() > 0) {
- try {
- return Long.parseLong(items.get(0).getValue().getExtendedDiscoInformation(Xmlns.HTTP_UPLOAD, "max-file-size"));
- } catch (Exception e) {
- return -1;
- }
- } else {
- return -1;
- }
+ List<Entry<Jid, ServiceDiscoveryResult>> items = findDiscoItemsByFeature(HttpUpload.NAMESPACE);
+ if (items.size() > 0) {
+ long maxsize = this.parseMaxHttpUploadSize(items.get(0), HttpUpload.NAMESPACE);
+ if (Long.MAX_VALUE == maxsize) { // For code compatibility - legacy behavior returns -1 in case of no max-file-size
+ return -1;
+ } else {
+ return maxsize;
+ }
+ } else {
+ return -1;
+ }
}
}
diff --git a/src/main/res/drawable-hdpi/ic_toast.png b/src/main/res/drawable-hdpi/ic_toast.png
new file mode 100644
index 00000000..fd5d1d8b
--- /dev/null
+++ b/src/main/res/drawable-hdpi/ic_toast.png
Binary files differ
diff --git a/src/main/res/drawable-hdpi/ic_toast_error.png b/src/main/res/drawable-hdpi/ic_toast_error.png
new file mode 100644
index 00000000..31de0901
--- /dev/null
+++ b/src/main/res/drawable-hdpi/ic_toast_error.png
Binary files differ
diff --git a/src/main/res/layout/cplus_toast_container.xml b/src/main/res/layout/cplus_toast_container.xml
new file mode 100644
index 00000000..f2aa09e3
--- /dev/null
+++ b/src/main/res/layout/cplus_toast_container.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/cplus_toast"
+ android:orientation="horizontal"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:padding="8dp"
+ android:background="#DAAA">
+
+ <ImageView android:id="@+id/cplus_toast_icon"
+ android:src="@drawable/ic_toast"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginRight="8dp"/>
+
+ <TextView android:id="@+id/cplus_toast_txt"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textColor="#FFF"
+ android:shadowColor="#BB000000"
+ android:shadowRadius="2.75"/>
+</LinearLayout> \ No newline at end of file
diff --git a/src/main/res/layout/message_sent.xml b/src/main/res/layout/message_sent.xml
index f59c51f3..8bda9c8f 100644
--- a/src/main/res/layout/message_sent.xml
+++ b/src/main/res/layout/message_sent.xml
@@ -117,7 +117,7 @@
android:textColor="@color/secondaryText"
android:textSize="?attr/TextSizeInfo"
android:visibility="gone"
- android:textStyle="italic"/>
+ android:textStyle="normal|italic"/>
</LinearLayout>
</LinearLayout>
diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml
index 5200fcb9..eb6800e0 100644
--- a/src/main/res/values/strings.xml
+++ b/src/main/res/values/strings.xml
@@ -682,4 +682,6 @@
<string name="file_not_on_remote_host">No file on remote host</string>
<string name="dlg_msg_details_original_filename">Original Filename</string>
<string name="cplus_open">Open</string>
+ <string name="cplus_remote_file_delete_service_unavailable">Remote File Deletion Service currently unavailable. Please try again later.</string>
+ <string name="cplus_remote_file_delete_failed">Failed to delete remote file.</string>
</resources>