Skip to content
This repository has been archived by the owner on Apr 12, 2022. It is now read-only.

Commit

Permalink
Add basic functionality for image previewing
Browse files Browse the repository at this point in the history
Add RecyclerView to MediasPreviewerActivity

Add Toolbar to MediasPreviewerActivity

Improve the layout of MediasPreviewerActivity

Add support for videos and gifs

Also changed the name of ImagePreviewAdapter to a more general name,
namely: MediasPreviewAdapter

Add general case for unsupported filetypes

Remove the border around the CardView

Properly handle camera URI

Make the previewer optional

Update code to most recent develop

Fix lint error

Remove forbidden patterns

Describe changes of PR and sign off

Signed-off-by: Nathan van Beelen <nathan at vanbeelen dot org>

Replace tab indentation with spaces

Remove forbidden pattern

Improve the code

Rename the Activity and Adapter

Also correct an incorrect reference to the ItemPositionChangeListener method.

Show filename for all files

Rename the layout file of the media previewer

Properly resize content in the WebView

Improve the code further

Add and update comments

Further improve the code
  • Loading branch information
nvbln committed Jul 17, 2018
1 parent 0f9b78a commit eb17636
Show file tree
Hide file tree
Showing 14 changed files with 484 additions and 9 deletions.
3 changes: 3 additions & 0 deletions AUTHORS.rst
Expand Up @@ -42,3 +42,6 @@ Safa AlFulaij <safa1996alfulaij at gmail.com>

Isa Cichon <isa4 at posteo.net>
* Add spacing to device keys

Nathan van Beelen <nathan at vanbeelen.org>
* PR #1742: Add a media previewer
1 change: 1 addition & 0 deletions CHANGES.rst
Expand Up @@ -3,6 +3,7 @@ Changes in Riot 0.8.13 (2018-XX-XX)

