/**
* Wire
* Copyright (C) 2016 Wire Swiss GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.waz.zclient.ui.cursor;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.drawable.ColorDrawable;
import android.os.Handler;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.res.ResourcesCompat;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.FrameLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.waz.api.EphemeralExpiration;
import com.waz.api.IConversation;
import com.waz.api.Message;
import com.waz.api.MessageContent;
import com.waz.zclient.core.api.scala.ModelObserver;
import com.waz.zclient.ui.R;
import com.waz.zclient.ui.animation.interpolators.penner.Expo;
import com.waz.zclient.ui.animation.interpolators.penner.Quart;
import com.waz.zclient.ui.theme.ThemeUtils;
import com.waz.zclient.ui.utils.ColorUtils;
import com.waz.zclient.ui.utils.CursorUtils;
import com.waz.zclient.ui.utils.ResourceUtils;
import com.waz.zclient.ui.utils.TypefaceUtils;
import com.waz.zclient.ui.views.CursorIconButton;
import com.waz.zclient.ui.views.OnDoubleClickListener;
import com.waz.zclient.utils.LayoutSpec;
import com.waz.zclient.utils.StringUtils;
import com.waz.zclient.utils.ViewUtils;
import java.util.Arrays;
import java.util.List;
public class CursorLayout extends FrameLayout implements
TextView.OnEditorActionListener,
TextWatcher,
CursorToolbar.Callback,
EditMessageCursorToolbar.Callback {
private static final long TOOLTIP_DURATION = 1500;
private static List<CursorMenuItem> mainCursorItems = Arrays.asList(CursorMenuItem.CAMERA,
CursorMenuItem.VIDEO_MESSAGE,
CursorMenuItem.SKETCH,
CursorMenuItem.GIF,
CursorMenuItem.AUDIO_MESSAGE,
CursorMenuItem.MORE);
private static List<CursorMenuItem> secondaryCursorItems = Arrays.asList(CursorMenuItem.PING,
CursorMenuItem.FILE,
CursorMenuItem.LOCATION,
CursorMenuItem.DUMMY,
CursorMenuItem.DUMMY,
CursorMenuItem.LESS);
private View editMessageBackgroundView;
private CursorToolbarFrame cursorToolbarFrame;
private CursorEditText newCursorEditText;
private CursorIconButton sendButton;
private CursorIconButton ephemeralButton;
private CursorToolbar mainToolbar;
private CursorToolbar secondaryToolbar;
private EditMessageCursorToolbar editMessageCursorToolbar;
private View topBorder;
private TextView tooltip;
private TextView hintView;
private View dividerView;
private CursorIconButton emojiButton;
private CursorIconButton keyboardButton;
private CursorCallback cursorCallback;
private boolean sendButtonIsVisible;
private boolean tooltipEnabled;
private boolean isEditingMessage;
private boolean ephemeralSelected;
private int anchorPositionPx2;
private int maxLines = 2;
private boolean keyboardIsVisible;
private int cursorHeight;
private int cursorToolbarAnimationDuration;
private ObjectAnimator showMainToolbarAnimator;
private ObjectAnimator showSecondaryToolbarAnimator;
private ObjectAnimator hideMainToolbarAnimator;
private ObjectAnimator hideSecondaryToolbarAnimator;
private ObjectAnimator showEditMessageToolbarAnimator;
private ObjectAnimator hideEditMessageToolbarAnimator;
private Message message;
private int defaultEditTextColor;
private int defaultDividerColor;
private int defaultHintTextColor;
private int ephemeralColor;
private int accentColor;
private IConversation conversation;
private ModelObserver<IConversation> conversationModelObserver = new ModelObserver<IConversation>() {
@Override
public void updated(IConversation conversation) {
if (isEditingMessage) {
dividerView.setBackgroundColor(ContextCompat.getColor(getContext(), R.color.separator_light));
} else if (conversation.isEphemeral() || ephemeralSelected) {
dividerView.setBackgroundColor(ephemeralColor);
hintView.setText(R.string.cursor__ephemeral_message);
hintView.setTextColor(ephemeralColor);
ephemeralButton.setTextColor(ephemeralColor);
updateEphemeralButtonBackground();
sendButton.setSolidBackgroundColor(ephemeralColor);
emojiButton.showEphemeralMode(ephemeralColor);
keyboardButton.showEphemeralMode(ephemeralColor);
mainToolbar.showEphemeralMode(ephemeralColor);
secondaryToolbar.showEphemeralMode(ephemeralColor);
} else {
dividerView.setBackgroundColor(defaultDividerColor);
hintView.setText(R.string.cursor__type_a_message);
hintView.setTextColor(defaultHintTextColor);
ephemeralButton.setTextColor(defaultEditTextColor);
updateEphemeralButtonBackground();
sendButton.setSolidBackgroundColor(accentColor);
emojiButton.hideEphemeralMode(defaultEditTextColor);
keyboardButton.hideEphemeralMode(defaultEditTextColor);
mainToolbar.hideEphemeraMode(defaultEditTextColor);
secondaryToolbar.hideEphemeraMode(defaultEditTextColor);
}
if (!isEditingMessage &&
conversation.isActive() &&
StringUtils.isBlank(newCursorEditText.getText().toString()) &&
!sendButtonIsVisible) {
ephemeralButton.setVisibility(VISIBLE);
} else {
ephemeralButton.setVisibility(GONE);
}
}
};
private OnDoubleClickListener ephemeralButtonDoubleClickListener = new OnDoubleClickListener() {
@Override
public void onDoubleClick() {
if (cursorCallback == null || conversation == null) {
return;
}
cursorCallback.onEphemeralButtonDoubleClicked(conversation.getEphemeralExpiration());
}
@Override
public void onSingleClick() {
if (cursorCallback == null || conversation == null) {
return;
}
cursorCallback.onEphemeralButtonClicked(conversation.getEphemeralExpiration());
ephemeralSelected = true;
conversationModelObserver.updated(conversation);
}
};
public CursorLayout(Context context) {
this(context, null);
}
public CursorLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CursorLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
anchorPositionPx2 = getResources().getDimensionPixelSize(R.dimen.cursor_anchor2);
ephemeralColor = ContextCompat.getColor(getContext(), R.color.ephemera);
}
/**
* The width of the view is needed as it defines the third
* anchor position.
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (LayoutSpec.get(getContext()) == LayoutSpec.LAYOUT_PHONE ||
LayoutSpec.get(getContext()) == LayoutSpec.LAYOUT_KINDLE) {
int paddingEdge = getResources().getDimensionPixelSize(R.dimen.cursor_toolbar_padding_horizontal_edge);
cursorToolbarFrame.setPadding(paddingEdge, 0, paddingEdge, 0);
return;
}
int width = MeasureSpec.getSize(widthMeasureSpec);
anchorPositionPx2 = CursorUtils.getCursorEditTextAnchorPosition(getContext(), width);
if (ViewUtils.isInPortrait(getContext())) {
int left = CursorUtils.getCursorMenuLeftMargin(getContext(), width);
((FrameLayout.LayoutParams) newCursorEditText.getLayoutParams()).leftMargin = anchorPositionPx2;
((FrameLayout.LayoutParams) hintView.getLayoutParams()).leftMargin = anchorPositionPx2;
cursorToolbarFrame.setPadding(left, 0, left, 0);
} else {
int left = CursorUtils.getCursorMenuLeftMargin(getContext(), width);
((FrameLayout.LayoutParams) newCursorEditText.getLayoutParams()).leftMargin = anchorPositionPx2;
((FrameLayout.LayoutParams) hintView.getLayoutParams()).leftMargin = anchorPositionPx2;
cursorToolbarFrame.setPadding(left, 0, left, 0);
}
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
editMessageBackgroundView = ViewUtils.getView(this, R.id.fl__edit_message__background);
cursorToolbarFrame = ViewUtils.getView(this, R.id.cal__cursor);
newCursorEditText = ViewUtils.getView(this, R.id.cet__cursor);
mainToolbar = ViewUtils.getView(this, R.id.c__cursor__main);
secondaryToolbar = ViewUtils.getView(this, R.id.c__cursor__secondary);
editMessageCursorToolbar = ViewUtils.getView(this, R.id.emct__edit_message__toolbar);
topBorder = ViewUtils.getView(this, R.id.v__top_bar__cursor);
tooltip = ViewUtils.getView(this, R.id.ctv__cursor);
hintView = ViewUtils.getView(this, R.id.ttv__cursor_hint);
defaultHintTextColor = hintView.getTextColors().getDefaultColor();
dividerView = ViewUtils.getView(this, R.id.v__cursor__divider);
FrameLayout emojiButtonContainer = ViewUtils.getView(this, R.id.fl__cursor__emoji_container);
FrameLayout sendButtonContainer = ViewUtils.getView(this, R.id.fl__cursor__send_button_container);
mainToolbar.setCursorItems(mainCursorItems);
secondaryToolbar.setCursorItems(secondaryCursorItems);
editMessageCursorToolbar.setVisibility(GONE);
editMessageCursorToolbar.setCallback(this);
cursorHeight = getResources().getDimensionPixelSize(R.dimen.new_cursor_height);
secondaryToolbar.setTranslationY(2 * cursorHeight);
cursorToolbarAnimationDuration = getResources().getInteger(R.integer.wire__animation__delay__regular);
tooltip.setVisibility(View.GONE);
connectEditText();
editMessageBackgroundView.setVisibility(GONE);
defaultEditTextColor = newCursorEditText.getCurrentTextColor();
ColorDrawable dividerBg = (ColorDrawable) dividerView.getBackground();
defaultDividerColor = dividerBg.getColor();
// Emoji & keyboard button
LayoutInflater inflater = LayoutInflater.from(getContext());
emojiButton = (CursorIconButton) inflater.inflate(R.layout.cursor__item, this, false);
emojiButton.setCursorMenuItem(CursorMenuItem.EMOJI);
emojiButton.setPressedBackgroundColor(ContextCompat.getColor(getContext(), R.color.light_graphite));
keyboardButton = (CursorIconButton) inflater.inflate(R.layout.cursor__item, this, false);
keyboardButton.setCursorMenuItem(CursorMenuItem.KEYBOARD);
keyboardButton.setPressedBackgroundColor(ContextCompat.getColor(getContext(), R.color.light_graphite));
keyboardButton.setVisibility(GONE);
int buttonWidth = getResources().getDimensionPixelSize(R.dimen.cursor__menu_button__diameter);
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(buttonWidth,
buttonWidth);
params.gravity = Gravity.END | Gravity.CENTER_VERTICAL;
params.setMarginEnd(getResources().getDimensionPixelSize(R.dimen.chathead__margin));
emojiButtonContainer.addView(keyboardButton, params);
emojiButtonContainer.addView(emojiButton, params);
emojiButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
if (cursorCallback == null) {
return;
}
mainToolbar.unselectItems();
emojiButton.setVisibility(GONE);
keyboardButton.setVisibility(VISIBLE);
cursorCallback.onEmojiButtonClicked(true);
resetEphemeralButton();
}
});
keyboardButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
if (cursorCallback == null) {
return;
}
mainToolbar.unselectItems();
emojiButton.setVisibility(VISIBLE);
keyboardButton.setVisibility(GONE);
cursorCallback.onEmojiButtonClicked(false);
resetEphemeralButton();
}
});
// Send button
int sendButtonWidth = getResources().getDimensionPixelSize(R.dimen.cursor__send_button__width);
int sendButtonHeight = getResources().getDimensionPixelSize(R.dimen.cursor__send_button__height);
sendButton = (CursorIconButton) inflater.inflate(R.layout.cursor__item, this, false);
sendButton.setText(R.string.glyph__send);
sendButton.setTextColor(ContextCompat.getColor(getContext(), R.color.text__primary_dark));
sendButtonContainer.addView(sendButton, new FrameLayout.LayoutParams(sendButtonWidth, sendButtonHeight));
sendButton.setVisibility(View.INVISIBLE);
// Ephemeral button
ephemeralButton = (CursorIconButton) inflater.inflate(R.layout.cursor__item__ephemeral, this, false);
ephemeralButton.setText(R.string.glyph__hourglass);
ephemeralButton.setTextColor(defaultEditTextColor);
ephemeralButton.setGravity(Gravity.CENTER);
params = new FrameLayout.LayoutParams(sendButtonWidth, sendButtonHeight);
params.gravity = Gravity.CENTER;
sendButtonContainer.addView(ephemeralButton, params);
ephemeralButton.setOnClickListener(ephemeralButtonDoubleClickListener);
ephemeralButton.setVisibility(GONE);
}
public void setCursorCallback(CursorCallback cursorCallback) {
this.cursorCallback = cursorCallback;
mainToolbar.setCallback(this);
secondaryToolbar.setCallback(this);
}
public void setAccentColor(int accentColor) {
ephemeralColor = accentColor;
newCursorEditText.setAccentColor(accentColor);
sendButton.setSolidBackgroundColor(accentColor);
mainToolbar.setAccentColor(accentColor);
this.accentColor = accentColor;
if (conversation == null || !conversation.isEphemeral()) {
sendButton.setSolidBackgroundColor(accentColor);
} else if (conversation.isEphemeral()) {
emojiButton.showEphemeralMode(ephemeralColor);
mainToolbar.showEphemeralMode(ephemeralColor);
secondaryToolbar.showEphemeralMode(ephemeralColor);
hintView.setTextColor(ephemeralColor);
dividerView.setBackgroundColor(ephemeralColor);
ephemeralButton.setTextColor(ephemeralColor);
keyboardButton.setTextColor(ephemeralColor);
updateEphemeralButtonBackground();
}
}
private void connectEditText() {
newCursorEditText.addTextChangedListener(this);
newCursorEditText.setOnEditorActionListener(this);
newCursorEditText.setOnFocusChangeListener(new OnFocusChangeListener() {
@Override
public void onFocusChange(View view, boolean hasFocus) {
if (hasFocus && cursorCallback != null) {
cursorCallback.onFocusChange(hasFocus);
}
}
});
newCursorEditText.setFocusableInTouchMode(true);
}
public void enableMessageWriting() {
newCursorEditText.requestFocus();
}
// Edit Text
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
/**
* Notifies container that edit text has changed. And if text is not empty it triggers
* also the typing indicator.
*/
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
if (isEditingMessage()) {
if (message == null) {
return;
}
boolean enableControls = !TextUtils.equals(newCursorEditText.getText(), message.getBody());
hintView.setVisibility(View.GONE);
editMessageCursorToolbar.enableEditControls(enableControls);
return;
}
String text = charSequence.toString();
if (cursorCallback != null) {
cursorCallback.onEditTextHasChanged(newCursorEditText.getSelectionStart(), text);
}
if (TextUtils.isEmpty(charSequence.toString())) {
hintView.setVisibility(View.VISIBLE);
} else {
hintView.setVisibility(View.GONE);
}
showTopbar(newCursorEditText.getLineCount() > maxLines);
}
@Override
public void afterTextChanged(Editable editable) {
// do nothing
}
/**
* EditText callback when user sent text.
*/
@Override
public boolean onEditorAction(TextView textView, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_SEND ||
(newCursorEditText.getImeOptions() == EditorInfo.IME_ACTION_SEND &&
event != null &&
event.getKeyCode() == KeyEvent.KEYCODE_ENTER &&
event.getAction() == KeyEvent.ACTION_DOWN)) {
if (isEditingMessage()) {
onApproveEditMessage();
return true;
}
String sendText = textView.getText().toString();
if (TextUtils.isEmpty(sendText)) {
return false;
}
if (cursorCallback != null) {
cursorCallback.onMessageSubmitted(sendText);
}
return true;
}
return false;
}
public void showSendButtonAsEnterKey(boolean show) {
if (show) {
newCursorEditText.setImeOptions(EditorInfo.IME_ACTION_SEND);
} else {
newCursorEditText.setImeOptions(EditorInfo.IME_ACTION_NONE);
}
}
public void showSendButton(boolean show) {
if (sendButtonIsVisible == show) {
return;
}
sendButtonIsVisible = show;
if (show) {
if (isEditingMessage()) {
return;
}
int duration = getResources().getInteger(R.integer.animation_duration_medium);
ephemeralButton.setVisibility(GONE);
sendButton.setVisibility(View.VISIBLE);
sendButton.setAlpha(0);
sendButton.animate()
.alpha(1f)
.setInterpolator(new Quart.EaseOut())
.setDuration(duration)
.setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
sendButton.setAlpha(1);
}
});
sendButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
if (cursorCallback != null) {
String sendText = newCursorEditText.getText().toString();
if (TextUtils.isEmpty(sendText)) {
return;
}
cursorCallback.onMessageSubmitted(sendText);
}
}
});
} else {
if (conversation != null &&
conversation.isActive()) {
ephemeralButton.setVisibility(VISIBLE);
}
sendButton.setVisibility(View.INVISIBLE);
sendButton.setOnClickListener(null);
}
}
public void setText(String text) {
newCursorEditText.setText(text);
newCursorEditText.setSelection(text.length());
}
public void insertText(String text) {
newCursorEditText.getText().insert(newCursorEditText.getSelectionStart(), text);
}
public void notifyKeyboardVisibilityChanged(boolean keyboardIsVisible, View currentFocus) {
this.keyboardIsVisible = keyboardIsVisible;
if (keyboardIsVisible) {
cursorToolbarFrame.shrink();
if (newCursorEditText.hasFocus() && cursorCallback != null) {
cursorCallback.onCursorClicked();
}
} else {
cursorToolbarFrame.expand();
}
}
public boolean hasText() {
return !TextUtils.isEmpty(newCursorEditText.getText().toString());
}
public String getText() {
return newCursorEditText.getText().toString();
}
public int getSelection() {
return newCursorEditText.getSelectionEnd();
}
public void setSelection(int selection) {
this.newCursorEditText.setSelection(selection);
}
public void setConversation(IConversation conversation) {
this.conversation = conversation;
enableMessageWriting();
resetMainAndSecondaryToolbars();
closeEditMessage(false);
conversationModelObserver.setAndUpdate(conversation);
}
@Override
public void onCursorButtonClicked(CursorMenuItem item) {
if (item == CursorMenuItem.DUMMY) {
return;
}
if (cursorCallback != null) {
cursorCallback.onCursorButtonClicked(item);
}
switch (item) {
case MORE:
showSecondaryCursorToolbar();
break;
case LESS:
hideSecondaryCursorToolbar();
break;
case CAMERA:
case AUDIO_MESSAGE:
resetEmojiButton();
resetEphemeralButton();
break;
}
}
@Override
public void onCursorButtonLongPressed(CursorMenuItem cursorMenuItem) {
if (cursorMenuItem == CursorMenuItem.DUMMY ||
cursorMenuItem == CursorMenuItem.KEYBOARD) {
return;
}
if (cursorCallback != null) {
cursorCallback.onCursorButtonLongPressed(cursorMenuItem);
}
}
@Override
public void onMotionEvent(CursorMenuItem cursorMenuItem, MotionEvent motionEvent) {
if (cursorCallback != null) {
cursorCallback.onMotionEventFromCursorButton(cursorMenuItem, motionEvent);
}
}
@Override
public void onShowTooltip(CursorMenuItem item, String message, View anchor) {
if (tooltipEnabled) {
return;
}
int w = (int) (anchor.getX() + anchor.getMeasuredWidth() / 2);
int gravity;
if (w < getMeasuredWidth() / 4) {
gravity = Gravity.LEFT | Gravity.CENTER_VERTICAL;
} else if (w > 3 * getMeasuredWidth() / 4) {
gravity = Gravity.RIGHT | Gravity.CENTER_VERTICAL;
} else {
gravity = Gravity.CENTER;
}
((FrameLayout.LayoutParams) tooltip.getLayoutParams()).gravity = gravity;
tooltipEnabled = true;
tooltip.setText(message);
tooltip
.animate()
.alpha(1)
.withStartAction(new Runnable() {
@Override
public void run() {
tooltip.setVisibility(View.VISIBLE);
tooltip.setAlpha(0);
}
});
if (cursorCallback != null) {
cursorCallback.onShowedActionHint(item);
}
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
dismissToolbar();
}
}, TOOLTIP_DURATION);
}
@Override
public void onCloseEditMessage() {
closeEditMessage(true);
}
@Override
public void onResetEditMessage() {
if (message == null) {
return;
}
newCursorEditText.setText(message.getBody());
newCursorEditText.setSelection(newCursorEditText.getText().length());
}
@Override
public void onApproveEditMessage() {
if (TextUtils.isEmpty(newCursorEditText.getText().toString().trim())) {
message.recall();
Toast.makeText(getContext(), R.string.conversation__message_action__delete__confirmation, Toast.LENGTH_SHORT).show();
} else {
message.update(new MessageContent.Text(newCursorEditText.getText().toString()));
}
if (cursorCallback != null) {
cursorCallback.onApprovedMessageEditing(message);
}
closeEditMessage(true);
}
public boolean isEditingMessage() {
return isEditingMessage;
}
public void editMessage(Message message) {
isEditingMessage = true;
this.message = message;
newCursorEditText.setText(message.getBody());
newCursorEditText.setSelection(newCursorEditText.getText().length());
if (sendButtonIsVisible) {
showSendButton(false);
}
ephemeralButton.setVisibility(GONE);
setBackgroundColor(ContextCompat.getColor(getContext(), R.color.white));
ViewUtils.fadeInView(editMessageBackgroundView);
newCursorEditText.setTextColor(ContextCompat.getColor(getContext(), R.color.text__primary_light));
dividerView.setBackgroundColor(ContextCompat.getColor(getContext(), R.color.separator_light));
emojiButton.setTextColor(ResourcesCompat.getColorStateList(getResources(), R.color.wire__text_color_primary_light_selector, null));
keyboardButton.setTextColor(ResourcesCompat.getColorStateList(getResources(), R.color.wire__text_color_primary_light_selector, null));
showEditMessageToolbar();
}
public void closeEditMessage(boolean animated) {
if (!isEditingMessage) {
return;
}
message = null;
newCursorEditText.setText("");
hintView.setVisibility(VISIBLE);
isEditingMessage = false;
if (animated) {
hideEditMessageToolbar();
ViewUtils.fadeOutView(editMessageBackgroundView);
} else {
editMessageCursorToolbar.setVisibility(GONE);
editMessageBackgroundView.setVisibility(GONE);
resetMainAndSecondaryToolbars();
}
setBackgroundColor(ContextCompat.getColor(getContext(), R.color.transparent));
newCursorEditText.setTextColor(defaultEditTextColor);
if (conversation != null && conversation.isEphemeral()) {
dividerView.setBackgroundColor(ContextCompat.getColor(getContext(), R.color.ephemera));
} else {
dividerView.setBackgroundColor(defaultDividerColor);
}
if (cursorCallback != null) {
cursorCallback.onClosedMessageEditing();
}
ColorStateList cursorButtonColor = ThemeUtils.isDarkTheme(getContext()) ?
ResourcesCompat.getColorStateList(getResources(), R.color.wire__text_color_primary_dark_selector, null) :
ResourcesCompat.getColorStateList(getResources(), R.color.wire__text_color_primary_light_selector, null);
emojiButton.setTextColor(cursorButtonColor);
keyboardButton.setTextColor(cursorButtonColor);
resetEphemeralButton();
}
private void dismissToolbar() {
if (!tooltipEnabled) {
return;
}
tooltipEnabled = false;
tooltip
.animate()
.alpha(0)
.withEndAction(new Runnable() {
@Override
public void run() {
tooltip.setVisibility(View.GONE);
}
});
}
private void hideEditMessageToolbar() {
if (showMainToolbarAnimator == null) {
showMainToolbarAnimator = getShowToolbarAnimator(mainToolbar, -cursorHeight, 0);
}
if (hideEditMessageToolbarAnimator == null) {
hideEditMessageToolbarAnimator = getHideToolbarAnimator(editMessageCursorToolbar, 0, 2 * cursorHeight);
}
mainToolbar.setVisibility(VISIBLE);
showMainToolbarAnimator.start();
hideEditMessageToolbarAnimator.start();
}
private void showEditMessageToolbar() {
ObjectAnimator hideAnimator;
if (mainToolbar.getVisibility() == VISIBLE) {
if (hideMainToolbarAnimator == null) {
hideMainToolbarAnimator = getHideToolbarAnimator(mainToolbar, 0, -cursorHeight);
}
hideAnimator = hideMainToolbarAnimator;
} else {
if (hideSecondaryToolbarAnimator == null) {
hideSecondaryToolbarAnimator = getHideToolbarAnimator(secondaryToolbar, 0, 2 * cursorHeight);
}
hideAnimator = hideSecondaryToolbarAnimator;
}
if (showEditMessageToolbarAnimator == null) {
showEditMessageToolbarAnimator = getShowToolbarAnimator(editMessageCursorToolbar, 2 * cursorHeight, 0);
}
editMessageCursorToolbar.setVisibility(VISIBLE);
hideAnimator.start();
showEditMessageToolbarAnimator.start();
}
private void showSecondaryCursorToolbar() {
if (hideMainToolbarAnimator == null) {
hideMainToolbarAnimator = getHideToolbarAnimator(mainToolbar, 0, -cursorHeight);
}
if (showSecondaryToolbarAnimator == null) {
showSecondaryToolbarAnimator = getShowToolbarAnimator(secondaryToolbar, 2 * cursorHeight, 0);
}
secondaryToolbar.setVisibility(VISIBLE);
hideMainToolbarAnimator.start();
showSecondaryToolbarAnimator.start();
}
private void hideSecondaryCursorToolbar() {
if (showMainToolbarAnimator == null) {
showMainToolbarAnimator = getShowToolbarAnimator(mainToolbar, -cursorHeight, 0);
}
if (hideSecondaryToolbarAnimator == null) {
hideSecondaryToolbarAnimator = getHideToolbarAnimator(secondaryToolbar, 0, 2 * cursorHeight);
}
mainToolbar.setVisibility(VISIBLE);
showMainToolbarAnimator.start();
hideSecondaryToolbarAnimator.start();
}
private ObjectAnimator getShowToolbarAnimator(View view, float fromValue, float toValue) {
ObjectAnimator animator = ObjectAnimator.ofFloat(view, View.TRANSLATION_Y, fromValue, toValue);
animator.setDuration(cursorToolbarAnimationDuration);
animator.setStartDelay(getResources().getInteger(R.integer.animation_delay_short));
animator.setInterpolator(new Expo.EaseOut());
return animator;
}
private ObjectAnimator getHideToolbarAnimator(final View view, float fromValue, float toValue) {
ObjectAnimator animator = ObjectAnimator.ofFloat(view, View.TRANSLATION_Y, fromValue, toValue);
animator.setDuration(cursorToolbarAnimationDuration);
animator.setInterpolator(new Expo.EaseIn());
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationCancel(Animator animation) {
if (view == null) {
return;
}
view.setVisibility(GONE);
}
@Override
public void onAnimationEnd(Animator animation) {
if (view == null) {
return;
}
view.setVisibility(GONE);
}
});
return animator;
}
public void showTopbar(boolean show) {
if (show) {
topBorder.setVisibility(View.VISIBLE);
} else {
topBorder.setVisibility(View.INVISIBLE);
}
}
public void onExtendedCursorClosed() {
mainToolbar.unselectItems();
resetEmojiButton();
resetEphemeralButton();
}
private void resetMainAndSecondaryToolbars() {
mainToolbar.setTranslationY(0);
mainToolbar.setVisibility(VISIBLE);
secondaryToolbar.setTranslationY(2 * cursorHeight);
secondaryToolbar.setVisibility(GONE);
}
private void resetEmojiButton() {
keyboardButton.setVisibility(GONE);
emojiButton.setVisibility(VISIBLE);
}
private void resetEphemeralButton() {
ephemeralSelected = false;
if (conversation != null) {
conversationModelObserver.updated(conversation);
}
}
private void updateEphemeralButtonBackground() {
if (conversation != null &&
conversation.isEphemeral()) {
EphemeralExpiration expiration = conversation.getEphemeralExpiration();
final String value;
switch (expiration) {
case ONE_DAY:
value = getResources().getString(R.string.cursor__ephemeral_message__timer_days,
String.valueOf(expiration.milliseconds / 1000 / 60 / 60 / 24));
break;
case ONE_MINUTE:
case FIVE_MINUTES:
value = getResources().getString(R.string.cursor__ephemeral_message__timer_min,
String.valueOf(expiration.milliseconds / 1000 / 60));
break;
case FIVE_SECONDS:
case FIFTEEN_SECONDS:
case THIRTY_SECONDS:
case NONE:
default:
value = getResources().getString(R.string.cursor__ephemeral_message__timer_seconds,
String.valueOf(expiration.milliseconds / 1000));
}
int bgColor = ColorUtils.injectAlpha(ResourceUtils.getResourceFloat(getResources(), R.dimen.ephemeral__accent__timer_alpha),
accentColor);
ephemeralButton.setBackground(ColorUtils.getTintedDrawable(getContext(), R.drawable.background__cursor__ephemeral_timer,
bgColor));
ephemeralButton.setText(value);
ephemeralButton.setTypeface(TypefaceUtils.getTypeface(getContext().getString(R.string.wire__typeface__regular)));
ephemeralButton.setTextSize(TypedValue.COMPLEX_UNIT_PX, getContext().getResources().getDimensionPixelSize(R.dimen.wire__text_size__small));
} else {
ephemeralButton.setBackground(null);
ephemeralButton.setTypeface(TypefaceUtils.getTypeface(TypefaceUtils.getGlyphsTypefaceName()));
ephemeralButton.setText(R.string.glyph__hourglass);
ephemeralButton.setTextSize(TypedValue.COMPLEX_UNIT_PX, getContext().getResources().getDimensionPixelSize(R.dimen.wire__text_size__regular));
}
}
}