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

@@ -98,7 +98,6 @@ import org.thoughtcrime.securesms.VerifyIdentityActivity;
import org.thoughtcrime.securesms.attachments.Attachment;
import org.thoughtcrime.securesms.attachments.TombstoneAttachment;
import org.thoughtcrime.securesms.audio.AudioRecorder;
import org.thoughtcrime.securesms.audio.AudioSlidePlayer;
import org.thoughtcrime.securesms.color.MaterialColor;
import org.thoughtcrime.securesms.components.AnimatingToggle;
import org.thoughtcrime.securesms.components.ComposeText;
@@ -557,7 +556,6 @@ public class ConversationActivity extends PassphraseRequiredActivity
fragment.setLastSeen(System.currentTimeMillis());
markLastSeen();
AudioSlidePlayer.stopAll();
EventBus.getDefault().unregister(this);
}

View File

@@ -52,6 +52,7 @@ import androidx.appcompat.widget.Toolbar;
import androidx.core.app.ActivityCompat;
import androidx.core.app.ActivityOptionsCompat;
import androidx.core.text.HtmlCompat;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
@@ -70,6 +71,8 @@ import org.thoughtcrime.securesms.components.ConversationScrollToView;
import org.thoughtcrime.securesms.components.ConversationTypingView;
import org.thoughtcrime.securesms.components.TooltipPopup;
import org.thoughtcrime.securesms.components.recyclerview.SmoothScrollingLinearLayoutManager;
import org.thoughtcrime.securesms.components.voice.VoiceNoteMediaController;
import org.thoughtcrime.securesms.components.voice.VoiceNotePlaybackState;
import org.thoughtcrime.securesms.contactshare.Contact;
import org.thoughtcrime.securesms.contactshare.ContactUtil;
import org.thoughtcrime.securesms.contactshare.SharedContactDetailsActivity;
@@ -179,6 +182,7 @@ public class ConversationFragment extends LoggingFragment {
private Animation mentionButtonOutAnimation;
private OnScrollListener conversationScrollListener;
private int pulsePosition = -1;
private VoiceNoteMediaController voiceNoteMediaController;
public static void prepare(@NonNull Context context) {
FrameLayout parent = new FrameLayout(context);
@@ -306,6 +310,7 @@ public class ConversationFragment extends LoggingFragment {
initializeResources();
initializeMessageRequestViewModel();
initializeListAdapter();
voiceNoteMediaController = new VoiceNoteMediaController((AppCompatActivity) requireActivity());
}
@Override
@@ -1355,6 +1360,31 @@ public class ConversationFragment extends LoggingFragment {
listener.onMessageWithErrorClicked(messageRecord);
}
@Override
public void onVoiceNotePause(@NonNull Uri uri) {
voiceNoteMediaController.pausePlayback(uri);
}
@Override
public void onVoiceNotePlay(@NonNull Uri uri, long messageId, long position) {
voiceNoteMediaController.startPlayback(uri, messageId, position);
}
@Override
public void onVoiceNoteSeekTo(@NonNull Uri uri, long position) {
voiceNoteMediaController.seekToPosition(uri, position);
}
@Override
public void onRegisterVoiceNoteCallbacks(@NonNull Observer<VoiceNotePlaybackState> onPlaybackStartObserver) {
voiceNoteMediaController.getVoiceNotePlaybackState().observe(getViewLifecycleOwner(), onPlaybackStartObserver);
}
@Override
public void onUnregisterVoiceNoteCallbacks(@NonNull Observer<VoiceNotePlaybackState> onPlaybackStartObserver) {
voiceNoteMediaController.getVoiceNotePlaybackState().removeObserver(onPlaybackStartObserver);
}
@Override
public boolean onUrlClicked(@NonNull String url) {
return CommunicationActions.handlePotentialGroupLinkUrl(requireActivity(), url);

View File

@@ -407,6 +407,9 @@ public class ConversationItem extends LinearLayout implements BindableConversati
conversationRecipient.removeForeverObserver(this);
}
cancelPulseOutlinerAnimation();
if (eventListener != null && audioViewStub.resolved()) {
eventListener.onUnregisterVoiceNoteCallbacks(audioViewStub.get().getPlaybackStateObserver());
}
}
public ConversationMessage getConversationMessage() {
@@ -655,6 +658,10 @@ public class ConversationItem extends LinearLayout implements BindableConversati
{
boolean showControls = !messageRecord.isFailed();
if (eventListener != null && audioViewStub.resolved()) {
eventListener.onUnregisterVoiceNoteCallbacks(audioViewStub.get().getPlaybackStateObserver());
}
if (isViewOnceMessage(messageRecord) && !messageRecord.isRemoteDelete()) {
revealableStub.get().setVisibility(VISIBLE);
if (mediaThumbnailStub.resolved()) mediaThumbnailStub.get().setVisibility(View.GONE);
@@ -738,10 +745,14 @@ public class ConversationItem extends LinearLayout implements BindableConversati
if (revealableStub.resolved()) revealableStub.get().setVisibility(View.GONE);
//noinspection ConstantConditions
audioViewStub.get().setAudio(((MediaMmsMessageRecord) messageRecord).getSlideDeck().getAudioSlide(), showControls);
audioViewStub.get().setAudio(((MediaMmsMessageRecord) messageRecord).getSlideDeck().getAudioSlide(), new AudioViewCallbacks(), showControls);
audioViewStub.get().setDownloadClickListener(singleDownloadClickListener);
audioViewStub.get().setOnLongClickListener(passthroughClickListener);
if (eventListener != null) {
eventListener.onRegisterVoiceNoteCallbacks(audioViewStub.get().getPlaybackStateObserver());
}
ViewUtil.updateLayoutParams(bodyText, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
ViewUtil.updateLayoutParamsIfNonNull(groupSenderHolder, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
@@ -1534,6 +1545,35 @@ public class ConversationItem extends LinearLayout implements BindableConversati
public void updateDrawState(@NonNull TextPaint ds) { }
}
private final class AudioViewCallbacks implements AudioView.Callbacks {
@Override
public void onPlay(@NonNull Uri audioUri, long position) {
if (eventListener == null) return;
eventListener.onVoiceNotePlay(audioUri, messageRecord.getId(), position);
}
@Override
public void onPause(@NonNull Uri audioUri) {
if (eventListener == null) return;
eventListener.onVoiceNotePause(audioUri);
}
@Override
public void onSeekTo(@NonNull Uri audioUri, long position) {
if (eventListener == null) return;
eventListener.onVoiceNoteSeekTo(audioUri, position);
}
@Override
public void onStopAndReset(@NonNull Uri audioUri) {
throw new UnsupportedOperationException();
}
}
private void handleMessageApproval() {
final int title;
final int message;