Features:
- Resurrect performance metrics (#2391)
- Add a previewer for previewing media before sending it into the room (#1742)

Improvements:
- Piwik: Update the way how stats are reported (#2402)
Expand Down
5 changes: 5 additions & 0 deletions vector/src/main/AndroidManifest.xml
Expand Up @@ -388,6 +388,11 @@
android:name=".activity.SimpleWebViewActivity"
android:theme="@style/AppTheme.NoActionBar" />

<activity
android:name="im.vector.activity.MediaPreviewerActivity"
android:configChanges="orientation|screenSize"
android:theme="@style/AppTheme.NoActionBar" />

<!-- broadcast receiver -->
<receiver
android:name=".receiver.VectorUniversalLinkReceiver"
Expand Down
213 changes: 213 additions & 0 deletions vector/src/main/java/im/vector/activity/MediaPreviewerActivity.java
@@ -0,0 +1,213 @@
package im.vector.activity;

import android.net.Uri;
import android.os.Build;
import android.app.Activity;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.webkit.WebView;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.VideoView;

import org.jetbrains.annotations.NotNull;
import org.matrix.androidsdk.data.RoomMediaMessage;
import org.matrix.androidsdk.util.Log;

import java.util.ArrayList;
import java.util.List;

import butterknife.BindView;
import butterknife.OnClick;
import im.vector.R;
import im.vector.adapters.MediaPreviewAdapter;
import im.vector.listeners.ItemPositionChangedListener;
import kotlin.Pair;

/**
* Previews media selected to be send.
*/
public class MediaPreviewerActivity extends MXCActionBarActivity implements ItemPositionChangedListener {

/**
* the picture uri if a picture is taken with the camera
*/
public static final String EXTRA_CAMERA_PICTURE_URI = "EXTRA_CAMERA_PICTURE_URI";
/**
* the room title (string)
*/
public static final String EXTRA_ROOM_TITLE = "EXTRA_ROOM_TITLE";

private static final String LOG_TAG = MediaPreviewerActivity.class.getSimpleName();

@BindView(R.id.images_preview)
RecyclerView mImagesPreview;

@BindView(R.id.image_previewer)
ImageView mImagePreview;

@BindView(R.id.web_previewer)
WebView mWebPreview;

@BindView(R.id.video_previewer)
VideoView mVideoPreview;

@BindView(R.id.file_previewer)
ImageView mFilePreview;

@BindView(R.id.file_name)
TextView mFileNameView;

private RoomMediaMessage mCurrentRoomMediaMessage;

List<RoomMediaMessage> mSharedDataItems;

@NotNull
@Override
public Pair getOtherThemes() {
return new Pair(R.style.AppTheme_NoActionBar_Dark, R.style.AppTheme_NoActionBar_Black);
}

@Override
public int getLayoutRes() {
return R.layout.activity_media_previewer;
}

@Override
public void onItemPositionChangedListener(int position) {
setPreview(mSharedDataItems.get(position));
}

@Override
public void initUiAndData() {

if (CommonActivityUtils.shouldRestartApp(this)) {
Log.d(LOG_TAG, "onCreate : restart the application");
CommonActivityUtils.restartApp(this);
return;
}

if (CommonActivityUtils.isGoingToSplash(this)) {
Log.d(LOG_TAG, "onCreate : Going to splash screen");
return;
}

configureToolbar();

String roomTitle = (String) getIntent().getExtras().get(EXTRA_ROOM_TITLE);
if (!TextUtils.isEmpty(roomTitle)) {
getSupportActionBar().setTitle(roomTitle);
}

setStatusBarColor(findViewById(R.id.status_bar_background),
ContextCompat.getColor(this, R.color.transparent_dark));

// Resize web content to prevent scrollbars.
mWebPreview.getSettings().setUseWideViewPort(true);
mWebPreview.getSettings().setLoadWithOverviewMode(true);

mSharedDataItems = new ArrayList<>(RoomMediaMessage.listRoomMediaMessages(getIntent(), RoomMediaMessage.class.getClassLoader()));

if (mSharedDataItems.isEmpty()) {
mSharedDataItems.add(new RoomMediaMessage(Uri.parse(getIntent().getStringExtra(EXTRA_CAMERA_PICTURE_URI))));
}

if (!mSharedDataItems.isEmpty()) {
LinearLayoutManager imagesPreviewLinearLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
mImagesPreview.setLayoutManager(imagesPreviewLinearLayoutManager);

MediaPreviewAdapter mediaPreviewAdapter = new MediaPreviewAdapter(mSharedDataItems, this);
mImagesPreview.setAdapter(mediaPreviewAdapter);

setPreview(mSharedDataItems.get(0));
}
}

@OnClick(R.id.send_floating_action_button)
public void onClick() {
setResult(Activity.RESULT_OK, getIntent());
finish();
}

private void setPreview(RoomMediaMessage roomMediaMessage) {

// Prevent blinking when tapping on the same item multiple times.
if (roomMediaMessage != mCurrentRoomMediaMessage) {
mCurrentRoomMediaMessage = roomMediaMessage;

mWebPreview.setVisibility(View.GONE);
mImagePreview.setVisibility(View.GONE);
mVideoPreview.setVisibility(View.GONE);
mFilePreview.setVisibility(View.GONE);
mFileNameView.setVisibility(View.GONE);

String mimeType = roomMediaMessage.getMimeType(this);
Uri uri = roomMediaMessage.getUri();

if (mimeType != null) {
if (mimeType.startsWith("image")) {
if (mimeType.endsWith("gif")) {
mWebPreview.loadUrl(uri.toString());
mWebPreview.setVisibility(View.VISIBLE);
} else {
mImagePreview.setImageURI(uri);
mImagePreview.setVisibility(View.VISIBLE);
}
} else if (mimeType.startsWith("video")) {
mVideoPreview.setVideoURI(uri);
mVideoPreview.seekTo(100);
mVideoPreview.setVisibility(View.VISIBLE);

// Pause/play video on click.
mVideoPreview.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if (!mVideoPreview.isPlaying()) {
mVideoPreview.start();
} else {
mVideoPreview.pause();
}
return false;
}
});
} else {
// As other files can't be previewed, show a generic file image.
mFilePreview.setVisibility(View.VISIBLE);
}

mFileNameView.setText(roomMediaMessage.getFileName(this));
mFileNameView.setVisibility(View.VISIBLE);
}
}
}


private void setStatusBarColor(View statusBar, int color) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Window window = getWindow();
window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,
WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);

