Fix several voice note beta bugs.

* Sim label positioning
* Bad player state when navigating to and from conversations
* Scrolling date header placement
This commit is contained in:
Alex Hart 2021-07-09 09:46:00 -03:00 committed by Cody Henthorne
parent 9876ffb5e4
commit e584a90f81
7 changed files with 52 additions and 16 deletions

View file

@ -264,19 +264,19 @@ public class VoiceNoteMediaController implements DefaultLifecycleObserver {
MediaControllerCompat.setMediaController(activity, mediaController); MediaControllerCompat.setMediaController(activity, mediaController);
mediaController.registerCallback(mediaControllerCompatCallback); MediaMetadataCompat mediaMetadataCompat = mediaController.getMetadata();
if (canExtractPlaybackInformationFromMetadata(mediaMetadataCompat)) {
VoiceNotePlaybackState newState = extractStateFromMetadata(mediaController, mediaMetadataCompat, null);
if (Objects.equals(voiceNotePlaybackState.getValue(), VoiceNotePlaybackState.NONE)) { if (newState != null) {
MediaMetadataCompat mediaMetadataCompat = mediaController.getMetadata(); voiceNotePlaybackState.postValue(newState);
if (canExtractPlaybackInformationFromMetadata(mediaMetadataCompat)) { } else {
VoiceNotePlaybackState newState = extractStateFromMetadata(mediaController, mediaMetadataCompat, null); voiceNotePlaybackState.postValue(VoiceNotePlaybackState.NONE);
if (newState != null) {
voiceNotePlaybackState.postValue(newState);
}
} }
} }
mediaController.registerCallback(mediaControllerCompatCallback);
mediaControllerCompatCallback.onPlaybackStateChanged(mediaController.getPlaybackState()); mediaControllerCompatCallback.onPlaybackStateChanged(mediaController.getPlaybackState());
} catch (RemoteException e) { } catch (RemoteException e) {
Log.w(TAG, "onConnected: Failed to set media controller", e); Log.w(TAG, "onConnected: Failed to set media controller", e);

View file

@ -52,6 +52,8 @@ class VoiceNotePlayerView @JvmOverloads constructor(
speedView = findViewById(R.id.voice_note_player_speed) speedView = findViewById(R.id.voice_note_player_speed)
closeButton = findViewById(R.id.voice_note_player_close) closeButton = findViewById(R.id.voice_note_player_close)
infoView.isSelected = true
val speedTouchTarget: View = findViewById(R.id.voice_note_player_speed_touch_target) val speedTouchTarget: View = findViewById(R.id.voice_note_player_speed_touch_target)
speedTouchTarget.setOnClickListener { speedTouchTarget.setOnClickListener {
speedView.performClick() speedView.performClick()

View file

@ -3392,6 +3392,11 @@ public class ConversationActivity extends PassphraseRequiredActivity
draftViewModel.deleteVoiceNoteDraft(); draftViewModel.deleteVoiceNoteDraft();
} }
@Override
public @NonNull VoiceNoteMediaController getVoiceNoteMediaController() {
return voiceNoteMediaController;
}
// Listeners // Listeners
private final class DeleteCanceledVoiceNoteListener implements ListenableFuture.Listener<VoiceNoteDraft> { private final class DeleteCanceledVoiceNoteListener implements ListenableFuture.Listener<VoiceNoteDraft> {

View file

@ -81,6 +81,7 @@ import org.thoughtcrime.securesms.components.TooltipPopup;
import org.thoughtcrime.securesms.components.TypingStatusRepository; import org.thoughtcrime.securesms.components.TypingStatusRepository;
import org.thoughtcrime.securesms.components.recyclerview.SmoothScrollingLinearLayoutManager; import org.thoughtcrime.securesms.components.recyclerview.SmoothScrollingLinearLayoutManager;
import org.thoughtcrime.securesms.components.settings.app.AppSettingsActivity; import org.thoughtcrime.securesms.components.settings.app.AppSettingsActivity;
import org.thoughtcrime.securesms.components.voice.VoiceNoteMediaControllerOwner;
import org.thoughtcrime.securesms.components.voice.VoiceNotePlaybackState; import org.thoughtcrime.securesms.components.voice.VoiceNotePlaybackState;
import org.thoughtcrime.securesms.contactshare.Contact; import org.thoughtcrime.securesms.contactshare.Contact;
import org.thoughtcrime.securesms.contactshare.ContactUtil; import org.thoughtcrime.securesms.contactshare.ContactUtil;
@ -334,6 +335,9 @@ public class ConversationFragment extends LoggingFragment {
conversationUpdateTick = new ConversationUpdateTick(this::updateConversationItemTimestamps); conversationUpdateTick = new ConversationUpdateTick(this::updateConversationItemTimestamps);
getViewLifecycleOwner().getLifecycle().addObserver(conversationUpdateTick); getViewLifecycleOwner().getLifecycle().addObserver(conversationUpdateTick);
listener.getVoiceNoteMediaController().getVoiceNotePlayerViewState().observe(getViewLifecycleOwner(), state -> conversationViewModel.setInlinePlayerVisible(state.isPresent()));
conversationViewModel.getScrollDateTopMargin().observe(getViewLifecycleOwner(), topMargin -> ViewUtil.setTopMargin(scrollDateHeader, topMargin));
return view; return view;
} }
@ -1280,15 +1284,14 @@ public class ConversationFragment extends LoggingFragment {
public void onGlobalLayout() { public void onGlobalLayout() {
Rect rect = new Rect(); Rect rect = new Rect();
toolbar.getGlobalVisibleRect(rect); toolbar.getGlobalVisibleRect(rect);
ViewUtil.setTopMargin(scrollDateHeader, rect.bottom + ViewUtil.dpToPx(8)); conversationViewModel.setToolbarBottom(rect.bottom + ViewUtil.dpToPx(8));
ViewUtil.setTopMargin(conversationBanner, rect.bottom + ViewUtil.dpToPx(16)); ViewUtil.setTopMargin(conversationBanner, rect.bottom + ViewUtil.dpToPx(16));
toolbar.getViewTreeObserver().removeOnGlobalLayoutListener(this); toolbar.getViewTreeObserver().removeOnGlobalLayoutListener(this);
} }
}); });
} }
public interface ConversationFragmentListener { public interface ConversationFragmentListener extends VoiceNoteMediaControllerOwner {
void setThreadId(long threadId); void setThreadId(long threadId);
void handleReplyMessage(ConversationMessage conversationMessage); void handleReplyMessage(ConversationMessage conversationMessage);
void onMessageActionToolbarOpened(); void onMessageActionToolbarOpened();

View file

@ -36,6 +36,7 @@ import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientId; import org.thoughtcrime.securesms.recipients.RecipientId;
import org.thoughtcrime.securesms.util.DefaultValueLiveData; import org.thoughtcrime.securesms.util.DefaultValueLiveData;
import org.thoughtcrime.securesms.util.SingleLiveEvent; import org.thoughtcrime.securesms.util.SingleLiveEvent;
import org.thoughtcrime.securesms.util.ViewUtil;
import org.thoughtcrime.securesms.util.livedata.LiveDataUtil; import org.thoughtcrime.securesms.util.livedata.LiveDataUtil;
import org.thoughtcrime.securesms.wallpaper.ChatWallpaper; import org.thoughtcrime.securesms.wallpaper.ChatWallpaper;
import org.whispersystems.libsignal.util.Pair; import org.whispersystems.libsignal.util.Pair;
@ -69,6 +70,9 @@ public class ConversationViewModel extends ViewModel {
private final LiveData<ChatWallpaper> wallpaper; private final LiveData<ChatWallpaper> wallpaper;
private final SingleLiveEvent<Event> events; private final SingleLiveEvent<Event> events;
private final LiveData<ChatColors> chatColors; private final LiveData<ChatColors> chatColors;
private final MutableLiveData<Integer> toolbarBottom;
private final MutableLiveData<Integer> inlinePlayerHeight;
private final LiveData<Integer> scrollDateTopMargin;
private final Map<GroupId, Set<Recipient>> sessionMemberCache = new HashMap<>(); private final Map<GroupId, Set<Recipient>> sessionMemberCache = new HashMap<>();
@ -87,6 +91,9 @@ public class ConversationViewModel extends ViewModel {
this.events = new SingleLiveEvent<>(); this.events = new SingleLiveEvent<>();
this.pagingController = new ProxyPagingController(); this.pagingController = new ProxyPagingController();
this.messageObserver = pagingController::onDataInvalidated; this.messageObserver = pagingController::onDataInvalidated;
this.toolbarBottom = new MutableLiveData<>();
this.inlinePlayerHeight = new MutableLiveData<>();
this.scrollDateTopMargin = Transformations.distinctUntilChanged(LiveDataUtil.combineLatest(toolbarBottom, inlinePlayerHeight, Integer::sum));
LiveData<Recipient> recipientLiveData = LiveDataUtil.mapAsync(recipientId, Recipient::resolved); LiveData<Recipient> recipientLiveData = LiveDataUtil.mapAsync(recipientId, Recipient::resolved);
LiveData<ThreadAndRecipient> threadAndRecipient = LiveDataUtil.combineLatest(threadId, recipientLiveData, ThreadAndRecipient::new); LiveData<ThreadAndRecipient> threadAndRecipient = LiveDataUtil.combineLatest(threadId, recipientLiveData, ThreadAndRecipient::new);
@ -144,6 +151,14 @@ public class ConversationViewModel extends ViewModel {
Recipient::getChatColors); Recipient::getChatColors);
} }
void setToolbarBottom(int bottom) {
toolbarBottom.postValue(bottom);
}
void setInlinePlayerVisible(boolean isVisible) {
inlinePlayerHeight.postValue(isVisible ? ViewUtil.dpToPx(36) : 0);
}
void onAttachmentKeyboardOpen() { void onAttachmentKeyboardOpen() {
mediaRepository.getMediaInBucket(context, Media.ALL_MEDIA_BUCKET_ID, recentMedia::postValue); mediaRepository.getMediaInBucket(context, Media.ALL_MEDIA_BUCKET_ID, recentMedia::postValue);
} }
@ -162,6 +177,10 @@ public class ConversationViewModel extends ViewModel {
this.threadId.postValue(-1L); this.threadId.postValue(-1L);
} }
@NonNull LiveData<Integer> getScrollDateTopMargin() {
return scrollDateTopMargin;
}
@NonNull LiveData<Boolean> canShowAsBubble() { @NonNull LiveData<Boolean> canShowAsBubble() {
return canShowAsBubble; return canShowAsBubble;
} }

