data transfer: allow to save, delete files from conversation
Change-Id: I0087aa1e241358b41b79e21327fc2c699a54490b
diff --git a/ring-android/app/src/main/AndroidManifest.xml b/ring-android/app/src/main/AndroidManifest.xml
index 036e25f..e690f49 100644
--- a/ring-android/app/src/main/AndroidManifest.xml
+++ b/ring-android/app/src/main/AndroidManifest.xml
@@ -325,13 +325,8 @@
<activity
android:name=".client.MediaViewerActivity"
android:label="@string/title_media_viewer"
- android:theme="@style/AppThemeBase.Dark">
- <intent-filter>
- <action android:name="android.intent.action.VIEW" />
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.OPENABLE" />
- <data android:scheme="content" android:mimeType="image/*"/>
- </intent-filter>
+ android:theme="@style/AppThemeBase.Dark"
+ android:exported="false">
</activity>
</application>
diff --git a/ring-android/app/src/main/java/cx/ring/adapters/ConversationAdapter.java b/ring-android/app/src/main/java/cx/ring/adapters/ConversationAdapter.java
index a0da02c..18dbd6e 100644
--- a/ring-android/app/src/main/java/cx/ring/adapters/ConversationAdapter.java
+++ b/ring-android/app/src/main/java/cx/ring/adapters/ConversationAdapter.java
@@ -20,11 +20,13 @@
*/
package cx.ring.adapters;
+import android.app.DownloadManager;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.content.Intent;
import android.net.Uri;
+import android.os.Environment;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityOptionsCompat;
@@ -33,13 +35,17 @@
import android.text.format.DateUtils;
import android.util.Log;
import android.util.TypedValue;
+import android.view.ContextMenu;
import android.view.Gravity;
import android.view.LayoutInflater;
+import android.view.MenuInflater;
+import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.ImageView;
import android.widget.LinearLayout;
+import android.widget.Toast;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.resource.bitmap.CenterInside;
@@ -87,6 +93,7 @@
private final int vPaddingEmoticon;
private final int mPictureMaxSize;
private final GlideOptions PICTURE_OPTIONS;
+ private RecyclerViewContextMenuInfo mCurrentLongItem = null;
public ConversationAdapter(ConversationFragment conversationFragment, ConversationPresenter presenter) {
this.conversationFragment = conversationFragment;
@@ -196,6 +203,15 @@
}
}
+ @Override
+ public void onViewRecycled(ConversationViewHolder holder) {
+ if (holder.itemView != null)
+ holder.itemView.setOnLongClickListener(null);
+ if (holder.mPhoto != null)
+ holder.mPhoto.setOnLongClickListener(null);
+ super.onViewRecycled(holder);
+ }
+
private static void runJustBeforeBeingDrawn(final ImageView view, final Runnable runnable) {
final ViewTreeObserver.OnPreDrawListener preDrawListener = new ViewTreeObserver.OnPreDrawListener() {
@@ -209,6 +225,62 @@
view.getViewTreeObserver().addOnPreDrawListener(preDrawListener);
}
+ public static class RecyclerViewContextMenuInfo implements ContextMenu.ContextMenuInfo {
+ public RecyclerViewContextMenuInfo(int position, long id) {
+ this.position = position;
+ this.id = id;
+ }
+ final public int position;
+ final public long id;
+ }
+
+ public RecyclerViewContextMenuInfo getCurrentLongItem() {
+ return mCurrentLongItem;
+ }
+
+ public boolean onContextItemSelected(MenuItem item) {
+ ConversationAdapter.RecyclerViewContextMenuInfo info = getCurrentLongItem();
+ if (info == null) {
+ return false;
+ }
+ IConversationElement conversationElement = mConversationElements.get(info.position);
+ if (conversationElement == null)
+ return false;
+ if (conversationElement.getType() != IConversationElement.CEType.FILE)
+ return false;
+ DataTransfer file = (DataTransfer) conversationElement;
+ Context context = conversationFragment.getActivity();
+ switch (item.getItemId()) {
+ case R.id.conv_action_download: {
+ File downloadDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "Ring");
+ if (!downloadDir.mkdirs()) {
+ Log.e(TAG, "Directory not created");
+ }
+ File newFile = new File(downloadDir, file.getDisplayName());
+ if (newFile.exists())
+ newFile.delete();
+ if (presenter.downloadFile(file, newFile)) {
+ DownloadManager downloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
+ if (downloadManager != null) {
+ downloadManager.addCompletedDownload(file.getDisplayName(),
+ file.getDisplayName(),
+ true,
+ file.isPicture() ? "image/jpeg" : "text/plain",
+ newFile.getAbsolutePath(),
+ newFile.length(),
+ true);
+ }
+ }
+ break;
+ }
+ case R.id.conv_action_delete:
+ presenter.deleteFile(file);
+ break;
+ }
+ return true;
+ }
+
+
private void configureForFileInfoTextMessage(final ConversationViewHolder conversationViewHolder,
final IConversationElement conversationElement) {
if (conversationViewHolder == null || conversationElement == null) {
@@ -227,7 +299,23 @@
timeSeparationString, FileUtils.readableFileSize(file.getTotalSize()),
ResourceMapper.getReadableFileTransferStatus(conversationFragment.getActivity(), file.getEventCode())));
}
- if (file.showPicture()) {
+
+ boolean showPicture = file.showPicture();
+ View longPressView = showPicture ? conversationViewHolder.mPhoto : conversationViewHolder.itemView;
+ longPressView.setOnCreateContextMenuListener((menu, v, menuInfo) -> {
+ menu.setHeaderTitle(file.getDisplayName());
+ conversationFragment.onCreateContextMenu(menu, v, menuInfo);
+ MenuInflater inflater = conversationFragment.getActivity().getMenuInflater();
+ inflater.inflate(R.menu.conversation_item_actions, menu);
+ if (!file.isComplete())
+ menu.removeItem(R.id.conv_action_download);
+ });
+ longPressView.setOnLongClickListener(v -> {
+ mCurrentLongItem = new RecyclerViewContextMenuInfo(conversationViewHolder.getLayoutPosition(), v.getId());
+ return false;
+ });
+
+ if (showPicture) {
Context context = conversationViewHolder.mPhoto.getContext();
File path = presenter.getDeviceRuntimeService().getConversationPath(file.getPeerId(), file.getStoragePath());
diff --git a/ring-android/app/src/main/java/cx/ring/fragments/ConversationFragment.java b/ring-android/app/src/main/java/cx/ring/fragments/ConversationFragment.java
index 4bc1c17..4adb06d 100644
--- a/ring-android/app/src/main/java/cx/ring/fragments/ConversationFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/fragments/ConversationFragment.java
@@ -214,6 +214,13 @@
}
}
+ @Override
+ public boolean onContextItemSelected(MenuItem item) {
+ if (mAdapter.onContextItemSelected(item))
+ return true;
+ return super.onContextItemSelected(item);
+ }
+
@OnClick(R.id.msg_send)
public void sendMessageText() {
presenter.sendTextMessage(mMsgEditTxt.getText().toString());
diff --git a/ring-android/app/src/main/res/drawable/ic_file_download.xml b/ring-android/app/src/main/res/drawable/ic_file_download.xml
new file mode 100644
index 0000000..bb72b2c
--- /dev/null
+++ b/ring-android/app/src/main/res/drawable/ic_file_download.xml
@@ -0,0 +1,8 @@
+<!-- drawable/download.xml -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="24dp"
+ android:width="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path android:fillColor="#000" android:pathData="M5,20H19V18H5M19,9H15V3H9V9H5L12,16L19,9Z" />
+</vector>
\ No newline at end of file
diff --git a/ring-android/app/src/main/res/menu/conversation_item_actions.xml b/ring-android/app/src/main/res/menu/conversation_item_actions.xml
new file mode 100644
index 0000000..8c2180e
--- /dev/null
+++ b/ring-android/app/src/main/res/menu/conversation_item_actions.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:tools="http://schemas.android.com/tools">
+
+ <item
+ android:id="@+id/conv_action_download"
+ android:icon="@drawable/ic_file_download"
+ android:title="@string/menu_file_download"
+ app:showAsAction="always" />
+
+ <item
+ android:id="@+id/conv_action_delete"
+ android:icon="@drawable/ic_delete_white"
+ android:title="@string/menu_file_delete"
+ app:showAsAction="always" />
+</menu>
\ No newline at end of file
diff --git a/ring-android/app/src/main/res/values/strings.xml b/ring-android/app/src/main/res/values/strings.xml
index e5af8ca..a1d3480 100644
--- a/ring-android/app/src/main/res/values/strings.xml
+++ b/ring-android/app/src/main/res/values/strings.xml
@@ -242,5 +242,7 @@
<string name="file_saved_in">File saved in %s</string>
<string name="no_space_left_on_device">No space left on device</string>
<string name="title_media_viewer">Media viewer</string>
+ <string name="menu_file_download">Download file</string>
+ <string name="menu_file_delete">Delete file</string>
</resources>