aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoriNPUTmice <daniel@gultsch.de>2014-10-23 21:27:41 +0200
committeriNPUTmice <daniel@gultsch.de>2014-10-23 21:27:41 +0200
commitd73a77643d7923cae0789c5ed9f6a2a4cf41385f (patch)
tree14012cf90146a8a1feacd29cbc6fa6ad959ba1c2
parentde3739970b32a927d8c1ec5f7a378fa50c4b4f99 (diff)
context menu for messages. allow to resend single messages
-rw-r--r--res/layout/message_received.xml4
-rw-r--r--res/layout/message_sent.xml4
-rw-r--r--res/menu/message_context.xml17
-rw-r--r--res/values/strings.xml19
-rw-r--r--src/eu/siacs/conversations/entities/Message.java11
-rw-r--r--src/eu/siacs/conversations/services/XmppConnectionService.java17
-rw-r--r--src/eu/siacs/conversations/ui/ConversationActivity.java1
-rw-r--r--src/eu/siacs/conversations/ui/ConversationFragment.java101
-rw-r--r--src/eu/siacs/conversations/ui/EditAccountActivity.java13
-rw-r--r--src/eu/siacs/conversations/ui/XmppActivity.java13
-rw-r--r--src/eu/siacs/conversations/ui/adapter/MessageAdapter.java28
11 files changed, 189 insertions, 39 deletions
diff --git a/res/layout/message_received.xml b/res/layout/message_received.xml
index 730d00d5..39bb842a 100644
--- a/res/layout/message_received.xml
+++ b/res/layout/message_received.xml
@@ -15,7 +15,8 @@
android:layout_alignParentBottom="true"
android:layout_toRightOf="@+id/message_photo"
android:background="@drawable/message_border"
- android:minHeight="48dp" >
+ android:minHeight="48dp"
+ android:longClickable="true">
<LinearLayout
android:layout_width="wrap_content"
@@ -43,7 +44,6 @@
android:layout_height="wrap_content"
android:autoLink="web"
android:textColor="@color/primarytext"
- android:textIsSelectable="true"
android:textSize="?attr/TextSizeBody" />
<Button
diff --git a/res/layout/message_sent.xml b/res/layout/message_sent.xml
index e3e9b673..3e854643 100644
--- a/res/layout/message_sent.xml
+++ b/res/layout/message_sent.xml
@@ -15,7 +15,8 @@
android:layout_alignParentBottom="true"
android:layout_toLeftOf="@+id/message_photo"
android:background="@drawable/message_border"
- android:minHeight="48dp" >
+ android:minHeight="48dp"
+ android:longClickable="true">
<LinearLayout
android:layout_width="wrap_content"
@@ -43,7 +44,6 @@
android:layout_height="wrap_content"
android:autoLink="web"
android:textColor="@color/primarytext"
- android:textIsSelectable="true"
android:textSize="?attr/TextSizeBody" />
<Button
diff --git a/res/menu/message_context.xml b/res/menu/message_context.xml
new file mode 100644
index 00000000..23d5d28d
--- /dev/null
+++ b/res/menu/message_context.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <item
+ android:id="@+id/copy_text"
+ android:title="@string/copy_text"/>
+ <item
+ android:id="@+id/share_image"
+ android:title="@string/share_image"/>
+ <item
+ android:id="@+id/copy_url"
+ android:title="@string/copy_original_url" />
+ <item
+ android:id="@+id/send_again"
+ android:title="@string/send_again"/>
+
+</menu> \ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 3862bb7b..0170b006 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -249,10 +249,10 @@
<string name="pref_force_encryption">Force end-to-end encryption</string>
<string name="pref_force_encryption_summary">Always send messages encrypted (except for conferences)</string>
<string name="pref_dont_save_encrypted">Don’t save encrypted messages</string>
- <string name="pref_dont_save_encrypted_summary">Warning: This could lead to message loss</string>
- <string name="pref_enable_legacy_ssl">Enable legacy SSL</string>
- <string name="pref_enable_legacy_ssl_summary">Enables SSLv3 support for legacy servers. Warning: SSLv3 is considered insecure.</string>
- <string name="pref_expert_options">Expert options</string>
+ <string name="pref_dont_save_encrypted_summary">Warning: This could lead to message loss</string>
+ <string name="pref_enable_legacy_ssl">Enable legacy SSL</string>
+ <string name="pref_enable_legacy_ssl_summary">Enables SSLv3 support for legacy servers. Warning: SSLv3 is considered insecure.</string>
+ <string name="pref_expert_options">Expert options</string>
<string name="pref_expert_options_summary">Please be careful with these</string>
<string name="pref_use_larger_font">Increase font size</string>
<string name="pref_use_larger_font_summary">Use larger font sizes across the entire app</string>
@@ -272,5 +272,14 @@
<string name="image_file_deleted">The image file has been deleted</string>
<string name="not_connected_try_again">You are not connected. Try again later</string>
<string name="check_image_filesize">Check image file size</string>
+ <string name="message_options">Message options</string>
+ <string name="copy_text">Copy text</string>
+ <string name="share_image">Share image</string>
+ <string name="copy_original_url">Copy original URL</string>
+ <string name="send_again">Send again</string>
+ <string name="image_url">Image URL</string>
+ <string name="message_text">Message text</string>
+ <string name="url_copied_to_clipboard">URL copied to clipboard</string>
+ <string name="message_copied_to_clipboard">Message copied to clipboard</string>
-</resources>
+</resources> \ No newline at end of file
diff --git a/src/eu/siacs/conversations/entities/Message.java b/src/eu/siacs/conversations/entities/Message.java
index a390c7ca..5fa16460 100644
--- a/src/eu/siacs/conversations/entities/Message.java
+++ b/src/eu/siacs/conversations/entities/Message.java
@@ -431,6 +431,11 @@ public class Message extends AbstractEntity {
params.size = Long.parseLong(parts[0]);
} catch (NumberFormatException e) {
params.origin = parts[0];
+ try {
+ params.url = new URL(parts[0]);
+ } catch (MalformedURLException e1) {
+ params.url = null;
+ }
}
} else if (parts.length == 3) {
try {
@@ -451,6 +456,11 @@ public class Message extends AbstractEntity {
} else if (parts.length == 4) {
params.origin = parts[0];
try {
+ params.url = new URL(parts[0]);
+ } catch (MalformedURLException e1) {
+ params.url = null;
+ }
+ try {
params.size = Long.parseLong(parts[1]);
} catch (NumberFormatException e) {
params.size = 0;
@@ -470,6 +480,7 @@ public class Message extends AbstractEntity {
}
public class ImageParams {
+ public URL url;
public long size = 0;
public int width = 0;
public int height = 0;
diff --git a/src/eu/siacs/conversations/services/XmppConnectionService.java b/src/eu/siacs/conversations/services/XmppConnectionService.java
index 37e334eb..6d6c672e 100644
--- a/src/eu/siacs/conversations/services/XmppConnectionService.java
+++ b/src/eu/siacs/conversations/services/XmppConnectionService.java
@@ -1924,4 +1924,21 @@ public class XmppConnectionService extends Service {
}
}
+
+ public void resendFailedMessages(Message message) {
+ List<Message> messages = new ArrayList<Message>();
+ Message current = message;
+ while(current.getStatus() == Message.STATUS_SEND_FAILED) {
+ messages.add(current);
+ if (current.mergable(current.next())) {
+ current = current.next();
+ } else {
+ break;
+ }
+ }
+ for(Message msg: messages) {
+ markMessage(msg, Message.STATUS_WAITING);
+ this.resendMessage(msg);
+ }
+ }
}
diff --git a/src/eu/siacs/conversations/ui/ConversationActivity.java b/src/eu/siacs/conversations/ui/ConversationActivity.java
index 91e1c81f..8a647f30 100644
--- a/src/eu/siacs/conversations/ui/ConversationActivity.java
+++ b/src/eu/siacs/conversations/ui/ConversationActivity.java
@@ -191,6 +191,7 @@ public class ConversationActivity extends XmppActivity implements
xmppConnectionService.getNotificationService()
.setOpenConversation(null);
}
+ closeContextMenu();
}
@Override
diff --git a/src/eu/siacs/conversations/ui/ConversationFragment.java b/src/eu/siacs/conversations/ui/ConversationFragment.java
index 580fa2d2..4c8d27e9 100644
--- a/src/eu/siacs/conversations/ui/ConversationFragment.java
+++ b/src/eu/siacs/conversations/ui/ConversationFragment.java
@@ -11,6 +11,7 @@ import eu.siacs.conversations.crypto.PgpEngine;
import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.entities.Contact;
import eu.siacs.conversations.entities.Conversation;
+import eu.siacs.conversations.entities.Downloadable;
import eu.siacs.conversations.entities.Message;
import eu.siacs.conversations.entities.MucOptions;
import eu.siacs.conversations.entities.Presences;
@@ -33,9 +34,12 @@ import android.content.IntentSender.SendIntentException;
import android.os.Bundle;
import android.text.Editable;
import android.text.Selection;
+import android.view.ContextMenu;
+import android.view.ContextMenu.ContextMenuInfo;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
+import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
@@ -45,6 +49,8 @@ import android.widget.AbsListView.OnScrollListener;
import android.widget.TextView.OnEditorActionListener;
import android.widget.AbsListView;
+import android.widget.AdapterView;
+import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.ListView;
import android.widget.ImageButton;
import android.widget.RelativeLayout;
@@ -193,6 +199,7 @@ public class ConversationFragment extends Fragment {
};
private ConversationActivity activity;
+ private Message selectedMessage;
private void sendMessage() {
if (this.conversation == null) {
@@ -326,9 +333,100 @@ public class ConversationFragment extends Fragment {
});
messagesView.setAdapter(messageListAdapter);
+ registerForContextMenu(messagesView);
+
return view;
}
+ @Override
+ public void onCreateContextMenu(ContextMenu menu, View v,
+ ContextMenuInfo menuInfo) {
+ super.onCreateContextMenu(menu, v, menuInfo);
+ AdapterView.AdapterContextMenuInfo acmi = (AdapterContextMenuInfo) menuInfo;
+ this.selectedMessage = this.messageList.get(acmi.position);
+ populateContextMenu(menu);
+ }
+
+ private void populateContextMenu(ContextMenu menu) {
+ if (this.selectedMessage.getType() != Message.TYPE_STATUS) {
+ activity.getMenuInflater().inflate(R.menu.message_context, menu);
+ menu.setHeaderTitle(R.string.message_options);
+ MenuItem copyText = menu.findItem(R.id.copy_text);
+ MenuItem shareImage = menu.findItem(R.id.share_image);
+ MenuItem sendAgain = menu.findItem(R.id.send_again);
+ MenuItem copyUrl = menu.findItem(R.id.copy_url);
+ if (this.selectedMessage.getType() != Message.TYPE_TEXT
+ || this.selectedMessage.getDownloadable() != null) {
+ copyText.setVisible(false);
+ }
+ if (this.selectedMessage.getType() != Message.TYPE_IMAGE
+ || (this.selectedMessage.getDownloadable() != null && this.selectedMessage
+ .getDownloadable().getStatus() == Downloadable.STATUS_DELETED)) {
+ shareImage.setVisible(false);
+ }
+ if (this.selectedMessage.getStatus() != Message.STATUS_SEND_FAILED) {
+ sendAgain.setVisible(false);
+ }
+ if ((this.selectedMessage.getType() != Message.TYPE_IMAGE && this.selectedMessage
+ .getDownloadable() == null)
+ || this.selectedMessage.getImageParams().url == null) {
+ copyUrl.setVisible(false);
+ }
+ }
+ }
+
+ @Override
+ public boolean onContextItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case R.id.share_image:
+ shareImage(selectedMessage);
+ return true;
+ case R.id.copy_text:
+ copyText(selectedMessage);
+ return true;
+ case R.id.send_again:
+ resendMessage(selectedMessage);
+ return true;
+ case R.id.copy_url:
+ copyUrl(selectedMessage);
+ return true;
+ default:
+ return super.onContextItemSelected(item);
+ }
+ }
+
+ private void shareImage(Message message) {
+ Intent shareIntent = new Intent();
+ shareIntent.setAction(Intent.ACTION_SEND);
+ shareIntent.putExtra(Intent.EXTRA_STREAM,
+ activity.xmppConnectionService.getFileBackend()
+ .getJingleFileUri(message));
+ shareIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ shareIntent.setType("image/webp");
+ activity.startActivity(Intent.createChooser(shareIntent,
+ getText(R.string.share_with)));
+ }
+
+ private void copyText(Message message) {
+ if (activity.copyTextToClipboard(message.getMergedBody(),
+ R.string.message_text)) {
+ Toast.makeText(activity, R.string.message_copied_to_clipboard,
+ Toast.LENGTH_SHORT).show();
+ }
+ }
+
+ private void resendMessage(Message message) {
+ activity.xmppConnectionService.resendFailedMessages(message);
+ }
+
+ private void copyUrl(Message message) {
+ if (activity.copyTextToClipboard(
+ message.getImageParams().url.toString(), R.string.image_url)) {
+ Toast.makeText(activity, R.string.url_copied_to_clipboard,
+ Toast.LENGTH_SHORT).show();
+ }
+ }
+
protected void privateMessageWith(String counterpart) {
this.mEditMessage.setText("");
this.conversation.setNextPresence(counterpart);
@@ -437,7 +535,8 @@ public class ConversationFragment extends Fragment {
for (Message message : this.conversation.getMessages()) {
if (message.getEncryption() == Message.ENCRYPTION_PGP
&& (message.getStatus() == Message.STATUS_RECEIVED || message
- .getStatus() >= Message.STATUS_SEND) && message.getDownloadable() == null) {
+ .getStatus() >= Message.STATUS_SEND)
+ && message.getDownloadable() == null) {
if (!mEncryptedMessages.contains(message)) {
mEncryptedMessages.add(message);
}
diff --git a/src/eu/siacs/conversations/ui/EditAccountActivity.java b/src/eu/siacs/conversations/ui/EditAccountActivity.java
index 1543d740..89c06592 100644
--- a/src/eu/siacs/conversations/ui/EditAccountActivity.java
+++ b/src/eu/siacs/conversations/ui/EditAccountActivity.java
@@ -389,7 +389,7 @@ public class EditAccountActivity extends XmppActivity {
@Override
public void onClick(View v) {
- if (OtrFingerprintToClipBoard(fingerprint)) {
+ if (copyTextToClipboard(fingerprint,R.string.otr_fingerprint)) {
Toast.makeText(
EditAccountActivity.this,
R.string.toast_message_otr_fingerprint,
@@ -409,15 +409,4 @@ public class EditAccountActivity extends XmppActivity {
this.mStats.setVisibility(View.GONE);
}
}
-
- private boolean OtrFingerprintToClipBoard(String fingerprint) {
- ClipboardManager mClipBoardManager = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
- String label = getResources().getString(R.string.otr_fingerprint);
- if (mClipBoardManager != null) {
- ClipData mClipData = ClipData.newPlainText(label, fingerprint);
- mClipBoardManager.setPrimaryClip(mClipData);
- return true;
- }
- return false;
- }
}
diff --git a/src/eu/siacs/conversations/ui/XmppActivity.java b/src/eu/siacs/conversations/ui/XmppActivity.java
index d26f0e31..c04a4c0b 100644
--- a/src/eu/siacs/conversations/ui/XmppActivity.java
+++ b/src/eu/siacs/conversations/ui/XmppActivity.java
@@ -21,6 +21,8 @@ import android.app.Activity;
import android.app.AlertDialog;
import android.app.PendingIntent;
import android.app.AlertDialog.Builder;
+import android.content.ClipData;
+import android.content.ClipboardManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
@@ -531,6 +533,17 @@ public abstract class XmppActivity extends Activity {
DisplayMetrics metrics = getResources().getDisplayMetrics();
return ((int) (dp * metrics.density));
}
+
+ public boolean copyTextToClipboard(String text,int labelResId) {
+ ClipboardManager mClipBoardManager = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
+ String label = getResources().getString(labelResId);
+ if (mClipBoardManager != null) {
+ ClipData mClipData = ClipData.newPlainText(label, text);
+ mClipBoardManager.setPrimaryClip(mClipData);
+ return true;
+ }
+ return false;
+ }
public AvatarService avatarService() {
return xmppConnectionService.getAvatarService();
diff --git a/src/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/eu/siacs/conversations/ui/adapter/MessageAdapter.java
index a9a55cbf..4e04e315 100644
--- a/src/eu/siacs/conversations/ui/adapter/MessageAdapter.java
+++ b/src/eu/siacs/conversations/ui/adapter/MessageAdapter.java
@@ -43,6 +43,15 @@ public class MessageAdapter extends ArrayAdapter<Message> {
private OnContactPictureClicked mOnContactPictureClickedListener;
private OnContactPictureLongClicked mOnContactPictureLongClickedListener;
+ private OnLongClickListener openContextMenu = new OnLongClickListener() {
+
+ @Override
+ public boolean onLongClick(View v) {
+ v.showContextMenu();
+ return true;
+ }
+ };
+
public MessageAdapter(ConversationActivity activity, List<Message> messages) {
super(activity, 0, messages);
this.activity = activity;
@@ -259,6 +268,7 @@ public class MessageAdapter extends ArrayAdapter<Message> {
startDonwloadable(message);
}
});
+ viewHolder.download_button.setOnLongClickListener(openContextMenu);
}
private void displayImageMessage(ViewHolder viewHolder,
@@ -292,23 +302,7 @@ public class MessageAdapter extends ArrayAdapter<Message> {
getContext().startActivity(intent);
}
});
- viewHolder.image.setOnLongClickListener(new OnLongClickListener() {
-
- @Override
- public boolean onLongClick(View v) {
- Intent shareIntent = new Intent();
- shareIntent.setAction(Intent.ACTION_SEND);
- shareIntent.putExtra(Intent.EXTRA_STREAM,
- activity.xmppConnectionService.getFileBackend()
- .getJingleFileUri(message));
- shareIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
- shareIntent.setType("image/webp");
- getContext().startActivity(
- Intent.createChooser(shareIntent,
- getContext().getText(R.string.share_with)));
- return true;
- }
- });
+ viewHolder.image.setOnLongClickListener(openContextMenu);
}
@Override