/**
* 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;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.widget.TextView;
import com.waz.api.IConversation;
import com.waz.api.User;
import com.waz.zclient.BaseActivity;
import com.waz.zclient.R;
import com.waz.zclient.controllers.accentcolor.AccentColorObserver;
import com.waz.zclient.controllers.navigation.NavigationController;
import com.waz.zclient.controllers.tracking.events.connect.UnblockingEvent;
import com.waz.zclient.core.stores.connect.ConnectStoreObserver;
import com.waz.zclient.core.stores.connect.IConnectStore;
import com.waz.zclient.pages.BaseFragment;
import com.waz.zclient.pages.main.participants.ProfileAnimation;
import com.waz.zclient.pages.main.participants.ProfileSourceAnimation;
import com.waz.zclient.pages.main.participants.ProfileTabletAnimation;
import com.waz.zclient.pages.main.participants.dialog.DialogLaunchMode;
import com.waz.zclient.tracking.GlobalTrackingController;
import com.waz.zclient.ui.animation.fragment.FadeAnimation;
import com.waz.zclient.ui.theme.ThemeUtils;
import com.waz.zclient.ui.views.UserDetailsView;
import com.waz.zclient.ui.views.ZetaButton;
import com.waz.zclient.utils.LayoutSpec;
import com.waz.zclient.utils.ViewUtils;
import com.waz.zclient.views.images.ImageAssetImageView;
import com.waz.zclient.views.menus.FooterMenu;
import com.waz.zclient.views.menus.FooterMenuCallback;
public class BlockedUserProfileFragment extends BaseFragment<BlockedUserProfileFragment.Container> implements UserProfile,
ConnectStoreObserver,
AccentColorObserver {
public static final String TAG = BlockedUserProfileFragment.class.getName();
public static final String ARGUMENT_USER_ID = "ARGUMENT_USER_ID";
public static final String ARGUMENT_USER_REQUESTER = "ARGUMENT_USER_REQUESTER";
public static final String STATE_IS_SHOWING_FOOTER_MENU = "STATE_IS_SHOWING_FOOTER_MENU";
private String userId;
private IConnectStore.UserRequester userRequester;
boolean isShowingFooterMenu;
private boolean isBelowUserProfile;
private boolean goToConversationWithUser;
private ZetaButton unblockButton;
private ZetaButton cancelButton;
private ZetaButton smallUnblockButton;
private TextView nameTextView;
private UserDetailsView userDetailsView;
private View unblockMenu;
private FooterMenu footerMenu;
private View separatorLine;
private ImageAssetImageView imageAssetImageViewProfile;
public static BlockedUserProfileFragment newInstance(String userId, IConnectStore.UserRequester userRequester) {
BlockedUserProfileFragment newFragment = new BlockedUserProfileFragment();
Bundle args = new Bundle();
args.putString(ARGUMENT_USER_REQUESTER, userRequester.toString());
args.putString(ARGUMENT_USER_ID, userId);
newFragment.setArguments(args);
return newFragment;
}
//////////////////////////////////////////////////////////////////////////////////////////
//
// Lifecycle
//
//////////////////////////////////////////////////////////////////////////////////////////
@Override
public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) {
Animation animation = super.onCreateAnimation(transit, enter, nextAnim);
if (getControllerFactory().getConversationScreenController().getPopoverLaunchMode() != DialogLaunchMode.AVATAR &&
getControllerFactory().getConversationScreenController().getPopoverLaunchMode() != DialogLaunchMode.COMMON_USER) {
int centerX = ViewUtils.getOrientationIndependentDisplayWidth(getActivity()) / 2;
int centerY = ViewUtils.getOrientationIndependentDisplayHeight(getActivity()) / 2;
int duration;
int delay = 0;
// Fade out animation when starting conversation directly with this user when unblocking
if (!goToConversationWithUser || enter) {
if (isBelowUserProfile) {
if (LayoutSpec.isTablet(getActivity())) {
animation = new ProfileTabletAnimation(enter,
getResources().getInteger(R.integer.framework_animation_duration_long),
-getResources().getDimensionPixelSize(R.dimen.participant_dialog__initial_width));
} else {
if (enter) {
isBelowUserProfile = false;
duration = getResources().getInteger(R.integer.reopen_profile_source__animation_duration);
delay = getResources().getInteger(R.integer.reopen_profile_source__delay);
} else {
duration = getResources().getInteger(R.integer.reopen_profile_source__animation_duration);
}
animation = new ProfileSourceAnimation(enter, duration, delay, centerX, centerY);
}
} else if (nextAnim != 0) {
if (LayoutSpec.isTablet(getActivity())) {
animation = new ProfileTabletAnimation(enter,
getResources().getInteger(R.integer.framework_animation_duration_long),
getResources().getDimensionPixelSize(R.dimen.participant_dialog__initial_width));
} else {
if (enter) {
duration = getResources().getInteger(R.integer.open_profile__animation_duration);
delay = getResources().getInteger(R.integer.open_profile__delay);
} else {
duration = getResources().getInteger(R.integer.close_profile__animation_duration);
}
animation = new ProfileAnimation(enter, duration, delay, centerX, centerY);
}
}
} else {
goToConversationWithUser = false;
duration = getResources().getInteger(R.integer.framework_animation_duration_medium);
animation = new FadeAnimation(duration, 1, 0);
}
}
return animation;
}
@Override
public View onCreateView(LayoutInflater inflater, final ViewGroup viewContainer, Bundle savedInstanceState) {
if (savedInstanceState != null) {
userId = savedInstanceState.getString(ARGUMENT_USER_ID);
userRequester = IConnectStore.UserRequester.valueOf(savedInstanceState.getString(ARGUMENT_USER_REQUESTER));
isShowingFooterMenu = savedInstanceState.getBoolean(STATE_IS_SHOWING_FOOTER_MENU);
} else {
userId = getArguments().getString(ARGUMENT_USER_ID);
userRequester = IConnectStore.UserRequester.valueOf(getArguments().getString(ARGUMENT_USER_REQUESTER));
isShowingFooterMenu = true;
}
View view = inflater.inflate(R.layout.fragment_blocked_user_profile, viewContainer, false);
unblockButton = ViewUtils.getView(view, R.id.zb__connect_request__unblock_button);
cancelButton = ViewUtils.getView(view, R.id.zb__connect_request__ignore_button);
smallUnblockButton = ViewUtils.getView(view, R.id.zb__connect_request__accept_button);
Toolbar toolbar = ViewUtils.getView(view, R.id.t__blocked_user__toolbar);
nameTextView = ViewUtils.getView(view, R.id.tv__blocked_user__toolbar__title);
userDetailsView = ViewUtils.getView(view, R.id.udv__blocked_user__user_details);
footerMenu = ViewUtils.getView(view, R.id.fm__footer);
unblockMenu = ViewUtils.getView(view, R.id.ll__connect_request__accept_menu);
separatorLine = ViewUtils.getView(view, R.id.v__connect_request__separator_line);
imageAssetImageViewProfile = ViewUtils.getView(view, R.id.iaiv__blocked_user);
imageAssetImageViewProfile.setDisplayType(ImageAssetImageView.DisplayType.CIRCLE);
if (ThemeUtils.isDarkTheme(getContext())) {
toolbar.setNavigationIcon(R.drawable.action_back_light);
} else {
toolbar.setNavigationIcon(R.drawable.action_back_dark);
}
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
getContainer().dismissUserProfile();
}
});
// Split Unblock / Cancel menu when opened from group conversation
cancelButton.setText(getString(R.string.confirmation_menu__cancel));
smallUnblockButton.setText(getString(R.string.connect_request__unblock__button__text));
// Hide some views irrelevant for blocking
footerMenu.setVisibility(View.GONE);
unblockButton.setVisibility(View.GONE);
separatorLine.setVisibility(View.GONE);
unblockButton.setVisibility(View.GONE);
View backgroundContainer = ViewUtils.getView(view, R.id.fl__blocked_user__background_container);
if ((LayoutSpec.isPhone(getActivity()) && getControllerFactory().getNavigationController().getPagerPosition() == NavigationController.FIRST_PAGE) ||
(getControllerFactory().getConversationScreenController().getPopoverLaunchMode() == DialogLaunchMode.AVATAR ||
getControllerFactory().getConversationScreenController().getPopoverLaunchMode() == DialogLaunchMode.COMMON_USER)) {
backgroundContainer.setClickable(true);
} else {
backgroundContainer.setBackgroundColor(Color.TRANSPARENT);
}
return view;
}
@Override
public void onStart() {
super.onStart();
getControllerFactory().getAccentColorController().addAccentColorObserver(this);
getStoreFactory().getConnectStore().addConnectRequestObserver(this);
getStoreFactory().getConnectStore().loadUser(userId, userRequester);
}
@Override
public void onSaveInstanceState(Bundle outState) {
outState.putString(ARGUMENT_USER_ID, userId);
if (userRequester != null) {
outState.putString(ARGUMENT_USER_REQUESTER, userRequester.toString());
}
// Save if footer menu was visible -> used to toggle unblock & footer menu when profile was opened from group participants
outState.putBoolean(STATE_IS_SHOWING_FOOTER_MENU, isShowingFooterMenu);
super.onSaveInstanceState(outState);
}
@Override
public void onStop() {
getStoreFactory().getConnectStore().removeConnectRequestObserver(this);
getControllerFactory().getAccentColorController().removeAccentColorObserver(this);
super.onStop();
}
@Override
public void onDestroyView() {
imageAssetImageViewProfile = null;
unblockButton = null;
cancelButton = null;
smallUnblockButton = null;
nameTextView = null;
footerMenu = null;
unblockMenu = null;
separatorLine = null;
userDetailsView.recycle();
userDetailsView = null;
super.onDestroyView();
}
//////////////////////////////////////////////////////////////////////////////////////////
//
// UserProfile
//
//////////////////////////////////////////////////////////////////////////////////////////
@Override
public void isBelowUserProfile(boolean isBelow) {
isBelowUserProfile = isBelow;
}
//////////////////////////////////////////////////////////////////////////////////////////
//
// ConnectStoreObserver
//
//////////////////////////////////////////////////////////////////////////////////////////
@Override
public void onConnectUserUpdated(final User user, IConnectStore.UserRequester userRequester) {
if (this.userRequester != userRequester ||
user == null) {
return;
}
imageAssetImageViewProfile.connectImageAsset(user.getPicture());
nameTextView.setText(user.getName());
userDetailsView.setUser(user);
setFooterMenu(user);
}
@Override
public void onInviteRequestSent(IConversation conversation) {
}
//////////////////////////////////////////////////////////////////////////////////////////
//
// AccentColorObserver
//
//////////////////////////////////////////////////////////////////////////////////////////
@Override
public void onAccentColorHasChanged(Object sender, int color) {
unblockButton.setAccentColor(color);
// Split Unblock / Cancel menu when opened from group conversation
cancelButton.setIsFilled(false);
cancelButton.setAccentColor(color);
smallUnblockButton.setAccentColor(color);
}
//////////////////////////////////////////////////////////////////////////////////////////
//
// Footer UI
//
//////////////////////////////////////////////////////////////////////////////////////////
private void setFooterMenu(final User user) {
unblockMenu.setVisibility(View.GONE);
if (userRequester == IConnectStore.UserRequester.PARTICIPANTS) {
setGroupConversationFooterMenu(user);
} else {
setRegularFooterMenu(user);
}
}
private void setRegularFooterMenu(final User user) {
unblockButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
unblockUser(user);
}
});
unblockButton.setVisibility(View.VISIBLE);
footerMenu.setVisibility(View.GONE);
unblockMenu.setVisibility(View.GONE);
}
private void setGroupConversationFooterMenu(final User user) {
unblockButton.setVisibility(View.GONE);
toggleUnblockAndFooterMenu(isShowingFooterMenu);
// Hook up callbacks
footerMenu.setLeftActionLabelText(getString(R.string.connect_request__footer__blocked_label));
footerMenu.setRightActionText(getString(R.string.glyph__minus));
footerMenu.setCallback(new FooterMenuCallback() {
@Override
public void onLeftActionClicked() {
toggleUnblockAndFooterMenu(false);
}
@Override
public void onRightActionClicked() {
getContainer().showRemoveConfirmation(user);
}
});
// Split unblock / cancel buttons
cancelButton.setEnabled(true);
cancelButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
toggleUnblockAndFooterMenu(true);
}
});
smallUnblockButton.setEnabled(true);
smallUnblockButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
unblockUser(user);
}
});
}
private void toggleUnblockAndFooterMenu(boolean showFooterMenu) {
if (showFooterMenu) {
footerMenu.setVisibility(View.VISIBLE);
unblockMenu.setVisibility(View.GONE);
} else {
footerMenu.setVisibility(View.GONE);
unblockMenu.setVisibility(View.VISIBLE);
}
isShowingFooterMenu = showFooterMenu;
}
private void unblockUser(User user) {
goToConversationWithUser = true;
((BaseActivity) getActivity()).injectJava(GlobalTrackingController.class).tagEvent(new UnblockingEvent());
IConversation conversation = getStoreFactory().getConnectStore().unblockUser(user);
if (conversation != null) {
// Note! important to pass conversation returned by unblockUser() instead of user.getConversation()
getContainer().onUnblockedUser(conversation);
}
}
public interface Container extends UserProfileContainer {
void onUnblockedUser(IConversation restoredConversationWithUser);
}
}