View file

@ -84,10 +84,11 @@
android:maxWidth="140dp" android:maxWidth="140dp"
android:maxLines="1" android:maxLines="1"
android:visibility="gone" android:visibility="gone"
app:layout_constraintStart_toEndOf="@id/date_and_expiry_wrapper"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/footer_insecure_indicator" app:layout_constraintEnd_toStartOf="@id/footer_insecure_indicator"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
tools:text="to SIM1" /> tools:text="Sim Op" />
<ImageView <ImageView
android:id="@+id/footer_insecure_indicator" android:id="@+id/footer_insecure_indicator"
@ -99,7 +100,7 @@
android:src="@drawable/ic_unlocked_white_18dp" android:src="@drawable/ic_unlocked_white_18dp"
android:visibility="gone" android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@id/date_and_expiry_wrapper" app:layout_constraintStart_toEndOf="@id/footer_sim_info"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
tools:visibility="visible" /> tools:visibility="visible" />

View file

@ -22,15 +22,21 @@
android:id="@+id/voice_note_player_info" android:id="@+id/voice_note_player_info"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:ellipsize="marquee"
android:gravity="center_vertical" android:gravity="center_vertical"
android:marqueeRepeatLimit="marquee_forever"
android:minHeight="36dp" android:minHeight="36dp"
android:paddingStart="0dp"
android:paddingEnd="13dp"
android:singleLine="true"
android:textAppearance="@style/TextAppearance.Signal.Body2" android:textAppearance="@style/TextAppearance.Signal.Body2"
android:textColor="@color/signal_icon_tint_primary" android:textColor="@color/signal_icon_tint_primary"
app:layout_constrainedWidth="true"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/voice_note_player_speed" app:layout_constraintEnd_toStartOf="@id/voice_note_player_speed_touch_target"
app:layout_constraintStart_toEndOf="@id/voice_note_player_play_pause_toggle" app:layout_constraintStart_toEndOf="@id/voice_note_player_play_pause_toggle"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
tools:text="Miles Morales · 5:20" /> tools:text="Miles Morales in Some strange spider-man group · 5:20" />
<FrameLayout <FrameLayout
android:id="@+id/voice_note_player_speed_touch_target" android:id="@+id/voice_note_player_speed_touch_target"