/** * 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.pickuser.controller; import android.content.Context; import android.text.TextUtils; import android.view.View; import com.waz.api.User; import com.waz.zclient.pages.main.profile.validator.EmailValidator; import com.waz.zclient.utils.LayoutSpec; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; public class PickUserController implements IPickUserController { private Set<PickUserControllerScreenObserver> pickUserControllerScreenObservers; private Set<PickUserControllerSearchObserver> pickUserControllerSearchObservers; private Set<Destination> visibleDestinations; private boolean isShowingUserProfile; private boolean hideWithoutAnimations; private final EmailValidator emailValidator; private String searchFilter; private Context context; private List<User> selectedUsers; public PickUserController(Context context) { this.context = context; this.emailValidator = EmailValidator.newInstance(); pickUserControllerScreenObservers = new HashSet<>(); pickUserControllerSearchObservers = new HashSet<>(); visibleDestinations = new HashSet<>(); selectedUsers = new ArrayList<>(); isShowingUserProfile = false; hideWithoutAnimations = false; } ////////////////////////////////////////////////////////////////////////////////////////// // // PickUserControllerScreenObserver - Screen actions // ////////////////////////////////////////////////////////////////////////////////////////// @Override public void addPickUserScreenControllerObserver(PickUserControllerScreenObserver observer) { pickUserControllerScreenObservers.add(observer); } @Override public void removePickUserScreenControllerObserver(PickUserControllerScreenObserver observer) { pickUserControllerScreenObservers.remove(observer); } // Showing people picker @Override public void showPickUser(Destination destination, View anchorView) { if (isShowingPickUser(destination)) { return; } visibleDestinations.add(destination); for (PickUserControllerScreenObserver pickUserControllerScreenObserver : pickUserControllerScreenObservers) { pickUserControllerScreenObserver.onShowPickUser(destination, anchorView); } } @Override public boolean hidePickUser(Destination destination, boolean closeWithoutSelectingPeople) { if (!isShowingPickUser(destination)) { return false; } for (PickUserControllerScreenObserver pickUserControllerScreenObserver : pickUserControllerScreenObservers) { pickUserControllerScreenObserver.onHidePickUser(destination, closeWithoutSelectingPeople); } visibleDestinations.remove(destination); selectedUsers.clear(); return true; } @Override public boolean isHideWithoutAnimations() { return hideWithoutAnimations; } @Override public void hidePickUserWithoutAnimations(Destination destination) { hideWithoutAnimations = true; hidePickUser(destination, false); hideWithoutAnimations = false; } @Override public boolean isShowingPickUser(Destination destination) { return visibleDestinations.contains(destination); } @Override public void resetShowingPickUser(Destination destination) { visibleDestinations.remove(destination); } @Override public void showUserProfile(User user, View anchorView) { for (PickUserControllerScreenObserver pickUserControllerScreenObserver : pickUserControllerScreenObservers) { pickUserControllerScreenObserver.onShowUserProfile(user, anchorView); } isShowingUserProfile = true; } @Override public void hideUserProfile() { for (PickUserControllerScreenObserver pickUserControllerScreenObserver : pickUserControllerScreenObservers) { pickUserControllerScreenObserver.onHideUserProfile(); } isShowingUserProfile = false; } @Override public boolean isShowingUserProfile() { // The PickUser fragment is only showing user profile for phone, // for tablet the user profile is shown in a dialog and this should always return false return isShowingUserProfile && LayoutSpec.isPhone(context); } ////////////////////////////////////////////////////////////////////////////////////////// // // PickUserControllerSearchObserver - Search Actions // ////////////////////////////////////////////////////////////////////////////////////////// @Override public void addPickUserSearchControllerObserver(PickUserControllerSearchObserver observer) { pickUserControllerSearchObservers.add(observer); } @Override public void removePickUserSearchControllerObserver(PickUserControllerSearchObserver observer) { pickUserControllerSearchObservers.remove(observer); } @Override public void notifySearchBoxHasNewSearchFilter(String filter) { for (PickUserControllerSearchObserver pickUserControllerSearchObserver : pickUserControllerSearchObservers) { pickUserControllerSearchObserver.onSearchBoxHasNewSearchFilter(filter); } } @Override public void notifyKeyboardDoneAction() { // Protect against ConcurrentModificationException - an observer might unsubscribe while notification is in progress Set<PickUserControllerSearchObserver> observers = new HashSet<>(pickUserControllerSearchObservers.size()); observers.addAll(pickUserControllerSearchObservers); for (PickUserControllerSearchObserver observer : observers) { observer.onKeyboardDoneAction(); } } @Override public void addUser(User user) { if (!selectedUsers.contains(user)) { selectedUsers.add(user); } for (PickUserControllerSearchObserver pickUserControllerSearchObserver : pickUserControllerSearchObservers) { pickUserControllerSearchObserver.onSelectedUserAdded(selectedUsers, user); } } @Override public void removeUser(User user) { selectedUsers.remove(user); final boolean isEmpty = selectedUsers.size() == 0; for (PickUserControllerSearchObserver pickUserControllerSearchObserver : pickUserControllerSearchObservers) { pickUserControllerSearchObserver.onSelectedUserRemoved(selectedUsers, user); if (isEmpty) { pickUserControllerSearchObserver.onSearchBoxIsEmpty(); } } } @Override public String getSearchFilter() { return searchFilter; } @Override public List<User> getSelectedUsers() { return new ArrayList<>(selectedUsers); } @Override public boolean hasSelectedUsers() { return getSelectedUsers().size() > 0; } @Override public boolean searchInputIsInvalidEmail() { if (TextUtils.isEmpty(searchFilter)) { return false; } return !emailValidator.validate(searchFilter); } @Override public void setSearchFilter(String newSearchFilter) { if (newSearchFilter.equalsIgnoreCase(searchFilter)) { return; } searchFilter = newSearchFilter; if (TextUtils.isEmpty(searchFilter)) { for (PickUserControllerSearchObserver pickUserControllerSearchObserver : pickUserControllerSearchObservers) { pickUserControllerSearchObserver.onSearchBoxIsEmpty(); } } else { notifySearchBoxHasNewSearchFilter(searchFilter); } } @Override public void tearDown() { context = null; if (pickUserControllerScreenObservers != null) { pickUserControllerScreenObservers.clear(); pickUserControllerScreenObservers = null; } if (pickUserControllerSearchObservers != null) { pickUserControllerSearchObservers.clear(); pickUserControllerSearchObservers = null; } selectedUsers = null; } private boolean hasOnlyTextContent() { return !hasSelectedUsers() && !TextUtils.isEmpty(searchFilter); } }