add context menu to MediaBrowser to
* share * open * delete
This commit is contained in:
parent
ad9f8fde90
commit
6dff9bc8a9
4 changed files with 140 additions and 15 deletions
|
@ -38,6 +38,15 @@ public class MediaBrowserActivity extends XmppActivity implements OnMediaLoaded
|
||||||
private String account;
|
private String account;
|
||||||
private String jid;
|
private String jid;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStart() {
|
||||||
|
super.onStart();
|
||||||
|
getPreferences().edit().putBoolean("show_videos_images_only", OnlyImagesVideos).apply();
|
||||||
|
filter(OnlyImagesVideos);
|
||||||
|
invalidateOptionsMenu();
|
||||||
|
refreshUiReal();
|
||||||
|
}
|
||||||
|
|
||||||
public static void launch(Context context, Contact contact) {
|
public static void launch(Context context, Contact contact) {
|
||||||
launch(context, contact.getAccount(), contact.getJid().asBareJid().toEscapedString());
|
launch(context, contact.getAccount(), contact.getJid().asBareJid().toEscapedString());
|
||||||
}
|
}
|
||||||
|
@ -79,7 +88,7 @@ public class MediaBrowserActivity extends XmppActivity implements OnMediaLoaded
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void refreshUiReal() {
|
public void refreshUiReal() {
|
||||||
mMediaAdapter.notifyDataSetChanged();
|
mMediaAdapter.notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,19 +154,18 @@ public class MediaBrowserActivity extends XmppActivity implements OnMediaLoaded
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onMediaLoaded(List<Attachment> attachments) {
|
public void onMediaLoaded(List<Attachment> attachments) {
|
||||||
|
allAttachments.clear();
|
||||||
allAttachments.addAll(attachments);
|
allAttachments.addAll(attachments);
|
||||||
runOnUiThread(() -> {
|
runOnUiThread(() -> {
|
||||||
if (OnlyImagesVideos) {
|
|
||||||
filter(OnlyImagesVideos);
|
filter(OnlyImagesVideos);
|
||||||
} else {
|
|
||||||
loadAttachments(allAttachments);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadAttachments(List<Attachment> attachments) {
|
private void loadAttachments(List<Attachment> attachments) {
|
||||||
if (attachments.size() > 0) {
|
if (attachments.size() > 0) {
|
||||||
|
if (mMediaAdapter.getItemCount() != attachments.size()) {
|
||||||
mMediaAdapter.setAttachments(attachments);
|
mMediaAdapter.setAttachments(attachments);
|
||||||
|
}
|
||||||
this.binding.noMedia.setVisibility(View.GONE);
|
this.binding.noMedia.setVisibility(View.GONE);
|
||||||
this.binding.progressbar.setVisibility(View.GONE);
|
this.binding.progressbar.setVisibility(View.GONE);
|
||||||
} else {
|
} else {
|
||||||
|
@ -172,20 +180,26 @@ public class MediaBrowserActivity extends XmppActivity implements OnMediaLoaded
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
filter(OnlyImagesVideos);
|
||||||
|
}
|
||||||
|
|
||||||
protected void filterAttachments(boolean needle) {
|
protected void filterAttachments(boolean needle) {
|
||||||
if (allAttachments.size() > 0) {
|
if (allAttachments.size() > 0) {
|
||||||
|
if (needle) {
|
||||||
final ArrayList<Attachment> attachments = new ArrayList<>(allAttachments);
|
final ArrayList<Attachment> attachments = new ArrayList<>(allAttachments);
|
||||||
filteredAttachments.clear();
|
filteredAttachments.clear();
|
||||||
if (needle) {
|
|
||||||
for (Attachment attachment : attachments) {
|
for (Attachment attachment : attachments) {
|
||||||
if (attachment.getMime() != null && (attachment.getMime().startsWith("image/") || attachment.getMime().startsWith("video/"))) {
|
if (attachment.getMime() != null && (attachment.getMime().startsWith("image/") || attachment.getMime().startsWith("video/"))) {
|
||||||
filteredAttachments.add(attachment);
|
filteredAttachments.add(attachment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
filteredAttachments.addAll(allAttachments);
|
|
||||||
}
|
|
||||||
loadAttachments(filteredAttachments);
|
loadAttachments(filteredAttachments);
|
||||||
|
} else {
|
||||||
|
loadAttachments(allAttachments);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -111,6 +111,7 @@ public abstract class XmppActivity extends ActionBarActivity {
|
||||||
public static final String EXTRA_ACCOUNT = "account";
|
public static final String EXTRA_ACCOUNT = "account";
|
||||||
|
|
||||||
public XmppConnectionService xmppConnectionService;
|
public XmppConnectionService xmppConnectionService;
|
||||||
|
public MediaBrowserActivity mediaBrowserActivity;
|
||||||
public boolean xmppConnectionServiceBound = false;
|
public boolean xmppConnectionServiceBound = false;
|
||||||
|
|
||||||
protected int mColorWarningButton;
|
protected int mColorWarningButton;
|
||||||
|
|
|
@ -1,34 +1,49 @@
|
||||||
package de.pixart.messenger.ui.adapter;
|
package de.pixart.messenger.ui.adapter;
|
||||||
|
|
||||||
|
import android.content.ActivityNotFoundException;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.content.pm.ResolveInfo;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.drawable.BitmapDrawable;
|
import android.graphics.drawable.BitmapDrawable;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.net.Uri;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.annotation.AttrRes;
|
import androidx.annotation.AttrRes;
|
||||||
import androidx.annotation.DimenRes;
|
import androidx.annotation.DimenRes;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.appcompat.app.AlertDialog;
|
||||||
|
import androidx.appcompat.widget.PopupMenu;
|
||||||
import androidx.databinding.DataBindingUtil;
|
import androidx.databinding.DataBindingUtil;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.RejectedExecutionException;
|
import java.util.concurrent.RejectedExecutionException;
|
||||||
|
|
||||||
|
import de.pixart.messenger.Config;
|
||||||
import de.pixart.messenger.R;
|
import de.pixart.messenger.R;
|
||||||
import de.pixart.messenger.databinding.MediaBinding;
|
import de.pixart.messenger.databinding.MediaBinding;
|
||||||
|
import de.pixart.messenger.persistance.FileBackend;
|
||||||
import de.pixart.messenger.services.ExportBackupService;
|
import de.pixart.messenger.services.ExportBackupService;
|
||||||
import de.pixart.messenger.ui.XmppActivity;
|
import de.pixart.messenger.ui.XmppActivity;
|
||||||
import de.pixart.messenger.ui.util.Attachment;
|
import de.pixart.messenger.ui.util.Attachment;
|
||||||
import de.pixart.messenger.ui.util.StyledAttributes;
|
import de.pixart.messenger.ui.util.StyledAttributes;
|
||||||
import de.pixart.messenger.ui.util.ViewUtil;
|
import de.pixart.messenger.ui.util.ViewUtil;
|
||||||
|
import de.pixart.messenger.utils.MimeUtils;
|
||||||
|
import me.drakeet.support.toast.ToastCompat;
|
||||||
|
|
||||||
public class MediaAdapter extends RecyclerView.Adapter<MediaAdapter.MediaViewHolder> {
|
public class MediaAdapter extends RecyclerView.Adapter<MediaAdapter.MediaViewHolder> {
|
||||||
|
|
||||||
|
@ -140,9 +155,105 @@ public class MediaAdapter extends RecyclerView.Adapter<MediaAdapter.MediaViewHol
|
||||||
loadPreview(attachment, holder.binding.media);
|
loadPreview(attachment, holder.binding.media);
|
||||||
} else {
|
} else {
|
||||||
cancelPotentialWork(attachment, holder.binding.media);
|
cancelPotentialWork(attachment, holder.binding.media);
|
||||||
renderPreview(activity, attachment, holder.binding.media);
|
renderPreview(this.activity, attachment, holder.binding.media);
|
||||||
}
|
}
|
||||||
holder.binding.getRoot().setOnClickListener(v -> ViewUtil.view(activity, attachment));
|
holder.binding.getRoot().setOnClickListener(v -> ViewUtil.view(this.activity, attachment));
|
||||||
|
holder.binding.getRoot().setOnLongClickListener(v -> {
|
||||||
|
setSelection(v);
|
||||||
|
final PopupMenu popupMenu = new PopupMenu(this.activity, v);
|
||||||
|
popupMenu.inflate(R.menu.media_viewer);
|
||||||
|
popupMenu.getMenu().findItem(R.id.action_delete).setVisible(isDeletableFile(new File(attachment.getUri().getPath())));
|
||||||
|
popupMenu.setOnMenuItemClickListener(item -> {
|
||||||
|
switch (item.getItemId()) {
|
||||||
|
case R.id.action_share:
|
||||||
|
share(attachment);
|
||||||
|
return true;
|
||||||
|
case R.id.action_open:
|
||||||
|
open(attachment);
|
||||||
|
return true;
|
||||||
|
case R.id.action_delete:
|
||||||
|
deleteFile(attachment);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
popupMenu.setOnDismissListener(menu -> resetSelection(v));
|
||||||
|
popupMenu.show();
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setSelection(final View v) {
|
||||||
|
v.setBackgroundColor(StyledAttributes.getColor(this.activity, R.attr.colorAccent));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void resetSelection(final View v) {
|
||||||
|
v.setBackgroundColor(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void share(final Attachment attachment) {
|
||||||
|
final Intent share = new Intent(Intent.ACTION_SEND);
|
||||||
|
final File file = new File(attachment.getUri().getPath());
|
||||||
|
share.setType(attachment.getMime());
|
||||||
|
share.putExtra(Intent.EXTRA_STREAM, FileBackend.getUriForFile(this.activity, file));
|
||||||
|
try {
|
||||||
|
this.activity.startActivity(Intent.createChooser(share, this.activity.getText(R.string.share_with)));
|
||||||
|
} catch (ActivityNotFoundException e) {
|
||||||
|
//This should happen only on faulty androids because normally chooser is always available
|
||||||
|
ToastCompat.makeText(this.activity, R.string.no_application_found_to_open_file, Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void deleteFile(final Attachment attachment) {
|
||||||
|
final File file = new File(attachment.getUri().getPath());
|
||||||
|
final int hash = attachment.hashCode();
|
||||||
|
final AlertDialog.Builder builder = new AlertDialog.Builder(this.activity);
|
||||||
|
builder.setNegativeButton(R.string.cancel, null);
|
||||||
|
builder.setTitle(R.string.delete_file_dialog);
|
||||||
|
builder.setMessage(R.string.delete_file_dialog_msg);
|
||||||
|
builder.setPositiveButton(R.string.confirm, (dialog, which) -> {
|
||||||
|
if (activity.xmppConnectionService.getFileBackend().deleteFile(file)) {
|
||||||
|
for (int i = 0; i < attachments.size(); i++) {
|
||||||
|
if (hash == attachments.get(i).hashCode()) {
|
||||||
|
attachments.remove(i);
|
||||||
|
notifyDataSetChanged();
|
||||||
|
this.activity.refreshUi();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
builder.create().show();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void open(final Attachment attachment) {
|
||||||
|
final File file = new File(attachment.getUri().getPath());
|
||||||
|
final Uri uri;
|
||||||
|
try {
|
||||||
|
uri = FileBackend.getUriForFile(this.activity, file);
|
||||||
|
} catch (SecurityException e) {
|
||||||
|
Log.d(Config.LOGTAG, "No permission to access " + file.getAbsolutePath(), e);
|
||||||
|
ToastCompat.makeText(this.activity, this.activity.getString(R.string.no_permission_to_access_x, file.getAbsolutePath()), Toast.LENGTH_SHORT).show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String mime = MimeUtils.guessMimeTypeFromUri(this.activity, uri);
|
||||||
|
Intent openIntent = new Intent(Intent.ACTION_VIEW);
|
||||||
|
openIntent.setDataAndType(uri, mime);
|
||||||
|
openIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||||
|
PackageManager manager = this.activity.getPackageManager();
|
||||||
|
List<ResolveInfo> info = manager.queryIntentActivities(openIntent, 0);
|
||||||
|
if (info.size() == 0) {
|
||||||
|
openIntent.setDataAndType(uri, "*/*");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
this.activity.startActivity(openIntent);
|
||||||
|
} catch (ActivityNotFoundException e) {
|
||||||
|
ToastCompat.makeText(this.activity, R.string.no_application_found_to_open_file, Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isDeletableFile(File file) {
|
||||||
|
return (file == null || !file.toString().startsWith("/") || file.toString().contains(FileBackend.getConversationsDirectory("null")));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAttachments(List<Attachment> attachments) {
|
public void setAttachments(List<Attachment> attachments) {
|
||||||
|
|
|
@ -14,6 +14,5 @@
|
||||||
android:id="@+id/action_delete"
|
android:id="@+id/action_delete"
|
||||||
android:icon="@drawable/ic_delete_white_24dp"
|
android:icon="@drawable/ic_delete_white_24dp"
|
||||||
android:orderInCategory="20"
|
android:orderInCategory="20"
|
||||||
android:title="@string/action_delete"
|
android:title="@string/action_delete" />
|
||||||
android:visible="false" />
|
|
||||||
</menu>
|
</menu>
|
Reference in a new issue