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:
parent
9876ffb5e4
commit
e584a90f81
7 changed files with 52 additions and 16 deletions
|
@ -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);
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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> {
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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" />
|
||||||
|
|
||||||
|
|
|
@ -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"
|
||||||
|
|
Loading…
Add table
Reference in a new issue