diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml index 8388c0157..acea6b555 100644 --- a/src/main/AndroidManifest.xml +++ b/src/main/AndroidManifest.xml @@ -380,6 +380,9 @@ + diff --git a/src/main/java/eu/siacs/conversations/ui/MediaViewerActivity.java b/src/main/java/eu/siacs/conversations/ui/MediaViewerActivity.java new file mode 100644 index 000000000..c487f91c3 --- /dev/null +++ b/src/main/java/eu/siacs/conversations/ui/MediaViewerActivity.java @@ -0,0 +1,142 @@ +package eu.siacs.conversations.ui; + +import android.graphics.Color; +import android.net.Uri; +import android.os.Bundle; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import androidx.databinding.DataBindingUtil; +import androidx.viewpager.widget.PagerAdapter; +import androidx.viewpager.widget.ViewPager; +import eu.siacs.conversations.R; +import eu.siacs.conversations.databinding.ActivityMediaViewerBinding; +import eu.siacs.conversations.entities.Conversation; +import eu.siacs.conversations.entities.Message; +import java.util.ArrayList; +import java.util.List; + +public class MediaViewerActivity extends XmppActivity { + + public static final String EXTRA_MESSAGE_UUID = + "eu.siacs.conversations.extra.MESSAGE_UUID"; + + private ActivityMediaViewerBinding binding; + private String conversationUuid; + private String messageUuid; + + @Override + protected void onCreate(final Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + this.binding = + DataBindingUtil.setContentView(this, R.layout.activity_media_viewer); + Activities.setStatusAndNavigationBarColors(this, binding.getRoot(), false, false); + setSupportActionBar(binding.toolbar); + configureActionBar(getSupportActionBar()); + final var intent = getIntent(); + if (intent != null) { + this.conversationUuid = intent.getStringExtra(ConversationsActivity.EXTRA_CONVERSATION); + this.messageUuid = intent.getStringExtra(EXTRA_MESSAGE_UUID); + } + } + + @Override + protected void refreshUiReal() {} + + @Override + protected void onBackendConnected() { + if (conversationUuid == null) { + return; + } + final Conversation conversation = + xmppConnectionService.findConversationByUuidReliable(conversationUuid); + if (conversation == null) { + return; + } + final List allMessages = new ArrayList<>(); + conversation.populateWithMessages(allMessages); + final List images = new ArrayList<>(); + for (final Message message : allMessages) { + if (isViewableImage(message)) { + images.add(message); + } + } + if (images.isEmpty()) { + return; + } + int startIndex = 0; + for (int i = 0; i < images.size(); i++) { + if (images.get(i).getUuid().equals(messageUuid)) { + startIndex = i; + break; + } + } + final int total = images.size(); + final MediaPagerAdapter adapter = new MediaPagerAdapter(images); + binding.mediaPager.setAdapter(adapter); + binding.mediaPager.setCurrentItem(startIndex, false); + updateTitle(startIndex + 1, total); + binding.mediaPager.addOnPageChangeListener( + new ViewPager.SimpleOnPageChangeListener() { + @Override + public void onPageSelected(final int position) { + updateTitle(position + 1, total); + } + }); + } + + private void updateTitle(final int current, final int total) { + setTitle(current + " / " + total); + } + + private static boolean isViewableImage(final Message message) { + if (!message.isFileOrImage()) { + return false; + } + if (message.getEncryption() == Message.ENCRYPTION_PGP) { + return false; + } + final Message.FileParams params = message.getFileParams(); + return params.width > 0 && params.height > 0; + } + + private class MediaPagerAdapter extends PagerAdapter { + + private final List images; + + MediaPagerAdapter(final List images) { + this.images = images; + } + + @Override + public int getCount() { + return images.size(); + } + + @Override + public boolean isViewFromObject(final View view, final Object object) { + return view == object; + } + + @Override + public Object instantiateItem(final ViewGroup container, final int position) { + final ImageView imageView = new ImageView(MediaViewerActivity.this); + imageView.setScaleType(ImageView.ScaleType.FIT_CENTER); + imageView.setBackgroundColor(Color.BLACK); + final Message message = images.get(position); + final var file = + xmppConnectionService.getFileBackend().getFile(message); + if (file.exists()) { + imageView.setImageURI(Uri.fromFile(file)); + } + container.addView(imageView); + return imageView; + } + + @Override + public void destroyItem( + final ViewGroup container, final int position, final Object object) { + container.removeView((View) object); + } + } +} 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 97828bbf9..d3d864c7c 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java @@ -69,6 +69,7 @@ import eu.siacs.conversations.ui.BindingAdapters; import eu.siacs.conversations.ui.ConversationFragment; import eu.siacs.conversations.ui.ConversationsActivity; +import eu.siacs.conversations.ui.MediaViewerActivity; import eu.siacs.conversations.ui.XmppActivity; import eu.siacs.conversations.ui.service.AudioPlayer; import eu.siacs.conversations.ui.text.DividerSpan; @@ -688,7 +689,7 @@ private void displayMediaPreviewMessage( new LinearLayout.LayoutParams(scaledW, scaledH); viewHolder.image().setLayoutParams(layoutParams); activity.loadBitmap(message, viewHolder.image()); - viewHolder.image().setOnClickListener(v -> openDownloadable(message)); + viewHolder.image().setOnClickListener(v -> openMediaViewer(message)); } private void toggleWhisperInfo( @@ -1352,6 +1353,13 @@ public void openDownloadable(Message message) { ViewUtil.view(activity, file); } + private void openMediaViewer(final Message message) { + final Intent intent = new Intent(activity, MediaViewerActivity.class); + intent.putExtra(ConversationsActivity.EXTRA_CONVERSATION, message.getConversationUuid()); + intent.putExtra(MediaViewerActivity.EXTRA_MESSAGE_UUID, message.getUuid()); + activity.startActivity(intent); + } + private void showLocation(Message message) { for (Intent intent : GeoHelper.createGeoIntentsFromMessage(activity, message)) { if (intent.resolveActivity(getContext().getPackageManager()) != null) { diff --git a/src/main/res/layout/activity_media_viewer.xml b/src/main/res/layout/activity_media_viewer.xml new file mode 100644 index 000000000..9fa601ed4 --- /dev/null +++ b/src/main/res/layout/activity_media_viewer.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + +