Update Mention UI/UX to match latest designs.

This commit is contained in:
Cody Henthorne
2020-08-13 09:54:33 -04:00
committed by Greyson Parrelli
parent d63e5165eb
commit 724f3e872b
30 changed files with 353 additions and 201 deletions

View File

@@ -23,9 +23,12 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.view.ContextThemeWrapper;
import androidx.core.util.Pair;
import androidx.core.util.Supplier;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModelProviders;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
@@ -51,6 +54,7 @@ import org.thoughtcrime.securesms.conversation.ui.mentions.MentionsPickerViewMod
import org.thoughtcrime.securesms.imageeditor.model.EditorModel;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.mediapreview.MediaRailAdapter;
import org.thoughtcrime.securesms.mediasend.MediaSendViewModel.HudState;
import org.thoughtcrime.securesms.mediasend.MediaSendViewModel.ViewOnceState;
import org.thoughtcrime.securesms.mms.GlideApp;
import org.thoughtcrime.securesms.permissions.Permissions;
@@ -66,8 +70,11 @@ import org.thoughtcrime.securesms.util.IOFunction;
import org.thoughtcrime.securesms.util.MediaUtil;
import org.thoughtcrime.securesms.util.ServiceUtil;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.thoughtcrime.securesms.util.ThemeUtil;
import org.thoughtcrime.securesms.util.Util;
import org.thoughtcrime.securesms.util.ViewUtil;
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
import org.thoughtcrime.securesms.util.livedata.LiveDataUtil;
import org.thoughtcrime.securesms.util.views.SimpleProgressDialog;
import org.thoughtcrime.securesms.util.views.Stub;
import org.thoughtcrime.securesms.video.VideoUtil;
@@ -82,6 +89,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
/**
@@ -120,8 +128,9 @@ public class MediaSendActivity extends PassphraseRequiredActivity implements Med
private @Nullable LiveRecipient recipient;
private TransportOption transport;
private MediaSendViewModel viewModel;
private TransportOption transport;
private MediaSendViewModel viewModel;
private MentionsPickerViewModel mentionsViewModel;
private InputAwareLayout hud;
private View captionAndRail;
@@ -317,8 +326,8 @@ public class MediaSendActivity extends PassphraseRequiredActivity implements Med
emojiToggle.setOnClickListener(this::onEmojiToggleClicked);
}
initViewModel();
if (FeatureFlags.mentions()) initializeMentionsViewModel();
initViewModel();
revealButton.setOnClickListener(v -> viewModel.onRevealButtonToggled());
continueButton.setOnClickListener(v -> navigateToContactSelect());
@@ -610,6 +619,27 @@ public class MediaSendActivity extends PassphraseRequiredActivity implements Med
}
private void initViewModel() {
LiveData<Pair<HudState, Boolean>> hudStateAndMentionShowing = LiveDataUtil.combineLatest(viewModel.getHudState(),
mentionsViewModel != null ? mentionsViewModel.isShowing()
: new MutableLiveData<>(false),
Pair::new);
hudStateAndMentionShowing.observe(this, p -> {
HudState state = Objects.requireNonNull(p.first);
boolean isMentionPickerShowing = Objects.requireNonNull(p.second);
int captionBackground = R.color.transparent_black_40;
if (state.getRailState() == MediaSendViewModel.RailState.VIEWABLE) {
captionBackground = R.color.core_grey_90;
} else if (state.getViewOnceState() == ViewOnceState.ENABLED) {
captionBackground = 0;
} else if (isMentionPickerShowing){
captionBackground = ThemeUtil.getThemedResourceId(this, R.attr.mention_picker_background_color);
}
captionAndRail.setBackgroundResource(captionBackground);
});
viewModel.getHudState().observe(this, state -> {
if (state == null) return;
@@ -617,18 +647,6 @@ public class MediaSendActivity extends PassphraseRequiredActivity implements Med
composeContainer.setVisibility(state.isComposeVisible() ? View.VISIBLE : (state.getViewOnceState() == ViewOnceState.GONE ? View.GONE : View.INVISIBLE));
captionText.setVisibility(state.isCaptionVisible() ? View.VISIBLE : View.GONE);
int captionBackground;
if (state.getRailState() == MediaSendViewModel.RailState.VIEWABLE) {
captionBackground = R.color.core_grey_90;
} else if (state.getViewOnceState() == ViewOnceState.ENABLED) {
captionBackground = 0;
} else {
captionBackground = R.color.transparent_black_40;
}
captionAndRail.setBackgroundResource(captionBackground);
switch (state.getButtonState()) {
case SEND:
sendButtonContainer.setVisibility(View.VISIBLE);
@@ -766,7 +784,7 @@ public class MediaSendActivity extends PassphraseRequiredActivity implements Med
return;
}
MentionsPickerViewModel mentionsViewModel = ViewModelProviders.of(this, new MentionsPickerViewModel.Factory()).get(MentionsPickerViewModel.class);
mentionsViewModel = ViewModelProviders.of(this, new MentionsPickerViewModel.Factory()).get(MentionsPickerViewModel.class);
recipient.observe(this, mentionsViewModel::onRecipientChange);
composeText.setMentionQueryChangedListener(query -> {
@@ -799,6 +817,17 @@ public class MediaSendActivity extends PassphraseRequiredActivity implements Med
}
composeText.replaceTextWithMention(replacementDisplayName, recipient.getId());
});
MentionPickerPlacer mentionPickerPlacer = new MentionPickerPlacer();
mentionsViewModel.isShowing().observe(this, isShowing -> {
if (isShowing) {
composeRow.getViewTreeObserver().addOnGlobalLayoutListener(mentionPickerPlacer);
} else {
composeRow.getViewTreeObserver().removeOnGlobalLayoutListener(mentionPickerPlacer);
}
mentionPickerPlacer.onGlobalLayout();
});
}
private void presentRecipient(@Nullable Recipient recipient) {
@@ -979,4 +1008,34 @@ public class MediaSendActivity extends PassphraseRequiredActivity implements Med
@Override
public void onFocusChange(View v, boolean hasFocus) {}
}
private class MentionPickerPlacer implements ViewTreeObserver.OnGlobalLayoutListener {
private final int composeMargin;
private final ViewGroup parent;
private final Rect composeCoordinates;
private int previousBottomMargin;
public MentionPickerPlacer() {
parent = findViewById(android.R.id.content);
composeMargin = ViewUtil.dpToPx(12);
composeCoordinates = new Rect();
}
@Override
public void onGlobalLayout() {
composeRow.getDrawingRect(composeCoordinates);
parent.offsetDescendantRectToMyCoords(composeRow, composeCoordinates);
int marginBottom = parent.getHeight() - composeCoordinates.top + composeMargin;
if (marginBottom != previousBottomMargin) {
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) mentionSuggestions.get().getLayoutParams();
params.setMargins(0, 0, 0, marginBottom);
mentionSuggestions.get().setLayoutParams(params);
previousBottomMargin = marginBottom;
}
}
}
}