Fix several Gif MP4 UX issues.
This commit is contained in:
parent
2029ea378f
commit
335ff61011
11 changed files with 75 additions and 50 deletions
|
@ -103,6 +103,7 @@ public final class MediaPreviewActivity extends PassphraseRequiredActivity
|
|||
public static final String HIDE_ALL_MEDIA_EXTRA = "came_from_all_media";
|
||||
public static final String SHOW_THREAD_EXTRA = "show_thread";
|
||||
public static final String SORTING_EXTRA = "sorting";
|
||||
public static final String IS_VIDEO_GIF = "is_video_gif";
|
||||
|
||||
private ViewPager mediaPager;
|
||||
private View detailsContainer;
|
||||
|
@ -115,6 +116,7 @@ public final class MediaPreviewActivity extends PassphraseRequiredActivity
|
|||
private String initialMediaType;
|
||||
private long initialMediaSize;
|
||||
private String initialCaption;
|
||||
private boolean initialMediaIsVideoGif;
|
||||
private boolean leftIsRecent;
|
||||
private MediaPreviewViewModel viewModel;
|
||||
private ViewPagerListener viewPagerListener;
|
||||
|
@ -139,6 +141,7 @@ public final class MediaPreviewActivity extends PassphraseRequiredActivity
|
|||
intent.putExtra(MediaPreviewActivity.SIZE_EXTRA, attachment.getSize());
|
||||
intent.putExtra(MediaPreviewActivity.CAPTION_EXTRA, attachment.getCaption());
|
||||
intent.putExtra(MediaPreviewActivity.LEFT_IS_RECENT_EXTRA, leftIsRecent);
|
||||
intent.putExtra(MediaPreviewActivity.IS_VIDEO_GIF, attachment.isVideoGif());
|
||||
intent.setDataAndType(attachment.getUri(), mediaRecord.getContentType());
|
||||
return intent;
|
||||
}
|
||||
|
@ -296,12 +299,13 @@ public final class MediaPreviewActivity extends PassphraseRequiredActivity
|
|||
showThread = intent.getBooleanExtra(SHOW_THREAD_EXTRA, false);
|
||||
sorting = MediaDatabase.Sorting.values()[intent.getIntExtra(SORTING_EXTRA, 0)];
|
||||
|
||||
initialMediaUri = intent.getData();
|
||||
initialMediaType = intent.getType();
|
||||
initialMediaSize = intent.getLongExtra(SIZE_EXTRA, 0);
|
||||
initialCaption = intent.getStringExtra(CAPTION_EXTRA);
|
||||
leftIsRecent = intent.getBooleanExtra(LEFT_IS_RECENT_EXTRA, false);
|
||||
restartItem = -1;
|
||||
initialMediaUri = intent.getData();
|
||||
initialMediaType = intent.getType();
|
||||
initialMediaSize = intent.getLongExtra(SIZE_EXTRA, 0);
|
||||
initialCaption = intent.getStringExtra(CAPTION_EXTRA);
|
||||
leftIsRecent = intent.getBooleanExtra(LEFT_IS_RECENT_EXTRA, false);
|
||||
initialMediaIsVideoGif = intent.getBooleanExtra(IS_VIDEO_GIF, false);
|
||||
restartItem = -1;
|
||||
}
|
||||
|
||||
private void initializeObservers() {
|
||||
|
@ -354,7 +358,7 @@ public final class MediaPreviewActivity extends PassphraseRequiredActivity
|
|||
if (isMediaInDb()) {
|
||||
LoaderManager.getInstance(this).restartLoader(0, null, this);
|
||||
} else {
|
||||
mediaPager.setAdapter(new SingleItemPagerAdapter(getSupportFragmentManager(), initialMediaUri, initialMediaType, initialMediaSize));
|
||||
mediaPager.setAdapter(new SingleItemPagerAdapter(getSupportFragmentManager(), initialMediaUri, initialMediaType, initialMediaSize, initialMediaIsVideoGif));
|
||||
|
||||
if (initialCaption != null) {
|
||||
detailsContainer.setVisibility(View.VISIBLE);
|
||||
|
@ -632,21 +636,24 @@ public final class MediaPreviewActivity extends PassphraseRequiredActivity
|
|||
|
||||
private static class SingleItemPagerAdapter extends FragmentStatePagerAdapter implements MediaItemAdapter {
|
||||
|
||||
private final Uri uri;
|
||||
private final String mediaType;
|
||||
private final long size;
|
||||
private final Uri uri;
|
||||
private final String mediaType;
|
||||
private final long size;
|
||||
private final boolean isVideoGif;
|
||||
|
||||
private MediaPreviewFragment mediaPreviewFragment;
|
||||
|
||||
SingleItemPagerAdapter(@NonNull FragmentManager fragmentManager,
|
||||
@NonNull Uri uri,
|
||||
@NonNull String mediaType,
|
||||
long size)
|
||||
long size,
|
||||
boolean isVideoGif)
|
||||
{
|
||||
super(fragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
|
||||
this.uri = uri;
|
||||
this.mediaType = mediaType;
|
||||
this.size = size;
|
||||
this.uri = uri;
|
||||
this.mediaType = mediaType;
|
||||
this.size = size;
|
||||
this.isVideoGif = isVideoGif;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -657,7 +664,7 @@ public final class MediaPreviewActivity extends PassphraseRequiredActivity
|
|||
@NonNull
|
||||
@Override
|
||||
public Fragment getItem(int position) {
|
||||
mediaPreviewFragment = MediaPreviewFragment.newInstance(uri, mediaType, size, true);
|
||||
mediaPreviewFragment = MediaPreviewFragment.newInstance(uri, mediaType, size, true, isVideoGif);
|
||||
return mediaPreviewFragment;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ import org.signal.core.util.logging.Log;
|
|||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.blurhash.BlurHash;
|
||||
import org.thoughtcrime.securesms.database.AttachmentDatabase;
|
||||
import org.thoughtcrime.securesms.giph.mp4.GiphyMp4PlaybackPolicy;
|
||||
import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader.DecryptableUri;
|
||||
import org.thoughtcrime.securesms.mms.GlideRequest;
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||
|
@ -61,7 +62,6 @@ public class ThumbnailView extends FrameLayout {
|
|||
private ImageView blurhash;
|
||||
private View playOverlay;
|
||||
private View captionIcon;
|
||||
private Stub<VideoPlayer> videoPlayer;
|
||||
private OnClickListener parentClickListener;
|
||||
|
||||
private final int[] dimens = new int[2];
|
||||
|
@ -93,7 +93,6 @@ public class ThumbnailView extends FrameLayout {
|
|||
this.blurhash = findViewById(R.id.thumbnail_blurhash);
|
||||
this.playOverlay = findViewById(R.id.play_overlay);
|
||||
this.captionIcon = findViewById(R.id.thumbnail_caption_icon);
|
||||
this.videoPlayer = new Stub<>(findViewById(R.id.thumbnail_player_stub));
|
||||
super.setOnClickListener(new ThumbnailClickDispatcher());
|
||||
|
||||
if (attrs != null) {
|
||||
|
|
|
@ -1734,6 +1734,7 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
|
|||
intent.putExtra(MediaPreviewActivity.DATE_EXTRA, messageRecord.getTimestamp());
|
||||
intent.putExtra(MediaPreviewActivity.SIZE_EXTRA, slide.asAttachment().getSize());
|
||||
intent.putExtra(MediaPreviewActivity.CAPTION_EXTRA, slide.getCaption().orNull());
|
||||
intent.putExtra(MediaPreviewActivity.IS_VIDEO_GIF, slide.isVideoGif());
|
||||
intent.putExtra(MediaPreviewActivity.LEFT_IS_RECENT_EXTRA, false);
|
||||
|
||||
context.startActivity(intent);
|
||||
|
|
|
@ -236,6 +236,7 @@ public final class MediaOverviewPageFragment extends Fragment
|
|||
intent.putExtra(MediaPreviewActivity.HIDE_ALL_MEDIA_EXTRA, true);
|
||||
intent.putExtra(MediaPreviewActivity.SHOW_THREAD_EXTRA, threadId == MediaDatabase.ALL_THREADS);
|
||||
intent.putExtra(MediaPreviewActivity.SORTING_EXTRA, sorting.ordinal());
|
||||
intent.putExtra(MediaPreviewActivity.IS_VIDEO_GIF, attachment.isVideoGif());
|
||||
|
||||
intent.setDataAndType(mediaRecord.getAttachment().getUri(), mediaRecord.getContentType());
|
||||
context.startActivity(intent);
|
||||
|
|
|
@ -24,21 +24,23 @@ public abstract class MediaPreviewFragment extends Fragment {
|
|||
static final String DATA_SIZE = "DATA_SIZE";
|
||||
static final String DATA_CONTENT_TYPE = "DATA_CONTENT_TYPE";
|
||||
static final String AUTO_PLAY = "AUTO_PLAY";
|
||||
static final String VIDEO_GIF = "VIDEO_GIF";
|
||||
|
||||
private AttachmentId attachmentId;
|
||||
protected Events events;
|
||||
|
||||
public static MediaPreviewFragment newInstance(@NonNull Attachment attachment, boolean autoPlay) {
|
||||
return newInstance(attachment.getUri(), attachment.getContentType(), attachment.getSize(), autoPlay);
|
||||
return newInstance(attachment.getUri(), attachment.getContentType(), attachment.getSize(), autoPlay, attachment.isVideoGif());
|
||||
}
|
||||
|
||||
public static MediaPreviewFragment newInstance(@NonNull Uri dataUri, @NonNull String contentType, long size, boolean autoPlay) {
|
||||
public static MediaPreviewFragment newInstance(@NonNull Uri dataUri, @NonNull String contentType, long size, boolean autoPlay, boolean isVideoGif) {
|
||||
Bundle args = new Bundle();
|
||||
|
||||
args.putParcelable(MediaPreviewFragment.DATA_URI, dataUri);
|
||||
args.putString(MediaPreviewFragment.DATA_CONTENT_TYPE, contentType);
|
||||
args.putLong(MediaPreviewFragment.DATA_SIZE, size);
|
||||
args.putBoolean(MediaPreviewFragment.AUTO_PLAY, autoPlay);
|
||||
args.putBoolean(MediaPreviewFragment.VIDEO_GIF, isVideoGif);
|
||||
|
||||
MediaPreviewFragment fragment = createCorrectFragmentType(contentType);
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ public final class VideoMediaPreviewFragment extends MediaPreviewFragment {
|
|||
private static final String TAG = Log.tag(VideoMediaPreviewFragment.class);
|
||||
|
||||
private VideoPlayer videoView;
|
||||
private boolean isVideoGif;
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
|
@ -35,6 +36,8 @@ public final class VideoMediaPreviewFragment extends MediaPreviewFragment {
|
|||
long size = arguments.getLong(DATA_SIZE);
|
||||
boolean autoPlay = arguments.getBoolean(AUTO_PLAY);
|
||||
|
||||
isVideoGif = arguments.getBoolean(VIDEO_GIF);
|
||||
|
||||
if (!MediaUtil.isVideo(contentType)) {
|
||||
throw new AssertionError("This fragment can only display video");
|
||||
}
|
||||
|
@ -44,6 +47,11 @@ public final class VideoMediaPreviewFragment extends MediaPreviewFragment {
|
|||
videoView.setWindow(requireActivity().getWindow());
|
||||
videoView.setVideoSource(new VideoSlide(getContext(), uri, size, false), autoPlay);
|
||||
|
||||
if (isVideoGif) {
|
||||
videoView.hideControls();
|
||||
videoView.loopForever();
|
||||
}
|
||||
|
||||
videoView.setOnClickListener(v -> events.singleTapOnMedia());
|
||||
|
||||
return itemView;
|
||||
|
@ -56,6 +64,14 @@ public final class VideoMediaPreviewFragment extends MediaPreviewFragment {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
if (videoView != null && isVideoGif) {
|
||||
videoView.play();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pause() {
|
||||
if (videoView != null) {
|
||||
|
@ -65,6 +81,6 @@ public final class VideoMediaPreviewFragment extends MediaPreviewFragment {
|
|||
|
||||
@Override
|
||||
public View getPlaybackControls() {
|
||||
return videoView != null ? videoView.getControlView() : null;
|
||||
return videoView != null && !isVideoGif ? videoView.getControlView() : null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ class MediaSendFragmentPagerAdapter extends FragmentStatePagerAdapter {
|
|||
private final MediaConstraints mediaConstraints;
|
||||
|
||||
MediaSendFragmentPagerAdapter(@NonNull FragmentManager fm, @NonNull MediaConstraints mediaConstraints) {
|
||||
super(fm);
|
||||
super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
|
||||
this.mediaConstraints = mediaConstraints;
|
||||
this.media = new ArrayList<>();
|
||||
this.fragments = new HashMap<>();
|
||||
|
@ -48,7 +48,8 @@ class MediaSendFragmentPagerAdapter extends FragmentStatePagerAdapter {
|
|||
} else if (MediaUtil.isVideoType(mediaItem.getMimeType())) {
|
||||
return MediaSendVideoFragment.newInstance(mediaItem.getUri(),
|
||||
mediaConstraints.getCompressedVideoMaxSize(ApplicationDependencies.getApplication()),
|
||||
mediaConstraints.getVideoMaxSize(ApplicationDependencies.getApplication()));
|
||||
mediaConstraints.getVideoMaxSize(ApplicationDependencies.getApplication()),
|
||||
mediaItem.isVideoGif());
|
||||
} else {
|
||||
throw new UnsupportedOperationException("Can only render images and videos. Found mimetype: '" + mediaItem.getMimeType() + "'");
|
||||
}
|
||||
|
|
|
@ -30,9 +30,10 @@ public class MediaSendVideoFragment extends Fragment implements VideoEditorHud.E
|
|||
|
||||
private static final String TAG = Log.tag(MediaSendVideoFragment.class);
|
||||
|
||||
private static final String KEY_URI = "uri";
|
||||
private static final String KEY_MAX_OUTPUT = "max_output_size";
|
||||
private static final String KEY_MAX_SEND = "max_send_size";
|
||||
private static final String KEY_URI = "uri";
|
||||
private static final String KEY_MAX_OUTPUT = "max_output_size";
|
||||
private static final String KEY_MAX_SEND = "max_send_size";
|
||||
private static final String KEY_IS_VIDEO_GIF = "is_video_gif";
|
||||
|
||||
private final Throttler videoScanThrottle = new Throttler(150);
|
||||
private final Handler handler = new Handler(Looper.getMainLooper());
|
||||
|
@ -40,15 +41,17 @@ public class MediaSendVideoFragment extends Fragment implements VideoEditorHud.E
|
|||
private Controller controller;
|
||||
private Data data = new Data();
|
||||
private Uri uri;
|
||||
private boolean isVideoGif;
|
||||
private VideoPlayer player;
|
||||
@Nullable private VideoEditorHud hud;
|
||||
private Runnable updatePosition;
|
||||
|
||||
public static MediaSendVideoFragment newInstance(@NonNull Uri uri, long maxCompressedVideoSize, long maxAttachmentSize) {
|
||||
public static MediaSendVideoFragment newInstance(@NonNull Uri uri, long maxCompressedVideoSize, long maxAttachmentSize, boolean isVideoGif) {
|
||||
Bundle args = new Bundle();
|
||||
args.putParcelable(KEY_URI, uri);
|
||||
args.putLong(KEY_MAX_OUTPUT, maxCompressedVideoSize);
|
||||
args.putLong(KEY_MAX_SEND, maxAttachmentSize);
|
||||
args.putBoolean(KEY_IS_VIDEO_GIF, isVideoGif);
|
||||
|
||||
MediaSendVideoFragment fragment = new MediaSendVideoFragment();
|
||||
fragment.setArguments(args);
|
||||
|
@ -76,15 +79,20 @@ public class MediaSendVideoFragment extends Fragment implements VideoEditorHud.E
|
|||
|
||||
player = view.findViewById(R.id.video_player);
|
||||
|
||||
uri = requireArguments().getParcelable(KEY_URI);
|
||||
long maxOutput = requireArguments().getLong(KEY_MAX_OUTPUT);
|
||||
long maxSend = requireArguments().getLong(KEY_MAX_SEND);
|
||||
VideoSlide slide = new VideoSlide(requireContext(), uri, 0, false);
|
||||
uri = requireArguments().getParcelable(KEY_URI);
|
||||
isVideoGif = requireArguments().getBoolean(KEY_IS_VIDEO_GIF);
|
||||
|
||||
long maxOutput = requireArguments().getLong(KEY_MAX_OUTPUT);
|
||||
long maxSend = requireArguments().getLong(KEY_MAX_SEND);
|
||||
VideoSlide slide = new VideoSlide(requireContext(), uri, 0, isVideoGif);
|
||||
|
||||
player.setWindow(requireActivity().getWindow());
|
||||
player.setVideoSource(slide, true);
|
||||
|
||||
if (MediaConstraints.isVideoTranscodeAvailable()) {
|
||||
if (slide.isVideoGif()) {
|
||||
player.hideControls();
|
||||
player.loopForever();
|
||||
} else if (MediaConstraints.isVideoTranscodeAvailable()) {
|
||||
hud = view.findViewById(R.id.video_editor_hud);
|
||||
hud.setEventListener(this);
|
||||
updateHud(data);
|
||||
|
@ -140,6 +148,10 @@ public class MediaSendVideoFragment extends Fragment implements VideoEditorHud.E
|
|||
public void onResume() {
|
||||
super.onResume();
|
||||
startPositionUpdates();
|
||||
|
||||
if (player != null && isVideoGif) {
|
||||
player.play();
|
||||
}
|
||||
}
|
||||
|
||||
private void startPositionUpdates() {
|
||||
|
@ -180,8 +192,9 @@ public class MediaSendVideoFragment extends Fragment implements VideoEditorHud.E
|
|||
@Override
|
||||
public @Nullable View getPlaybackControls() {
|
||||
if (hud != null && hud.getVisibility() == View.VISIBLE) return null;
|
||||
|
||||
return player != null ? player.getControlView() : null;
|
||||
else if (isVideoGif) return null;
|
||||
else if (player != null) return player.getControlView();
|
||||
else return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -27,6 +27,7 @@ import androidx.annotation.Nullable;
|
|||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.attachments.Attachment;
|
||||
import org.thoughtcrime.securesms.database.AttachmentDatabase;
|
||||
import org.thoughtcrime.securesms.giph.mp4.GiphyMp4PlaybackPolicy;
|
||||
import org.thoughtcrime.securesms.util.MediaUtil;
|
||||
|
||||
public class VideoSlide extends Slide {
|
||||
|
@ -54,7 +55,7 @@ public class VideoSlide extends Slide {
|
|||
|
||||
@Override
|
||||
public boolean hasPlayOverlay() {
|
||||
return true;
|
||||
return !(isVideoGif() && GiphyMp4PlaybackPolicy.autoplay());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<org.thoughtcrime.securesms.video.VideoPlayer xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clickable="false"
|
||||
android:contentDescription="@string/conversation_item__mms_image_description"
|
||||
android:longClickable="false" />
|
|
@ -24,15 +24,6 @@
|
|||
android:scaleType="fitCenter"
|
||||
android:contentDescription="@string/conversation_item__mms_image_description" />
|
||||
|
||||
<ViewStub
|
||||
android:id="@+id/thumbnail_player_stub"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clickable="false"
|
||||
android:inflatedId="@id/thumbnail_player_stub"
|
||||
android:layout="@layout/thumbnail_player_stub"
|
||||
android:longClickable="false" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/thumbnail_caption_icon"
|
||||
android:layout_width="wrap_content"
|
||||
|
|
Loading…
Add table
Reference in a new issue