Allow voice notes to continue playback after leaving conversation.

This commit is contained in:
Alex Hart
2020-10-13 09:20:52 -03:00
committed by Greyson Parrelli
parent 7ef57cc0cf
commit 9effa47dd8
25 changed files with 1211 additions and 469 deletions

View File

@@ -17,6 +17,7 @@
package org.thoughtcrime.securesms.mediaoverview;
import android.content.Context;
import android.net.Uri;
import android.os.Handler;
import android.view.LayoutInflater;
import android.view.View;
@@ -63,6 +64,7 @@ final class MediaGalleryAllAdapter extends StickyHeaderGridAdapter {
private final GlideRequests glideRequests;
private final ItemClickListener itemClickListener;
private final Map<AttachmentId, MediaRecord> selected = new HashMap<>();
private final AudioView.Callbacks audioViewCallbacks;
private GroupedThreadMedia media;
private boolean showFileSizes;
@@ -73,12 +75,6 @@ final class MediaGalleryAllAdapter extends StickyHeaderGridAdapter {
private static final int GALLERY_DETAIL = 3;
private static final int DOCUMENT_DETAIL = 4;
void pause(RecyclerView.ViewHolder holder) {
if (holder instanceof AudioDetailViewHolder) {
((AudioDetailViewHolder) holder).pause();
}
}
void detach(RecyclerView.ViewHolder holder) {
if (holder instanceof SelectableViewHolder) {
((SelectableViewHolder) holder).onDetached();
@@ -98,15 +94,17 @@ final class MediaGalleryAllAdapter extends StickyHeaderGridAdapter {
@NonNull GlideRequests glideRequests,
GroupedThreadMedia media,
ItemClickListener clickListener,
@NonNull AudioView.Callbacks audioViewCallbacks,
boolean showFileSizes,
boolean showThread)
{
this.context = context;
this.glideRequests = glideRequests;
this.media = media;
this.itemClickListener = clickListener;
this.showFileSizes = showFileSizes;
this.showThread = showThread;
this.context = context;
this.glideRequests = glideRequests;
this.media = media;
this.itemClickListener = clickListener;
this.audioViewCallbacks = audioViewCallbacks;
this.showFileSizes = showFileSizes;
this.showThread = showThread;
}
public void setMedia(GroupedThreadMedia media) {
@@ -437,25 +435,15 @@ final class MediaGalleryAllAdapter extends StickyHeaderGridAdapter {
throw new AssertionError();
}
audioView.setAudio((AudioSlide) slide, true);
audioView.setAudio((AudioSlide) slide, audioViewCallbacks, true);
audioView.setOnClickListener(view -> itemClickListener.onMediaClicked(mediaRecord));
itemView.setOnClickListener(view -> itemClickListener.onMediaClicked(mediaRecord));
}
@Override
void unbind() {
audioView.stopPlaybackAndReset();
super.unbind();
}
@Override
protected String getFileTypeDescription(@NonNull Context context, @NonNull Slide slide) {
return context.getString(R.string.MediaOverviewActivity_audio);
}
public void pause() {
audioView.stopPlaybackAndReset();
}
}
private class GalleryDetailViewHolder extends DetailViewHolder {

View File

@@ -17,6 +17,7 @@ import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.view.ActionMode;
import androidx.fragment.app.Fragment;
@@ -30,6 +31,8 @@ import com.codewaves.stickyheadergrid.StickyHeaderGridLayoutManager;
import org.thoughtcrime.securesms.MediaPreviewActivity;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.attachments.DatabaseAttachment;
import org.thoughtcrime.securesms.components.AudioView;
import org.thoughtcrime.securesms.components.voice.VoiceNoteMediaController;
import org.thoughtcrime.securesms.database.MediaDatabase;
import org.thoughtcrime.securesms.database.loaders.GroupedThreadMediaLoader;
import org.thoughtcrime.securesms.database.loaders.MediaLoader;
@@ -41,6 +44,7 @@ import org.thoughtcrime.securesms.util.Util;
public final class MediaOverviewPageFragment extends Fragment
implements MediaGalleryAllAdapter.ItemClickListener,
AudioView.Callbacks,
LoaderManager.LoaderCallbacks<GroupedThreadMediaLoader.GroupedThreadMedia>
{
@@ -61,6 +65,7 @@ public final class MediaOverviewPageFragment extends Fragment
private boolean detail;
private MediaGalleryAllAdapter adapter;
private GridMode gridMode;
private VoiceNoteMediaController voiceNoteMediaController;
public static @NonNull Fragment newInstance(long threadId,
@NonNull MediaLoader.MediaType mediaType,
@@ -91,6 +96,13 @@ public final class MediaOverviewPageFragment extends Fragment
LoaderManager.getInstance(this).initLoader(0, null, this);
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
voiceNoteMediaController = new VoiceNoteMediaController((AppCompatActivity) requireActivity());
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Context context = requireContext();
@@ -104,6 +116,7 @@ public final class MediaOverviewPageFragment extends Fragment
GlideApp.with(this),
new GroupedThreadMediaLoader.EmptyGroupedThreadMedia(),
this,
this,
sorting.isRelatedToFileSize(),
threadId == MediaDatabase.ALL_THREADS);
this.recyclerView.setAdapter(adapter);
@@ -180,15 +193,6 @@ public final class MediaOverviewPageFragment extends Fragment
}
}
@Override
public void onPause() {
super.onPause();
int childCount = recyclerView.getChildCount();
for (int i = 0; i < childCount; i++) {
adapter.pause(recyclerView.getChildViewHolder(recyclerView.getChildAt(i)));
}
}
@Override
public void onDestroy() {
super.onDestroy();
@@ -305,6 +309,26 @@ public final class MediaOverviewPageFragment extends Fragment
((MediaOverviewActivity) activity).onEnterMultiSelect();
}
@Override
public void onPlay(@NonNull Uri audioUri, long position) {
voiceNoteMediaController.startPlayback(audioUri, -1, position);
}
@Override
public void onPause(@NonNull Uri audioUri) {
voiceNoteMediaController.pausePlayback(audioUri);
}
@Override
public void onSeekTo(@NonNull Uri audioUri, long position) {
voiceNoteMediaController.seekToPosition(audioUri, position);
}
@Override
public void onStopAndReset(@NonNull Uri audioUri) {
voiceNoteMediaController.stopPlaybackAndReset(audioUri);
}
private class ActionModeCallback implements ActionMode.Callback {
private int originalStatusBarColor;