com.waz.zclient.pages.main.RootFragment.java Source code

Java tutorial

Introduction

Here is the source code for com.waz.zclient.pages.main.RootFragment.java

Source

/**
 * 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;

import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Interpolator;
import com.waz.api.ConversationsList;
import com.waz.api.IConversation;
import com.waz.api.ImageAsset;
import com.waz.api.MessageContent;
import com.waz.api.OtrClient;
import com.waz.api.SyncState;
import com.waz.api.User;
import com.waz.api.UsersList;
import com.waz.api.Verification;
import com.waz.api.Message;
import com.waz.zclient.OnBackPressedListener;
import com.waz.zclient.R;
import com.waz.zclient.controllers.drawing.DrawingController;
import com.waz.zclient.controllers.drawing.DrawingObserver;
import com.waz.zclient.controllers.giphy.GiphyObserver;
import com.waz.zclient.controllers.location.LocationObserver;
import com.waz.zclient.controllers.navigation.Page;
import com.waz.zclient.controllers.navigation.PagerControllerObserver;
import com.waz.zclient.core.api.scala.ModelObserver;
import com.waz.zclient.core.controllers.tracking.events.media.SentPictureEvent;
import com.waz.zclient.core.stores.connect.IConnectStore;
import com.waz.zclient.core.stores.conversation.ConversationChangeRequester;
import com.waz.zclient.core.stores.conversation.ConversationStoreObserver;
import com.waz.zclient.core.stores.participants.ParticipantsStoreObserver;
import com.waz.zclient.pages.BaseFragment;
import com.waz.zclient.pages.main.connect.ConnectRequestInboxManagerFragment;
import com.waz.zclient.pages.main.connect.ConnectRequestLoadMode;
import com.waz.zclient.pages.main.connect.PendingConnectRequestManagerFragment;
import com.waz.zclient.pages.main.conversation.ConversationFragment;
import com.waz.zclient.pages.main.conversation.LocationFragment;
import com.waz.zclient.pages.main.conversation.controller.ConversationScreenControllerObserver;
import com.waz.zclient.pages.main.conversation.controller.IConversationScreenController;
import com.waz.zclient.pages.main.conversationlist.ConversationListManagerFragment;
import com.waz.zclient.pages.main.conversationpager.SlidingPaneLayout;
import com.waz.zclient.pages.main.conversationpager.controller.SlidingPaneObserver;
import com.waz.zclient.pages.main.drawing.DrawingFragment;
import com.waz.zclient.pages.main.giphy.GiphySharingPreviewFragment;
import com.waz.zclient.pages.main.participants.TabbedParticipantBodyFragment;
import com.waz.zclient.pages.main.participants.dialog.DialogLaunchMode;
import com.waz.zclient.pages.main.participants.dialog.ParticipantsDialogFragment;
import com.waz.zclient.pages.main.pickuser.controller.IPickUserController;
import com.waz.zclient.pages.main.pickuser.controller.PickUserControllerScreenObserver;
import com.waz.zclient.pages.main.profile.camera.CameraContext;
import com.waz.zclient.pages.main.profile.camera.CameraFragment;
import com.waz.zclient.ui.animation.interpolators.penner.Quart;
import com.waz.zclient.ui.utils.KeyboardUtils;
import com.waz.zclient.ui.utils.MathUtils;
import com.waz.zclient.utils.LayoutSpec;
import com.waz.zclient.utils.TrackingUtils;
import com.waz.zclient.utils.ViewUtils;

import java.util.ArrayList;

public class RootFragment extends BaseFragment<RootFragment.Container>
        implements ConversationStoreObserver, SlidingPaneObserver, PendingConnectRequestManagerFragment.Container,
        ConnectRequestInboxManagerFragment.Container, ParticipantsDialogFragment.Container, PagerControllerObserver,
        ConversationScreenControllerObserver, OnBackPressedListener, CameraFragment.Container,
        PickUserControllerScreenObserver, BlankProgressFragment.Container, GiphyObserver, DrawingObserver,
        LocationObserver, ParticipantsStoreObserver, ConversationFragment.Container {
    public static final String TAG = RootFragment.class.getName();
    private static final Interpolator RIGHT_VIEW_ALPHA_INTERPOLATOR = new Quart.EaseOut();
    private View leftView;
    private View rightView;
    private SlidingPaneLayout slidingPaneLayout;
    private Handler mainHandler = new Handler();
    private View backgroundColorRightView;
    private boolean conversationSwapInProgress = false;
    private boolean panelSliding = false;
    private boolean groupConversation;
    private User otherUser;

    private final ModelObserver<IConversation> conversationModelObserver = new ModelObserver<IConversation>() {
        @Override
        public void updated(IConversation model) {
            groupConversation = IConversation.Type.GROUP.equals(model.getType());
            if (groupConversation) {
                otherUser = null;
            } else {
                otherUser = model.getOtherParticipant();
            }
        }
    };

    public static Fragment newInstance() {
        return new RootFragment();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        adjustLayout(true, newConfig);
    }

    private void adjustLayout(final boolean onOrientationChange, Configuration newConfig) {

        boolean isInLandscape = ViewUtils.isInLandscape(newConfig);
        getControllerFactory().getNavigationController().setIsLandscape(isInLandscape);
        getStoreFactory().getInAppNotificationStore().setIsLandscape(isInLandscape);

        slidingPaneLayout.setSideBarWidth(newConfig);
        if (isInLandscape) {
            slidingPaneLayout.setPreservedOpenState(false);
            // left view adjustments
            leftView.setTranslationX(0);

            // right view adjustments
            SlidingPaneLayout.LayoutParams params = (SlidingPaneLayout.LayoutParams) backgroundColorRightView
                    .getLayoutParams();
            params.leftMargin = getResources().getDimensionPixelSize(R.dimen.framework__sidebar_width);

            slidingPaneLayout.openPane();
        } else {

            // left view adjustments
            leftView.setTranslationX(0);

            // right view adjustments
            SlidingPaneLayout.LayoutParams params = (SlidingPaneLayout.LayoutParams) backgroundColorRightView
                    .getLayoutParams();
            params.leftMargin = 0;

            boolean open = !onOrientationChange || getControllerFactory().getPickUserController()
                    .isShowingPickUser(IPickUserController.Destination.CONVERSATION_LIST);
            slidingPaneLayout.setPreservedOpenState(open);
            if (open) {
                getControllerFactory().getSlidingPaneController().onPanelOpened(leftView);
            } else {
                getControllerFactory().getSlidingPaneController().onPanelClosed(leftView);
            }
        }

        // Hide start ui on screen rotation
        if (onOrientationChange) {
            getControllerFactory().getPickUserController()
                    .hidePickUserWithoutAnimations(IPickUserController.Destination.CONVERSATION_LIST);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
            @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_root, container, false);
        slidingPaneLayout = ViewUtils.getView(view, R.id.spl__root);
        slidingPaneLayout.setCloseOnClick(true);

        // get references
        leftView = ViewUtils.getView(view, R.id.fl__root__left_view);
        rightView = ViewUtils.getView(view, R.id.fl__root__right_view);
        backgroundColorRightView = ViewUtils.getView(view, R.id.fl__root_backgroundcolor_view);

        if (savedInstanceState == null) {
            getChildFragmentManager().beginTransaction().add(R.id.fl__root__left_view,
                    ConversationListManagerFragment.newInstance(), ConversationListManagerFragment.TAG).commit();

            getControllerFactory().getNavigationController().setLeftPage(Page.CONVERSATION_LIST, TAG);
        }
        backgroundColorRightView.setBackgroundColor(Color.TRANSPARENT);

        return view;
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        adjustLayout(savedInstanceState != null, getActivity().getResources().getConfiguration());
    }

    @Override
    public void onStart() {
        super.onStart();

        slidingPaneLayout.setPanelSlideController(getControllerFactory().getSlidingPaneController());
        // Conversation update can trigger sliding pane movement, add as observer before subscribing to conversation store
        getControllerFactory().getSlidingPaneController().addObserver(this);

        getControllerFactory().getConversationScreenController().addConversationControllerObservers(this);
        getControllerFactory().getNavigationController().addPagerControllerObserver(this);
        if (!getControllerFactory().getConversationScreenController().isConversationStreamUiInitialized()) {
            getStoreFactory().getConversationStore().addConversationStoreObserverAndUpdate(this);
        } else {
            getStoreFactory().getConversationStore().addConversationStoreObserver(this);
        }
        getControllerFactory().getCameraController().addCameraActionObserver(this);
        getControllerFactory().getPickUserController().addPickUserScreenControllerObserver(this);
        getControllerFactory().getGiphyController().addObserver(this);
        getControllerFactory().getDrawingController().addDrawingObserver(this);
        getStoreFactory().getParticipantsStore().addParticipantsStoreObserver(this);
        getControllerFactory().getLocationController().addObserver(this);
        onPagerEnabledStateHasChanged(getControllerFactory().getNavigationController().isPagerEnabled());
    }

    @Override
    public void onStop() {
        slidingPaneLayout.setPanelSlideController(null);
        getControllerFactory().getLocationController().removeObserver(this);
        getStoreFactory().getParticipantsStore().removeParticipantsStoreObserver(this);
        getControllerFactory().getConversationScreenController().removeConversationControllerObservers(this);
        getControllerFactory().getSlidingPaneController().removeObserver(this);
        getControllerFactory().getCameraController().removeCameraActionObserver(this);
        getControllerFactory().getNavigationController().removePagerControllerObserver(this);
        getStoreFactory().getConversationStore().removeConversationStoreObserver(this);
        getControllerFactory().getPickUserController().removePickUserScreenControllerObserver(this);
        getControllerFactory().getGiphyController().removeObserver(this);
        getControllerFactory().getDrawingController().removeDrawingObserver(this);
        super.onStop();
    }

    @Override
    public void onDestroyView() {
        backgroundColorRightView = null;
        leftView = null;
        rightView = null;
        slidingPaneLayout = null;
        super.onDestroyView();
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        // So far I only know of the camera view that needs onActivityResult
        Fragment fragment = getChildFragmentManager().findFragmentById(R.id.fl__root__camera);
        if (fragment != null) {
            fragment.onActivityResult(requestCode, resultCode, data);
        }
    }

    @Override
    public void onCurrentConversationHasChanged(final IConversation fromConversation,
            final IConversation toConversation, final ConversationChangeRequester conversationChangerSender) {
        if (toConversation == null) {
            return;
        }

        conversationModelObserver.setAndUpdate(toConversation);
        getStoreFactory().getParticipantsStore().setCurrentConversation(toConversation);

        getControllerFactory().getBackgroundController().expand(false);

        final IConversation.Type type = toConversation.getType();
        // This must be posted because onCurrentConversationHasChanged()
        // might still be running and iterating over the observers -
        // while the posted call triggers things to register/unregister
        // from the list of observers, causing ConcurrentModificationException
        mainHandler.post(new Runnable() {
            @Override
            public void run() {
                Page page;
                Fragment fragment;
                String tag;
                switch (type) {
                case WAIT_FOR_CONNECTION:
                    fragment = PendingConnectRequestManagerFragment.newInstance(null, toConversation.getId(),
                            ConnectRequestLoadMode.LOAD_BY_CONVERSATION_ID,
                            IConnectStore.UserRequester.CONVERSATION);
                    tag = PendingConnectRequestManagerFragment.TAG;
                    page = Page.PENDING_CONNECT_REQUEST_AS_CONVERSATION;
                    break;
                case INCOMING_CONNECTION:
                    fragment = ConnectRequestInboxManagerFragment.newInstance(toConversation.getId());
                    tag = ConnectRequestInboxManagerFragment.TAG;
                    page = Page.CONNECT_REQUEST_INBOX;
                    break;
                case GROUP:
                case ONE_TO_ONE:
                default:
                    page = Page.MESSAGE_STREAM;
                    fragment = ConversationFragment.newInstance();
                    tag = ConversationFragment.TAG;
                    break;
                }

                openMessageStream(page, fragment, tag);
            }
        });

        if (ViewUtils.isInPortrait(getActivity())
                && conversationChangerSender != ConversationChangeRequester.FIRST_LOAD) {
            slidingPaneLayout.closePane();
            getControllerFactory().getSlidingPaneController().onPanelClosed(leftView);
        }
    }

    @Override
    public void onConversationSyncingStateHasChanged(SyncState syncState) {

    }

    @Override
    public void onMenuConversationHasChanged(IConversation fromConversation) {

    }

    @Override
    public void onVerificationStateChanged(String conversationId, Verification previousVerification,
            Verification currentVerification) {

    }

    @Override
    public void onConversationListUpdated(ConversationsList conversationsList) {
    }

    @Override
    public void onConversationListStateHasChanged(ConversationsList.ConversationsListState state) {

    }

    private void openMessageStream(Page page, Fragment fragment, String tag) {
        getControllerFactory().getNavigationController().setRightPage(page, TAG);

        int animIn = R.anim.fragment_animation_swap_conversation_tablet_in;
        int animOut = R.anim.fragment_animation_swap_conversation_tablet_out;

        if (ViewUtils.isInPortrait(getActivity())) {
            animIn = R.anim.fragment_animation_portrait_swap_conversation_tablet_in;
            animOut = R.anim.fragment_animation_swap_conversation_tablet_out;
        }

        getChildFragmentManager().beginTransaction().setCustomAnimations(animIn, animOut)
                .replace(R.id.fl__root__right_view, fragment, tag).commit();
    }

    @Override
    public void onOpenUrl(String url) {
        getContainer().onOpenUrl(url);
    }

    @Override
    public void dismissInboxFragment() {
        IConversation nextConversation = getStoreFactory().getConversationStore().getNextConversation();
        if (nextConversation == null) {
            return;
        }
        getStoreFactory().getConversationStore().setCurrentConversation(nextConversation,
                ConversationChangeRequester.START_CONVERSATION);
    }

    @Override
    public void onAcceptedUser(IConversation conversation) {
        getStoreFactory().getConversationStore().setCurrentConversation(conversation,
                ConversationChangeRequester.START_CONVERSATION);
    }

    @Override
    public void onPanelSlide(View panel, float slideOffset) {
        getControllerFactory().getNavigationController().onPageScrolled(0, 1 - slideOffset, 0);
        float translationX = (slideOffset - 1)
                * getResources().getDimensionPixelSize(R.dimen.root__parallax_distance);
        leftView.setTranslationX(translationX);
        if (MathUtils.floatEqual(slideOffset, 0f) || MathUtils.floatEqual(slideOffset, 1f)) {
            panelSliding = false;
        } else if (!panelSliding) {
            panelSliding = true;
            KeyboardUtils.hideKeyboard(getActivity());
        }
    }

    @Override
    public void onPanelOpened(View panel) {
        getControllerFactory().getNavigationController().setPagerPosition(0);
        getControllerFactory().getFocusController().restoreToNextFocus(getActivity(),
                getControllerFactory().getNavigationController().getPagerPosition(),
                getControllerFactory().getNavigationController().getCurrentPage(),
                getControllerFactory().getPickUserController()
                        .isShowingPickUser(IPickUserController.Destination.CONVERSATION_LIST));
    }

    @Override
    public void onPanelClosed(View panel) {
        getControllerFactory().getNavigationController().setPagerPosition(1);
        if (!conversationSwapInProgress) {
            rightView.setAlpha(1f);
        }
        getControllerFactory().getFocusController().restoreToNextFocus(getActivity(),
                getControllerFactory().getNavigationController().getPagerPosition(),
                getControllerFactory().getNavigationController().getCurrentPage(),
                getControllerFactory().getPickUserController()
                        .isShowingPickUser(IPickUserController.Destination.CONVERSATION_LIST));
    }

    @Override
    public void onPagerEnabledStateHasChanged(boolean enabled) {
        slidingPaneLayout.setIsSlidingEnabled(enabled);
    }

    //////////////////////////////////////////////////////////////////////////////
    //
    // CameraFragment.Container
    //
    //////////////////////////////////////////////////////////////////////////////

    @Override
    public void onBitmapSelected(ImageAsset imageAsset, boolean imageFromCamera, CameraContext cameraContext) {
        if (cameraContext != CameraContext.MESSAGE) {
            return;
        }
        getControllerFactory().getCameraController().closeCamera(cameraContext);
        getStoreFactory().getConversationStore().sendMessage(imageAsset);

        // Tablet doesn't have keyboard camera interface
        TrackingUtils.onSentPhotoMessage(getControllerFactory().getTrackingController(),
                getStoreFactory().getConversationStore().getCurrentConversation(),
                imageFromCamera ? SentPictureEvent.Source.CAMERA : SentPictureEvent.Source.GALLERY,
                SentPictureEvent.Method.TABLET);
    }

    @Override
    public void onCameraNotAvailable() {

    }

    @Override
    public void onShowDrawing(ImageAsset image, DrawingController.DrawingDestination drawingDestination) {
        slidingPaneLayout.setVisibility(View.GONE);
        getControllerFactory().getCameraController().closeCamera(CameraContext.MESSAGE);
        getChildFragmentManager().beginTransaction().add(R.id.fl__root__sketch,
                DrawingFragment.newInstance(image, drawingDestination), DrawingFragment.TAG).commit();
        getControllerFactory().getNavigationController().setRightPage(Page.DRAWING, TAG);
    }

    @Override
    public void onHideDrawing(DrawingController.DrawingDestination drawingDestination, boolean imageSent) {
        if (LayoutSpec.isTablet(getActivity())) {
            ViewUtils.unlockOrientation(getActivity());
        }
        Fragment fragment = getChildFragmentManager().findFragmentById(R.id.fl__root__sketch);
        if (fragment != null) {
            getChildFragmentManager().beginTransaction().remove(fragment).commit();
        }
        slidingPaneLayout.setVisibility(View.VISIBLE);
        switch (drawingDestination) {
        case CAMERA_PREVIEW_VIEW:
            if (imageSent) {
                getControllerFactory().getCameraController().closeCamera(CameraContext.MESSAGE);
                getControllerFactory().getNavigationController().setRightPage(Page.MESSAGE_STREAM, TAG);
            } else {
                if (getChildFragmentManager().findFragmentById(R.id.fl__root__camera) == null) {
                    getControllerFactory().getCameraController().openCamera(CameraContext.MESSAGE);
                }
                getControllerFactory().getNavigationController().setRightPage(Page.CAMERA, TAG);
            }
            break;
        case SINGLE_IMAGE_VIEW:
        case SKETCH_BUTTON:
            getControllerFactory().getNavigationController().setRightPage(Page.MESSAGE_STREAM, TAG);
            break;
        }
    }

    @Override
    public void onSearch(String keyword) {
        getChildFragmentManager().beginTransaction().add(R.id.fl__root__giphy,
                GiphySharingPreviewFragment.newInstance(keyword), GiphySharingPreviewFragment.TAG).commit();
    }

    @Override
    public void onRandomSearch() {
        getChildFragmentManager().beginTransaction().add(R.id.fl__root__giphy,
                GiphySharingPreviewFragment.newInstance(), GiphySharingPreviewFragment.TAG).commit();
    }

    @Override
    public void onTrendingSearch() {

    }

    @Override
    public void onCloseGiphy() {
        Fragment fragment = getChildFragmentManager().findFragmentById(R.id.fl__root__giphy);
        if (fragment != null) {
            getChildFragmentManager().beginTransaction().remove(fragment).commit();
        }
    }

    @Override
    public void onCancelGiphy() {
        Fragment fragment = getChildFragmentManager().findFragmentById(R.id.fl__root__giphy);
        if (fragment != null) {
            getChildFragmentManager().beginTransaction().remove(fragment).commit();
        }
    }

    @Override
    public void onOpenCamera(CameraContext cameraContext) {
        getChildFragmentManager().beginTransaction()
                .add(R.id.fl__root__camera, CameraFragment.newInstance(cameraContext), CameraFragment.TAG).commit();
    }

    @Override
    public void onCloseCamera(CameraContext cameraContext) {
        Fragment fragment = getChildFragmentManager().findFragmentById(R.id.fl__root__camera);
        if (fragment != null) {
            getChildFragmentManager().beginTransaction().remove(fragment).commit();
        }
    }

    @Override
    public void onShowParticipants(View anchorView, boolean isSingleConversation, boolean isMemberOfConversation,
            boolean showDeviceTabSingle) {
        if (LayoutSpec.isPhone(getActivity()) || anchorView == null) {
            return;
        }

        final Rect outRect = new Rect();
        anchorView.getDrawingRect(outRect);
        final Point locationOnScreen = ViewUtils.getLocationOnScreen(anchorView);
        final Point rootViewLocation = ViewUtils
                .getLocationOnScreen(ViewUtils.getView(getActivity(), R.id.fl_main_content));

        locationOnScreen.offset(-rootViewLocation.x, -rootViewLocation.y);

        final int posX = locationOnScreen.x;
        final int posY = locationOnScreen.y;
        if (anchorView instanceof Toolbar) {
            getControllerFactory().getConversationScreenController()
                    .setPopoverLaunchedMode(DialogLaunchMode.CONVERSATION_TOOLBAR);
        } else {
            getControllerFactory().getConversationScreenController()
                    .setPopoverLaunchedMode(DialogLaunchMode.PARTICIPANT_BUTTON);
        }
        int firstPage = (isSingleConversation && showDeviceTabSingle) ? TabbedParticipantBodyFragment.DEVICE_PAGE
                : TabbedParticipantBodyFragment.USER_PAGE;
        getChildFragmentManager().beginTransaction()
                .replace(R.id.fl__root__participant_container,
                        ParticipantsDialogFragment.newParticipantButtonInstance(posX, posY, outRect, firstPage),
                        ParticipantsDialogFragment.TAG)
                .commit();
    }

    @Override
    public void onHideParticipants(boolean backOrButtonPressed, boolean hideByConversationChange,
            boolean isSingleConversation) {

    }

    @Override
    public void onShowEditConversationName(boolean show) {

    }

    @Override
    public void setListOffset(int offset) {

    }

    @Override
    public void onHeaderViewMeasured(int participantHeaderHeight) {

    }

    @Override
    public void onScrollParticipantsList(int verticalOffset, boolean scrolledToBottom) {

    }

    @Override
    public void onConversationLoaded() {
        if (!conversationSwapInProgress) {
            return;
        }

        int startDelay = getResources().getInteger(R.integer.framework_animation_delay_short);
        rightView.animate().alpha(1f).setInterpolator(RIGHT_VIEW_ALPHA_INTERPOLATOR)
                .setDuration(getResources().getInteger(R.integer.framework_animation_duration_long))
                .withEndAction(new Runnable() {
                    @Override
                    public void run() {
                        conversationSwapInProgress = false;
                    }
                }).start();

        slidingPaneLayout.postDelayed(new Runnable() {
            @Override
            public void run() {
                if (slidingPaneLayout == null) {
                    return;
                }
                slidingPaneLayout.closePane();
            }
        }, startDelay);
    }

    @Override
    public void onShowUser(User user) {

    }

    @Override
    public void onHideUser() {

    }

    @Override
    public void onShowCommonUser(User user) {

    }

    @Override
    public void onHideCommonUser() {

    }

    @Override
    public void onAddPeopleToConversation() {

    }

    @Override
    public void onShowConversationMenu(@IConversationScreenController.ConversationMenuRequester int requester,
            IConversation conversation, View anchorView) {

    }

    @Override
    public void onShowOtrClient(OtrClient otrClient, User user) {

    }

    @Override
    public void onShowCurrentOtrClient() {

    }

    @Override
    public void onHideOtrClient() {

    }

    @Override
    public void onShowLikesList(Message message) {

    }

    @Override
    public boolean onBackPressed() {
        Fragment fragment = getChildFragmentManager().findFragmentByTag(ParticipantsDialogFragment.TAG);
        if (fragment instanceof OnBackPressedListener && ((OnBackPressedListener) fragment).onBackPressed()) {
            return true;
        }

        fragment = getChildFragmentManager().findFragmentById(R.id.fl__root__right_view);
        if (fragment instanceof OnBackPressedListener && ((OnBackPressedListener) fragment).onBackPressed()) {
            return true;
        }

        fragment = getChildFragmentManager().findFragmentById(R.id.fl__root__camera);
        if (fragment instanceof CameraFragment) {
            //TODO: https://wearezeta.atlassian.net/browse/AN-2311 Refactor camera into one view
            getControllerFactory().getCameraController()
                    .closeCamera(((CameraFragment) fragment).getCameraContext());
            return true;
        } else if (fragment instanceof OnBackPressedListener) {
            ((OnBackPressedListener) fragment).onBackPressed();
            return true;
        }

        fragment = getChildFragmentManager().findFragmentById(R.id.fl__root__giphy);
        if (fragment instanceof GiphySharingPreviewFragment) {
            if (!((GiphySharingPreviewFragment) fragment).onBackPressed()) {
                getControllerFactory().getGiphyController().cancel();
            }
            return true;
        }

        fragment = getChildFragmentManager().findFragmentById(R.id.fl__root__sketch);
        if (fragment instanceof OnBackPressedListener) {
            ((OnBackPressedListener) fragment).onBackPressed();
            return true;
        }

        if (getControllerFactory().getPickUserController()
                .isShowingPickUser(IPickUserController.Destination.CONVERSATION_LIST)) {
            getControllerFactory().getPickUserController()
                    .hidePickUser(IPickUserController.Destination.CONVERSATION_LIST, true);
            return true;
        }

        if (slidingPaneLayout != null && !slidingPaneLayout.isOpen()) {
            slidingPaneLayout.openPane();
            return true;
        }

        return false;
    }

    @Override
    public void onShowPickUser(IPickUserController.Destination destination, View anchorView) {
        if (LayoutSpec.isPhone(getActivity()) || anchorView == null
                || !destination.equals(IPickUserController.Destination.CURSOR)) {
            return;
        }

        final Rect outRect = new Rect();
        anchorView.getDrawingRect(outRect);
        final Point locationOnScreen = ViewUtils.getLocationOnScreen(anchorView);
        final Point rootViewLocation = ViewUtils
                .getLocationOnScreen(ViewUtils.getView(getActivity(), R.id.fl_main_content));

        locationOnScreen.offset(-rootViewLocation.x, -rootViewLocation.y);

        final int posX = locationOnScreen.x;
        final int posY = locationOnScreen.y;
        if (!groupConversation && otherUser != null) {
            getControllerFactory().getPickUserController().addUser(otherUser);
        }
        getControllerFactory().getConversationScreenController()
                .setPopoverLaunchedMode(DialogLaunchMode.PARTICIPANT_BUTTON);
        getChildFragmentManager().beginTransaction()
                .replace(R.id.fl__root__participant_container,
                        ParticipantsDialogFragment.newStartUiInstance(posX, posY, outRect, groupConversation),
                        ParticipantsDialogFragment.TAG)
                .commit();
    }

    @Override
    public void onHidePickUser(IPickUserController.Destination destination, boolean closeWithoutSelectingPeople) {
        getChildFragmentManager().popBackStack(ParticipantsDialogFragment.TAG,
                FragmentManager.POP_BACK_STACK_INCLUSIVE);
    }

    @Override
    public void onShowUserProfile(User user, View anchorView) {
        if (LayoutSpec.isPhone(getActivity())) {
            return;
        }

        final Rect outRect = new Rect();
        anchorView.getDrawingRect(outRect);

        final Point locationOnScreen = ViewUtils.getLocationOnScreen(anchorView);
        final Point rootViewLocation = ViewUtils
                .getLocationOnScreen(ViewUtils.getView(getActivity(), R.id.fl_main_content));

        locationOnScreen.offset(-rootViewLocation.x, -rootViewLocation.y);

        final int posX = locationOnScreen.x;
        final int posY = locationOnScreen.y;

        getChildFragmentManager().beginTransaction()
                .replace(R.id.fl__root__participant_container,
                        ParticipantsDialogFragment.newAvatarPopoverInstance(posX, posY, outRect, user.getId()),
                        ParticipantsDialogFragment.TAG)
                .commit();
    }

    @Override
    public void onHideUserProfile() {

    }

    @Override
    public void onShowCommonUserProfile(User user) {

    }

    @Override
    public void onHideCommonUserProfile() {

    }

    @Override
    public void onAcceptedConnectRequest(IConversation conversation) {

    }

    @Override
    public void onAcceptedPendingOutgoingConnectRequest(IConversation conversation) {

    }

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

    }

    @Override
    public void onPageSelected(int position) {

    }

    @Override
    public void onPageScrollStateChanged(int state) {

    }

    @Override
    public void dismissUserProfile() {

    }

    @Override
    public void dismissSingleUserProfile() {

    }

    @Override
    public void showRemoveConfirmation(User user) {

    }

    @Override
    public void openCommonUserProfile(View anchor, User commonUser) {

    }

    // ParticipantsStoreObserver

    @Override
    public void conversationUpdated(IConversation conversation) {

    }

    @Override
    public void participantsUpdated(UsersList participants) {
        ArrayList<String> participantIds = new ArrayList<>();
        for (int i = 0; i < participants.size(); i++) {
            participantIds.add(participants.get(i).getId());
        }

        // Exclude existing participants of conversation when adding people
        getStoreFactory().getPickUserStore()
                .setExcludedUsers(participantIds.toArray(new String[participantIds.size()]));
    }

    @Override
    public void otherUserUpdated(User otherUser) {
        getStoreFactory().getPickUserStore().setExcludedUsers(new String[] {});
    }

    @Override
    public void onShowShareLocation() {
        getChildFragmentManager().beginTransaction()
                .replace(R.id.fl__root__camera, LocationFragment.newInstance(), LocationFragment.TAG)
                .addToBackStack(LocationFragment.TAG).commit();
    }

    @Override
    public void onHideShareLocation(MessageContent.Location location) {
        if (location != null) {
            getStoreFactory().getConversationStore().sendMessage(location);
        }
        getChildFragmentManager().popBackStack(LocationFragment.TAG, FragmentManager.POP_BACK_STACK_INCLUSIVE);
    }

    public interface Container {
        void onOpenUrl(String url);
    }
}