mirror of
				https://github.com/KokaKiwi/BarInsta
				synced 2025-10-31 11:35:34 +00:00 
			
		
		
		
	Handle multiple videos in PostViewV2Fragment. Should fix https://github.com/austinhuang0131/barinsta/issues/337 and also fix videos playing after closing view.
This commit is contained in:
		
							parent
							
								
									6b370ca251
								
							
						
					
					
						commit
						dccfcaf78a
					
				| @ -22,7 +22,7 @@ public final class SliderItemsAdapter extends ListAdapter<PostChild, SliderItemV | |||||||
|     private final VerticalDragHelper.OnVerticalDragListener onVerticalDragListener; |     private final VerticalDragHelper.OnVerticalDragListener onVerticalDragListener; | ||||||
|     private final boolean loadVideoOnItemClick; |     private final boolean loadVideoOnItemClick; | ||||||
|     private final SliderCallback sliderCallback; |     private final SliderCallback sliderCallback; | ||||||
|     private final awais.instagrabber.databinding.LayoutExoCustomControlsBinding controlsBinding; |     private final LayoutExoCustomControlsBinding controlsBinding; | ||||||
| 
 | 
 | ||||||
|     private static final DiffUtil.ItemCallback<PostChild> DIFF_CALLBACK = new DiffUtil.ItemCallback<PostChild>() { |     private static final DiffUtil.ItemCallback<PostChild> DIFF_CALLBACK = new DiffUtil.ItemCallback<PostChild>() { | ||||||
|         @Override |         @Override | ||||||
|  | |||||||
| @ -135,6 +135,16 @@ public class SliderVideoViewHolder extends SliderItemViewHolder { | |||||||
|         videoPlayerViewHelper.releasePlayer(); |         videoPlayerViewHelper.releasePlayer(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     public void resetPlayerTimeline() { | ||||||
|  |         if (videoPlayerViewHelper == null) return; | ||||||
|  |         videoPlayerViewHelper.resetTimeline(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void removeCallbacks() { | ||||||
|  |         if (videoPlayerViewHelper == null) return; | ||||||
|  |         videoPlayerViewHelper.removeCallbacks(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     // private void setDimensions(final FeedModel feedModel, final int spanCount, final boolean animate) { |     // private void setDimensions(final FeedModel feedModel, final int spanCount, final boolean animate) { | ||||||
|     //     final ViewGroup.LayoutParams layoutParams = binding.imageViewer.getLayoutParams(); |     //     final ViewGroup.LayoutParams layoutParams = binding.imageViewer.getLayoutParams(); | ||||||
|     //     final int deviceWidth = Utils.displayMetrics.widthPixels; |     //     final int deviceWidth = Utils.displayMetrics.widthPixels; | ||||||
|  | |||||||
| @ -10,6 +10,7 @@ import android.view.View; | |||||||
| 
 | 
 | ||||||
| import androidx.annotation.NonNull; | import androidx.annotation.NonNull; | ||||||
| import androidx.appcompat.view.ContextThemeWrapper; | import androidx.appcompat.view.ContextThemeWrapper; | ||||||
|  | import androidx.appcompat.widget.AppCompatTextView; | ||||||
| import androidx.appcompat.widget.PopupMenu; | import androidx.appcompat.widget.PopupMenu; | ||||||
| 
 | 
 | ||||||
| import com.facebook.drawee.backends.pipeline.Fresco; | import com.facebook.drawee.backends.pipeline.Fresco; | ||||||
| @ -26,6 +27,8 @@ import com.google.android.exoplayer2.SimpleExoPlayer; | |||||||
| import com.google.android.exoplayer2.audio.AudioListener; | import com.google.android.exoplayer2.audio.AudioListener; | ||||||
| import com.google.android.exoplayer2.source.ProgressiveMediaSource; | import com.google.android.exoplayer2.source.ProgressiveMediaSource; | ||||||
| import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory; | import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory; | ||||||
|  | import com.google.android.material.slider.LabelFormatter; | ||||||
|  | import com.google.android.material.slider.Slider; | ||||||
| 
 | 
 | ||||||
| import awais.instagrabber.R; | import awais.instagrabber.R; | ||||||
| import awais.instagrabber.databinding.LayoutExoCustomControlsBinding; | import awais.instagrabber.databinding.LayoutExoCustomControlsBinding; | ||||||
| @ -39,6 +42,8 @@ import static com.google.android.exoplayer2.Player.STATE_READY; | |||||||
| 
 | 
 | ||||||
| public class VideoPlayerViewHelper implements Player.EventListener { | public class VideoPlayerViewHelper implements Player.EventListener { | ||||||
|     private static final String TAG = "VideoPlayerViewHelper"; |     private static final String TAG = "VideoPlayerViewHelper"; | ||||||
|  |     private static final long INITIAL_DELAY = 0; | ||||||
|  |     private static final long RECURRING_DELAY = 60; | ||||||
| 
 | 
 | ||||||
|     private final Context context; |     private final Context context; | ||||||
|     private final awais.instagrabber.databinding.LayoutVideoPlayerWithThumbnailBinding binding; |     private final awais.instagrabber.databinding.LayoutVideoPlayerWithThumbnailBinding binding; | ||||||
| @ -52,6 +57,62 @@ public class VideoPlayerViewHelper implements Player.EventListener { | |||||||
|     private final DefaultDataSourceFactory dataSourceFactory; |     private final DefaultDataSourceFactory dataSourceFactory; | ||||||
|     private SimpleExoPlayer player; |     private SimpleExoPlayer player; | ||||||
|     private PopupMenu speedPopup; |     private PopupMenu speedPopup; | ||||||
|  |     private Runnable positionChecker; | ||||||
|  | 
 | ||||||
|  |     private final Handler positionUpdateHandler = new Handler(); | ||||||
|  |     private final Player.EventListener listener = new Player.EventListener() { | ||||||
|  |         @Override | ||||||
|  |         public void onPlaybackStateChanged(final int state) { | ||||||
|  |             switch (state) { | ||||||
|  |                 case Player.STATE_BUFFERING: | ||||||
|  |                 case STATE_IDLE: | ||||||
|  |                 case STATE_ENDED: | ||||||
|  |                     positionUpdateHandler.removeCallbacks(positionChecker); | ||||||
|  |                     return; | ||||||
|  |                 case STATE_READY: | ||||||
|  |                     setupTimeline(); | ||||||
|  |                     positionUpdateHandler.postDelayed(positionChecker, INITIAL_DELAY); | ||||||
|  |                     break; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         @Override | ||||||
|  |         public void onPlayWhenReadyChanged(final boolean playWhenReady, final int reason) { | ||||||
|  |             updatePlayPauseDrawable(playWhenReady); | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|  |     private final AudioListener audioListener = new AudioListener() { | ||||||
|  |         @Override | ||||||
|  |         public void onVolumeChanged(final float volume) { | ||||||
|  |             updateMuteIcon(volume); | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|  |     private final Slider.OnChangeListener onChangeListener = (slider, value, fromUser) -> { | ||||||
|  |         if (!fromUser) return; | ||||||
|  |         long actualValue = (long) value; | ||||||
|  |         if (actualValue < 0) { | ||||||
|  |             actualValue = 0; | ||||||
|  |         } else if (actualValue > player.getDuration()) { | ||||||
|  |             actualValue = player.getDuration(); | ||||||
|  |         } | ||||||
|  |         player.seekTo(actualValue); | ||||||
|  |     }; | ||||||
|  |     private final View.OnClickListener onClickListener = v -> player.setPlayWhenReady(!player.getPlayWhenReady()); | ||||||
|  |     private final LabelFormatter labelFormatter = value -> TextUtils.millisToTimeString((long) value); | ||||||
|  |     private final View.OnClickListener muteOnClickListener = v -> toggleMute(); | ||||||
|  |     private final View.OnClickListener rewOnClickListener = v -> { | ||||||
|  |         final long positionMs = player.getCurrentPosition() - 5000; | ||||||
|  |         player.seekTo(positionMs < 0 ? 0 : positionMs); | ||||||
|  |     }; | ||||||
|  |     private final View.OnClickListener ffOnClickListener = v -> { | ||||||
|  |         long positionMs = player.getCurrentPosition() + 5000; | ||||||
|  |         long duration = player.getDuration(); | ||||||
|  |         if (duration == TIME_UNSET) { | ||||||
|  |             duration = 0; | ||||||
|  |         } | ||||||
|  |         player.seekTo(Math.min(positionMs, duration)); | ||||||
|  |     }; | ||||||
|  |     private final View.OnClickListener showMenu = this::showMenu; | ||||||
| 
 | 
 | ||||||
|     public VideoPlayerViewHelper(@NonNull final Context context, |     public VideoPlayerViewHelper(@NonNull final Context context, | ||||||
|                                  @NonNull final LayoutVideoPlayerWithThumbnailBinding binding, |                                  @NonNull final LayoutVideoPlayerWithThumbnailBinding binding, | ||||||
| @ -130,6 +191,10 @@ public class VideoPlayerViewHelper implements Player.EventListener { | |||||||
|         player = new SimpleExoPlayer.Builder(context) |         player = new SimpleExoPlayer.Builder(context) | ||||||
|                 .setLooper(Looper.getMainLooper()) |                 .setLooper(Looper.getMainLooper()) | ||||||
|                 .build(); |                 .build(); | ||||||
|  |         positionChecker = new PositionCheckRunnable(positionUpdateHandler, | ||||||
|  |                                                     player, | ||||||
|  |                                                     controlsBinding.timeline, | ||||||
|  |                                                     controlsBinding.fromTime); | ||||||
|         player.addListener(this); |         player.addListener(this); | ||||||
|         player.setVolume(initialVolume); |         player.setVolume(initialVolume); | ||||||
|         player.setPlayWhenReady(true); |         player.setPlayWhenReady(true); | ||||||
| @ -148,87 +213,22 @@ public class VideoPlayerViewHelper implements Player.EventListener { | |||||||
|         binding.playerView.setUseController(false); |         binding.playerView.setUseController(false); | ||||||
|         if (player == null) { |         if (player == null) { | ||||||
|             enableControls(false); |             enableControls(false); | ||||||
|             controlsBinding.playPause.setEnabled(true); |             // controlsBinding.playPause.setEnabled(true); | ||||||
|             controlsBinding.playPause.setOnClickListener(v -> binding.thumbnailParent.performClick()); |             // controlsBinding.playPause.setOnClickListener(new NoPlayerPlayPauseClickListener(binding.thumbnailParent)); | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|         enableControls(true); |         enableControls(true); | ||||||
|         final Handler handler = new Handler(); |  | ||||||
|         final long initialDelay = 0; |  | ||||||
|         final long recurringDelay = 60; |  | ||||||
|         final Runnable positionChecker = new Runnable() { |  | ||||||
|             @Override |  | ||||||
|             public void run() { |  | ||||||
|                 handler.removeCallbacks(this); |  | ||||||
|                 if (player == null) return; |  | ||||||
|                 final long currentPosition = player.getCurrentPosition(); |  | ||||||
|                 final long duration = player.getDuration(); |  | ||||||
|                 if (duration == TIME_UNSET) { |  | ||||||
|                     controlsBinding.timeline.setValueFrom(0); |  | ||||||
|                     controlsBinding.timeline.setValueTo(0); |  | ||||||
|                     controlsBinding.timeline.setEnabled(false); |  | ||||||
|                     return; |  | ||||||
|                 } |  | ||||||
|                 controlsBinding.timeline.setValue(Math.min(currentPosition, duration)); |  | ||||||
|                 controlsBinding.fromTime.setText(TextUtils.millisToTimeString(currentPosition)); |  | ||||||
|                 handler.postDelayed(this, recurringDelay); |  | ||||||
|             } |  | ||||||
|         }; |  | ||||||
|         updatePlayPauseDrawable(player.getPlayWhenReady()); |         updatePlayPauseDrawable(player.getPlayWhenReady()); | ||||||
|         updateMuteIcon(player.getVolume()); |         updateMuteIcon(player.getVolume()); | ||||||
|         player.addListener(new Player.EventListener() { |         player.addListener(listener); | ||||||
|             @Override |         player.addAudioListener(audioListener); | ||||||
|             public void onPlaybackStateChanged(final int state) { |         controlsBinding.timeline.addOnChangeListener(onChangeListener); | ||||||
|                 switch (state) { |         controlsBinding.timeline.setLabelFormatter(labelFormatter); | ||||||
|                     case Player.STATE_BUFFERING: |         controlsBinding.playPause.setOnClickListener(onClickListener); | ||||||
|                     case STATE_IDLE: |         controlsBinding.mute.setOnClickListener(muteOnClickListener); | ||||||
|                     case STATE_ENDED: |         controlsBinding.rewWithAmount.setOnClickListener(rewOnClickListener); | ||||||
|                         handler.removeCallbacks(positionChecker); |         controlsBinding.ffWithAmount.setOnClickListener(ffOnClickListener); | ||||||
|                         return; |         controlsBinding.speed.setOnClickListener(showMenu); | ||||||
|                     case STATE_READY: |  | ||||||
|                         setupTimeline(); |  | ||||||
|                         handler.postDelayed(positionChecker, initialDelay); |  | ||||||
|                         break; |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             @Override |  | ||||||
|             public void onPlayWhenReadyChanged(final boolean playWhenReady, final int reason) { |  | ||||||
|                 updatePlayPauseDrawable(playWhenReady); |  | ||||||
|             } |  | ||||||
|         }); |  | ||||||
|         player.addAudioListener(new AudioListener() { |  | ||||||
|             @Override |  | ||||||
|             public void onVolumeChanged(final float volume) { |  | ||||||
|                 updateMuteIcon(volume); |  | ||||||
|             } |  | ||||||
|         }); |  | ||||||
|         controlsBinding.timeline.addOnChangeListener((slider, value, fromUser) -> { |  | ||||||
|             if (!fromUser) return; |  | ||||||
|             long actualValue = (long) value; |  | ||||||
|             if (actualValue < 0) { |  | ||||||
|                 actualValue = 0; |  | ||||||
|             } else if (actualValue > player.getDuration()) { |  | ||||||
|                 actualValue = player.getDuration(); |  | ||||||
|             } |  | ||||||
|             player.seekTo(actualValue); |  | ||||||
|         }); |  | ||||||
|         controlsBinding.timeline.setLabelFormatter(value -> TextUtils.millisToTimeString((long) value)); |  | ||||||
|         controlsBinding.playPause.setOnClickListener(v -> player.setPlayWhenReady(!player.getPlayWhenReady())); |  | ||||||
|         controlsBinding.mute.setOnClickListener(v -> toggleMute()); |  | ||||||
|         controlsBinding.rewWithAmount.setOnClickListener(v -> { |  | ||||||
|             final long positionMs = player.getCurrentPosition() - 5000; |  | ||||||
|             player.seekTo(positionMs < 0 ? 0 : positionMs); |  | ||||||
|         }); |  | ||||||
|         controlsBinding.ffWithAmount.setOnClickListener(v -> { |  | ||||||
|             long positionMs = player.getCurrentPosition() + 5000; |  | ||||||
|             long duration = player.getDuration(); |  | ||||||
|             if (duration == TIME_UNSET) { |  | ||||||
|                 duration = 0; |  | ||||||
|             } |  | ||||||
|             player.seekTo(Math.min(positionMs, duration)); |  | ||||||
|         }); |  | ||||||
|         controlsBinding.speed.setOnClickListener(this::showMenu); |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private void setupTimeline() { |     private void setupTimeline() { | ||||||
| @ -242,12 +242,18 @@ public class VideoPlayerViewHelper implements Player.EventListener { | |||||||
| 
 | 
 | ||||||
|     private void enableControls(final boolean enable) { |     private void enableControls(final boolean enable) { | ||||||
|         controlsBinding.speed.setEnabled(enable); |         controlsBinding.speed.setEnabled(enable); | ||||||
|  |         controlsBinding.speed.setClickable(enable); | ||||||
|         controlsBinding.mute.setEnabled(enable); |         controlsBinding.mute.setEnabled(enable); | ||||||
|  |         controlsBinding.mute.setClickable(enable); | ||||||
|         controlsBinding.ffWithAmount.setEnabled(enable); |         controlsBinding.ffWithAmount.setEnabled(enable); | ||||||
|  |         controlsBinding.ffWithAmount.setClickable(enable); | ||||||
|         controlsBinding.rewWithAmount.setEnabled(enable); |         controlsBinding.rewWithAmount.setEnabled(enable); | ||||||
|  |         controlsBinding.rewWithAmount.setClickable(enable); | ||||||
|         controlsBinding.fromTime.setEnabled(enable); |         controlsBinding.fromTime.setEnabled(enable); | ||||||
|         controlsBinding.toTime.setEnabled(enable); |         controlsBinding.toTime.setEnabled(enable); | ||||||
|         controlsBinding.playPause.setEnabled(enable); |         controlsBinding.playPause.setEnabled(enable); | ||||||
|  |         controlsBinding.playPause.setClickable(enable); | ||||||
|  |         controlsBinding.timeline.setEnabled(enable); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public void showMenu(View anchor) { |     public void showMenu(View anchor) { | ||||||
| @ -302,10 +308,10 @@ public class VideoPlayerViewHelper implements Player.EventListener { | |||||||
| 
 | 
 | ||||||
|     private void updateMuteIcon(final float volume) { |     private void updateMuteIcon(final float volume) { | ||||||
|         if (volume == 0) { |         if (volume == 0) { | ||||||
|             controlsBinding.mute.setIconResource(R.drawable.ic_volume_off_24); |             controlsBinding.mute.setIconResource(R.drawable.ic_volume_off_24_states); | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|         controlsBinding.mute.setIconResource(R.drawable.ic_volume_up_24); |         controlsBinding.mute.setIconResource(R.drawable.ic_volume_up_24_states); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private void updatePlayPauseDrawable(final boolean playWhenReady) { |     private void updatePlayPauseDrawable(final boolean playWhenReady) { | ||||||
| @ -313,7 +319,7 @@ public class VideoPlayerViewHelper implements Player.EventListener { | |||||||
|             controlsBinding.playPause.setIconResource(R.drawable.ic_pause_24); |             controlsBinding.playPause.setIconResource(R.drawable.ic_pause_24); | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|         controlsBinding.playPause.setIconResource(R.drawable.ic_play_arrow_24); |         controlsBinding.playPause.setIconResource(R.drawable.ic_play_states); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
| @ -338,23 +344,88 @@ public class VideoPlayerViewHelper implements Player.EventListener { | |||||||
|         return vol; |         return vol; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public void togglePlayback() { |     // public void togglePlayback() { | ||||||
|         if (player == null) return; |     //     if (player == null) return; | ||||||
|         final int playbackState = player.getPlaybackState(); |     //     final int playbackState = player.getPlaybackState(); | ||||||
|         if (playbackState == STATE_IDLE || playbackState == STATE_ENDED) return; |     //     if (playbackState == STATE_IDLE || playbackState == STATE_ENDED) return; | ||||||
|         final boolean playWhenReady = player.getPlayWhenReady(); |     //     final boolean playWhenReady = player.getPlayWhenReady(); | ||||||
|         player.setPlayWhenReady(!playWhenReady); |     //     player.setPlayWhenReady(!playWhenReady); | ||||||
|     } |     // } | ||||||
| 
 | 
 | ||||||
|     public void releasePlayer() { |     public void releasePlayer() { | ||||||
|         if (player == null) return; |         if (player == null) return; | ||||||
|         player.release(); |         player.release(); | ||||||
|         player = null; |         player = null; | ||||||
|  |         if (positionUpdateHandler != null && positionChecker != null) { | ||||||
|  |             positionUpdateHandler.removeCallbacks(positionChecker); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public void pause() { |     public void pause() { | ||||||
|         if (player == null) return; |         if (player == null) return; | ||||||
|         player.pause(); |         player.pause(); | ||||||
|  |         if (positionUpdateHandler != null && positionChecker != null) { | ||||||
|  |             positionUpdateHandler.removeCallbacks(positionChecker); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void resetTimeline() { | ||||||
|  |         if (player == null) { | ||||||
|  |             enableControls(false); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |         setupTimeline(); | ||||||
|  |         final long currentPosition = player.getCurrentPosition(); | ||||||
|  |         controlsBinding.timeline.setValue(Math.min(currentPosition, player.getDuration())); | ||||||
|  |         setupControls(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void removeCallbacks() { | ||||||
|  |         if (player != null) { | ||||||
|  |             player.removeListener(listener); | ||||||
|  |             player.removeAudioListener(audioListener); | ||||||
|  |         } | ||||||
|  |         controlsBinding.timeline.removeOnChangeListener(onChangeListener); | ||||||
|  |         controlsBinding.timeline.setLabelFormatter(null); | ||||||
|  |         controlsBinding.playPause.setOnClickListener(null); | ||||||
|  |         controlsBinding.mute.setOnClickListener(null); | ||||||
|  |         controlsBinding.rewWithAmount.setOnClickListener(null); | ||||||
|  |         controlsBinding.ffWithAmount.setOnClickListener(null); | ||||||
|  |         controlsBinding.speed.setOnClickListener(null); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private static class PositionCheckRunnable implements Runnable { | ||||||
|  |         private final Handler positionUpdateHandler; | ||||||
|  |         private final SimpleExoPlayer player; | ||||||
|  |         private final Slider timeline; | ||||||
|  |         private final AppCompatTextView fromTime; | ||||||
|  | 
 | ||||||
|  |         public PositionCheckRunnable(final Handler positionUpdateHandler, | ||||||
|  |                                      final SimpleExoPlayer simpleExoPlayer, | ||||||
|  |                                      final Slider slider, | ||||||
|  |                                      final AppCompatTextView fromTime) { | ||||||
|  |             this.positionUpdateHandler = positionUpdateHandler; | ||||||
|  |             this.player = simpleExoPlayer; | ||||||
|  |             this.timeline = slider; | ||||||
|  |             this.fromTime = fromTime; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         @Override | ||||||
|  |         public void run() { | ||||||
|  |             positionUpdateHandler.removeCallbacks(this); | ||||||
|  |             if (player == null) return; | ||||||
|  |             final long currentPosition = player.getCurrentPosition(); | ||||||
|  |             final long duration = player.getDuration(); | ||||||
|  |             if (duration == TIME_UNSET) { | ||||||
|  |                 timeline.setValueFrom(0); | ||||||
|  |                 timeline.setValueTo(0); | ||||||
|  |                 timeline.setEnabled(false); | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  |             timeline.setValue(Math.min(currentPosition, duration)); | ||||||
|  |             fromTime.setText(TextUtils.millisToTimeString(currentPosition)); | ||||||
|  |             positionUpdateHandler.postDelayed(this, RECURRING_DELAY); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public interface VideoPlayerCallback { |     public interface VideoPlayerCallback { | ||||||
|  | |||||||
| @ -113,6 +113,7 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment { | |||||||
|     private int sliderPosition = -1; |     private int sliderPosition = -1; | ||||||
|     private DialogInterface.OnShowListener onShowListener; |     private DialogInterface.OnShowListener onShowListener; | ||||||
|     private boolean isLoggedIn; |     private boolean isLoggedIn; | ||||||
|  |     private boolean hasBeenToggled = false; | ||||||
| 
 | 
 | ||||||
|     private final VerticalDragHelper.OnVerticalDragListener onVerticalDragListener = new VerticalDragHelper.OnVerticalDragListener() { |     private final VerticalDragHelper.OnVerticalDragListener onVerticalDragListener = new VerticalDragHelper.OnVerticalDragListener() { | ||||||
| 
 | 
 | ||||||
| @ -303,8 +304,8 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
|     public void onDestroy() { |     public void onDestroyView() { | ||||||
|         super.onDestroy(); |         super.onDestroyView(); | ||||||
|         switch (feedModel.getItemType()) { |         switch (feedModel.getItemType()) { | ||||||
|             case MEDIA_TYPE_VIDEO: |             case MEDIA_TYPE_VIDEO: | ||||||
|                 if (videoPlayerViewHelper != null) { |                 if (videoPlayerViewHelper != null) { | ||||||
| @ -870,6 +871,20 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment { | |||||||
|         if (!wasPaused && sharedMainPostElement != null) { |         if (!wasPaused && sharedMainPostElement != null) { | ||||||
|             addSharedElement(sharedMainPostElement, binding.sliderParent); |             addSharedElement(sharedMainPostElement, binding.sliderParent); | ||||||
|         } |         } | ||||||
|  |         final boolean hasVideo = feedModel.getSliderItems() | ||||||
|  |                                           .stream() | ||||||
|  |                                           .anyMatch(postChild -> postChild.getItemType() == MediaItemType.MEDIA_TYPE_VIDEO); | ||||||
|  |         if (hasVideo) { | ||||||
|  |             final View child = binding.sliderParent.getChildAt(0); | ||||||
|  |             if (child instanceof RecyclerView) { | ||||||
|  |                 ((RecyclerView) child).setItemViewCacheSize(feedModel.getSliderItems().size()); | ||||||
|  |                 ((RecyclerView) child).addRecyclerListener(holder -> { | ||||||
|  |                     if (holder instanceof SliderVideoViewHolder) { | ||||||
|  |                         ((SliderVideoViewHolder) holder).releasePlayer(); | ||||||
|  |                     } | ||||||
|  |                 }); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|         sliderItemsAdapter = new SliderItemsAdapter(onVerticalDragListener, binding.playerControls, true, new SliderCallbackAdapter() { |         sliderItemsAdapter = new SliderItemsAdapter(onVerticalDragListener, binding.playerControls, true, new SliderCallbackAdapter() { | ||||||
|             @Override |             @Override | ||||||
|             public void onThumbnailLoaded(final int position) { |             public void onThumbnailLoaded(final int position) { | ||||||
| @ -879,19 +894,17 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment { | |||||||
| 
 | 
 | ||||||
|             @Override |             @Override | ||||||
|             public void onItemClicked(final int position) { |             public void onItemClicked(final int position) { | ||||||
|                 toggleDetails(); |  | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             @Override |             @Override | ||||||
|             public void onPlayerPlay(final int position) { |             public void onPlayerPlay(final int position) { | ||||||
|                 if (!detailsVisible) return; |                 if (!detailsVisible || hasBeenToggled) return; | ||||||
|                 toggleDetails(); |  | ||||||
|                 showPlayerControls(); |                 showPlayerControls(); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             @Override |             @Override | ||||||
|             public void onPlayerPause(final int position) { |             public void onPlayerPause(final int position) { | ||||||
|                 if (detailsVisible) return; |                 if (detailsVisible || hasBeenToggled) return; | ||||||
|                 toggleDetails(); |                 toggleDetails(); | ||||||
|             } |             } | ||||||
|         }); |         }); | ||||||
| @ -924,7 +937,22 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment { | |||||||
|                 final String text = (position + 1) + "/" + size; |                 final String text = (position + 1) + "/" + size; | ||||||
|                 binding.mediaCounter.setText(text); |                 binding.mediaCounter.setText(text); | ||||||
|                 final PostChild postChild = feedModel.getSliderItems().get(position); |                 final PostChild postChild = feedModel.getSliderItems().get(position); | ||||||
|  |                 final View view = binding.sliderParent.getChildAt(0); | ||||||
|  |                 if (prevPosition != -1) { | ||||||
|  |                     if (view instanceof RecyclerView) { | ||||||
|  |                         final RecyclerView.ViewHolder viewHolder = ((RecyclerView) view).findViewHolderForAdapterPosition(prevPosition); | ||||||
|  |                         if (viewHolder instanceof SliderVideoViewHolder) { | ||||||
|  |                             ((SliderVideoViewHolder) viewHolder).removeCallbacks(); | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|                 if (postChild.getItemType() == MediaItemType.MEDIA_TYPE_VIDEO) { |                 if (postChild.getItemType() == MediaItemType.MEDIA_TYPE_VIDEO) { | ||||||
|  |                     if (view instanceof RecyclerView) { | ||||||
|  |                         final RecyclerView.ViewHolder viewHolder = ((RecyclerView) view).findViewHolderForAdapterPosition(position); | ||||||
|  |                         if (viewHolder instanceof SliderVideoViewHolder) { | ||||||
|  |                             ((SliderVideoViewHolder) viewHolder).resetPlayerTimeline(); | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|                     enablePlayerControls(true); |                     enablePlayerControls(true); | ||||||
|                     return; |                     return; | ||||||
|                 } |                 } | ||||||
| @ -1052,6 +1080,9 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment { | |||||||
|         hideCaption(); |         hideCaption(); | ||||||
|         // previously invisible view |         // previously invisible view | ||||||
|         View view = binding.playerControls.getRoot(); |         View view = binding.playerControls.getRoot(); | ||||||
|  |         if (view != null && view.getVisibility() == View.VISIBLE) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|         if (!ViewCompat.isAttachedToWindow(view)) { |         if (!ViewCompat.isAttachedToWindow(view)) { | ||||||
|             view.setVisibility(View.VISIBLE); |             view.setVisibility(View.VISIBLE); | ||||||
|             return; |             return; | ||||||
| @ -1076,6 +1107,9 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment { | |||||||
|     private void hidePlayerControls() { |     private void hidePlayerControls() { | ||||||
|         // previously visible view |         // previously visible view | ||||||
|         final View view = binding.playerControls.getRoot(); |         final View view = binding.playerControls.getRoot(); | ||||||
|  |         if (view != null && view.getVisibility() == View.GONE) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|         if (!ViewCompat.isAttachedToWindow(view)) { |         if (!ViewCompat.isAttachedToWindow(view)) { | ||||||
|             view.setVisibility(View.GONE); |             view.setVisibility(View.GONE); | ||||||
|             return; |             return; | ||||||
| @ -1106,6 +1140,7 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private void toggleDetails() { |     private void toggleDetails() { | ||||||
|  |         hasBeenToggled = true; | ||||||
|         binding.getRoot().post(() -> { |         binding.getRoot().post(() -> { | ||||||
|             TransitionManager.beginDelayedTransition(binding.getRoot()); |             TransitionManager.beginDelayedTransition(binding.getRoot()); | ||||||
|             if (detailsVisible) { |             if (detailsVisible) { | ||||||
|  | |||||||
							
								
								
									
										15
									
								
								app/src/main/res/drawable/ic_forward_5_24_a50.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								app/src/main/res/drawable/ic_forward_5_24_a50.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | |||||||
|  | <vector xmlns:android="http://schemas.android.com/apk/res/android" | ||||||
|  |     android:width="24dp" | ||||||
|  |     android:height="24dp" | ||||||
|  |     android:tint="?attr/colorControlNormal" | ||||||
|  |     android:viewportWidth="24" | ||||||
|  |     android:viewportHeight="24"> | ||||||
|  |     <path | ||||||
|  |         android:fillAlpha="0.5" | ||||||
|  |         android:fillColor="@android:color/white" | ||||||
|  |         android:pathData="M18,13c0,3.31 -2.69,6 -6,6s-6,-2.69 -6,-6s2.69,-6 6,-6v4l5,-5l-5,-5v4c-4.42,0 -8,3.58 -8,8c0,4.42 3.58,8 8,8c4.42,0 8,-3.58 8,-8H18z" /> | ||||||
|  |     <path | ||||||
|  |         android:fillAlpha="0.5" | ||||||
|  |         android:fillColor="@android:color/white" | ||||||
|  |         android:pathData="M12.03,15.38c-0.44,0 -0.58,-0.31 -0.6,-0.56h-0.84c0.03,0.85 0.79,1.25 1.44,1.25c0.93,0 1.44,-0.63 1.44,-1.43c0,-1.33 -0.97,-1.44 -1.3,-1.44c-0.2,0 -0.43,0.05 -0.64,0.16l0.11,-0.92h1.7v-0.71h-2.39l-0.25,2.17l0.67,0.17c0.13,-0.13 0.28,-0.23 0.57,-0.23c0.4,0 0.69,0.23 0.69,0.75C12.62,14.64 12.65,15.38 12.03,15.38z" /> | ||||||
|  | </vector> | ||||||
							
								
								
									
										5
									
								
								app/src/main/res/drawable/ic_forward_5_24_states.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								app/src/main/res/drawable/ic_forward_5_24_states.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | |||||||
|  | <?xml version="1.0" encoding="utf-8"?> | ||||||
|  | <selector xmlns:android="http://schemas.android.com/apk/res/android"> | ||||||
|  |     <item android:drawable="@drawable/ic_forward_5_24_a50" android:state_enabled="false" /> | ||||||
|  |     <item android:drawable="@drawable/ic_forward_5_24" android:state_enabled="true" /> | ||||||
|  | </selector> | ||||||
							
								
								
									
										11
									
								
								app/src/main/res/drawable/ic_play_arrow_24_a50.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								app/src/main/res/drawable/ic_play_arrow_24_a50.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | |||||||
|  | <vector xmlns:android="http://schemas.android.com/apk/res/android" | ||||||
|  |     android:width="24dp" | ||||||
|  |     android:height="24dp" | ||||||
|  |     android:viewportWidth="24" | ||||||
|  |     android:viewportHeight="24" | ||||||
|  |     android:tint="?attr/colorControlNormal"> | ||||||
|  |   <path | ||||||
|  |       android:fillColor="@android:color/white" | ||||||
|  |       android:fillAlpha="0.5" | ||||||
|  |       android:pathData="M8,5v14l11,-7z"/> | ||||||
|  | </vector> | ||||||
							
								
								
									
										5
									
								
								app/src/main/res/drawable/ic_play_states.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								app/src/main/res/drawable/ic_play_states.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | |||||||
|  | <?xml version="1.0" encoding="utf-8"?> | ||||||
|  | <selector xmlns:android="http://schemas.android.com/apk/res/android"> | ||||||
|  |     <item android:drawable="@drawable/ic_play_arrow_24_a50" android:state_enabled="false" /> | ||||||
|  |     <item android:drawable="@drawable/ic_play_arrow_24" android:state_enabled="true" /> | ||||||
|  | </selector> | ||||||
							
								
								
									
										15
									
								
								app/src/main/res/drawable/ic_replay_5_24_a50.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								app/src/main/res/drawable/ic_replay_5_24_a50.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | |||||||
|  | <vector xmlns:android="http://schemas.android.com/apk/res/android" | ||||||
|  |     android:width="24dp" | ||||||
|  |     android:height="24dp" | ||||||
|  |     android:tint="?attr/colorControlNormal" | ||||||
|  |     android:viewportWidth="24" | ||||||
|  |     android:viewportHeight="24"> | ||||||
|  |     <path | ||||||
|  |         android:fillAlpha="0.5" | ||||||
|  |         android:fillColor="@android:color/white" | ||||||
|  |         android:pathData="M12,5V1L7,6l5,5V7c3.31,0 6,2.69 6,6s-2.69,6 -6,6s-6,-2.69 -6,-6H4c0,4.42 3.58,8 8,8s8,-3.58 8,-8S16.42,5 12,5z" /> | ||||||
|  |     <path | ||||||
|  |         android:fillAlpha="0.5" | ||||||
|  |         android:fillColor="@android:color/white" | ||||||
|  |         android:pathData="M10.69,13.9l0.25,-2.17h2.39v0.71h-1.7l-0.11,0.92c0.03,-0.02 0.07,-0.03 0.11,-0.05s0.09,-0.04 0.15,-0.05s0.12,-0.03 0.18,-0.04s0.13,-0.02 0.2,-0.02c0.21,0 0.39,0.03 0.55,0.1s0.3,0.16 0.41,0.28s0.2,0.27 0.25,0.45s0.09,0.38 0.09,0.6c0,0.19 -0.03,0.37 -0.09,0.54s-0.15,0.32 -0.27,0.45s-0.27,0.24 -0.45,0.31s-0.39,0.12 -0.64,0.12c-0.18,0 -0.36,-0.03 -0.53,-0.08s-0.32,-0.14 -0.46,-0.24s-0.24,-0.24 -0.32,-0.39s-0.13,-0.33 -0.13,-0.53h0.84c0.02,0.18 0.08,0.32 0.19,0.41s0.25,0.15 0.42,0.15c0.11,0 0.2,-0.02 0.27,-0.06s0.14,-0.1 0.18,-0.17s0.08,-0.15 0.11,-0.25s0.03,-0.2 0.03,-0.31s-0.01,-0.21 -0.04,-0.31s-0.07,-0.17 -0.13,-0.24s-0.13,-0.12 -0.21,-0.15s-0.19,-0.05 -0.3,-0.05c-0.08,0 -0.15,0.01 -0.2,0.02s-0.11,0.03 -0.15,0.05s-0.08,0.05 -0.12,0.07s-0.07,0.06 -0.1,0.09L10.69,13.9z" /> | ||||||
|  | </vector> | ||||||
							
								
								
									
										5
									
								
								app/src/main/res/drawable/ic_replay_5_24_states.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								app/src/main/res/drawable/ic_replay_5_24_states.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | |||||||
|  | <?xml version="1.0" encoding="utf-8"?> | ||||||
|  | <selector xmlns:android="http://schemas.android.com/apk/res/android"> | ||||||
|  |     <item android:drawable="@drawable/ic_replay_5_24_a50" android:state_enabled="false" /> | ||||||
|  |     <item android:drawable="@drawable/ic_replay_5_24" android:state_enabled="true" /> | ||||||
|  | </selector> | ||||||
							
								
								
									
										11
									
								
								app/src/main/res/drawable/ic_volume_off_24_a50.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								app/src/main/res/drawable/ic_volume_off_24_a50.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | |||||||
|  | <vector xmlns:android="http://schemas.android.com/apk/res/android" | ||||||
|  |     android:width="24dp" | ||||||
|  |     android:height="24dp" | ||||||
|  |     android:tint="?attr/colorControlNormal" | ||||||
|  |     android:viewportWidth="24" | ||||||
|  |     android:viewportHeight="24"> | ||||||
|  |     <path | ||||||
|  |         android:fillAlpha="0.5" | ||||||
|  |         android:fillColor="@android:color/white" | ||||||
|  |         android:pathData="M16.5,12c0,-1.77 -1.02,-3.29 -2.5,-4.03v2.21l2.45,2.45c0.03,-0.2 0.05,-0.41 0.05,-0.63zM19,12c0,0.94 -0.2,1.82 -0.54,2.64l1.51,1.51C20.63,14.91 21,13.5 21,12c0,-4.28 -2.99,-7.86 -7,-8.77v2.06c2.89,0.86 5,3.54 5,6.71zM4.27,3L3,4.27 7.73,9L3,9v6h4l5,5v-6.73l4.25,4.25c-0.67,0.52 -1.42,0.93 -2.25,1.18v2.06c1.38,-0.31 2.63,-0.95 3.69,-1.81L19.73,21 21,19.73l-9,-9L4.27,3zM12,4L9.91,6.09 12,8.18L12,4z" /> | ||||||
|  | </vector> | ||||||
							
								
								
									
										5
									
								
								app/src/main/res/drawable/ic_volume_off_24_states.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								app/src/main/res/drawable/ic_volume_off_24_states.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | |||||||
|  | <?xml version="1.0" encoding="utf-8"?> | ||||||
|  | <selector xmlns:android="http://schemas.android.com/apk/res/android"> | ||||||
|  |     <item android:drawable="@drawable/ic_volume_off_24_a50" android:state_enabled="false" /> | ||||||
|  |     <item android:drawable="@drawable/ic_volume_off_24" android:state_enabled="true" /> | ||||||
|  | </selector> | ||||||
							
								
								
									
										11
									
								
								app/src/main/res/drawable/ic_volume_up_24_a50.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								app/src/main/res/drawable/ic_volume_up_24_a50.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | |||||||
|  | <vector xmlns:android="http://schemas.android.com/apk/res/android" | ||||||
|  |     android:width="24dp" | ||||||
|  |     android:height="24dp" | ||||||
|  |     android:tint="?attr/colorControlNormal" | ||||||
|  |     android:viewportWidth="24" | ||||||
|  |     android:viewportHeight="24"> | ||||||
|  |     <path | ||||||
|  |         android:fillAlpha="0.5" | ||||||
|  |         android:fillColor="@android:color/white" | ||||||
|  |         android:pathData="M3,9v6h4l5,5L12,4L7,9L3,9zM16.5,12c0,-1.77 -1.02,-3.29 -2.5,-4.03v8.05c1.48,-0.73 2.5,-2.25 2.5,-4.02zM14,3.23v2.06c2.89,0.86 5,3.54 5,6.71s-2.11,5.85 -5,6.71v2.06c4.01,-0.91 7,-4.49 7,-8.77s-2.99,-7.86 -7,-8.77z" /> | ||||||
|  | </vector> | ||||||
							
								
								
									
										5
									
								
								app/src/main/res/drawable/ic_volume_up_24_states.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								app/src/main/res/drawable/ic_volume_up_24_states.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | |||||||
|  | <?xml version="1.0" encoding="utf-8"?> | ||||||
|  | <selector xmlns:android="http://schemas.android.com/apk/res/android"> | ||||||
|  |     <item android:drawable="@drawable/ic_volume_up_24_a50" android:state_enabled="false" /> | ||||||
|  |     <item android:drawable="@drawable/ic_volume_up_24" android:state_enabled="true" /> | ||||||
|  | </selector> | ||||||
							
								
								
									
										5
									
								
								app/src/main/res/drawable/speed_text_color_states.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								app/src/main/res/drawable/speed_text_color_states.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | |||||||
|  | <?xml version="1.0" encoding="utf-8"?> | ||||||
|  | <selector xmlns:android="http://schemas.android.com/apk/res/android"> | ||||||
|  |     <item android:color="@color/white_a50" android:state_enabled="false" /> | ||||||
|  |     <item android:color="@color/white" android:state_enabled="true" /> | ||||||
|  | </selector> | ||||||
| @ -53,13 +53,14 @@ | |||||||
|         android:layout_width="0dp" |         android:layout_width="0dp" | ||||||
|         android:layout_height="wrap_content" |         android:layout_height="wrap_content" | ||||||
|         android:visibility="visible" |         android:visibility="visible" | ||||||
|         app:icon="@drawable/ic_replay_5_24" |         app:icon="@drawable/ic_replay_5_24_states" | ||||||
|         app:iconSize="24dp" |         app:iconSize="24dp" | ||||||
|         app:iconTint="@color/white" |         app:iconTint="@color/white" | ||||||
|         app:layout_constraintBottom_toBottomOf="parent" |         app:layout_constraintBottom_toBottomOf="parent" | ||||||
|         app:layout_constraintEnd_toStartOf="@id/play_pause" |         app:layout_constraintEnd_toStartOf="@id/play_pause" | ||||||
|         app:layout_constraintStart_toStartOf="parent" |         app:layout_constraintStart_toStartOf="parent" | ||||||
|         app:layout_constraintTop_toBottomOf="@id/timeline" |         app:layout_constraintTop_toBottomOf="@id/timeline" | ||||||
|  |         tools:enabled="false" | ||||||
|         tools:visibility="visible" /> |         tools:visibility="visible" /> | ||||||
| 
 | 
 | ||||||
|     <com.google.android.material.button.MaterialButton |     <com.google.android.material.button.MaterialButton | ||||||
| @ -67,13 +68,14 @@ | |||||||
|         style="@style/Widget.App.MaterialButton.IconOnly.BorderlessRipple" |         style="@style/Widget.App.MaterialButton.IconOnly.BorderlessRipple" | ||||||
|         android:layout_width="0dp" |         android:layout_width="0dp" | ||||||
|         android:layout_height="wrap_content" |         android:layout_height="wrap_content" | ||||||
|         app:icon="@drawable/ic_play_arrow_24" |         app:icon="@drawable/ic_play_states" | ||||||
|         app:iconSize="24dp" |         app:iconSize="24dp" | ||||||
|         app:iconTint="@color/white" |         app:iconTint="@color/white" | ||||||
|         app:layout_constraintBottom_toBottomOf="parent" |         app:layout_constraintBottom_toBottomOf="parent" | ||||||
|         app:layout_constraintEnd_toStartOf="@id/ff_with_amount" |         app:layout_constraintEnd_toStartOf="@id/ff_with_amount" | ||||||
|         app:layout_constraintStart_toEndOf="@id/rew_with_amount" |         app:layout_constraintStart_toEndOf="@id/rew_with_amount" | ||||||
|         app:layout_constraintTop_toBottomOf="@id/timeline" |         app:layout_constraintTop_toBottomOf="@id/timeline" | ||||||
|  |         tools:enabled="false" | ||||||
|         tools:visibility="visible" /> |         tools:visibility="visible" /> | ||||||
| 
 | 
 | ||||||
|     <com.google.android.material.button.MaterialButton |     <com.google.android.material.button.MaterialButton | ||||||
| @ -81,13 +83,14 @@ | |||||||
|         style="@style/Widget.App.MaterialButton.IconOnly.BorderlessRipple" |         style="@style/Widget.App.MaterialButton.IconOnly.BorderlessRipple" | ||||||
|         android:layout_width="0dp" |         android:layout_width="0dp" | ||||||
|         android:layout_height="wrap_content" |         android:layout_height="wrap_content" | ||||||
|         app:icon="@drawable/ic_forward_5_24" |         app:icon="@drawable/ic_forward_5_24_states" | ||||||
|         app:iconSize="24dp" |         app:iconSize="24dp" | ||||||
|         app:iconTint="@color/white" |         app:iconTint="@color/white" | ||||||
|         app:layout_constraintBottom_toBottomOf="parent" |         app:layout_constraintBottom_toBottomOf="parent" | ||||||
|         app:layout_constraintEnd_toStartOf="@id/mute" |         app:layout_constraintEnd_toStartOf="@id/mute" | ||||||
|         app:layout_constraintStart_toEndOf="@id/play_pause" |         app:layout_constraintStart_toEndOf="@id/play_pause" | ||||||
|         app:layout_constraintTop_toBottomOf="@id/timeline" |         app:layout_constraintTop_toBottomOf="@id/timeline" | ||||||
|  |         tools:enabled="false" | ||||||
|         tools:visibility="visible" /> |         tools:visibility="visible" /> | ||||||
| 
 | 
 | ||||||
|     <com.google.android.material.button.MaterialButton |     <com.google.android.material.button.MaterialButton | ||||||
| @ -95,13 +98,14 @@ | |||||||
|         style="@style/Widget.App.MaterialButton.IconOnly.BorderlessRipple" |         style="@style/Widget.App.MaterialButton.IconOnly.BorderlessRipple" | ||||||
|         android:layout_width="0dp" |         android:layout_width="0dp" | ||||||
|         android:layout_height="wrap_content" |         android:layout_height="wrap_content" | ||||||
|         app:icon="@drawable/ic_volume_off_24" |         app:icon="@drawable/ic_volume_off_24_states" | ||||||
|         app:iconSize="24dp" |         app:iconSize="24dp" | ||||||
|         app:iconTint="@color/white" |         app:iconTint="@color/white" | ||||||
|         app:layout_constraintBottom_toBottomOf="parent" |         app:layout_constraintBottom_toBottomOf="parent" | ||||||
|         app:layout_constraintEnd_toStartOf="@id/speed" |         app:layout_constraintEnd_toStartOf="@id/speed" | ||||||
|         app:layout_constraintStart_toEndOf="@id/ff_with_amount" |         app:layout_constraintStart_toEndOf="@id/ff_with_amount" | ||||||
|         app:layout_constraintTop_toBottomOf="@id/timeline" |         app:layout_constraintTop_toBottomOf="@id/timeline" | ||||||
|  |         tools:enabled="false" | ||||||
|         tools:visibility="visible" /> |         tools:visibility="visible" /> | ||||||
| 
 | 
 | ||||||
|     <com.google.android.material.button.MaterialButton |     <com.google.android.material.button.MaterialButton | ||||||
| @ -111,10 +115,11 @@ | |||||||
|         android:layout_height="wrap_content" |         android:layout_height="wrap_content" | ||||||
|         android:text="@string/one_x" |         android:text="@string/one_x" | ||||||
|         android:textAllCaps="false" |         android:textAllCaps="false" | ||||||
|         android:textColor="@color/white" |         android:textColor="@drawable/speed_text_color_states" | ||||||
|         app:layout_constraintBottom_toBottomOf="parent" |         app:layout_constraintBottom_toBottomOf="parent" | ||||||
|         app:layout_constraintEnd_toEndOf="parent" |         app:layout_constraintEnd_toEndOf="parent" | ||||||
|         app:layout_constraintStart_toEndOf="@id/mute" |         app:layout_constraintStart_toEndOf="@id/mute" | ||||||
|         app:layout_constraintTop_toBottomOf="@id/timeline" |         app:layout_constraintTop_toBottomOf="@id/timeline" | ||||||
|  |         tools:enabled="false" | ||||||
|         tools:visibility="visible" /> |         tools:visibility="visible" /> | ||||||
| </androidx.constraintlayout.widget.ConstraintLayout> | </androidx.constraintlayout.widget.ConstraintLayout> | ||||||
| @ -33,6 +33,7 @@ | |||||||
|     <color name="comment_selected">#888888</color> |     <color name="comment_selected">#888888</color> | ||||||
| 
 | 
 | ||||||
|     <color name="white">#FFFFFF</color> |     <color name="white">#FFFFFF</color> | ||||||
|  |     <color name="white_a50">#80FFFFFF</color> | ||||||
| 
 | 
 | ||||||
|     <color name="black">#000000</color> |     <color name="black">#000000</color> | ||||||
|     <color name="black_800">#121212</color> |     <color name="black_800">#121212</color> | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user