int statusBarHeight = getStatusBarHeight();

statusBar.getLayoutParams().height = statusBarHeight;
statusBar.setBackgroundColor(color);
}
}

private int getStatusBarHeight() {
int result = 0;
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
result = getResources().getDimensionPixelSize(resourceId);
}

return result;
}
}
40 changes: 31 additions & 9 deletions vector/src/main/java/im/vector/activity/VectorRoomActivity.java
Expand Up @@ -205,6 +205,8 @@ public class VectorRoomActivity extends MXCActionBarActivity implements
private static final String CAMERA_VALUE_TITLE = "attachment"; // Samsung devices need a filepath to write to or else won't return a Uri (!!!)
private String mLatestTakePictureCameraUri = null; // has to be String not Uri because of Serializable

public static final int CONFIRM_MEDIA_REQUEST_CODE = 7;

private VectorMessageListFragment mVectorMessageListFragment;
private MXSession mSession;

Expand Down Expand Up @@ -1422,6 +1424,14 @@ protected void onActivityResult(int requestCode, int resultCode, final Intent da
case UNREAD_PREVIEW_REQUEST_CODE:
mVectorMessageListFragment.scrollToBottom(0);
break;
case CONFIRM_MEDIA_REQUEST_CODE:
List<RoomMediaMessage> sharedDataItems =
new ArrayList<>(RoomMediaMessage.listRoomMediaMessages(data, RoomMediaMessage.class.getClassLoader()));
if (0 == sharedDataItems.size()) {
sharedDataItems.add(new RoomMediaMessage(Uri.parse(data.getStringExtra(MediaPreviewerActivity.EXTRA_CAMERA_PICTURE_URI))));
}
mVectorRoomMediasSender.sendMedias(sharedDataItems);
break;
}
}
}
Expand Down Expand Up @@ -2020,7 +2030,7 @@ public void sendEmote(String emote, String formattedEmote, String format) {
* They are listed, checked and sent when it is possible.
*/
@SuppressLint("NewApi")
private void sendMediasIntent(final Intent intent) {
private void sendMediasIntent(Intent intent) {
// sanity check
if ((null == intent) && (null == mLatestTakePictureCameraUri)) {
return;
Expand All @@ -2032,13 +2042,6 @@ private void sendMediasIntent(final Intent intent) {
sharedDataItems = new ArrayList<>(RoomMediaMessage.listRoomMediaMessages(intent, RoomMediaMessage.class.getClassLoader()));
}

if (null != mLatestTakePictureCameraUri) {
if (0 == sharedDataItems.size()) {
sharedDataItems.add(new RoomMediaMessage(Uri.parse(mLatestTakePictureCameraUri)));
}
mLatestTakePictureCameraUri = null;
}

// check the extras
if ((0 == sharedDataItems.size()) && (null != intent)) {
Bundle bundle = intent.getExtras();
Expand All @@ -2058,9 +2061,28 @@ public void run() {
}
}

if (0 != sharedDataItems.size()) {
if (PreferencesManager.previewMediaWhenSending(this)) {
if (null != intent) {
intent.setClass(this, MediaPreviewerActivity.class);
} else {
intent = new Intent(this, MediaPreviewerActivity.class);
}

intent.putExtra(MediaPreviewerActivity.EXTRA_ROOM_TITLE, VectorUtils.getRoomDisplayName(this, mSession, mRoom));
if (null != mLatestTakePictureCameraUri) {
intent.putExtra(MediaPreviewerActivity.EXTRA_CAMERA_PICTURE_URI, mLatestTakePictureCameraUri);
}
startActivityForResult(intent, CONFIRM_MEDIA_REQUEST_CODE);
} else {
if (null != mLatestTakePictureCameraUri) {
if (0 == sharedDataItems.size()) {
sharedDataItems.add(new RoomMediaMessage(Uri.parse(mLatestTakePictureCameraUri)));
}
}
mVectorRoomMediasSender.sendMedias(sharedDataItems);
}

mLatestTakePictureCameraUri = null;
}

/**
Expand Down

0 comments on commit eb17636

Please sign in to comment.