kopia lustrzana https://github.com/ryukoposting/Signal-Android
Media Preview V2 Visual Redesign
rodzic
6c0b63d72c
commit
469cab284e
|
@ -24,7 +24,6 @@ import android.content.Intent;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.os.Build;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuInflater;
|
import android.view.MenuInflater;
|
||||||
|
@ -490,17 +489,8 @@ public final class MediaPreviewActivity extends PassphraseRequiredActivity
|
||||||
@Override
|
@Override
|
||||||
public boolean onPrepareOptionsMenu(Menu menu) {
|
public boolean onPrepareOptionsMenu(Menu menu) {
|
||||||
if (!isMediaInDb()) {
|
if (!isMediaInDb()) {
|
||||||
menu.findItem(R.id.media_preview__overview).setVisible(false);
|
|
||||||
menu.findItem(R.id.delete).setVisible(false);
|
menu.findItem(R.id.delete).setVisible(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restricted to API26 because of MemoryFileUtil not supporting lower API levels well
|
|
||||||
menu.findItem(R.id.media_preview__share).setVisible(Build.VERSION.SDK_INT >= 26);
|
|
||||||
|
|
||||||
if (cameFromAllMedia) {
|
|
||||||
menu.findItem(R.id.media_preview__overview).setVisible(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
super.onPrepareOptionsMenu(menu);
|
super.onPrepareOptionsMenu(menu);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -511,9 +501,6 @@ public final class MediaPreviewActivity extends PassphraseRequiredActivity
|
||||||
|
|
||||||
int itemId = item.getItemId();
|
int itemId = item.getItemId();
|
||||||
|
|
||||||
if (itemId == R.id.media_preview__overview) { showOverview(); return true; }
|
|
||||||
if (itemId == R.id.media_preview__forward) { forward(); return true; }
|
|
||||||
if (itemId == R.id.media_preview__share) { share(); return true; }
|
|
||||||
if (itemId == R.id.save) { saveToDisk(); return true; }
|
if (itemId == R.id.save) { saveToDisk(); return true; }
|
||||||
if (itemId == R.id.delete) { deleteMedia(); return true; }
|
if (itemId == R.id.delete) { deleteMedia(); return true; }
|
||||||
if (itemId == android.R.id.home) { finish(); return true; }
|
if (itemId == android.R.id.home) { finish(); return true; }
|
||||||
|
@ -701,7 +688,7 @@ public final class MediaPreviewActivity extends PassphraseRequiredActivity
|
||||||
@Override
|
@Override
|
||||||
public @Nullable View getPlaybackControls(int position) {
|
public @Nullable View getPlaybackControls(int position) {
|
||||||
if (mediaPreviewFragment != null) {
|
if (mediaPreviewFragment != null) {
|
||||||
return mediaPreviewFragment.getPlaybackControls();
|
return mediaPreviewFragment.getBottomBarControls();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -831,7 +818,7 @@ public final class MediaPreviewActivity extends PassphraseRequiredActivity
|
||||||
@Override
|
@Override
|
||||||
public @Nullable View getPlaybackControls(int position) {
|
public @Nullable View getPlaybackControls(int position) {
|
||||||
MediaPreviewFragment mediaView = mediaFragments.get(position);
|
MediaPreviewFragment mediaView = mediaFragments.get(position);
|
||||||
if (mediaView != null) return mediaView.getPlaybackControls();
|
if (mediaView != null) return mediaView.getBottomBarControls();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ import android.os.Bundle;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.ImageButton;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
@ -15,6 +16,7 @@ import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||||
import org.thoughtcrime.securesms.util.MediaUtil;
|
import org.thoughtcrime.securesms.util.MediaUtil;
|
||||||
|
|
||||||
public final class ImageMediaPreviewFragment extends MediaPreviewFragment {
|
public final class ImageMediaPreviewFragment extends MediaPreviewFragment {
|
||||||
|
private View bottomBarControlView;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
|
@ -39,6 +41,26 @@ public final class ImageMediaPreviewFragment extends MediaPreviewFragment {
|
||||||
|
|
||||||
zoomingImageView.setOnClickListener(v -> events.singleTapOnMedia());
|
zoomingImageView.setOnClickListener(v -> events.singleTapOnMedia());
|
||||||
|
|
||||||
|
bottomBarControlView = getLayoutInflater().inflate(R.layout.image_media_preview_bottom_bar, null);
|
||||||
return zoomingImageView;
|
return zoomingImageView;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setShareButtonListener(View.OnClickListener listener) {
|
||||||
|
ImageButton forwardButton = bottomBarControlView.findViewById(R.id.image_preview_forward);
|
||||||
|
forwardButton.setOnClickListener(listener);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setForwardButtonListener(View.OnClickListener listener) {
|
||||||
|
ImageButton shareButton = bottomBarControlView.findViewById(R.id.image_preview_share);
|
||||||
|
shareButton.setOnClickListener(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public View getBottomBarControls() {
|
||||||
|
return bottomBarControlView;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,9 +87,9 @@ public abstract class MediaPreviewFragment extends Fragment {
|
||||||
public void pause() {
|
public void pause() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public @Nullable PlayerControlView getPlaybackControls() {
|
abstract public void setShareButtonListener(View.OnClickListener listener);
|
||||||
return null;
|
abstract public void setForwardButtonListener(View.OnClickListener listener);
|
||||||
}
|
abstract public @Nullable View getBottomBarControls();
|
||||||
|
|
||||||
private void checkMediaStillAvailable() {
|
private void checkMediaStillAvailable() {
|
||||||
if (attachmentId == null) {
|
if (attachmentId == null) {
|
||||||
|
|
|
@ -7,6 +7,7 @@ import android.content.DialogInterface
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
@ -20,7 +21,6 @@ import androidx.fragment.app.viewModels
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.viewpager2.widget.ViewPager2.OFFSCREEN_PAGE_LIMIT_DEFAULT
|
import androidx.viewpager2.widget.ViewPager2.OFFSCREEN_PAGE_LIMIT_DEFAULT
|
||||||
import androidx.viewpager2.widget.ViewPager2.OnPageChangeCallback
|
import androidx.viewpager2.widget.ViewPager2.OnPageChangeCallback
|
||||||
import com.google.android.exoplayer2.ui.PlayerControlView
|
|
||||||
import com.google.android.material.appbar.MaterialToolbar
|
import com.google.android.material.appbar.MaterialToolbar
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import com.google.android.material.snackbar.Snackbar
|
import com.google.android.material.snackbar.Snackbar
|
||||||
|
@ -35,7 +35,6 @@ import org.thoughtcrime.securesms.conversation.mutiselect.forward.MultiselectFor
|
||||||
import org.thoughtcrime.securesms.conversation.mutiselect.forward.MultiselectForwardFragmentArgs
|
import org.thoughtcrime.securesms.conversation.mutiselect.forward.MultiselectForwardFragmentArgs
|
||||||
import org.thoughtcrime.securesms.database.MediaDatabase
|
import org.thoughtcrime.securesms.database.MediaDatabase
|
||||||
import org.thoughtcrime.securesms.databinding.FragmentMediaPreviewV2Binding
|
import org.thoughtcrime.securesms.databinding.FragmentMediaPreviewV2Binding
|
||||||
import org.thoughtcrime.securesms.mediaoverview.MediaOverviewActivity
|
|
||||||
import org.thoughtcrime.securesms.mediasend.Media
|
import org.thoughtcrime.securesms.mediasend.Media
|
||||||
import org.thoughtcrime.securesms.mms.GlideApp
|
import org.thoughtcrime.securesms.mms.GlideApp
|
||||||
import org.thoughtcrime.securesms.mms.PartAuthority
|
import org.thoughtcrime.securesms.mms.PartAuthority
|
||||||
|
@ -64,13 +63,18 @@ class MediaPreviewV2Fragment : Fragment(R.layout.fragment_media_preview_v2), Med
|
||||||
fullscreenHelper = FullscreenHelper(requireActivity())
|
fullscreenHelper = FullscreenHelper(requireActivity())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||||
|
lifecycleDisposable.bindTo(viewLifecycleOwner)
|
||||||
|
return super.onCreateView(inflater, container, savedInstanceState)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
val args = MediaIntentFactory.requireArguments(requireArguments())
|
val args = MediaIntentFactory.requireArguments(requireArguments())
|
||||||
|
|
||||||
initializeViewModel(args)
|
initializeViewModel(args)
|
||||||
initializeToolbar(binding.toolbar, args)
|
initializeToolbar(binding.toolbar)
|
||||||
initializeViewPager()
|
initializeViewPager()
|
||||||
initializeFullScreenUi()
|
initializeFullScreenUi()
|
||||||
initializeAlbumRail()
|
initializeAlbumRail()
|
||||||
|
@ -96,19 +100,12 @@ class MediaPreviewV2Fragment : Fragment(R.layout.fragment_media_preview_v2), Med
|
||||||
viewModel.fetchAttachments(PartAuthority.requireAttachmentId(args.initialMediaUri), args.threadId, sorting)
|
viewModel.fetchAttachments(PartAuthority.requireAttachmentId(args.initialMediaUri), args.threadId, sorting)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initializeToolbar(toolbar: MaterialToolbar, args: MediaIntentFactory.MediaPreviewArgs) {
|
private fun initializeToolbar(toolbar: MaterialToolbar) {
|
||||||
toolbar.setNavigationOnClickListener {
|
toolbar.setNavigationOnClickListener {
|
||||||
requireActivity().onBackPressed()
|
requireActivity().onBackPressed()
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.toolbar.inflateMenu(R.menu.media_preview)
|
binding.toolbar.inflateMenu(R.menu.media_preview)
|
||||||
|
|
||||||
// Restricted to API26 because of MemoryFileUtil not supporting lower API levels well
|
|
||||||
binding.toolbar.menu.findItem(R.id.media_preview__share).isVisible = Build.VERSION.SDK_INT >= 26
|
|
||||||
|
|
||||||
if (args.hideAllMedia) {
|
|
||||||
binding.toolbar.menu.findItem(R.id.media_preview__overview).isVisible = false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initializeViewPager() {
|
private fun initializeViewPager() {
|
||||||
|
@ -175,15 +172,11 @@ class MediaPreviewV2Fragment : Fragment(R.layout.fragment_media_preview_v2), Med
|
||||||
|
|
||||||
val menu: Menu = binding.toolbar.menu
|
val menu: Menu = binding.toolbar.menu
|
||||||
if (currentItem.threadId == MediaIntentFactory.NOT_IN_A_THREAD.toLong()) {
|
if (currentItem.threadId == MediaIntentFactory.NOT_IN_A_THREAD.toLong()) {
|
||||||
menu.findItem(R.id.media_preview__overview).isVisible = false
|
|
||||||
menu.findItem(R.id.delete).isVisible = false
|
menu.findItem(R.id.delete).isVisible = false
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.toolbar.setOnMenuItemClickListener {
|
binding.toolbar.setOnMenuItemClickListener {
|
||||||
when (it.itemId) {
|
when (it.itemId) {
|
||||||
R.id.media_preview__overview -> showOverview(currentItem.threadId)
|
|
||||||
R.id.media_preview__forward -> forward(currentItem)
|
|
||||||
R.id.media_preview__share -> share(currentItem)
|
|
||||||
R.id.save -> saveToDisk(currentItem)
|
R.id.save -> saveToDisk(currentItem)
|
||||||
R.id.delete -> deleteMedia(currentItem)
|
R.id.delete -> deleteMedia(currentItem)
|
||||||
android.R.id.home -> requireActivity().finish()
|
android.R.id.home -> requireActivity().finish()
|
||||||
|
@ -214,12 +207,16 @@ class MediaPreviewV2Fragment : Fragment(R.layout.fragment_media_preview_v2), Med
|
||||||
(binding.mediaPreviewAlbumRail.adapter as MediaRailAdapter).setMedia(albumThumbnailMedia, currentState.position)
|
(binding.mediaPreviewAlbumRail.adapter as MediaRailAdapter).setMedia(albumThumbnailMedia, currentState.position)
|
||||||
binding.mediaPreviewAlbumRail.smoothScrollToPosition(currentState.position)
|
binding.mediaPreviewAlbumRail.smoothScrollToPosition(currentState.position)
|
||||||
|
|
||||||
binding.mediaPreviewCaptionContainer.visibility = if (caption == null) View.GONE else View.VISIBLE
|
if (caption != null) {
|
||||||
binding.mediaPreviewCaption.text = caption
|
binding.mediaPreviewCaption.text = caption
|
||||||
|
binding.mediaPreviewCaption.visibility = View.VISIBLE
|
||||||
|
} else {
|
||||||
|
binding.mediaPreviewCaption.visibility = View.GONE
|
||||||
|
}
|
||||||
|
|
||||||
val fragmentTag = "f${currentState.position}"
|
val fragmentTag = "f${currentState.position}"
|
||||||
val currentFragment: Fragment? = childFragmentManager.findFragmentByTag(fragmentTag)
|
val currentFragment: MediaPreviewFragment? = childFragmentManager.findFragmentByTag(fragmentTag) as? MediaPreviewFragment
|
||||||
val playbackControls: PlayerControlView? = (currentFragment as? MediaPreviewFragment)?.playbackControls
|
val playbackControls: View? = currentFragment?.bottomBarControls
|
||||||
if (albumThumbnailMedia.size <= 1 && caption == null && playbackControls == null) {
|
if (albumThumbnailMedia.size <= 1 && caption == null && playbackControls == null) {
|
||||||
binding.mediaPreviewDetailsContainer.visibility = View.GONE
|
binding.mediaPreviewDetailsContainer.visibility = View.GONE
|
||||||
} else {
|
} else {
|
||||||
|
@ -231,6 +228,8 @@ class MediaPreviewV2Fragment : Fragment(R.layout.fragment_media_preview_v2), Med
|
||||||
playbackControls.layoutParams = params
|
playbackControls.layoutParams = params
|
||||||
binding.mediaPreviewPlaybackControlsContainer.addView(playbackControls)
|
binding.mediaPreviewPlaybackControlsContainer.addView(playbackControls)
|
||||||
}
|
}
|
||||||
|
currentFragment?.setShareButtonListener { share(currentItem) }
|
||||||
|
currentFragment?.setForwardButtonListener { forward(currentItem) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getTitleText(mediaRecord: MediaDatabase.MediaRecord, showThread: Boolean): String {
|
private fun getTitleText(mediaRecord: MediaDatabase.MediaRecord, showThread: Boolean): String {
|
||||||
|
@ -319,11 +318,6 @@ class MediaPreviewV2Fragment : Fragment(R.layout.fragment_media_preview_v2), Med
|
||||||
Log.d(TAG, "onMediaReady()")
|
Log.d(TAG, "onMediaReady()")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showOverview(threadId: Long) {
|
|
||||||
val context = requireContext()
|
|
||||||
context.startActivity(MediaOverviewActivity.forThread(context, threadId))
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun forward(mediaItem: MediaDatabase.MediaRecord) {
|
private fun forward(mediaItem: MediaDatabase.MediaRecord) {
|
||||||
val attachment = mediaItem.attachment
|
val attachment = mediaItem.attachment
|
||||||
val uri = attachment?.uri
|
val uri = attachment?.uri
|
||||||
|
|
|
@ -6,6 +6,7 @@ import android.os.Bundle;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.ImageButton;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
@ -29,6 +30,8 @@ public final class VideoMediaPreviewFragment extends MediaPreviewFragment {
|
||||||
|
|
||||||
private VideoPlayer videoView;
|
private VideoPlayer videoView;
|
||||||
private boolean isVideoGif;
|
private boolean isVideoGif;
|
||||||
|
private ImageButton shareButton;
|
||||||
|
private ImageButton forwardButton;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
|
@ -92,12 +95,16 @@ public final class VideoMediaPreviewFragment extends MediaPreviewFragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
videoView.setOnClickListener(v -> events.singleTapOnMedia());
|
videoView.setOnClickListener(v -> events.singleTapOnMedia());
|
||||||
|
final PlayerControlView controlView = videoView.getControlView();
|
||||||
|
if (controlView != null) {
|
||||||
|
shareButton = controlView.findViewById(R.id.exo_share);
|
||||||
|
forwardButton = controlView.findViewById(R.id.exo_forward);
|
||||||
|
}
|
||||||
return itemView;
|
return itemView;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateSkipButtonState() {
|
private void updateSkipButtonState() {
|
||||||
final PlayerControlView playbackControls = getPlaybackControls();
|
final PlayerControlView playbackControls = getBottomBarControls();
|
||||||
if (playbackControls != null) {
|
if (playbackControls != null) {
|
||||||
boolean shouldShowSkipButtons = videoView.getDuration() > MINIMUM_DURATION_FOR_SKIP_MS;
|
boolean shouldShowSkipButtons = videoView.getDuration() > MINIMUM_DURATION_FOR_SKIP_MS;
|
||||||
playbackControls.setShowFastForwardButton(shouldShowSkipButtons);
|
playbackControls.setShowFastForwardButton(shouldShowSkipButtons);
|
||||||
|
@ -142,9 +149,19 @@ public final class VideoMediaPreviewFragment extends MediaPreviewFragment {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setShareButtonListener(View.OnClickListener listener) {
|
||||||
|
shareButton.setOnClickListener(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setForwardButtonListener(View.OnClickListener listener) {
|
||||||
|
forwardButton.setOnClickListener(listener);
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public PlayerControlView getPlaybackControls() {
|
public PlayerControlView getBottomBarControls() {
|
||||||
return videoView != null && !isVideoGif ? videoView.getControlView() : null;
|
return videoView != null && !isVideoGif ? videoView.getControlView() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -102,7 +102,6 @@ public final class FeatureFlags {
|
||||||
private static final String SMS_EXPORTER = "android.sms.exporter.2";
|
private static final String SMS_EXPORTER = "android.sms.exporter.2";
|
||||||
public static final String STORIES_LOCALE = "android.stories.locale.1";
|
public static final String STORIES_LOCALE = "android.stories.locale.1";
|
||||||
private static final String HIDE_CONTACTS = "android.hide.contacts";
|
private static final String HIDE_CONTACTS = "android.hide.contacts";
|
||||||
private static final String MEDIA_PREVIEW_V2 = "android.mediaPreviewV2";
|
|
||||||
private static final String SMS_EXPORT_MEGAPHONE_DELAY_DAYS = "android.smsExport.megaphoneDelayDays";
|
private static final String SMS_EXPORT_MEGAPHONE_DELAY_DAYS = "android.smsExport.megaphoneDelayDays";
|
||||||
public static final String CREDIT_CARD_PAYMENTS = "android.credit.card.payments";
|
public static final String CREDIT_CARD_PAYMENTS = "android.credit.card.payments";
|
||||||
|
|
||||||
|
@ -159,7 +158,6 @@ public final class FeatureFlags {
|
||||||
SMS_EXPORTER,
|
SMS_EXPORTER,
|
||||||
STORIES_LOCALE,
|
STORIES_LOCALE,
|
||||||
HIDE_CONTACTS,
|
HIDE_CONTACTS,
|
||||||
MEDIA_PREVIEW_V2,
|
|
||||||
SMS_EXPORT_MEGAPHONE_DELAY_DAYS,
|
SMS_EXPORT_MEGAPHONE_DELAY_DAYS,
|
||||||
CREDIT_CARD_PAYMENTS
|
CREDIT_CARD_PAYMENTS
|
||||||
);
|
);
|
||||||
|
@ -557,13 +555,6 @@ public final class FeatureFlags {
|
||||||
return getBoolean(HIDE_CONTACTS, false);
|
return getBoolean(HIDE_CONTACTS, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether or not we should use the new media preview fragment implementation.
|
|
||||||
*/
|
|
||||||
public static boolean mediaPreviewV2() {
|
|
||||||
return getBoolean(MEDIA_PREVIEW_V2, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Number of days to postpone the sms export megaphone and Phase 1 start.
|
* Number of days to postpone the sms export megaphone and Phase 1 start.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -90,8 +90,7 @@ public class VideoPlayer extends FrameLayout {
|
||||||
this.mediaSourceFactory = new DefaultMediaSourceFactory(context);
|
this.mediaSourceFactory = new DefaultMediaSourceFactory(context);
|
||||||
|
|
||||||
this.exoView = findViewById(R.id.video_view);
|
this.exoView = findViewById(R.id.video_view);
|
||||||
this.exoControls = new PlayerControlView(getContext());
|
this.exoControls = createPlayerControls(getContext());
|
||||||
this.exoControls.setShowTimeoutMs(-1);
|
|
||||||
|
|
||||||
this.exoPlayerListener = new ExoPlayerListener();
|
this.exoPlayerListener = new ExoPlayerListener();
|
||||||
this.playerListener = new Player.Listener() {
|
this.playerListener = new Player.Listener() {
|
||||||
|
@ -129,6 +128,14 @@ public class VideoPlayer extends FrameLayout {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private PlayerControlView createPlayerControls(Context context) {
|
||||||
|
final PlayerControlView playerControlView = new PlayerControlView(context);
|
||||||
|
playerControlView.setShowTimeoutMs(-1);
|
||||||
|
playerControlView.setShowNextButton(false);
|
||||||
|
playerControlView.setShowPreviousButton(false);
|
||||||
|
return playerControlView;
|
||||||
|
}
|
||||||
|
|
||||||
private MediaItem mediaItem;
|
private MediaItem mediaItem;
|
||||||
|
|
||||||
public void setVideoSource(@NonNull VideoSlide videoSource, boolean autoplay, String poolTag) {
|
public void setVideoSource(@NonNull VideoSlide videoSource, boolean autoplay, String poolTag) {
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="@color/core_white"
|
||||||
|
android:pathData="M17,15a2.98,2.98 0,0 0,-2.184 0.955L8.9,12.728a2.726,2.726 0,0 0,0 -1.456l5.915,-3.227A3.1,3.1 0,1 0,14.1 6.728L8.184,9.955a3,3 0,1 0,0 4.09L14.1,17.272A2.995,2.995 0,1 0,17 15ZM17,4.5A1.5,1.5 0,1 1,15.5 6,1.5 1.5,0 0,1 17,4.5ZM6,13.5A1.5,1.5 0,1 1,7.5 12,1.5 1.5,0 0,1 6,13.5ZM17,19.5A1.5,1.5 0,1 1,18.5 18,1.5 1.5,0 0,1 17,19.5Z"/>
|
||||||
|
</vector>
|
|
@ -0,0 +1,119 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout 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"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="bottom"
|
||||||
|
android:background="#CC000000"
|
||||||
|
android:layoutDirection="ltr"
|
||||||
|
android:orientation="vertical"
|
||||||
|
tools:targetApi="28">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@id/exo_position"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:includeFontPadding="false"
|
||||||
|
android:paddingLeft="4dp"
|
||||||
|
android:paddingRight="4dp"
|
||||||
|
android:textColor="#FFBEBEBE"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:id="@id/exo_progress_placeholder"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="26dp"
|
||||||
|
android:layout_weight="1" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@id/exo_duration"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:includeFontPadding="false"
|
||||||
|
android:paddingLeft="4dp"
|
||||||
|
android:paddingRight="4dp"
|
||||||
|
android:textColor="#FFBEBEBE"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:paddingTop="4dp">
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/exo_share"
|
||||||
|
android:layout_width="@dimen/exo_media_button_width"
|
||||||
|
android:layout_height="@dimen/exo_media_button_height"
|
||||||
|
android:background="?selectableItemBackground"
|
||||||
|
app:srcCompat="@drawable/ic_share_24_outline_white" />
|
||||||
|
|
||||||
|
<Space
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_weight="1.0" />
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@id/exo_prev"
|
||||||
|
style="@style/ExoMediaButton.Previous" />
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@id/exo_rew"
|
||||||
|
style="@style/ExoMediaButton.Rewind" />
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@id/exo_shuffle"
|
||||||
|
style="@style/ExoMediaButton" />
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@id/exo_repeat_toggle"
|
||||||
|
style="@style/ExoMediaButton" />
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@id/exo_play"
|
||||||
|
style="@style/ExoMediaButton.Play" />
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@id/exo_pause"
|
||||||
|
style="@style/ExoMediaButton.Pause" />
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@id/exo_ffwd"
|
||||||
|
style="@style/ExoMediaButton.FastForward" />
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@id/exo_next"
|
||||||
|
style="@style/ExoMediaButton.Next" />
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@id/exo_vr"
|
||||||
|
style="@style/ExoMediaButton.VR" />
|
||||||
|
|
||||||
|
<Space
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_weight="1.0" />
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/exo_forward"
|
||||||
|
android:layout_width="@dimen/exo_media_button_width"
|
||||||
|
android:layout_height="@dimen/exo_media_button_height"
|
||||||
|
android:background="?selectableItemBackground"
|
||||||
|
app:srcCompat="@drawable/ic_forward_24" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
|
</LinearLayout>
|
|
@ -24,27 +24,17 @@
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
tools:visibility="visible">
|
tools:visibility="visible">
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.components.MaxHeightScrollView
|
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
|
||||||
android:id="@+id/media_preview_caption_container"
|
android:id="@+id/media_preview_caption"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:paddingTop="32dp"
|
android:paddingStart="16dp"
|
||||||
android:animateLayoutChanges="true"
|
android:paddingEnd="16dp"
|
||||||
app:scrollView_maxHeight="120dp">
|
android:paddingBottom="8dp"
|
||||||
|
style="@style/Signal.Text.Body"
|
||||||
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
|
android:textColor="@color/core_white"
|
||||||
android:id="@+id/media_preview_caption"
|
android:gravity="bottom"
|
||||||
android:layout_width="match_parent"
|
tools:text="With great power comes great responsibility." />
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:paddingStart="16dp"
|
|
||||||
android:paddingEnd="16dp"
|
|
||||||
android:paddingBottom="8dp"
|
|
||||||
style="@style/Signal.Text.Body"
|
|
||||||
android:textColor="@color/core_white"
|
|
||||||
android:gravity="bottom"
|
|
||||||
tools:text="With great power comes great responsibility." />
|
|
||||||
|
|
||||||
</org.thoughtcrime.securesms.components.MaxHeightScrollView>
|
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/media_preview_album_rail"
|
android:id="@+id/media_preview_album_rail"
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout 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"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="bottom"
|
||||||
|
android:background="#CC000000"
|
||||||
|
android:layoutDirection="ltr"
|
||||||
|
android:orientation="vertical"
|
||||||
|
tools:targetApi="28">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/image_preview_share"
|
||||||
|
android:layout_width="@dimen/exo_media_button_width"
|
||||||
|
android:layout_height="@dimen/exo_media_button_height"
|
||||||
|
android:background="?selectableItemBackground"
|
||||||
|
app:srcCompat="@drawable/ic_share_24_outline_white" />
|
||||||
|
|
||||||
|
<Space
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_weight="1.0" />
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/image_preview_forward"
|
||||||
|
android:layout_width="@dimen/exo_media_button_width"
|
||||||
|
android:layout_height="@dimen/exo_media_button_height"
|
||||||
|
android:background="?selectableItemBackground"
|
||||||
|
app:srcCompat="@drawable/ic_forward_24" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
|
@ -1,23 +1,12 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
<item android:id="@+id/media_preview__forward"
|
|
||||||
android:title="@string/media_preview__forward_title"
|
|
||||||
android:icon="@drawable/ic_forward_24"
|
|
||||||
app:showAsAction="ifRoom"/>
|
|
||||||
<item android:id="@+id/media_preview__share"
|
|
||||||
android:title="@string/media_preview__share_title"
|
|
||||||
app:showAsAction="never"/>
|
|
||||||
<item android:id="@+id/save"
|
<item android:id="@+id/save"
|
||||||
android:title="@string/media_preview__save_title"
|
android:title="@string/media_preview__save_title"
|
||||||
android:icon="@drawable/ic_download_filled_white_24"
|
android:icon="@drawable/ic_download_filled_white_24"
|
||||||
app:showAsAction="ifRoom"/>
|
|
||||||
<item android:id="@+id/media_preview__overview"
|
|
||||||
android:title="@string/media_preview__all_media_title"
|
|
||||||
android:icon="@drawable/ic_photo_library_white_24dp"
|
|
||||||
app:showAsAction="never"/>
|
app:showAsAction="never"/>
|
||||||
<item android:id="@+id/delete"
|
<item android:id="@+id/delete"
|
||||||
android:title="@string/delete"
|
android:title="@string/delete"
|
||||||
android:icon="@drawable/ic_trash_24"
|
android:icon="@drawable/ic_trash_24"
|
||||||
app:showAsAction="ifRoom"/>
|
app:showAsAction="never"/>
|
||||||
</menu>
|
</menu>
|
||||||
|
|
|
@ -3237,6 +3237,8 @@
|
||||||
<string name="media_preview__forward_title">Forward</string>
|
<string name="media_preview__forward_title">Forward</string>
|
||||||
<string name="media_preview__share_title">Share</string>
|
<string name="media_preview__share_title">Share</string>
|
||||||
<string name="media_preview__all_media_title">All media</string>
|
<string name="media_preview__all_media_title">All media</string>
|
||||||
|
<string name="media_preview__edit_title">Edit</string>
|
||||||
|
|
||||||
|
|
||||||
<!-- media_preview_activity -->
|
<!-- media_preview_activity -->
|
||||||
<string name="media_preview_activity__media_content_description">Media preview</string>
|
<string name="media_preview_activity__media_content_description">Media preview</string>
|
||||||
|
|
Ładowanie…
Reference in New Issue