/**
* 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.pages.main.connect.views;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.waz.api.IConversation;
import com.waz.api.User;
import com.waz.zclient.core.api.scala.ModelObserver;
import com.waz.zclient.ui.views.UserDetailsView;
import com.waz.zclient.utils.LayoutSpec;
import com.waz.zclient.R;
import com.waz.zclient.pages.main.connect.ConnectActionsCallback;
import com.waz.zclient.ui.utils.TextViewUtils;
import com.waz.zclient.utils.ViewUtils;
import com.waz.zclient.ui.animation.interpolators.penner.Expo;
import com.waz.zclient.ui.animation.interpolators.penner.Quart;
import com.waz.zclient.ui.views.ZetaButton;
import com.waz.zclient.views.images.ImageAssetImageView;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class ConnectRequestInboxRow extends FrameLayout {
public static final String TAG = ConnectRequestInboxRow.class.getName();
// Model this view is bound to
private User user;
private ConnectActionsCallback connectActionCallback;
private ZetaButton ignoreButton;
private ZetaButton acceptButton;
private TextView displayNameTextView;
private UserDetailsView userDetailsView;
private LinearLayout acceptMenu;
private ValueAnimator rowHeightAnimator;
private ImageAssetImageView imageAssetImageViewProfile;
private final ModelObserver<User> userModelObserver = new ModelObserver<User>() {
@Override
public void updated(User user) {
if (imageAssetImageViewProfile != null) {
imageAssetImageViewProfile.connectImageAsset(user.getPicture());
}
displayNameTextView.setText(user.getName());
TextViewUtils.boldText(displayNameTextView);
userDetailsView.setUser(user);
// Toggle accept / ignore buttons
if (user.getConnectionStatus() == User.ConnectionStatus.PENDING_FROM_OTHER ||
user.getConnectionStatus() == User.ConnectionStatus.IGNORED) {
acceptMenu.setVisibility(View.VISIBLE);
ignoreButton.setEnabled(true);
ignoreButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
ignoreButton.setEnabled(false);
animateIgnore(ConnectRequestInboxRow.this.user);
}
});
acceptButton.setEnabled(true);
acceptButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
acceptButton.setEnabled(false);
animateAccept(ConnectRequestInboxRow.this.user);
}
});
} else {
acceptMenu.setVisibility(View.GONE);
ignoreButton.setOnClickListener(null);
acceptButton.setOnClickListener(null);
}
}
};
public ConnectRequestInboxRow(Context context) {
this(context, null);
}
public ConnectRequestInboxRow(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ConnectRequestInboxRow(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
View container = LayoutInflater.from(getContext()).inflate(R.layout.fragment_connect_request_pending_inbox, this, true);
ignoreButton = ViewUtils.getView(container, R.id.zb__connect_request__ignore_button);
acceptButton = ViewUtils.getView(container, R.id.zb__connect_request__accept_button);
displayNameTextView = ViewUtils.getView(container, R.id.ttv__connect_request__display_name);
userDetailsView = ViewUtils.getView(container, R.id.udv__connect_request__user_details);
acceptMenu = ViewUtils.getView(container, R.id.ll__connect_request__accept_menu);
if (LayoutSpec.isTablet(getContext())) {
View mainContainerView = ViewUtils.getView(container,
R.id.ll__connect_request__main_container);
ViewUtils.setWidth(mainContainerView,
getResources().getDimensionPixelSize(R.dimen.connect_request__inbox__max_width));
}
imageAssetImageViewProfile = ViewUtils.getView(container, R.id.iaiv__pending_connect);
if (imageAssetImageViewProfile != null) {
imageAssetImageViewProfile.setDisplayType(ImageAssetImageView.DisplayType.CIRCLE);
}
// Hide accept menu, check later when user loaded
acceptMenu.setVisibility(View.GONE);
}
public void setConnectActionCallback(ConnectActionsCallback callback) {
connectActionCallback = callback;
}
public void setAccentColor(int accentColor) {
// Accept / ignore buttons
ignoreButton.setIsFilled(false);
ignoreButton.setAccentColor(accentColor);
ignoreButton.setTextColor(accentColor);
acceptButton.setAccentColor(accentColor);
}
public void loadUser(User user) {
this.user = user;
userModelObserver.setAndUpdate(user);
for (View v : Arrays.asList(ignoreButton,
displayNameTextView, acceptButton, acceptMenu)) {
if (v == null) {
continue;
}
v.setAlpha(1f);
v.setTranslationX(0f);
}
if (LayoutSpec.isTablet(getContext())) {
if (rowHeightAnimator != null) {
rowHeightAnimator.cancel();
rowHeightAnimator = null;
}
ViewGroup.LayoutParams params = getLayoutParams();
if (params != null) {
params.height = ViewGroup.LayoutParams.MATCH_PARENT;
setLayoutParams(params);
}
}
}
private void animateAccept(final User user) {
final int animationDuration = getResources().getInteger(R.integer.framework_animation_duration_medium);
final List<Animator> animatorList = new ArrayList<>();
final int translationDestination = -displayNameTextView.getWidth();
for (View v : Arrays.asList(displayNameTextView)) {
if (v == null) {
continue;
}
ObjectAnimator animator = ObjectAnimator.ofFloat(v, View.TRANSLATION_X, translationDestination);
animator.setInterpolator(new Expo.EaseIn());
animatorList.add(animator);
}
for (View v : Arrays.asList(ignoreButton, acceptButton, acceptMenu)) {
if (v == null) {
continue;
}
ObjectAnimator animator = ObjectAnimator.ofFloat(v, View.ALPHA, 0f);
animator.setInterpolator(new Quart.EaseOut());
animatorList.add(animator);
}
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
scaleOutIfNecessary(new Runnable() {
@Override
public void run() {
final IConversation conversation = user.acceptConnection();
if (connectActionCallback != null) {
connectActionCallback.onAccepted(conversation);
}
}
});
}
});
animatorSet.setDuration(animationDuration);
animatorSet.playTogether(animatorList);
animatorSet.start();
}
private void scaleOutIfNecessary(final Runnable callback) {
if (LayoutSpec.isPhone(getContext())) {
post(callback);
} else {
rowHeightAnimator = ValueAnimator.ofInt(getHeight(), 1);
rowHeightAnimator.setDuration(getResources().getInteger(R.integer.framework_animation_duration_medium));
rowHeightAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(final ValueAnimator valueAnimator) {
ViewGroup.LayoutParams layoutParams = getLayoutParams();
layoutParams.height = (Integer) valueAnimator.getAnimatedValue();
setLayoutParams(layoutParams);
}
});
rowHeightAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
rowHeightAnimator = null;
post(callback);
}
});
rowHeightAnimator.start();
}
}
private void animateIgnore(final User user) {
final int animationDuration = getResources().getInteger(R.integer.framework_animation_duration_medium);
final List<Animator> animatorList = new ArrayList<>();
for (View v : Arrays.asList(ignoreButton,
displayNameTextView, acceptButton, acceptMenu)) {
if (v == null) {
continue;
}
ObjectAnimator animator = ObjectAnimator.ofFloat(v, View.ALPHA, 0f);
animator.setInterpolator(new Quart.EaseOut());
animatorList.add(animator);
}
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
scaleOutIfNecessary(new Runnable() {
@Override
public void run() {
if (connectActionCallback != null) {
user.ignoreConnection();
connectActionCallback.onIgnored(user);
}
}
});
}
});
animatorSet.setDuration(animationDuration);
animatorSet.playTogether(animatorList);
animatorSet.start();
}
}