Example usage for android.view MotionEvent ACTION_POINTER_UP

List of usage examples for android.view MotionEvent ACTION_POINTER_UP

Introduction

In this page you can find the example usage for android.view MotionEvent ACTION_POINTER_UP.

Prototype

int ACTION_POINTER_UP

To view the source code for android.view MotionEvent ACTION_POINTER_UP.

Click Source Link

Document

Constant for #getActionMasked : A non-primary pointer has gone up.

Usage

From source file:com.android.internal.widget.ViewPager.java

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    /*//from www.j  a v a 2  s. co m
     * This method JUST determines whether we want to intercept the motion.
     * If we return true, onMotionEvent will be called and we do the actual
     * scrolling there.
     */

    final int action = ev.getAction() & MotionEvent.ACTION_MASK;

    // Always take care of the touch gesture being complete.
    if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
        // Release the drag.
        if (DEBUG)
            Log.v(TAG, "Intercept done!");
        mIsBeingDragged = false;
        mIsUnableToDrag = false;
        mActivePointerId = INVALID_POINTER;
        if (mVelocityTracker != null) {
            mVelocityTracker.recycle();
            mVelocityTracker = null;
        }
        return false;
    }

    // Nothing more to do here if we have decided whether or not we
    // are dragging.
    if (action != MotionEvent.ACTION_DOWN) {
        if (mIsBeingDragged) {
            if (DEBUG)
                Log.v(TAG, "Being dragged, intercept returning true!");
            return true;
        }
        if (mIsUnableToDrag) {
            if (DEBUG)
                Log.v(TAG, "Unable to drag, intercept returning false!");
            return false;
        }
    }

    switch (action) {
    case MotionEvent.ACTION_MOVE: {
        /*
         * mIsBeingDragged == false, otherwise the shortcut would have caught it. Check
         * whether the user has moved far enough from his original down touch.
         */

        /*
        * Locally do absolute value. mLastMotionY is set to the y value
        * of the down event.
        */
        final int activePointerId = mActivePointerId;
        if (activePointerId == INVALID_POINTER) {
            // If we don't have a valid id, the touch down wasn't on content.
            break;
        }

        final int pointerIndex = ev.findPointerIndex(activePointerId);
        final float x = ev.getX(pointerIndex);
        final float dx = x - mLastMotionX;
        final float xDiff = Math.abs(dx);
        final float y = ev.getY(pointerIndex);
        final float yDiff = Math.abs(y - mInitialMotionY);
        if (DEBUG)
            Log.v(TAG, "Moved x to " + x + "," + y + " diff=" + xDiff + "," + yDiff);

        if (dx != 0 && !isGutterDrag(mLastMotionX, dx) && canScroll(this, false, (int) dx, (int) x, (int) y)) {
            // Nested view has scrollable area under this point. Let it be handled there.
            mLastMotionX = x;
            mLastMotionY = y;
            mIsUnableToDrag = true;
            return false;
        }
        if (xDiff > mTouchSlop && xDiff * 0.5f > yDiff) {
            if (DEBUG)
                Log.v(TAG, "Starting drag!");
            mIsBeingDragged = true;
            requestParentDisallowInterceptTouchEvent(true);
            setScrollState(SCROLL_STATE_DRAGGING);
            mLastMotionX = dx > 0 ? mInitialMotionX + mTouchSlop : mInitialMotionX - mTouchSlop;
            mLastMotionY = y;
            setScrollingCacheEnabled(true);
        } else if (yDiff > mTouchSlop) {
            // The finger has moved enough in the vertical
            // direction to be counted as a drag...  abort
            // any attempt to drag horizontally, to work correctly
            // with children that have scrolling containers.
            if (DEBUG)
                Log.v(TAG, "Starting unable to drag!");
            mIsUnableToDrag = true;
        }
        if (mIsBeingDragged) {
            // Scroll to follow the motion event
            if (performDrag(x)) {
                postInvalidateOnAnimation();
            }
        }
        break;
    }

    case MotionEvent.ACTION_DOWN: {
        /*
         * Remember location of down touch.
         * ACTION_DOWN always refers to pointer index 0.
         */
        mLastMotionX = mInitialMotionX = ev.getX();
        mLastMotionY = mInitialMotionY = ev.getY();
        mActivePointerId = ev.getPointerId(0);
        mIsUnableToDrag = false;

        mScroller.computeScrollOffset();
        if (mScrollState == SCROLL_STATE_SETTLING
                && Math.abs(mScroller.getFinalX() - mScroller.getCurrX()) > mCloseEnough) {
            // Let the user 'catch' the pager as it animates.
            mScroller.abortAnimation();
            mPopulatePending = false;
            populate();
            mIsBeingDragged = true;
            requestParentDisallowInterceptTouchEvent(true);
            setScrollState(SCROLL_STATE_DRAGGING);
        } else {
            completeScroll(false);
            mIsBeingDragged = false;
        }

        if (DEBUG)
            Log.v(TAG, "Down at " + mLastMotionX + "," + mLastMotionY + " mIsBeingDragged=" + mIsBeingDragged
                    + "mIsUnableToDrag=" + mIsUnableToDrag);
        break;
    }

    case MotionEvent.ACTION_POINTER_UP:
        onSecondaryPointerUp(ev);
        break;
    }

    if (mVelocityTracker == null) {
        mVelocityTracker = VelocityTracker.obtain();
    }
    mVelocityTracker.addMovement(ev);

    /*
     * The only time we want to intercept motion events is if we are in the
     * drag mode.
     */
    return mIsBeingDragged;
}

From source file:cc.flydev.launcher.Page.java

@Override
public boolean onTouchEvent(MotionEvent ev) {
    if (DISABLE_TOUCH_INTERACTION) {
        return false;
    }/*  w  w w .  j a va2s.c  o  m*/

    super.onTouchEvent(ev);

    // Skip touch handling if there are no pages to swipe
    if (getChildCount() <= 0)
        return super.onTouchEvent(ev);

    acquireVelocityTrackerAndAddMovement(ev);

    final int action = ev.getAction();

    switch (action & MotionEvent.ACTION_MASK) {
    case MotionEvent.ACTION_DOWN:
        /*
         * If being flinged and user touches, stop the fling. isFinished
         * will be false if being flinged.
         */
        if (!mScroller.isFinished()) {
            mScroller.abortAnimation();
        }

        // Remember where the motion event started
        mDownMotionX = mLastMotionX = ev.getX();
        mDownMotionY = mLastMotionY = ev.getY();
        mDownScrollX = getScrollX();
        float[] p = mapPointFromViewToParent(this, mLastMotionX, mLastMotionY);
        mParentDownMotionX = p[0];
        mParentDownMotionY = p[1];
        mLastMotionXRemainder = 0;
        mTotalMotionX = 0;
        mActivePointerId = ev.getPointerId(0);

        if (mTouchState == TOUCH_STATE_SCROLLING) {
            pageBeginMoving();
        }
        break;

    case MotionEvent.ACTION_MOVE:
        if (mTouchState == TOUCH_STATE_SCROLLING) {
            // Scroll to follow the motion event
            final int pointerIndex = ev.findPointerIndex(mActivePointerId);

            if (pointerIndex == -1)
                return true;

            final float x = ev.getX(pointerIndex);
            final float deltaX = mLastMotionX + mLastMotionXRemainder - x;

            mTotalMotionX += Math.abs(deltaX);

            // Only scroll and update mLastMotionX if we have moved some discrete amount.  We
            // keep the remainder because we are actually testing if we've moved from the last
            // scrolled position (which is discrete).
            if (Math.abs(deltaX) >= 1.0f) {
                mTouchX += deltaX;
                mSmoothingTime = System.nanoTime() / NANOTIME_DIV;
                if (!mDeferScrollUpdate) {
                    scrollBy((int) deltaX, 0);
                    if (DEBUG)
                        Log.d(TAG, "onTouchEvent().Scrolling: " + deltaX);
                } else {
                    invalidate();
                }
                mLastMotionX = x;
                mLastMotionXRemainder = deltaX - (int) deltaX;
            } else {
                awakenScrollBars();
            }
        } else if (mTouchState == TOUCH_STATE_REORDERING) {
            // Update the last motion position
            mLastMotionX = ev.getX();
            mLastMotionY = ev.getY();

            // Update the parent down so that our zoom animations take this new movement into
            // account
            float[] pt = mapPointFromViewToParent(this, mLastMotionX, mLastMotionY);
            mParentDownMotionX = pt[0];
            mParentDownMotionY = pt[1];
            updateDragViewTranslationDuringDrag();

            // Find the closest page to the touch point
            final int dragViewIndex = indexOfChild(mDragView);

            // Change the drag view if we are hovering over the drop target
            boolean isHoveringOverDelete = isHoveringOverDeleteDropTarget((int) mParentDownMotionX,
                    (int) mParentDownMotionY);
            setPageHoveringOverDeleteDropTarget(dragViewIndex, isHoveringOverDelete);

            if (DEBUG)
                Log.d(TAG, "mLastMotionX: " + mLastMotionX);
            if (DEBUG)
                Log.d(TAG, "mLastMotionY: " + mLastMotionY);
            if (DEBUG)
                Log.d(TAG, "mParentDownMotionX: " + mParentDownMotionX);
            if (DEBUG)
                Log.d(TAG, "mParentDownMotionY: " + mParentDownMotionY);

            final int pageUnderPointIndex = getNearestHoverOverPageIndex();
            if (pageUnderPointIndex > -1 && pageUnderPointIndex != indexOfChild(mDragView)
                    && !isHoveringOverDelete) {
                mTempVisiblePagesRange[0] = 0;
                mTempVisiblePagesRange[1] = getPageCount() - 1;
                getOverviewModePages(mTempVisiblePagesRange);
                if (mTempVisiblePagesRange[0] <= pageUnderPointIndex
                        && pageUnderPointIndex <= mTempVisiblePagesRange[1]
                        && pageUnderPointIndex != mSidePageHoverIndex && mScroller.isFinished()) {
                    mSidePageHoverIndex = pageUnderPointIndex;
                    mSidePageHoverRunnable = new Runnable() {
                        @Override
                        public void run() {
                            // Setup the scroll to the correct page before we swap the views
                            snapToPage(pageUnderPointIndex);

                            // For each of the pages between the paged view and the drag view,
                            // animate them from the previous position to the new position in
                            // the layout (as a result of the drag view moving in the layout)
                            int shiftDelta = (dragViewIndex < pageUnderPointIndex) ? -1 : 1;
                            int lowerIndex = (dragViewIndex < pageUnderPointIndex) ? dragViewIndex + 1
                                    : pageUnderPointIndex;
                            int upperIndex = (dragViewIndex > pageUnderPointIndex) ? dragViewIndex - 1
                                    : pageUnderPointIndex;
                            for (int i = lowerIndex; i <= upperIndex; ++i) {
                                View v = getChildAt(i);
                                // dragViewIndex < pageUnderPointIndex, so after we remove the
                                // drag view all subsequent views to pageUnderPointIndex will
                                // shift down.
                                int oldX = getViewportOffsetX() + getChildOffset(i);
                                int newX = getViewportOffsetX() + getChildOffset(i + shiftDelta);

                                // Animate the view translation from its old position to its new
                                // position
                                AnimatorSet anim = (AnimatorSet) v.getTag(ANIM_TAG_KEY);
                                if (anim != null) {
                                    anim.cancel();
                                }

                                v.setTranslationX(oldX - newX);
                                anim = new AnimatorSet();
                                anim.setDuration(REORDERING_REORDER_REPOSITION_DURATION);
                                anim.playTogether(ObjectAnimator.ofFloat(v, "translationX", 0f));
                                anim.start();
                                v.setTag(anim);
                            }

                            removeView(mDragView);
                            onRemoveView(mDragView, false);
                            addView(mDragView, pageUnderPointIndex);
                            onAddView(mDragView, pageUnderPointIndex);
                            mSidePageHoverIndex = -1;
                            mPageIndicator.setActiveMarker(getNextPage());
                        }
                    };
                    postDelayed(mSidePageHoverRunnable, REORDERING_SIDE_PAGE_HOVER_TIMEOUT);
                }
            } else {
                removeCallbacks(mSidePageHoverRunnable);
                mSidePageHoverIndex = -1;
            }
        } else {
            determineScrollingStart(ev);
        }
        break;

    case MotionEvent.ACTION_UP:
        if (mTouchState == TOUCH_STATE_SCROLLING) {
            final int activePointerId = mActivePointerId;
            final int pointerIndex = ev.findPointerIndex(activePointerId);
            final float x = ev.getX(pointerIndex);
            final VelocityTracker velocityTracker = mVelocityTracker;
            velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
            int velocityX = (int) velocityTracker.getXVelocity(activePointerId);
            final int deltaX = (int) (x - mDownMotionX);
            final int pageWidth = getPageAt(mCurrentPage).getMeasuredWidth();
            boolean isSignificantMove = Math.abs(deltaX) > pageWidth * SIGNIFICANT_MOVE_THRESHOLD;

            mTotalMotionX += Math.abs(mLastMotionX + mLastMotionXRemainder - x);

            boolean isFling = mTotalMotionX > MIN_LENGTH_FOR_FLING
                    && Math.abs(velocityX) > mFlingThresholdVelocity;

            if (!mFreeScroll) {
                // In the case that the page is moved far to one direction and then is flung
                // in the opposite direction, we use a threshold to determine whether we should
                // just return to the starting page, or if we should skip one further.
                boolean returnToOriginalPage = false;
                if (Math.abs(deltaX) > pageWidth * RETURN_TO_ORIGINAL_PAGE_THRESHOLD
                        && Math.signum(velocityX) != Math.signum(deltaX) && isFling) {
                    returnToOriginalPage = true;
                }

                int finalPage;
                // We give flings precedence over large moves, which is why we short-circuit our
                // test for a large move if a fling has been registered. That is, a large
                // move to the left and fling to the right will register as a fling to the right.
                final boolean isRtl = isLayoutRtl();
                boolean isDeltaXLeft = isRtl ? deltaX > 0 : deltaX < 0;
                boolean isVelocityXLeft = isRtl ? velocityX > 0 : velocityX < 0;
                if (((isSignificantMove && !isDeltaXLeft && !isFling) || (isFling && !isVelocityXLeft))
                        && mCurrentPage > 0) {
                    finalPage = returnToOriginalPage ? mCurrentPage : mCurrentPage - 1;
                    snapToPageWithVelocity(finalPage, velocityX);
                } else if (((isSignificantMove && isDeltaXLeft && !isFling) || (isFling && isVelocityXLeft))
                        && mCurrentPage < getChildCount() - 1) {
                    finalPage = returnToOriginalPage ? mCurrentPage : mCurrentPage + 1;
                    snapToPageWithVelocity(finalPage, velocityX);
                } else {
                    snapToDestination();
                }
            } else if (mTouchState == TOUCH_STATE_PREV_PAGE) {
                // at this point we have not moved beyond the touch slop
                // (otherwise mTouchState would be TOUCH_STATE_SCROLLING), so
                // we can just page
                int nextPage = Math.max(0, mCurrentPage - 1);
                if (nextPage != mCurrentPage) {
                    snapToPage(nextPage);
                } else {
                    snapToDestination();
                }
            } else {
                if (!mScroller.isFinished()) {
                    mScroller.abortAnimation();
                }

                float scaleX = getScaleX();
                int vX = (int) (-velocityX * scaleX);
                int initialScrollX = (int) (getScrollX() * scaleX);

                mScroller.fling(initialScrollX, getScrollY(), vX, 0, Integer.MIN_VALUE, Integer.MAX_VALUE, 0,
                        0);
                invalidate();
            }
        } else if (mTouchState == TOUCH_STATE_NEXT_PAGE) {
            // at this point we have not moved beyond the touch slop
            // (otherwise mTouchState would be TOUCH_STATE_SCROLLING), so
            // we can just page
            int nextPage = Math.min(getChildCount() - 1, mCurrentPage + 1);
            if (nextPage != mCurrentPage) {
                snapToPage(nextPage);
            } else {
                snapToDestination();
            }
        } else if (mTouchState == TOUCH_STATE_REORDERING) {
            // Update the last motion position
            mLastMotionX = ev.getX();
            mLastMotionY = ev.getY();

            // Update the parent down so that our zoom animations take this new movement into
            // account
            float[] pt = mapPointFromViewToParent(this, mLastMotionX, mLastMotionY);
            mParentDownMotionX = pt[0];
            mParentDownMotionY = pt[1];
            updateDragViewTranslationDuringDrag();
            boolean handledFling = false;
            if (!DISABLE_FLING_TO_DELETE) {
                // Check the velocity and see if we are flinging-to-delete
                PointF flingToDeleteVector = isFlingingToDelete();
                if (flingToDeleteVector != null) {
                    onFlingToDelete(flingToDeleteVector);
                    handledFling = true;
                }
            }
            if (!handledFling
                    && isHoveringOverDeleteDropTarget((int) mParentDownMotionX, (int) mParentDownMotionY)) {
                onDropToDelete();
            }
        } else {
            if (!mCancelTap) {
                onUnhandledTap(ev);
            }
        }

        // Remove the callback to wait for the side page hover timeout
        removeCallbacks(mSidePageHoverRunnable);
        // End any intermediate reordering states
        resetTouchState();
        break;

    case MotionEvent.ACTION_CANCEL:
        if (mTouchState == TOUCH_STATE_SCROLLING) {
            snapToDestination();
        }
        resetTouchState();
        break;

    case MotionEvent.ACTION_POINTER_UP:
        onSecondaryPointerUp(ev);
        releaseVelocityTracker();
        break;
    }

    return true;
}

From source file:com.n2hsu.launcher.Page.java

@Override
public boolean onTouchEvent(MotionEvent ev) {
    if (DISABLE_TOUCH_INTERACTION) {
        return false;
    }//from   w  w  w. j  a v  a2  s.  co  m

    super.onTouchEvent(ev);

    // Skip touch handling if there are no pages to swipe
    if (getChildCount() <= 0)
        return super.onTouchEvent(ev);

    acquireVelocityTrackerAndAddMovement(ev);

    final int action = ev.getAction();

    switch (action & MotionEvent.ACTION_MASK) {
    case MotionEvent.ACTION_DOWN:
        /*
         * If being flinged and user touches, stop the fling. isFinished
         * will be false if being flinged.
         */
        if (!mScroller.isFinished()) {
            mScroller.abortAnimation();
        }

        // Remember where the motion event started
        mDownMotionX = mLastMotionX = ev.getX();
        mDownMotionY = mLastMotionY = ev.getY();
        mDownScrollX = getScrollX();
        float[] p = mapPointFromViewToParent(this, mLastMotionX, mLastMotionY);
        mParentDownMotionX = p[0];
        mParentDownMotionY = p[1];
        mLastMotionXRemainder = 0;
        mTotalMotionX = 0;
        mActivePointerId = ev.getPointerId(0);

        if (mTouchState == TOUCH_STATE_SCROLLING) {
            pageBeginMoving();
        }
        break;

    case MotionEvent.ACTION_MOVE:
        if (mTouchState == TOUCH_STATE_SCROLLING) {
            // Scroll to follow the motion event
            final int pointerIndex = ev.findPointerIndex(mActivePointerId);

            if (pointerIndex == -1)
                return true;

            final float x = ev.getX(pointerIndex);
            final float deltaX = mLastMotionX + mLastMotionXRemainder - x;

            mTotalMotionX += Math.abs(deltaX);

            // Only scroll and update mLastMotionX if we have moved some
            // discrete amount. We
            // keep the remainder because we are actually testing if we've
            // moved from the last
            // scrolled position (which is discrete).
            if (Math.abs(deltaX) >= 1.0f) {
                mTouchX += deltaX;
                mSmoothingTime = System.nanoTime() / NANOTIME_DIV;
                if (!mDeferScrollUpdate) {
                    scrollBy((int) deltaX, 0);
                    if (DEBUG)
                        Log.d(TAG, "onTouchEvent().Scrolling: " + deltaX);
                } else {
                    invalidate();
                }
                mLastMotionX = x;
                mLastMotionXRemainder = deltaX - (int) deltaX;
            } else {
                awakenScrollBars();
            }
        } else if (mTouchState == TOUCH_STATE_REORDERING) {
            // Update the last motion position
            mLastMotionX = ev.getX();
            mLastMotionY = ev.getY();

            // Update the parent down so that our zoom animations take this
            // new movement into
            // account
            float[] pt = mapPointFromViewToParent(this, mLastMotionX, mLastMotionY);
            mParentDownMotionX = pt[0];
            mParentDownMotionY = pt[1];
            updateDragViewTranslationDuringDrag();

            // Find the closest page to the touch point
            final int dragViewIndex = indexOfChild(mDragView);

            // Change the drag view if we are hovering over the drop target
            boolean isHoveringOverDelete = isHoveringOverDeleteDropTarget((int) mParentDownMotionX,
                    (int) mParentDownMotionY);
            setPageHoveringOverDeleteDropTarget(dragViewIndex, isHoveringOverDelete);

            if (DEBUG)
                Log.d(TAG, "mLastMotionX: " + mLastMotionX);
            if (DEBUG)
                Log.d(TAG, "mLastMotionY: " + mLastMotionY);
            if (DEBUG)
                Log.d(TAG, "mParentDownMotionX: " + mParentDownMotionX);
            if (DEBUG)
                Log.d(TAG, "mParentDownMotionY: " + mParentDownMotionY);

            final int pageUnderPointIndex = getNearestHoverOverPageIndex();
            if (pageUnderPointIndex > -1 && pageUnderPointIndex != indexOfChild(mDragView)
                    && !isHoveringOverDelete) {
                mTempVisiblePagesRange[0] = 0;
                mTempVisiblePagesRange[1] = getPageCount() - 1;
                getOverviewModePages(mTempVisiblePagesRange);
                if (mTempVisiblePagesRange[0] <= pageUnderPointIndex
                        && pageUnderPointIndex <= mTempVisiblePagesRange[1]
                        && pageUnderPointIndex != mSidePageHoverIndex && mScroller.isFinished()) {
                    mSidePageHoverIndex = pageUnderPointIndex;
                    mSidePageHoverRunnable = new Runnable() {
                        @Override
                        public void run() {
                            // Setup the scroll to the correct page before
                            // we swap the views
                            snapToPage(pageUnderPointIndex);

                            // For each of the pages between the paged view
                            // and the drag view,
                            // animate them from the previous position to
                            // the new position in
                            // the layout (as a result of the drag view
                            // moving in the layout)
                            int shiftDelta = (dragViewIndex < pageUnderPointIndex) ? -1 : 1;
                            int lowerIndex = (dragViewIndex < pageUnderPointIndex) ? dragViewIndex + 1
                                    : pageUnderPointIndex;
                            int upperIndex = (dragViewIndex > pageUnderPointIndex) ? dragViewIndex - 1
                                    : pageUnderPointIndex;
                            for (int i = lowerIndex; i <= upperIndex; ++i) {
                                View v = getChildAt(i);
                                // dragViewIndex < pageUnderPointIndex, so
                                // after we remove the
                                // drag view all subsequent views to
                                // pageUnderPointIndex will
                                // shift down.
                                int oldX = getViewportOffsetX() + getChildOffset(i);
                                int newX = getViewportOffsetX() + getChildOffset(i + shiftDelta);

                                // Animate the view translation from its old
                                // position to its new
                                // position
                                AnimatorSet anim = (AnimatorSet) v.getTag(ANIM_TAG_KEY);
                                if (anim != null) {
                                    anim.cancel();
                                }

                                v.setTranslationX(oldX - newX);
                                anim = new AnimatorSet();
                                anim.setDuration(REORDERING_REORDER_REPOSITION_DURATION);
                                anim.playTogether(ObjectAnimator.ofFloat(v, "translationX", 0f));
                                anim.start();
                                v.setTag(anim);
                            }

                            removeView(mDragView);
                            onRemoveView(mDragView, false);
                            addView(mDragView, pageUnderPointIndex);
                            onAddView(mDragView, pageUnderPointIndex);
                            mSidePageHoverIndex = -1;
                            mPageIndicator.setActiveMarker(getNextPage());
                        }
                    };
                    postDelayed(mSidePageHoverRunnable, REORDERING_SIDE_PAGE_HOVER_TIMEOUT);
                }
            } else {
                removeCallbacks(mSidePageHoverRunnable);
                mSidePageHoverIndex = -1;
            }
        } else {
            determineScrollingStart(ev);
        }
        break;

    case MotionEvent.ACTION_UP:
        if (mTouchState == TOUCH_STATE_SCROLLING) {
            final int activePointerId = mActivePointerId;
            final int pointerIndex = ev.findPointerIndex(activePointerId);
            final float x = ev.getX(pointerIndex);
            final VelocityTracker velocityTracker = mVelocityTracker;
            velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
            int velocityX = (int) velocityTracker.getXVelocity(activePointerId);
            final int deltaX = (int) (x - mDownMotionX);
            final int pageWidth = getPageAt(mCurrentPage).getMeasuredWidth();
            boolean isSignificantMove = Math.abs(deltaX) > pageWidth * SIGNIFICANT_MOVE_THRESHOLD;

            mTotalMotionX += Math.abs(mLastMotionX + mLastMotionXRemainder - x);

            boolean isFling = mTotalMotionX > MIN_LENGTH_FOR_FLING
                    && Math.abs(velocityX) > mFlingThresholdVelocity;

            if (!mFreeScroll) {
                // In the case that the page is moved far to one direction
                // and then is flung
                // in the opposite direction, we use a threshold to
                // determine whether we should
                // just return to the starting page, or if we should skip
                // one further.
                boolean returnToOriginalPage = false;
                if (Math.abs(deltaX) > pageWidth * RETURN_TO_ORIGINAL_PAGE_THRESHOLD
                        && Math.signum(velocityX) != Math.signum(deltaX) && isFling) {
                    returnToOriginalPage = true;
                }

                int finalPage;
                // We give flings precedence over large moves, which is why
                // we short-circuit our
                // test for a large move if a fling has been registered.
                // That is, a large
                // move to the left and fling to the right will register as
                // a fling to the right.
                final boolean isRtl = isLayoutRtl();
                boolean isDeltaXLeft = isRtl ? deltaX > 0 : deltaX < 0;
                boolean isVelocityXLeft = isRtl ? velocityX > 0 : velocityX < 0;
                if (((isSignificantMove && !isDeltaXLeft && !isFling) || (isFling && !isVelocityXLeft))
                        && mCurrentPage > 0) {
                    finalPage = returnToOriginalPage ? mCurrentPage : mCurrentPage - 1;
                    snapToPageWithVelocity(finalPage, velocityX);
                } else if (((isSignificantMove && isDeltaXLeft && !isFling) || (isFling && isVelocityXLeft))
                        && mCurrentPage < getChildCount() - 1) {
                    finalPage = returnToOriginalPage ? mCurrentPage : mCurrentPage + 1;
                    snapToPageWithVelocity(finalPage, velocityX);
                } else {
                    snapToDestination();
                }
            } else if (mTouchState == TOUCH_STATE_PREV_PAGE) {
                // at this point we have not moved beyond the touch slop
                // (otherwise mTouchState would be TOUCH_STATE_SCROLLING),
                // so
                // we can just page
                int nextPage = Math.max(0, mCurrentPage - 1);
                if (nextPage != mCurrentPage) {
                    snapToPage(nextPage);
                } else {
                    snapToDestination();
                }
            } else {
                if (!mScroller.isFinished()) {
                    mScroller.abortAnimation();
                }

                float scaleX = getScaleX();
                int vX = (int) (-velocityX * scaleX);
                int initialScrollX = (int) (getScrollX() * scaleX);

                mScroller.fling(initialScrollX, getScrollY(), vX, 0, Integer.MIN_VALUE, Integer.MAX_VALUE, 0,
                        0);
                invalidate();
            }
        } else if (mTouchState == TOUCH_STATE_NEXT_PAGE) {
            // at this point we have not moved beyond the touch slop
            // (otherwise mTouchState would be TOUCH_STATE_SCROLLING), so
            // we can just page
            int nextPage = Math.min(getChildCount() - 1, mCurrentPage + 1);
            if (nextPage != mCurrentPage) {
                snapToPage(nextPage);
            } else {
                snapToDestination();
            }
        } else if (mTouchState == TOUCH_STATE_REORDERING) {
            // Update the last motion position
            mLastMotionX = ev.getX();
            mLastMotionY = ev.getY();

            // Update the parent down so that our zoom animations take this
            // new movement into
            // account
            float[] pt = mapPointFromViewToParent(this, mLastMotionX, mLastMotionY);
            mParentDownMotionX = pt[0];
            mParentDownMotionY = pt[1];
            updateDragViewTranslationDuringDrag();
            boolean handledFling = false;
            if (!DISABLE_FLING_TO_DELETE) {
                // Check the velocity and see if we are flinging-to-delete
                PointF flingToDeleteVector = isFlingingToDelete();
                if (flingToDeleteVector != null) {
                    onFlingToDelete(flingToDeleteVector);
                    handledFling = true;
                }
            }
            if (!handledFling
                    && isHoveringOverDeleteDropTarget((int) mParentDownMotionX, (int) mParentDownMotionY)) {
                onDropToDelete();
            }
        } else {
            if (!mCancelTap) {
                onUnhandledTap(ev);
            }
        }

        // Remove the callback to wait for the side page hover timeout
        removeCallbacks(mSidePageHoverRunnable);
        // End any intermediate reordering states
        resetTouchState();
        break;

    case MotionEvent.ACTION_CANCEL:
        if (mTouchState == TOUCH_STATE_SCROLLING) {
            snapToDestination();
        }
        resetTouchState();
        break;

    case MotionEvent.ACTION_POINTER_UP:
        onSecondaryPointerUp(ev);
        releaseVelocityTracker();
        break;
    }

    return true;
}

From source file:com.android.internal.widget.ViewPager.java

@Override
public boolean onTouchEvent(MotionEvent ev) {
    if (ev.getAction() == MotionEvent.ACTION_DOWN && ev.getEdgeFlags() != 0) {
        // Don't handle edge touches immediately -- they may actually belong to one of our
        // descendants.
        return false;
    }//from   w w w  . ja  v  a  2s.  c  o  m

    if (mAdapter == null || mAdapter.getCount() == 0) {
        // Nothing to present or scroll; nothing to touch.
        return false;
    }

    if (mVelocityTracker == null) {
        mVelocityTracker = VelocityTracker.obtain();
    }
    mVelocityTracker.addMovement(ev);

    final int action = ev.getAction();
    boolean needsInvalidate = false;

    switch (action & MotionEvent.ACTION_MASK) {
    case MotionEvent.ACTION_DOWN: {
        mScroller.abortAnimation();
        mPopulatePending = false;
        populate();

        // Remember where the motion event started
        mLastMotionX = mInitialMotionX = ev.getX();
        mLastMotionY = mInitialMotionY = ev.getY();
        mActivePointerId = ev.getPointerId(0);
        break;
    }
    case MotionEvent.ACTION_MOVE:
        if (!mIsBeingDragged) {
            final int pointerIndex = ev.findPointerIndex(mActivePointerId);
            final float x = ev.getX(pointerIndex);
            final float xDiff = Math.abs(x - mLastMotionX);
            final float y = ev.getY(pointerIndex);
            final float yDiff = Math.abs(y - mLastMotionY);
            if (DEBUG)
                Log.v(TAG, "Moved x to " + x + "," + y + " diff=" + xDiff + "," + yDiff);
            if (xDiff > mTouchSlop && xDiff > yDiff) {
                if (DEBUG)
                    Log.v(TAG, "Starting drag!");
                mIsBeingDragged = true;
                requestParentDisallowInterceptTouchEvent(true);
                mLastMotionX = x - mInitialMotionX > 0 ? mInitialMotionX + mTouchSlop
                        : mInitialMotionX - mTouchSlop;
                mLastMotionY = y;
                setScrollState(SCROLL_STATE_DRAGGING);
                setScrollingCacheEnabled(true);

                // Disallow Parent Intercept, just in case
                ViewParent parent = getParent();
                if (parent != null) {
                    parent.requestDisallowInterceptTouchEvent(true);
                }
            }
        }
        // Not else! Note that mIsBeingDragged can be set above.
        if (mIsBeingDragged) {
            // Scroll to follow the motion event
            final int activePointerIndex = ev.findPointerIndex(mActivePointerId);
            final float x = ev.getX(activePointerIndex);
            needsInvalidate |= performDrag(x);
        }
        break;
    case MotionEvent.ACTION_UP:
        if (mIsBeingDragged) {
            final VelocityTracker velocityTracker = mVelocityTracker;
            velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
            final int initialVelocity = (int) velocityTracker.getXVelocity(mActivePointerId);

            mPopulatePending = true;

            final float scrollStart = getScrollStart();
            final float scrolledPages = scrollStart / getPaddedWidth();
            final ItemInfo ii = infoForFirstVisiblePage();
            final int currentPage = ii.position;
            final float nextPageOffset;
            if (isLayoutRtl()) {
                nextPageOffset = (ii.offset - scrolledPages) / ii.widthFactor;
            } else {
                nextPageOffset = (scrolledPages - ii.offset) / ii.widthFactor;
            }

            final int activePointerIndex = ev.findPointerIndex(mActivePointerId);
            final float x = ev.getX(activePointerIndex);
            final int totalDelta = (int) (x - mInitialMotionX);
            final int nextPage = determineTargetPage(currentPage, nextPageOffset, initialVelocity, totalDelta);
            setCurrentItemInternal(nextPage, true, true, initialVelocity);

            mActivePointerId = INVALID_POINTER;
            endDrag();
            mLeftEdge.onRelease();
            mRightEdge.onRelease();
            needsInvalidate = true;
        }
        break;
    case MotionEvent.ACTION_CANCEL:
        if (mIsBeingDragged) {
            scrollToItem(mCurItem, true, 0, false);
            mActivePointerId = INVALID_POINTER;
            endDrag();
            mLeftEdge.onRelease();
            mRightEdge.onRelease();
            needsInvalidate = true;
        }
        break;
    case MotionEvent.ACTION_POINTER_DOWN: {
        final int index = ev.getActionIndex();
        final float x = ev.getX(index);
        mLastMotionX = x;
        mActivePointerId = ev.getPointerId(index);
        break;
    }
    case MotionEvent.ACTION_POINTER_UP:
        onSecondaryPointerUp(ev);
        mLastMotionX = ev.getX(ev.findPointerIndex(mActivePointerId));
        break;
    }
    if (needsInvalidate) {
        postInvalidateOnAnimation();
    }
    return true;
}

From source file:de.tum.in.tumcampus.auxiliary.calendar.DayView.java

@Override
public boolean onTouchEvent(MotionEvent ev) {
    int action = ev.getAction();

    if ((ev.getActionMasked() == MotionEvent.ACTION_DOWN) || (ev.getActionMasked() == MotionEvent.ACTION_UP)
            || (ev.getActionMasked() == MotionEvent.ACTION_POINTER_UP)
            || (ev.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN)) {
        mRecalCenterHour = true;/*www . j a v  a 2 s .  com*/
    }

    if ((mTouchMode & TOUCH_MODE_HSCROLL) == 0) {
        mScaleGestureDetector.onTouchEvent(ev);
    }

    switch (action) {
    case MotionEvent.ACTION_DOWN:
        mStartingScroll = true;

        mHandleActionUp = true;
        mGestureDetector.onTouchEvent(ev);
        return true;

    case MotionEvent.ACTION_MOVE:
        mGestureDetector.onTouchEvent(ev);
        return true;

    case MotionEvent.ACTION_UP:
        mEdgeEffectTop.onRelease();
        mEdgeEffectBottom.onRelease();
        mStartingScroll = false;
        mGestureDetector.onTouchEvent(ev);
        if (!mHandleActionUp) {
            mHandleActionUp = true;
            mViewStartX = 0;
            invalidate();
            return true;
        }

        if (mOnFlingCalled) {
            return true;
        }

        // If we were scrolling, then reset the selected hour so that it is visible.
        if (mScrolling) {
            mScrolling = false;
            resetSelectedHour();
            invalidate();
        }

        if ((mTouchMode & TOUCH_MODE_HSCROLL) != 0) {
            mTouchMode = TOUCH_MODE_INITIAL_STATE;
            if (Math.abs(mViewStartX) > mHorizontalSnapBackThreshold) {
                // The user has gone beyond the threshold so switch views
                switchViews(mViewStartX > 0, mViewStartX, mViewWidth, 0);
                mViewStartX = 0;
                return true;
            } else {
                // Not beyond the threshold so invalidate which will cause
                // the view to snap back. Also call recalc() to ensure
                // that we have the correct starting date and title.
                recalc();
                invalidate();
                mViewStartX = 0;
            }
        }

        return true;

    // This case isn't expected to happen.
    case MotionEvent.ACTION_CANCEL:
        mGestureDetector.onTouchEvent(ev);
        mScrolling = false;
        resetSelectedHour();
        return true;

    default:
        if (mGestureDetector.onTouchEvent(ev)) {
            return true;
        }
        return super.onTouchEvent(ev);
    }
}

From source file:processing.core.PApplet.java

/**
 * Take action based on a motion event. Internally updates mouseX, mouseY,
 * mousePressed, and mouseEvent. Then it calls the event type with no
 * params, i.e. mousePressed() or mouseReleased() that the user may have
 * overloaded to do something more useful.
 *//*from w w  w .jav a2s .  co  m*/
protected void handleMotionEvent(PMotionEvent pme) {
    pmotionX = emotionX;
    pmotionY = emotionY;
    motionX = pme.motionX[0];
    motionY = pme.motionY[0];
    motionPressure = pme.motionPressure[0];

    // replace previous mouseX/Y with the last from the event handlers
    pmouseX = emouseX;
    pmouseY = emouseY;
    mouseX = pme.mouseX[0];
    mouseY = pme.mouseY[0];

    // this used to only be called on mouseMoved and mouseDragged
    // change it back if people run into trouble
    if (firstMotion) {
        pmouseX = mouseX;
        pmouseY = mouseY;
        dmouseX = mouseX; // set it as the first value to be used inside
                          // draw() too
        dmouseY = mouseY;

        pmotionX = motionX;
        pmotionY = motionY;
        dmotionX = motionX;
        dmotionY = motionY;

        firstMotion = false;
    }

    if (ppointersX.length < numPointers) {
        ppointersX = new float[numPointers];
        ppointersY = new float[numPointers];
        ppointersPressure = new float[numPointers];
    }
    arrayCopy(pointersX, ppointersX);
    arrayCopy(pointersY, ppointersY);
    arrayCopy(pointersPressure, ppointersPressure);

    numPointers = pme.numPointers;
    if (pointersX.length < numPointers) {
        pointersX = new float[numPointers];
        pointersY = new float[numPointers];
        pointersPressure = new float[numPointers];
    }
    arrayCopy(pme.motionX, pointersX);
    arrayCopy(pme.motionY, pointersY);
    arrayCopy(pme.motionPressure, pointersPressure);

    // Triggering the appropriate event methods
    if (pme.action == MotionEvent.ACTION_DOWN || (!mousePressed && numPointers == 1)) {
        // First pointer is down
        mousePressed = true;
        onePointerGesture = true;
        twoPointerGesture = false;
        downMillis = millis();
        downX = pointersX[0];
        downY = pointersY[0];

        mousePressed();
        pressEvent();

    } else if ((pme.action == MotionEvent.ACTION_POINTER_DOWN && numPointers == 2)
            || (pme.action == MotionEvent.ACTION_POINTER_2_DOWN) || // 2.3
            // seems
            // to
            // use
            // this
            // action
            // constant
            // (supposedly
            // deprecated)
            // instead
            // of
            // ACTION_POINTER_DOWN
            (pnumPointers == 1 && numPointers == 2)) { // 2.1 just uses MOVE
        // as the action
        // constant, so the
        // only way to know
        // we have a new
        // pointer is to
        // compare the
        // counters.

        // An additional pointer is down (we keep track of multitouch only
        // for 2 pointers)
        onePointerGesture = false;
        twoPointerGesture = true;

    } else if ((pme.action == MotionEvent.ACTION_POINTER_UP && numPointers == 2)
            || (pme.action == MotionEvent.ACTION_POINTER_2_UP) || // 2.1
            // doesn't
            // use
            // the
            // ACTION_POINTER_UP
            // constant,
            // but
            // this
            // one,
            // apparently
            // deprecated
            // in
            // newer
            // versions
            // of
            // the
            // SDK.
            (twoPointerGesture && numPointers < 2)) { // Sometimes it seems
        // that it doesn't
        // generate the up
        // event.
        // A previously detected pointer is up

        twoPointerGesture = false; // Not doing a 2-pointer gesture anymore,
        // but neither a 1-pointer.

    } else if (pme.action == MotionEvent.ACTION_MOVE) {
        // Pointer motion

        if (onePointerGesture) {
            if (mousePressed) {
                mouseDragged();
                dragEvent();
            } else {
                mouseMoved();
                moveEvent();
            }
        } else if (twoPointerGesture) {
            float d0 = PApplet.dist(ppointersX[0], ppointersY[0], ppointersX[1], ppointersY[1]);
            float d1 = PApplet.dist(pointersX[0], pointersY[0], pointersX[1], pointersY[1]);

            if (0 < d0 && 0 < d1) {
                float centerX = 0.5f * (pointersX[0] + pointersX[1]);
                float centerY = 0.5f * (pointersY[0] + pointersY[1]);

                zoomEvent(centerX, centerY, d0, d1);
            }
        }

    } else if (pme.action == MotionEvent.ACTION_UP) {
        // Final pointer is up
        mousePressed = false;
        mouseReleased();

        float upX = pointersX[0];
        float upY = pointersY[0];
        float gestureLength = PApplet.dist(downX, downY, upX, upY);

        int upMillis = millis();
        int gestureTime = upMillis - downMillis;

        if (onePointerGesture) {

            // First, lets determine if this 1-pointer event is a tap
            boolean tap = gestureLength <= MAX_TAP_DISP && gestureTime <= MAX_TAP_DURATION;
            if (tap) {
                mouseClicked();
                tapEvent(downX, downY);
            } else if (MIN_SWIPE_LENGTH <= gestureLength && gestureTime <= MAX_SWIPE_DURATION) {
                swipeEvent(downX, downY, upX, upY);
            } else {
                mouseReleased();
                releaseEvent();
            }

        } else {
            mouseReleased();
            releaseEvent();
        }

        onePointerGesture = twoPointerGesture = false;
    } else if (pme.action == MotionEvent.ACTION_CANCEL) {
        // Current gesture is canceled.
        onePointerGesture = twoPointerGesture = false;
        mousePressed = false;

        mouseReleased();
        releaseEvent();
    } else {
        // System.out.println("Unknown MotionEvent action: " + action);
    }

    pnumPointers = numPointers;

    if (pme.action == MotionEvent.ACTION_MOVE) {
        emotionX = motionX;
        emotionY = motionY;
        emouseX = mouseX;
        emouseY = mouseY;
    }
}

From source file:com.wb.launcher3.Page.java

@Override
public boolean onTouchEvent(MotionEvent ev) {
    if (DISABLE_TOUCH_INTERACTION) {
        return false;
    }/*from  w  w w  .  ja v  a2 s . com*/

    super.onTouchEvent(ev);

    // Skip touch handling if there are no pages to swipe
    if (getChildCount() <= 0)
        return super.onTouchEvent(ev);

    acquireVelocityTrackerAndAddMovement(ev);

    final int action = ev.getAction();

    switch (action & MotionEvent.ACTION_MASK) {
    case MotionEvent.ACTION_DOWN:
        /*
         * If being flinged and user touches, stop the fling. isFinished
         * will be false if being flinged.
         */
        if (!mScroller.isFinished()) {
            mScroller.abortAnimation();
        }

        // Remember where the motion event started
        mDownMotionX = mLastMotionX = ev.getX();
        mDownMotionY = mLastMotionY = ev.getY();
        mDownScrollX = getScrollX();
        float[] p = mapPointFromViewToParent(this, mLastMotionX, mLastMotionY);
        mParentDownMotionX = p[0];
        mParentDownMotionY = p[1];
        mLastMotionXRemainder = 0;
        mTotalMotionX = 0;
        mActivePointerId = ev.getPointerId(0);

        if (mTouchState == TOUCH_STATE_SCROLLING) {
            pageBeginMoving();
        }
        break;

    case MotionEvent.ACTION_MOVE:
        //*/zhangwuba add 2014-5-8
        if (getLauncherDeleteAppSate()) {
            return true;
        }
        //*/
        if (mTouchState == TOUCH_STATE_SCROLLING) {
            // Scroll to follow the motion event
            final int pointerIndex = ev.findPointerIndex(mActivePointerId);

            if (pointerIndex == -1)
                return true;

            final float x = ev.getX(pointerIndex);
            final float deltaX = mLastMotionX + mLastMotionXRemainder - x;

            mTotalMotionX += Math.abs(deltaX);

            // Only scroll and update mLastMotionX if we have moved some discrete amount.  We
            // keep the remainder because we are actually testing if we've moved from the last
            // scrolled position (which is discrete).
            if (Math.abs(deltaX) >= 1.0f) {
                mTouchX += deltaX;
                mSmoothingTime = System.nanoTime() / NANOTIME_DIV;
                if (!mDeferScrollUpdate) {
                    scrollBy((int) deltaX, 0);
                    if (DEBUG)
                        Log.d(TAG, "onTouchEvent().Scrolling: " + deltaX);
                } else {
                    invalidate();
                }
                mLastMotionX = x;
                mLastMotionXRemainder = deltaX - (int) deltaX;
            } else {
                awakenScrollBars();
            }
        } else if (mTouchState == TOUCH_STATE_REORDERING) {
            // Update the last motion position
            mLastMotionX = ev.getX();
            mLastMotionY = ev.getY();

            // Update the parent down so that our zoom animations take this new movement into
            // account
            float[] pt = mapPointFromViewToParent(this, mLastMotionX, mLastMotionY);
            mParentDownMotionX = pt[0];
            mParentDownMotionY = pt[1];
            updateDragViewTranslationDuringDrag();

            // Find the closest page to the touch point
            final int dragViewIndex = indexOfChild(mDragView);

            // Change the drag view if we are hovering over the drop target
            boolean isHoveringOverDelete = isHoveringOverDeleteDropTarget((int) mParentDownMotionX,
                    (int) mParentDownMotionY);
            setPageHoveringOverDeleteDropTarget(dragViewIndex, isHoveringOverDelete);

            if (DEBUG)
                Log.d(TAG, "mLastMotionX: " + mLastMotionX);
            if (DEBUG)
                Log.d(TAG, "mLastMotionY: " + mLastMotionY);
            if (DEBUG)
                Log.d(TAG, "mParentDownMotionX: " + mParentDownMotionX);
            if (DEBUG)
                Log.d(TAG, "mParentDownMotionY: " + mParentDownMotionY);

            final int pageUnderPointIndex = getNearestHoverOverPageIndex();
            if (pageUnderPointIndex > -1 && pageUnderPointIndex != indexOfChild(mDragView)
                    && !isHoveringOverDelete) {
                mTempVisiblePagesRange[0] = 0;
                mTempVisiblePagesRange[1] = getPageCount() - 1;
                getOverviewModePages(mTempVisiblePagesRange);
                if (mTempVisiblePagesRange[0] <= pageUnderPointIndex
                        && pageUnderPointIndex <= mTempVisiblePagesRange[1]
                        && pageUnderPointIndex != mSidePageHoverIndex && mScroller.isFinished()) {
                    mSidePageHoverIndex = pageUnderPointIndex;
                    mSidePageHoverRunnable = new Runnable() {
                        @Override
                        public void run() {
                            // Setup the scroll to the correct page before we swap the views
                            snapToPage(pageUnderPointIndex);

                            // For each of the pages between the paged view and the drag view,
                            // animate them from the previous position to the new position in
                            // the layout (as a result of the drag view moving in the layout)
                            int shiftDelta = (dragViewIndex < pageUnderPointIndex) ? -1 : 1;
                            int lowerIndex = (dragViewIndex < pageUnderPointIndex) ? dragViewIndex + 1
                                    : pageUnderPointIndex;
                            int upperIndex = (dragViewIndex > pageUnderPointIndex) ? dragViewIndex - 1
                                    : pageUnderPointIndex;
                            for (int i = lowerIndex; i <= upperIndex; ++i) {
                                View v = getChildAt(i);
                                // dragViewIndex < pageUnderPointIndex, so after we remove the
                                // drag view all subsequent views to pageUnderPointIndex will
                                // shift down.
                                int oldX = getViewportOffsetX() + getChildOffset(i);
                                int newX = getViewportOffsetX() + getChildOffset(i + shiftDelta);

                                // Animate the view translation from its old position to its new
                                // position
                                AnimatorSet anim = (AnimatorSet) v.getTag(ANIM_TAG_KEY);
                                if (anim != null) {
                                    anim.cancel();
                                }

                                v.setTranslationX(oldX - newX);
                                anim = new AnimatorSet();
                                anim.setDuration(REORDERING_REORDER_REPOSITION_DURATION);
                                anim.playTogether(ObjectAnimator.ofFloat(v, "translationX", 0f));
                                anim.start();
                                v.setTag(anim);
                            }

                            removeView(mDragView);
                            onRemoveView(mDragView, false);
                            addView(mDragView, pageUnderPointIndex);
                            onAddView(mDragView, pageUnderPointIndex);
                            mSidePageHoverIndex = -1;
                            mPageIndicator.setActiveMarker(getNextPage());
                        }
                    };
                    postDelayed(mSidePageHoverRunnable, REORDERING_SIDE_PAGE_HOVER_TIMEOUT);
                }
            } else {
                removeCallbacks(mSidePageHoverRunnable);
                mSidePageHoverIndex = -1;
            }
        } else {
            determineScrollingStart(ev);
        }
        break;

    case MotionEvent.ACTION_UP:
        if (mTouchState == TOUCH_STATE_SCROLLING) {
            final int activePointerId = mActivePointerId;
            final int pointerIndex = ev.findPointerIndex(activePointerId);
            final float x = ev.getX(pointerIndex);
            final VelocityTracker velocityTracker = mVelocityTracker;
            velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
            int velocityX = (int) velocityTracker.getXVelocity(activePointerId);
            final int deltaX = (int) (x - mDownMotionX);
            final int pageWidth = getPageAt(mCurrentPage).getMeasuredWidth();
            boolean isSignificantMove = Math.abs(deltaX) > pageWidth * SIGNIFICANT_MOVE_THRESHOLD;

            mTotalMotionX += Math.abs(mLastMotionX + mLastMotionXRemainder - x);

            boolean isFling = mTotalMotionX > MIN_LENGTH_FOR_FLING
                    && Math.abs(velocityX) > mFlingThresholdVelocity;

            if (!mFreeScroll) {
                // In the case that the page is moved far to one direction and then is flung
                // in the opposite direction, we use a threshold to determine whether we should
                // just return to the starting page, or if we should skip one further.
                boolean returnToOriginalPage = false;
                if (Math.abs(deltaX) > pageWidth * RETURN_TO_ORIGINAL_PAGE_THRESHOLD
                        && Math.signum(velocityX) != Math.signum(deltaX) && isFling) {
                    returnToOriginalPage = true;
                }

                //*/Added by tyd Greg 2014-03-20,for transition effect
                if (TydtechConfig.CYCLE_ROLL_PAGES_ENABLED) {
                    m_moveNextDeltaX = deltaX;
                    m_isSignificantMoveNext = (!returnToOriginalPage && (isSignificantMove || isFling));
                }
                //*/

                int finalPage;
                // We give flings precedence over large moves, which is why we short-circuit our
                // test for a large move if a fling has been registered. That is, a large
                // move to the left and fling to the right will register as a fling to the right.
                final boolean isRtl = isLayoutRtl();
                boolean isDeltaXLeft = isRtl ? deltaX > 0 : deltaX < 0;
                boolean isVelocityXLeft = isRtl ? velocityX > 0 : velocityX < 0;
                if (((isSignificantMove && !isDeltaXLeft && !isFling) || (isFling && !isVelocityXLeft))
                        && mCurrentPage > 0) {
                    finalPage = returnToOriginalPage ? mCurrentPage : mCurrentPage - 1;
                    snapToPageWithVelocity(finalPage, velocityX);
                } else if (((isSignificantMove && isDeltaXLeft && !isFling) || (isFling && isVelocityXLeft))
                        && mCurrentPage < getChildCount() - 1) {
                    finalPage = returnToOriginalPage ? mCurrentPage : mCurrentPage + 1;
                    snapToPageWithVelocity(finalPage, velocityX);
                } else {
                    snapToDestination();
                }
            } else if (mTouchState == TOUCH_STATE_PREV_PAGE) {
                // at this point we have not moved beyond the touch slop
                // (otherwise mTouchState would be TOUCH_STATE_SCROLLING), so
                // we can just page
                int nextPage = Math.max(0, mCurrentPage - 1);
                if (nextPage != mCurrentPage) {
                    snapToPage(nextPage);
                } else {
                    snapToDestination();
                }
            } else {
                if (!mScroller.isFinished()) {
                    mScroller.abortAnimation();
                }

                float scaleX = getScaleX();
                int vX = (int) (-velocityX * scaleX);
                int initialScrollX = (int) (getScrollX() * scaleX);

                mScroller.fling(initialScrollX, getScrollY(), vX, 0, Integer.MIN_VALUE, Integer.MAX_VALUE, 0,
                        0);
                invalidate();
            }
        } else if (mTouchState == TOUCH_STATE_NEXT_PAGE) {
            // at this point we have not moved beyond the touch slop
            // (otherwise mTouchState would be TOUCH_STATE_SCROLLING), so
            // we can just page
            int nextPage = Math.min(getChildCount() - 1, mCurrentPage + 1);
            if (nextPage != mCurrentPage) {
                snapToPage(nextPage);
            } else {
                snapToDestination();
            }
        } else if (mTouchState == TOUCH_STATE_REORDERING) {
            // Update the last motion position
            mLastMotionX = ev.getX();
            mLastMotionY = ev.getY();

            // Update the parent down so that our zoom animations take this new movement into
            // account
            float[] pt = mapPointFromViewToParent(this, mLastMotionX, mLastMotionY);
            mParentDownMotionX = pt[0];
            mParentDownMotionY = pt[1];
            updateDragViewTranslationDuringDrag();
            boolean handledFling = false;
            if (!DISABLE_FLING_TO_DELETE) {
                // Check the velocity and see if we are flinging-to-delete
                PointF flingToDeleteVector = isFlingingToDelete();
                if (flingToDeleteVector != null) {
                    onFlingToDelete(flingToDeleteVector);
                    handledFling = true;
                }
            }
            if (!handledFling
                    && isHoveringOverDeleteDropTarget((int) mParentDownMotionX, (int) mParentDownMotionY)) {
                onDropToDelete();
            }
        }
        //*/Added by tyd Greg 2014-03-21,for support the touch swipe gesture
        else if (mTouchState == TOUCH_SWIPE_DOWN_GESTURE) {
            if (mOnTouchSwipeGestureListener != null) {
                mOnTouchSwipeGestureListener.fireSwipeDownAction();
            }
        } else if (mTouchState == TOUCH_SWIPE_UP_GESTURE) {
            if (mOnTouchSwipeGestureListener != null) {
                mOnTouchSwipeGestureListener.fireSwipeUpAction();
            }
        }
        //*/

        else {
            if (!mCancelTap) {
                onUnhandledTap(ev);
            }
        }

        // Remove the callback to wait for the side page hover timeout
        removeCallbacks(mSidePageHoverRunnable);
        // End any intermediate reordering states
        resetTouchState();
        break;

    case MotionEvent.ACTION_CANCEL:
        if (mTouchState == TOUCH_STATE_SCROLLING) {
            snapToDestination();
        }
        resetTouchState();
        break;

    case MotionEvent.ACTION_POINTER_UP:
        onSecondaryPointerUp(ev);
        releaseVelocityTracker();
        break;
    }

    return true;
}

From source file:net.bluehack.ui.ChatActivity.java

@Override
public View createView(Context context) {

    if (chatMessageCellsCache.isEmpty()) {
        for (int a = 0; a < 8; a++) {
            chatMessageCellsCache.add(new ChatMessageCell(context));
        }/*  ww w . ja v a  2s  .c o m*/
    }
    for (int a = 1; a >= 0; a--) {
        selectedMessagesIds[a].clear();
        selectedMessagesCanCopyIds[a].clear();
    }
    cantDeleteMessagesCount = 0;

    hasOwnBackground = true;
    if (chatAttachAlert != null) {
        chatAttachAlert.onDestroy();
        chatAttachAlert = null;
    }

    Theme.loadRecources(context);
    Theme.loadChatResources(context);

    actionBar.setAddToContainer(false);
    actionBar.setBackButtonDrawable(new BackDrawable(false));
    actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() {
        @Override
        public void onItemClick(final int id) {
            if (id == -1) {
                if (actionBar.isActionModeShowed()) {
                    for (int a = 1; a >= 0; a--) {
                        selectedMessagesIds[a].clear();
                        selectedMessagesCanCopyIds[a].clear();
                    }
                    cantDeleteMessagesCount = 0;
                    if (chatActivityEnterView.isEditingMessage()) {
                        chatActivityEnterView.setEditingMessageObject(null, false);
                    } else {
                        actionBar.hideActionMode();
                        updatePinnedMessageView(true);
                    }
                    updateVisibleRows();
                } else {
                    finishFragment();
                }
            } else if (id == copy) {
                String str = "";
                int previousUid = 0;
                for (int a = 1; a >= 0; a--) {
                    ArrayList<Integer> ids = new ArrayList<>(selectedMessagesCanCopyIds[a].keySet());
                    if (currentEncryptedChat == null) {
                        Collections.sort(ids);
                    } else {
                        Collections.sort(ids, Collections.reverseOrder());
                    }
                    for (int b = 0; b < ids.size(); b++) {
                        Integer messageId = ids.get(b);
                        MessageObject messageObject = selectedMessagesCanCopyIds[a].get(messageId);
                        if (str.length() != 0) {
                            str += "\n\n";
                        }
                        str += getMessageContent(messageObject, previousUid, true);
                        previousUid = messageObject.messageOwner.from_id;
                    }
                }
                if (str.length() != 0) {
                    AndroidUtilities.addToClipboard(str);
                }
                for (int a = 1; a >= 0; a--) {
                    selectedMessagesIds[a].clear();
                    selectedMessagesCanCopyIds[a].clear();
                }
                cantDeleteMessagesCount = 0;
                actionBar.hideActionMode();
                updatePinnedMessageView(true);
                updateVisibleRows();
            } else if (id == edit_done) {
                if (chatActivityEnterView != null
                        && (chatActivityEnterView.isEditingCaption() || chatActivityEnterView.hasText())) {
                    chatActivityEnterView.doneEditingMessage();
                }
            } else if (id == delete) {
                if (getParentActivity() == null) {
                    return;
                }
                createDeleteMessagesAlert(null);
            } else if (id == forward) {
                Bundle args = new Bundle();
                args.putBoolean("onlySelect", true);
                args.putInt("dialogsType", 1);
                DialogsActivity fragment = new DialogsActivity(args);
                fragment.setDelegate(ChatActivity.this);
                presentFragment(fragment);
            } else if (id == chat_enc_timer) {
                if (getParentActivity() == null) {
                    return;
                }
                showDialog(AndroidUtilities.buildTTLAlert(getParentActivity(), currentEncryptedChat).create());
            } else if (id == clear_history || id == delete_chat) {
                if (getParentActivity() == null) {
                    return;
                }
                final boolean isChat = (int) dialog_id < 0 && (int) (dialog_id >> 32) != 1;
                AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity());
                builder.setTitle(LocaleController.getString("AppName", R.string.AppName));
                if (id == clear_history) {
                    builder.setMessage(LocaleController.getString("AreYouSureClearHistory",
                            R.string.AreYouSureClearHistory));
                } else {
                    if (isChat) {
                        builder.setMessage(LocaleController.getString("AreYouSureDeleteAndExit",
                                R.string.AreYouSureDeleteAndExit));
                    } else {
                        builder.setMessage(LocaleController.getString("AreYouSureDeleteThisChat",
                                R.string.AreYouSureDeleteThisChat));
                    }
                }
                builder.setPositiveButton(LocaleController.getString("OK", R.string.OK),
                        new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialogInterface, int i) {
                                if (id != clear_history) {
                                    if (isChat) {
                                        if (ChatObject.isNotInChat(currentChat)) {
                                            MessagesController.getInstance().deleteDialog(dialog_id, 0);
                                        } else {
                                            MessagesController.getInstance()
                                                    .deleteUserFromChat(
                                                            (int) -dialog_id, MessagesController.getInstance()
                                                                    .getUser(UserConfig.getClientUserId()),
                                                            null);
                                        }
                                    } else {
                                        MessagesController.getInstance().deleteDialog(dialog_id, 0);
                                    }
                                    finishFragment();
                                } else {
                                    MessagesController.getInstance().deleteDialog(dialog_id, 1);
                                }
                            }
                        });
                builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null);
                showDialog(builder.create());
            } else if (id == share_contact) {
                if (currentUser == null || getParentActivity() == null) {
                    return;
                }
                if (currentUser.phone != null && currentUser.phone.length() != 0) {
                    Bundle args = new Bundle();
                    args.putInt("user_id", currentUser.id);
                    args.putBoolean("addContact", true);
                    presentFragment(new ContactAddActivity(args));
                } else {
                    shareMyContact(replyingMessageObject);
                }
            } else if (id == mute) {
                toggleMute(false);
            } else if (id == report) {
                showDialog(AlertsCreator.createReportAlert(getParentActivity(), dialog_id, ChatActivity.this));
            } else if (id == reply) {
                MessageObject messageObject = null;
                for (int a = 1; a >= 0; a--) {
                    if (messageObject == null && selectedMessagesIds[a].size() == 1) {
                        ArrayList<Integer> ids = new ArrayList<>(selectedMessagesIds[a].keySet());
                        messageObject = messagesDict[a].get(ids.get(0));
                    }
                    selectedMessagesIds[a].clear();
                    selectedMessagesCanCopyIds[a].clear();
                }
                if (messageObject != null && (messageObject.messageOwner.id > 0
                        || messageObject.messageOwner.id < 0 && currentEncryptedChat != null)) {
                    showReplyPanel(true, messageObject, null, null, false, true);
                }
                cantDeleteMessagesCount = 0;
                actionBar.hideActionMode();
                updatePinnedMessageView(true);
                updateVisibleRows();
            } else if (id == chat_menu_attach) {
                if (getParentActivity() == null) {
                    return;
                }

                createChatAttachView();
                chatAttachAlert.loadGalleryPhotos();
                if (Build.VERSION.SDK_INT == 21 || Build.VERSION.SDK_INT == 22) {
                    chatActivityEnterView.closeKeyboard();
                }
                chatAttachAlert.init();
                showDialog(chatAttachAlert);
            } else if (id == bot_help) {
                SendMessagesHelper.getInstance().sendMessage("/help", dialog_id, null, null, false, null, null,
                        null);
            } else if (id == bot_settings) {
                SendMessagesHelper.getInstance().sendMessage("/settings", dialog_id, null, null, false, null,
                        null, null);
            } else if (id == search) {
                openSearchWithText(null);
            }
        }
    });

    avatarContainer = new ChatAvatarContainer(context, this, currentEncryptedChat != null);
    actionBar.addView(avatarContainer, 0, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT,
            LayoutHelper.MATCH_PARENT, Gravity.TOP | Gravity.LEFT, 56, 0, 40, 0));

    if (currentChat != null) {
        if (!ChatObject.isChannel(currentChat)) {
            int count = currentChat.participants_count;
            if (info != null) {
                count = info.participants.participants.size();
            }
            if (count == 0 || currentChat.deactivated || currentChat.left
                    || currentChat instanceof TLRPC.TL_chatForbidden
                    || info != null && info.participants instanceof TLRPC.TL_chatParticipantsForbidden) {
                avatarContainer.setEnabled(false);
            }
        }
    }

    ActionBarMenu menu = actionBar.createMenu();

    if (currentEncryptedChat == null && !isBroadcast) {
        searchItem = menu.addItem(0, R.drawable.ic_ab_search).setIsSearchField(true)
                .setActionBarMenuItemSearchListener(new ActionBarMenuItem.ActionBarMenuItemSearchListener() {

                    @Override
                    public void onSearchCollapse() {
                        avatarContainer.setVisibility(View.VISIBLE);
                        if (chatActivityEnterView.hasText()) {
                            if (headerItem != null) {
                                headerItem.setVisibility(View.GONE);
                            }
                            if (attachItem != null) {
                                attachItem.setVisibility(View.VISIBLE);
                            }
                        } else {
                            if (headerItem != null) {
                                headerItem.setVisibility(View.VISIBLE);
                            }
                            if (attachItem != null) {
                                attachItem.setVisibility(View.GONE);
                            }
                        }
                        searchItem.setVisibility(View.GONE);
                        highlightMessageId = Integer.MAX_VALUE;
                        updateVisibleRows();
                        scrollToLastMessage(false);
                        updateBottomOverlay();
                    }

                    @Override
                    public void onSearchExpand() {
                        if (!openSearchKeyboard) {
                            return;
                        }
                        AndroidUtilities.runOnUIThread(new Runnable() {
                            @Override
                            public void run() {
                                searchItem.getSearchField().requestFocus();
                                AndroidUtilities.showKeyboard(searchItem.getSearchField());
                            }
                        }, 300);
                    }

                    @Override
                    public void onSearchPressed(EditText editText) {
                        updateSearchButtons(0, 0, 0);
                        MessagesSearchQuery.searchMessagesInChat(editText.getText().toString(), dialog_id,
                                mergeDialogId, classGuid, 0);
                    }
                });
        searchItem.getSearchField().setHint(LocaleController.getString("Search", R.string.Search));
        searchItem.setVisibility(View.GONE);
    }

    headerItem = menu.addItem(0, R.drawable.ic_ab_other);
    if (searchItem != null) {
        headerItem.addSubItem(search, LocaleController.getString("Search", R.string.Search), 0);
    }
    if (ChatObject.isChannel(currentChat) && !currentChat.creator
            && (!currentChat.megagroup || currentChat.username != null && currentChat.username.length() > 0)) {
        headerItem.addSubItem(report, LocaleController.getString("ReportChat", R.string.ReportChat), 0);
    }
    if (currentUser != null) {
        addContactItem = headerItem.addSubItem(share_contact, "", 0);
    }
    if (currentEncryptedChat != null) {
        timeItem2 = headerItem.addSubItem(chat_enc_timer,
                LocaleController.getString("SetTimer", R.string.SetTimer), 0);
    }
    if (!ChatObject.isChannel(currentChat)) {
        headerItem.addSubItem(clear_history, LocaleController.getString("ClearHistory", R.string.ClearHistory),
                0);
        if (currentChat != null && !isBroadcast) {
            headerItem.addSubItem(delete_chat,
                    LocaleController.getString("DeleteAndExit", R.string.DeleteAndExit), 0);
        } else {
            headerItem.addSubItem(delete_chat,
                    LocaleController.getString("DeleteChatUser", R.string.DeleteChatUser), 0);
        }
    }
    if (currentUser == null || !currentUser.self) {
        muteItem = headerItem.addSubItem(mute, null, 0);
    }
    if (currentUser != null && currentEncryptedChat == null && currentUser.bot) {
        headerItem.addSubItem(bot_settings, LocaleController.getString("BotSettings", R.string.BotSettings), 0);
        headerItem.addSubItem(bot_help, LocaleController.getString("BotHelp", R.string.BotHelp), 0);
        updateBotButtons();
    }

    updateTitle();
    avatarContainer.updateOnlineCount();
    avatarContainer.updateSubtitle();
    updateTitleIcons();

    attachItem = menu.addItem(chat_menu_attach, R.drawable.ic_ab_other).setOverrideMenuClick(true)
            .setAllowCloseAnimation(false);
    attachItem.setVisibility(View.GONE);
    menuItem = menu.addItem(chat_menu_attach, R.drawable.ic_ab_attach).setAllowCloseAnimation(false);
    menuItem.setBackgroundDrawable(null);

    actionModeViews.clear();

    final ActionBarMenu actionMode = actionBar.createActionMode();

    selectedMessagesCountTextView = new NumberTextView(actionMode.getContext());
    selectedMessagesCountTextView.setTextSize(18);
    selectedMessagesCountTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
    selectedMessagesCountTextView.setTextColor(Theme.ACTION_BAR_ACTION_MODE_TEXT_COLOR);
    actionMode.addView(selectedMessagesCountTextView,
            LayoutHelper.createLinear(0, LayoutHelper.MATCH_PARENT, 1.0f, 65, 0, 0, 0));
    selectedMessagesCountTextView.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            return true;
        }
    });

    actionModeTitleContainer = new FrameLayout(context) {

        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            int width = MeasureSpec.getSize(widthMeasureSpec);
            int height = MeasureSpec.getSize(heightMeasureSpec);

            setMeasuredDimension(width, height);

            actionModeTextView.setTextSize(!AndroidUtilities.isTablet()
                    && getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE ? 18
                            : 20);
            actionModeTextView.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST),
                    MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(24), MeasureSpec.AT_MOST));

            if (actionModeSubTextView.getVisibility() != GONE) {
                actionModeSubTextView.setTextSize(!AndroidUtilities.isTablet()
                        && getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE
                                ? 14
                                : 16);
                actionModeSubTextView.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST),
                        MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(20), MeasureSpec.AT_MOST));
            }
        }

        @Override
        protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
            int height = bottom - top;

            int textTop;
            if (actionModeSubTextView.getVisibility() != GONE) {
                textTop = (height / 2 - actionModeTextView.getTextHeight()) / 2
                        + AndroidUtilities.dp(!AndroidUtilities.isTablet() && getResources()
                                .getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE ? 2 : 3);
            } else {
                textTop = (height - actionModeTextView.getTextHeight()) / 2;
            }
            actionModeTextView.layout(0, textTop, actionModeTextView.getMeasuredWidth(),
                    textTop + actionModeTextView.getTextHeight());

            if (actionModeSubTextView.getVisibility() != GONE) {
                textTop = height / 2 + (height / 2 - actionModeSubTextView.getTextHeight()) / 2
                        - AndroidUtilities.dp(!AndroidUtilities.isTablet() && getResources()
                                .getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE ? 1 : 1);
                actionModeSubTextView.layout(0, textTop, actionModeSubTextView.getMeasuredWidth(),
                        textTop + actionModeSubTextView.getTextHeight());
            }
        }
    };
    actionMode.addView(actionModeTitleContainer,
            LayoutHelper.createLinear(0, LayoutHelper.MATCH_PARENT, 1.0f, 65, 0, 0, 0));
    actionModeTitleContainer.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            return true;
        }
    });
    actionModeTitleContainer.setVisibility(View.GONE);

    actionModeTextView = new SimpleTextView(context);
    actionModeTextView.setTextSize(18);
    actionModeTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
    actionModeTextView.setTextColor(Theme.ACTION_BAR_ACTION_MODE_TEXT_COLOR);
    actionModeTextView.setText(LocaleController.getString("Edit", R.string.Edit));
    actionModeTitleContainer.addView(actionModeTextView,
            LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));

    actionModeSubTextView = new SimpleTextView(context);
    actionModeSubTextView.setGravity(Gravity.LEFT);
    actionModeSubTextView.setTextColor(Theme.ACTION_BAR_ACTION_MODE_TEXT_COLOR);
    actionModeTitleContainer.addView(actionModeSubTextView,
            LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));

    if (currentEncryptedChat == null) {
        if (!isBroadcast) {
            actionModeViews.add(actionMode.addItem(reply, R.drawable.ic_ab_reply,
                    Theme.ACTION_BAR_MODE_SELECTOR_COLOR, null, AndroidUtilities.dp(54)));
        }
        actionModeViews.add(actionMode.addItem(copy, R.drawable.ic_ab_fwd_copy,
                Theme.ACTION_BAR_MODE_SELECTOR_COLOR, null, AndroidUtilities.dp(54)));
        actionModeViews.add(actionMode.addItem(forward, R.drawable.ic_ab_fwd_forward,
                Theme.ACTION_BAR_MODE_SELECTOR_COLOR, null, AndroidUtilities.dp(54)));
        actionModeViews.add(actionMode.addItem(delete, R.drawable.ic_ab_fwd_delete,
                Theme.ACTION_BAR_MODE_SELECTOR_COLOR, null, AndroidUtilities.dp(54)));
        actionModeViews.add(editDoneItem = actionMode.addItem(edit_done, R.drawable.check_blue,
                Theme.ACTION_BAR_MODE_SELECTOR_COLOR, null, AndroidUtilities.dp(54)));
        editDoneItem.setVisibility(View.GONE);
        editDoneItemProgress = new ContextProgressView(context, 0);
        editDoneItem.addView(editDoneItemProgress,
                LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
        editDoneItemProgress.setVisibility(View.INVISIBLE);
    } else {
        actionModeViews.add(actionMode.addItem(reply, R.drawable.ic_ab_reply,
                Theme.ACTION_BAR_MODE_SELECTOR_COLOR, null, AndroidUtilities.dp(54)));
        actionModeViews.add(actionMode.addItem(copy, R.drawable.ic_ab_fwd_copy,
                Theme.ACTION_BAR_MODE_SELECTOR_COLOR, null, AndroidUtilities.dp(54)));
        actionModeViews.add(actionMode.addItem(delete, R.drawable.ic_ab_fwd_delete,
                Theme.ACTION_BAR_MODE_SELECTOR_COLOR, null, AndroidUtilities.dp(54)));
    }
    actionMode.getItem(copy)
            .setVisibility(selectedMessagesCanCopyIds[0].size() + selectedMessagesCanCopyIds[1].size() != 0
                    ? View.VISIBLE
                    : View.GONE);
    actionMode.getItem(delete).setVisibility(cantDeleteMessagesCount == 0 ? View.VISIBLE : View.GONE);
    checkActionBarMenu();

    fragmentView = new SizeNotifierFrameLayout(context) {

        int inputFieldHeight = 0;

        @Override
        protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
            boolean result = super.drawChild(canvas, child, drawingTime);
            if (child == actionBar) {
                parentLayout.drawHeaderShadow(canvas, actionBar.getMeasuredHeight());
            }
            return result;
        }

        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            int widthSize = MeasureSpec.getSize(widthMeasureSpec);
            int heightSize = MeasureSpec.getSize(heightMeasureSpec);

            setMeasuredDimension(widthSize, heightSize);
            heightSize -= getPaddingTop();

            measureChildWithMargins(actionBar, widthMeasureSpec, 0, heightMeasureSpec, 0);
            int actionBarHeight = actionBar.getMeasuredHeight();
            heightSize -= actionBarHeight;

            int keyboardSize = getKeyboardHeight();

            if (keyboardSize <= AndroidUtilities.dp(20) && !AndroidUtilities.isInMultiwindow) {
                heightSize -= chatActivityEnterView.getEmojiPadding();
            }

            int childCount = getChildCount();

            measureChildWithMargins(chatActivityEnterView, widthMeasureSpec, 0, heightMeasureSpec, 0);
            inputFieldHeight = chatActivityEnterView.getMeasuredHeight();

            for (int i = 0; i < childCount; i++) {
                View child = getChildAt(i);
                if (child == null || child.getVisibility() == GONE || child == chatActivityEnterView
                        || child == actionBar) {
                    continue;
                }
                if (child == chatListView || child == progressView) {
                    int contentWidthSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY);
                    int contentHeightSpec = MeasureSpec
                            .makeMeasureSpec(
                                    Math.max(AndroidUtilities.dp(10),
                                            heightSize - inputFieldHeight + AndroidUtilities.dp(
                                                    2 + (chatActivityEnterView.isTopViewVisible() ? 48 : 0))),
                                    MeasureSpec.EXACTLY);
                    child.measure(contentWidthSpec, contentHeightSpec);
                } else if (child == emptyViewContainer) {
                    int contentWidthSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY);
                    int contentHeightSpec = MeasureSpec.makeMeasureSpec(heightSize, MeasureSpec.EXACTLY);
                    child.measure(contentWidthSpec, contentHeightSpec);
                } else if (chatActivityEnterView.isPopupView(child)) {
                    if (AndroidUtilities.isInMultiwindow) {
                        if (AndroidUtilities.isTablet()) {
                            child.measure(MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY),
                                    MeasureSpec.makeMeasureSpec(Math.min(AndroidUtilities.dp(320),
                                            heightSize - inputFieldHeight + actionBarHeight
                                                    - AndroidUtilities.statusBarHeight + getPaddingTop()),
                                            MeasureSpec.EXACTLY));
                        } else {
                            child.measure(MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY),
                                    MeasureSpec.makeMeasureSpec(
                                            heightSize - inputFieldHeight + actionBarHeight
                                                    - AndroidUtilities.statusBarHeight + getPaddingTop(),
                                            MeasureSpec.EXACTLY));
                        }
                    } else {
                        child.measure(MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY), MeasureSpec
                                .makeMeasureSpec(child.getLayoutParams().height, MeasureSpec.EXACTLY));
                    }
                } else if (child == mentionContainer) {
                    FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) mentionContainer
                            .getLayoutParams();
                    int height;
                    mentionListViewIgnoreLayout = true;

                    if (mentionsAdapter.isBotContext() && mentionsAdapter.isMediaLayout()) {
                        int size = mentionGridLayoutManager.getRowsCount(widthSize);
                        int maxHeight = size * 102;
                        if (mentionsAdapter.isBotContext()) {
                            if (mentionsAdapter.getBotContextSwitch() != null) {
                                maxHeight += 34;
                            }
                        }
                        height = heightSize - chatActivityEnterView.getMeasuredHeight()
                                + (maxHeight != 0 ? AndroidUtilities.dp(2) : 0);
                        mentionListView.setPadding(0,
                                Math.max(0, height - AndroidUtilities.dp(Math.min(maxHeight, 68 * 1.8f))), 0,
                                0);
                    } else {
                        int size = mentionsAdapter.getItemCount();
                        int maxHeight = 0;
                        if (mentionsAdapter.isBotContext()) {
                            if (mentionsAdapter.getBotContextSwitch() != null) {
                                maxHeight += 36;
                                size -= 1;
                            }
                            maxHeight += size * 68;
                        } else {
                            maxHeight += size * 36;
                        }
                        height = heightSize - chatActivityEnterView.getMeasuredHeight()
                                + (maxHeight != 0 ? AndroidUtilities.dp(2) : 0);
                        mentionListView.setPadding(0,
                                Math.max(0, height - AndroidUtilities.dp(Math.min(maxHeight, 68 * 1.8f))), 0,
                                0);
                    }

                    layoutParams.height = height;
                    layoutParams.topMargin = 0;

                    mentionListViewIgnoreLayout = false;
                    child.measure(MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY),
                            MeasureSpec.makeMeasureSpec(layoutParams.height, MeasureSpec.EXACTLY));
                } else {
                    measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, 0);
                }
            }
        }

        @Override
        protected void onLayout(boolean changed, int l, int t, int r, int b) {
            final int count = getChildCount();

            int paddingBottom = getKeyboardHeight() <= AndroidUtilities.dp(20)
                    && !AndroidUtilities.isInMultiwindow ? chatActivityEnterView.getEmojiPadding() : 0;
            setBottomClip(paddingBottom);

            for (int i = 0; i < count; i++) {
                final View child = getChildAt(i);
                if (child.getVisibility() == GONE) {
                    continue;
                }
                final LayoutParams lp = (LayoutParams) child.getLayoutParams();

                final int width = child.getMeasuredWidth();
                final int height = child.getMeasuredHeight();

                int childLeft;
                int childTop;

                int gravity = lp.gravity;
                if (gravity == -1) {
                    gravity = Gravity.TOP | Gravity.LEFT;
                }

                final int absoluteGravity = gravity & Gravity.HORIZONTAL_GRAVITY_MASK;
                final int verticalGravity = gravity & Gravity.VERTICAL_GRAVITY_MASK;

                switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
                case Gravity.CENTER_HORIZONTAL:
                    childLeft = (r - l - width) / 2 + lp.leftMargin - lp.rightMargin;
                    break;
                case Gravity.RIGHT:
                    childLeft = r - width - lp.rightMargin;
                    break;
                case Gravity.LEFT:
                default:
                    childLeft = lp.leftMargin;
                }

                switch (verticalGravity) {
                case Gravity.TOP:
                    childTop = lp.topMargin + getPaddingTop();
                    if (child != actionBar) {
                        childTop += actionBar.getMeasuredHeight();
                    }
                    break;
                case Gravity.CENTER_VERTICAL:
                    childTop = ((b - paddingBottom) - t - height) / 2 + lp.topMargin - lp.bottomMargin;
                    break;
                case Gravity.BOTTOM:
                    childTop = ((b - paddingBottom) - t) - height - lp.bottomMargin;
                    break;
                default:
                    childTop = lp.topMargin;
                }

                if (child == mentionContainer) {
                    childTop -= chatActivityEnterView.getMeasuredHeight() - AndroidUtilities.dp(2);
                } else if (child == pagedownButton) {
                    childTop -= chatActivityEnterView.getMeasuredHeight();
                } else if (child == emptyViewContainer) {
                    childTop -= inputFieldHeight / 2 - actionBar.getMeasuredHeight() / 2;
                } else if (chatActivityEnterView.isPopupView(child)) {
                    if (AndroidUtilities.isInMultiwindow) {
                        childTop = chatActivityEnterView.getTop() - child.getMeasuredHeight()
                                + AndroidUtilities.dp(1);
                    } else {
                        childTop = chatActivityEnterView.getBottom();
                    }
                } else if (child == gifHintTextView) {
                    childTop -= inputFieldHeight;
                } else if (child == chatListView || child == progressView) {
                    if (chatActivityEnterView.isTopViewVisible()) {
                        childTop -= AndroidUtilities.dp(48);
                    }
                } else if (child == actionBar) {
                    childTop -= getPaddingTop();
                }
                child.layout(childLeft, childTop, childLeft + width, childTop + height);
            }

            updateMessagesVisisblePart();
            notifyHeightChanged();
        }
    };

    SizeNotifierFrameLayout contentView = (SizeNotifierFrameLayout) fragmentView;

    contentView.setBackgroundImage(ApplicationLoader.getCachedWallpaper());

    emptyViewContainer = new FrameLayout(context);
    emptyViewContainer.setVisibility(View.INVISIBLE);
    contentView.addView(emptyViewContainer,
            LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER));
    emptyViewContainer.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            return true;
        }
    });

    if (currentEncryptedChat == null) {
        if (currentUser != null && currentUser.self) {
            bigEmptyView = new ChatBigEmptyView(context, false);
            emptyViewContainer.addView(bigEmptyView, new FrameLayout.LayoutParams(LayoutHelper.WRAP_CONTENT,
                    LayoutHelper.WRAP_CONTENT, Gravity.CENTER));
        } else {
            TextView emptyView = new TextView(context);
            if (currentUser != null && currentUser.id != 777000 && currentUser.id != 429000
                    && (currentUser.id / 1000 == 333 || currentUser.id % 1000 == 0)) {
                emptyView.setText(LocaleController.getString("GotAQuestion", R.string.GotAQuestion));
            } else {
                emptyView.setText(LocaleController.getString("NoMessages", R.string.NoMessages));
            }
            emptyView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
            emptyView.setGravity(Gravity.CENTER);
            emptyView.setTextColor(Theme.CHAT_EMPTY_VIEW_TEXT_COLOR);
            emptyView.setBackgroundResource(R.drawable.system);
            emptyView.getBackground().setColorFilter(Theme.colorFilter);
            emptyView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
            emptyView.setPadding(AndroidUtilities.dp(10), AndroidUtilities.dp(2), AndroidUtilities.dp(10),
                    AndroidUtilities.dp(3));
            emptyViewContainer.addView(emptyView, new FrameLayout.LayoutParams(LayoutHelper.WRAP_CONTENT,
                    LayoutHelper.WRAP_CONTENT, Gravity.CENTER));
        }
    } else {
        bigEmptyView = new ChatBigEmptyView(context, true);
        if (currentEncryptedChat.admin_id == UserConfig.getClientUserId()) {
            bigEmptyView.setSecretText(LocaleController.formatString("EncryptedPlaceholderTitleOutgoing",
                    R.string.EncryptedPlaceholderTitleOutgoing, UserObject.getFirstName(currentUser)));
        } else {
            bigEmptyView.setSecretText(LocaleController.formatString("EncryptedPlaceholderTitleIncoming",
                    R.string.EncryptedPlaceholderTitleIncoming, UserObject.getFirstName(currentUser)));
        }
        emptyViewContainer.addView(bigEmptyView, new FrameLayout.LayoutParams(LayoutHelper.WRAP_CONTENT,
                LayoutHelper.WRAP_CONTENT, Gravity.CENTER));
    }

    if (chatActivityEnterView != null) {
        chatActivityEnterView.onDestroy();
    }
    if (mentionsAdapter != null) {
        mentionsAdapter.onDestroy();
    }

    chatListView = new RecyclerListView(context) {
        @Override
        protected void onLayout(boolean changed, int l, int t, int r, int b) {
            super.onLayout(changed, l, t, r, b);
            forceScrollToTop = false;
            if (chatAdapter.isBot) {
                int childCount = getChildCount();
                for (int a = 0; a < childCount; a++) {
                    View child = getChildAt(a);
                    if (child instanceof BotHelpCell) {
                        int height = b - t;
                        int top = height / 2 - child.getMeasuredHeight() / 2;
                        if (child.getTop() > top) {
                            child.layout(0, top, r - l, top + child.getMeasuredHeight());
                        }
                        break;
                    }
                }
            }
        }
    };
    chatListView.setTag(1);
    chatListView.setVerticalScrollBarEnabled(true);
    chatListView.setAdapter(chatAdapter = new ChatActivityAdapter(context));
    chatListView.setClipToPadding(false);
    chatListView.setPadding(0, AndroidUtilities.dp(4), 0, AndroidUtilities.dp(3));
    chatListView.setItemAnimator(null);
    chatListView.setLayoutAnimation(null);
    chatLayoutManager = new LinearLayoutManager(context) {
        @Override
        public boolean supportsPredictiveItemAnimations() {
            return false;
        }
    };
    chatLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
    chatLayoutManager.setStackFromEnd(true);
    chatListView.setLayoutManager(chatLayoutManager);
    contentView.addView(chatListView,
            LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
    chatListView.setOnItemLongClickListener(onItemLongClickListener);
    chatListView.setOnItemClickListener(onItemClickListener);
    chatListView.setOnScrollListener(new RecyclerView.OnScrollListener() {

        private float totalDy = 0;
        private final int scrollValue = AndroidUtilities.dp(100);

        @Override
        public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
            if (newState == RecyclerView.SCROLL_STATE_DRAGGING && highlightMessageId != Integer.MAX_VALUE) {
                highlightMessageId = Integer.MAX_VALUE;
                updateVisibleRows();
            }
        }

        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            checkScrollForLoad(true);
            int firstVisibleItem = chatLayoutManager.findFirstVisibleItemPosition();
            int visibleItemCount = firstVisibleItem == RecyclerView.NO_POSITION ? 0
                    : Math.abs(chatLayoutManager.findLastVisibleItemPosition() - firstVisibleItem) + 1;
            if (visibleItemCount > 0) {
                int totalItemCount = chatAdapter.getItemCount();
                if (firstVisibleItem + visibleItemCount == totalItemCount && forwardEndReached[0]) {
                    showPagedownButton(false, true);
                } else {
                    if (dy > 0) {
                        if (pagedownButton.getTag() == null) {
                            totalDy += dy;
                            if (totalDy > scrollValue) {
                                totalDy = 0;
                                showPagedownButton(true, true);
                                pagedownButtonShowedByScroll = true;
                            }
                        }
                    } else {
                        if (pagedownButtonShowedByScroll && pagedownButton.getTag() != null) {
                            totalDy += dy;
                            if (totalDy < -scrollValue) {
                                showPagedownButton(false, true);
                                totalDy = 0;
                            }
                        }
                    }
                }
            }
            updateMessagesVisisblePart();
        }
    });
    chatListView.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if (openSecretPhotoRunnable != null || SecretPhotoViewer.getInstance().isVisible()) {
                if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL
                        || event.getAction() == MotionEvent.ACTION_POINTER_UP) {
                    AndroidUtilities.runOnUIThread(new Runnable() {
                        @Override
                        public void run() {
                            chatListView.setOnItemClickListener(onItemClickListener);
                        }
                    }, 150);
                    if (openSecretPhotoRunnable != null) {
                        AndroidUtilities.cancelRunOnUIThread(openSecretPhotoRunnable);
                        openSecretPhotoRunnable = null;
                        try {
                            Toast.makeText(v.getContext(),
                                    LocaleController.getString("PhotoTip", R.string.PhotoTip),
                                    Toast.LENGTH_SHORT).show();
                        } catch (Exception e) {
                            FileLog.e("tmessages", e);
                        }
                    } else if (SecretPhotoViewer.getInstance().isVisible()) {
                        AndroidUtilities.runOnUIThread(new Runnable() {
                            @Override
                            public void run() {
                                chatListView.setOnItemLongClickListener(onItemLongClickListener);
                                chatListView.setLongClickable(true);
                            }
                        });
                        SecretPhotoViewer.getInstance().closePhoto();
                    }
                } else if (event.getAction() != MotionEvent.ACTION_DOWN) {
                    if (SecretPhotoViewer.getInstance().isVisible()) {
                        return true;
                    } else if (openSecretPhotoRunnable != null) {
                        if (event.getAction() == MotionEvent.ACTION_MOVE) {
                            if (Math.hypot(startX - event.getX(), startY - event.getY()) > AndroidUtilities
                                    .dp(5)) {
                                AndroidUtilities.cancelRunOnUIThread(openSecretPhotoRunnable);
                                openSecretPhotoRunnable = null;
                            }
                        } else {
                            AndroidUtilities.cancelRunOnUIThread(openSecretPhotoRunnable);
                            openSecretPhotoRunnable = null;
                        }
                        chatListView.setOnItemClickListener(onItemClickListener);
                        chatListView.setOnItemLongClickListener(onItemLongClickListener);
                        chatListView.setLongClickable(true);
                    }
                }
            }
            return false;
        }
    });
    chatListView.setOnInterceptTouchListener(new RecyclerListView.OnInterceptTouchListener() {
        @Override
        public boolean onInterceptTouchEvent(MotionEvent event) {
            if (chatActivityEnterView != null && chatActivityEnterView.isEditingMessage()) {
                return true;
            }
            if (actionBar.isActionModeShowed()) {
                return false;
            }
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                int x = (int) event.getX();
                int y = (int) event.getY();
                int count = chatListView.getChildCount();
                for (int a = 0; a < count; a++) {
                    View view = chatListView.getChildAt(a);
                    int top = view.getTop();
                    int bottom = view.getBottom();
                    if (top > y || bottom < y) {
                        continue;
                    }
                    if (!(view instanceof ChatMessageCell)) {
                        break;
                    }
                    final ChatMessageCell cell = (ChatMessageCell) view;
                    final MessageObject messageObject = cell.getMessageObject();
                    if (messageObject == null || messageObject.isSending() || !messageObject.isSecretPhoto()
                            || !cell.getPhotoImage().isInsideImage(x, y - top)) {
                        break;
                    }
                    File file = FileLoader.getPathToMessage(messageObject.messageOwner);
                    if (!file.exists()) {
                        break;
                    }
                    startX = x;
                    startY = y;
                    chatListView.setOnItemClickListener(null);
                    openSecretPhotoRunnable = new Runnable() {
                        @Override
                        public void run() {
                            if (openSecretPhotoRunnable == null) {
                                return;
                            }
                            chatListView.requestDisallowInterceptTouchEvent(true);
                            chatListView.setOnItemLongClickListener(null);
                            chatListView.setLongClickable(false);
                            openSecretPhotoRunnable = null;
                            if (sendSecretMessageRead(messageObject)) {
                                cell.invalidate();
                            }
                            SecretPhotoViewer.getInstance().setParentActivity(getParentActivity());
                            SecretPhotoViewer.getInstance().openPhoto(messageObject);
                        }
                    };
                    AndroidUtilities.runOnUIThread(openSecretPhotoRunnable, 100);
                    return true;
                }
            }
            return false;
        }
    });

    progressView = new FrameLayout(context);
    progressView.setVisibility(View.INVISIBLE);
    contentView.addView(progressView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT,
            LayoutHelper.MATCH_PARENT, Gravity.TOP | Gravity.LEFT));

    View view = new View(context);
    view.setBackgroundResource(R.drawable.system_loader);
    view.getBackground().setColorFilter(Theme.colorFilter);
    progressView.addView(view, LayoutHelper.createFrame(36, 36, Gravity.CENTER));

    ProgressBar progressBar = new ProgressBar(context);
    try {
        progressBar.setIndeterminateDrawable(context.getResources().getDrawable(R.drawable.loading_animation));
    } catch (Exception e) {
        //don't promt
    }
    progressBar.setIndeterminate(true);
    AndroidUtilities.setProgressBarAnimationDuration(progressBar, 1500);
    progressView.addView(progressBar, LayoutHelper.createFrame(32, 32, Gravity.CENTER));

    if (ChatObject.isChannel(currentChat)) {
        pinnedMessageView = new FrameLayout(context);
        pinnedMessageView.setTag(1);
        pinnedMessageView.setTranslationY(-AndroidUtilities.dp(50));
        pinnedMessageView.setVisibility(View.GONE);
        pinnedMessageView.setBackgroundResource(R.drawable.blockpanel);
        contentView.addView(pinnedMessageView,
                LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 50, Gravity.TOP | Gravity.LEFT));
        pinnedMessageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                scrollToMessageId(info.pinned_msg_id, 0, true, 0);
            }
        });

        View lineView = new View(context);
        lineView.setBackgroundColor(0xff6c9fd2);
        pinnedMessageView.addView(lineView,
                LayoutHelper.createFrame(2, 32, Gravity.LEFT | Gravity.TOP, 8, 8, 0, 0));

        pinnedMessageImageView = new BackupImageView(context);
        pinnedMessageView.addView(pinnedMessageImageView,
                LayoutHelper.createFrame(32, 32, Gravity.TOP | Gravity.LEFT, 17, 8, 0, 0));

        pinnedMessageNameTextView = new SimpleTextView(context);
        pinnedMessageNameTextView.setTextSize(14);
        pinnedMessageNameTextView.setTextColor(Theme.PINNED_PANEL_NAME_TEXT_COLOR);
        pinnedMessageNameTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
        pinnedMessageView.addView(pinnedMessageNameTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT,
                AndroidUtilities.dp(18), Gravity.TOP | Gravity.LEFT, 18, 7.3f, 52, 0));

        pinnedMessageTextView = new SimpleTextView(context);
        pinnedMessageTextView.setTextSize(14);
        pinnedMessageTextView.setTextColor(Theme.PINNED_PANEL_MESSAGE_TEXT_COLOR);
        pinnedMessageView.addView(pinnedMessageTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT,
                AndroidUtilities.dp(18), Gravity.TOP | Gravity.LEFT, 18, 25.3f, 52, 0));

        ImageView closePinned = new ImageView(context);
        closePinned.setImageResource(R.drawable.miniplayer_close);
        closePinned.setScaleType(ImageView.ScaleType.CENTER);
        pinnedMessageView.addView(closePinned, LayoutHelper.createFrame(48, 48, Gravity.RIGHT | Gravity.TOP));
        closePinned.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (getParentActivity() == null) {
                    return;
                }
                if (currentChat.creator || currentChat.editor) {
                    AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity());
                    builder.setMessage(
                            LocaleController.getString("UnpinMessageAlert", R.string.UnpinMessageAlert));
                    builder.setPositiveButton(LocaleController.getString("OK", R.string.OK),
                            new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialogInterface, int i) {
                                    MessagesController.getInstance().pinChannelMessage(currentChat, 0, false);
                                }
                            });
                    builder.setTitle(LocaleController.getString("AppName", R.string.AppName));
                    builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null);
                    showDialog(builder.create());
                } else {
                    SharedPreferences preferences = ApplicationLoader.applicationContext
                            .getSharedPreferences("Notifications", Activity.MODE_PRIVATE);
                    preferences.edit().putInt("pin_" + dialog_id, info.pinned_msg_id).commit();
                    updatePinnedMessageView(true);
                }
            }
        });
    }

    reportSpamView = new LinearLayout(context);
    reportSpamView.setTag(1);
    reportSpamView.setTranslationY(-AndroidUtilities.dp(50));
    reportSpamView.setVisibility(View.GONE);
    reportSpamView.setBackgroundResource(R.drawable.blockpanel);
    contentView.addView(reportSpamView,
            LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 50, Gravity.TOP | Gravity.LEFT));

    addToContactsButton = new TextView(context);
    addToContactsButton.setTextColor(Theme.CHAT_ADD_CONTACT_TEXT_COLOR);
    addToContactsButton.setVisibility(View.GONE);
    addToContactsButton.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
    addToContactsButton.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
    addToContactsButton.setSingleLine(true);
    addToContactsButton.setMaxLines(1);
    addToContactsButton.setPadding(AndroidUtilities.dp(4), 0, AndroidUtilities.dp(4), 0);
    addToContactsButton.setGravity(Gravity.CENTER);
    addToContactsButton.setText(LocaleController.getString("AddContactChat", R.string.AddContactChat));
    reportSpamView.addView(addToContactsButton, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT,
            LayoutHelper.MATCH_PARENT, 0.5f, Gravity.LEFT | Gravity.TOP, 0, 0, 0, AndroidUtilities.dp(1)));
    addToContactsButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Bundle args = new Bundle();
            args.putInt("user_id", currentUser.id);
            args.putBoolean("addContact", true);
            presentFragment(new ContactAddActivity(args));
        }
    });

    reportSpamContainer = new FrameLayout(context);
    reportSpamView.addView(reportSpamContainer, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT,
            LayoutHelper.MATCH_PARENT, 1.0f, Gravity.LEFT | Gravity.TOP, 0, 0, 0, AndroidUtilities.dp(1)));

    reportSpamButton = new TextView(context);
    reportSpamButton.setTextColor(Theme.CHAT_REPORT_SPAM_TEXT_COLOR);
    reportSpamButton.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
    reportSpamButton.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
    reportSpamButton.setSingleLine(true);
    reportSpamButton.setMaxLines(1);
    if (currentChat != null) {
        reportSpamButton.setText(LocaleController.getString("ReportSpamAndLeave", R.string.ReportSpamAndLeave));
    } else {
        reportSpamButton.setText(LocaleController.getString("ReportSpam", R.string.ReportSpam));
    }
    reportSpamButton.setGravity(Gravity.CENTER);
    reportSpamButton.setPadding(AndroidUtilities.dp(50), 0, AndroidUtilities.dp(50), 0);
    reportSpamContainer.addView(reportSpamButton, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT,
            LayoutHelper.MATCH_PARENT, Gravity.LEFT | Gravity.TOP));
    reportSpamButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (getParentActivity() == null) {
                return;
            }
            AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity());
            if (ChatObject.isChannel(currentChat) && !currentChat.megagroup) {
                builder.setMessage(
                        LocaleController.getString("ReportSpamAlertChannel", R.string.ReportSpamAlertChannel));
            } else if (currentChat != null) {
                builder.setMessage(
                        LocaleController.getString("ReportSpamAlertGroup", R.string.ReportSpamAlertGroup));
            } else {
                builder.setMessage(LocaleController.getString("ReportSpamAlert", R.string.ReportSpamAlert));
            }
            builder.setTitle(LocaleController.getString("AppName", R.string.AppName));
            builder.setPositiveButton(LocaleController.getString("OK", R.string.OK),
                    new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {
                            if (currentUser != null) {
                                MessagesController.getInstance().blockUser(currentUser.id);
                            }
                            MessagesController.getInstance().reportSpam(dialog_id, currentUser, currentChat);
                            updateSpamView();
                            if (currentChat != null) {
                                if (ChatObject.isNotInChat(currentChat)) {
                                    MessagesController.getInstance().deleteDialog(dialog_id, 0);
                                } else {
                                    MessagesController.getInstance().deleteUserFromChat((int) -dialog_id,
                                            MessagesController.getInstance()
                                                    .getUser(UserConfig.getClientUserId()),
                                            null);
                                }
                            } else {
                                MessagesController.getInstance().deleteDialog(dialog_id, 0);
                            }
                            finishFragment();
                        }
                    });
            builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null);
            showDialog(builder.create());
        }
    });

    ImageView closeReportSpam = new ImageView(context);
    closeReportSpam.setImageResource(R.drawable.miniplayer_close);
    closeReportSpam.setScaleType(ImageView.ScaleType.CENTER);
    reportSpamContainer.addView(closeReportSpam, LayoutHelper.createFrame(48, 48, Gravity.RIGHT | Gravity.TOP));
    closeReportSpam.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            MessagesController.getInstance().hideReportSpam(dialog_id, currentUser, currentChat);
            updateSpamView();
        }
    });

    alertView = new FrameLayout(context);
    alertView.setTag(1);
    alertView.setTranslationY(-AndroidUtilities.dp(50));
    alertView.setVisibility(View.GONE);
    alertView.setBackgroundResource(R.drawable.blockpanel);
    contentView.addView(alertView,
            LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 50, Gravity.TOP | Gravity.LEFT));

    alertNameTextView = new TextView(context);
    alertNameTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
    alertNameTextView.setTextColor(Theme.ALERT_PANEL_NAME_TEXT_COLOR);
    alertNameTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
    alertNameTextView.setSingleLine(true);
    alertNameTextView.setEllipsize(TextUtils.TruncateAt.END);
    alertNameTextView.setMaxLines(1);
    alertView.addView(alertNameTextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT,
            LayoutHelper.WRAP_CONTENT, Gravity.TOP | Gravity.LEFT, 8, 5, 8, 0));

    alertTextView = new TextView(context);
    alertTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
    alertTextView.setTextColor(Theme.ALERT_PANEL_MESSAGE_TEXT_COLOR);
    alertTextView.setSingleLine(true);
    alertTextView.setEllipsize(TextUtils.TruncateAt.END);
    alertTextView.setMaxLines(1);
    alertView.addView(alertTextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT,
            LayoutHelper.WRAP_CONTENT, Gravity.TOP | Gravity.LEFT, 8, 23, 8, 0));

    if (!isBroadcast) {
        mentionContainer = new FrameLayout(context) {

            private Drawable background;

            @Override
            public void onDraw(Canvas canvas) {
                if (mentionListView.getChildCount() <= 0) {
                    return;
                }
                if (mentionsAdapter.isBotContext() && mentionsAdapter.isMediaLayout()
                        && mentionsAdapter.getBotContextSwitch() == null) {
                    background.setBounds(0, mentionListViewScrollOffsetY - AndroidUtilities.dp(4),
                            getMeasuredWidth(), getMeasuredHeight());
                } else {
                    background.setBounds(0, mentionListViewScrollOffsetY - AndroidUtilities.dp(2),
                            getMeasuredWidth(), getMeasuredHeight());
                }
                background.draw(canvas);
            }

            @Override
            public void setBackgroundResource(int resid) {
                background = getContext().getResources().getDrawable(resid);
            }

            @Override
            public void requestLayout() {
                if (mentionListViewIgnoreLayout) {
                    return;
                }
                super.requestLayout();
            }
        };
        mentionContainer.setBackgroundResource(R.drawable.compose_panel);
        mentionContainer.setVisibility(View.GONE);
        mentionContainer.setWillNotDraw(false);
        contentView.addView(mentionContainer,
                LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 110, Gravity.LEFT | Gravity.BOTTOM));

        mentionListView = new RecyclerListView(context) {

            private int lastWidth;
            private int lastHeight;

            @Override
            public boolean onInterceptTouchEvent(MotionEvent event) {
                if (!mentionListViewIsScrolling && mentionListViewScrollOffsetY != 0
                        && event.getY() < mentionListViewScrollOffsetY) {
                    return false;
                }
                boolean result = StickerPreviewViewer.getInstance().onInterceptTouchEvent(event,
                        mentionListView, 0);
                return super.onInterceptTouchEvent(event) || result;
            }

            @Override
            public boolean onTouchEvent(MotionEvent event) {
                if (!mentionListViewIsScrolling && mentionListViewScrollOffsetY != 0
                        && event.getY() < mentionListViewScrollOffsetY) {
                    return false;
                }
                //supress warning
                return super.onTouchEvent(event);
            }

            @Override
            public void requestLayout() {
                if (mentionListViewIgnoreLayout) {
                    return;
                }
                super.requestLayout();
            }

            @Override
            protected void onLayout(boolean changed, int l, int t, int r, int b) {
                int width = r - l;
                int height = b - t;

                int newPosition = -1;
                int newTop = 0;
                if (mentionListView != null && mentionListViewLastViewPosition >= 0 && width == lastWidth
                        && height - lastHeight != 0) {
                    newPosition = mentionListViewLastViewPosition;
                    newTop = mentionListViewLastViewTop + height - lastHeight - getPaddingTop();
                }

                super.onLayout(changed, l, t, r, b);

                if (newPosition != -1) {
                    mentionListViewIgnoreLayout = true;
                    if (mentionsAdapter.isBotContext() && mentionsAdapter.isMediaLayout()) {
                        mentionGridLayoutManager.scrollToPositionWithOffset(newPosition, newTop);
                    } else {
                        mentionLayoutManager.scrollToPositionWithOffset(newPosition, newTop);
                    }
                    super.onLayout(false, l, t, r, b);
                    mentionListViewIgnoreLayout = false;
                }

                lastHeight = height;
                lastWidth = width;
                mentionListViewUpdateLayout();
            }
        };
        mentionListView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return StickerPreviewViewer.getInstance().onTouch(event, mentionListView, 0,
                        mentionsOnItemClickListener);
            }
        });
        mentionListView.setTag(2);
        mentionLayoutManager = new LinearLayoutManager(context) {
            @Override
            public boolean supportsPredictiveItemAnimations() {
                return false;
            }
        };
        mentionLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        mentionGridLayoutManager = new ExtendedGridLayoutManager(context, 100) {

            private Size size = new Size();

            @Override
            protected Size getSizeForItem(int i) {
                if (mentionsAdapter.getBotContextSwitch() != null) {
                    i++;
                }
                Object object = mentionsAdapter.getItem(i);
                if (object instanceof TLRPC.BotInlineResult) {
                    TLRPC.BotInlineResult inlineResult = (TLRPC.BotInlineResult) object;
                    if (inlineResult.document != null) {
                        size.width = inlineResult.document.thumb != null ? inlineResult.document.thumb.w : 100;
                        size.height = inlineResult.document.thumb != null ? inlineResult.document.thumb.h : 100;
                        for (int b = 0; b < inlineResult.document.attributes.size(); b++) {
                            TLRPC.DocumentAttribute attribute = inlineResult.document.attributes.get(b);
                            if (attribute instanceof TLRPC.TL_documentAttributeImageSize
                                    || attribute instanceof TLRPC.TL_documentAttributeVideo) {
                                size.width = attribute.w;
                                size.height = attribute.h;
                                break;
                            }
                        }
                    } else {
                        size.width = inlineResult.w;
                        size.height = inlineResult.h;
                    }
                }
                return size;
            }

            @Override
            protected int getFlowItemCount() {
                if (mentionsAdapter.getBotContextSwitch() != null) {
                    return getItemCount() - 1;
                }
                return super.getFlowItemCount();
            }
        };
        mentionGridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
            @Override
            public int getSpanSize(int position) {
                Object object = mentionsAdapter.getItem(position);
                if (object instanceof TLRPC.TL_inlineBotSwitchPM) {
                    return 100;
                } else {
                    if (mentionsAdapter.getBotContextSwitch() != null) {
                        position--;
                    }
                    return mentionGridLayoutManager.getSpanSizeForItem(position);
                }
            }
        });
        mentionListView.addItemDecoration(new RecyclerView.ItemDecoration() {
            @Override
            public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
                outRect.left = 0;
                outRect.right = 0;
                outRect.top = 0;
                outRect.bottom = 0;
                if (parent.getLayoutManager() == mentionGridLayoutManager) {
                    int position = parent.getChildAdapterPosition(view);
                    if (mentionsAdapter.getBotContextSwitch() != null) {
                        if (position == 0) {
                            return;
                        }
                        position--;
                        if (!mentionGridLayoutManager.isFirstRow(position)) {
                            outRect.top = AndroidUtilities.dp(2);
                        }
                    } else {
                        outRect.top = AndroidUtilities.dp(2);
                    }
                    outRect.right = mentionGridLayoutManager.isLastInRow(position) ? 0 : AndroidUtilities.dp(2);
                }
            }
        });
        mentionListView.setItemAnimator(null);
        mentionListView.setLayoutAnimation(null);
        mentionListView.setClipToPadding(false);
        mentionListView.setLayoutManager(mentionLayoutManager);
        mentionListView.setOverScrollMode(ListView.OVER_SCROLL_NEVER);
        mentionContainer.addView(mentionListView,
                LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));

        mentionListView.setAdapter(mentionsAdapter = new MentionsAdapter(context, false, dialog_id,
                new MentionsAdapter.MentionsAdapterDelegate() {
                    @Override
                    public void needChangePanelVisibility(boolean show) {
                        if (mentionsAdapter.isBotContext() && mentionsAdapter.isMediaLayout()) {
                            mentionListView.setLayoutManager(mentionGridLayoutManager);
                        } else {
                            mentionListView.setLayoutManager(mentionLayoutManager);
                        }
                        if (show) {
                            if (mentionListAnimation != null) {
                                mentionListAnimation.cancel();
                                mentionListAnimation = null;
                            }

                            if (mentionContainer.getVisibility() == View.VISIBLE) {
                                mentionContainer.setAlpha(1.0f);
                                return;
                            }
                            if (mentionsAdapter.isBotContext() && mentionsAdapter.isMediaLayout()) {
                                mentionGridLayoutManager.scrollToPositionWithOffset(0, 10000);
                            } else {
                                mentionLayoutManager.scrollToPositionWithOffset(0, 10000);
                            }
                            if (allowStickersPanel && (!mentionsAdapter.isBotContext()
                                    || (allowContextBotPanel || allowContextBotPanelSecond))) {
                                if (currentEncryptedChat != null && mentionsAdapter.isBotContext()) {
                                    SharedPreferences preferences = ApplicationLoader.applicationContext
                                            .getSharedPreferences("mainconfig", Activity.MODE_PRIVATE);
                                    if (!preferences.getBoolean("secretbot", false)) {
                                        AlertDialog.Builder builder = new AlertDialog.Builder(
                                                getParentActivity());
                                        builder.setTitle(
                                                LocaleController.getString("AppName", R.string.AppName));
                                        builder.setMessage(
                                                LocaleController.getString("SecretChatContextBotAlert",
                                                        R.string.SecretChatContextBotAlert));
                                        builder.setPositiveButton(LocaleController.getString("OK", R.string.OK),
                                                null);
                                        showDialog(builder.create());
                                        preferences.edit().putBoolean("secretbot", true).commit();
                                    }
                                }
                                mentionContainer.setVisibility(View.VISIBLE);
                                mentionContainer.setTag(null);
                                mentionListAnimation = new AnimatorSet();
                                mentionListAnimation.playTogether(
                                        ObjectAnimator.ofFloat(mentionContainer, "alpha", 0.0f, 1.0f));
                                mentionListAnimation.addListener(new AnimatorListenerAdapterProxy() {
                                    @Override
                                    public void onAnimationEnd(Animator animation) {
                                        if (mentionListAnimation != null
                                                && mentionListAnimation.equals(animation)) {
                                            mentionListAnimation = null;
                                        }
                                    }

                                    @Override
                                    public void onAnimationCancel(Animator animation) {
                                        if (mentionListAnimation != null
                                                && mentionListAnimation.equals(animation)) {
                                            mentionListAnimation = null;
                                        }
                                    }
                                });
                                mentionListAnimation.setDuration(200);
                                mentionListAnimation.start();
                            } else {
                                mentionContainer.setAlpha(1.0f);
                                mentionContainer.setVisibility(View.INVISIBLE);
                            }
                        } else {
                            if (mentionListAnimation != null) {
                                mentionListAnimation.cancel();
                                mentionListAnimation = null;
                            }

                            if (mentionContainer.getVisibility() == View.GONE) {
                                return;
                            }
                            if (allowStickersPanel) {
                                mentionListAnimation = new AnimatorSet();
                                mentionListAnimation
                                        .playTogether(ObjectAnimator.ofFloat(mentionContainer, "alpha", 0.0f));
                                mentionListAnimation.addListener(new AnimatorListenerAdapterProxy() {
                                    @Override
                                    public void onAnimationEnd(Animator animation) {
                                        if (mentionListAnimation != null
                                                && mentionListAnimation.equals(animation)) {
                                            mentionContainer.setVisibility(View.GONE);
                                            mentionContainer.setTag(null);
                                            mentionListAnimation = null;
                                        }
                                    }

                                    @Override
                                    public void onAnimationCancel(Animator animation) {
                                        if (mentionListAnimation != null
                                                && mentionListAnimation.equals(animation)) {
                                            mentionListAnimation = null;
                                        }
                                    }
                                });
                                mentionListAnimation.setDuration(200);
                                mentionListAnimation.start();
                            } else {
                                mentionContainer.setTag(null);
                                mentionContainer.setVisibility(View.GONE);
                            }
                        }
                    }

                    @Override
                    public void onContextSearch(boolean searching) {
                        if (chatActivityEnterView != null) {
                            chatActivityEnterView.setCaption(mentionsAdapter.getBotCaption());
                            chatActivityEnterView.showContextProgress(searching);
                        }
                    }

                    @Override
                    public void onContextClick(TLRPC.BotInlineResult result) {
                        if (getParentActivity() == null || result.content_url == null) {
                            return;
                        }
                        if (result.type.equals("video") || result.type.equals("web_player_video")) {
                            BottomSheet.Builder builder = new BottomSheet.Builder(getParentActivity());
                            builder.setCustomView(new WebFrameLayout(getParentActivity(), builder.create(),
                                    result.title != null ? result.title : "", result.description,
                                    result.content_url, result.content_url, result.w, result.h));
                            builder.setUseFullWidth(true);
                            showDialog(builder.create());
                        } else {
                            Browser.openUrl(getParentActivity(), result.content_url);
                        }
                    }
                }));
        if (!ChatObject.isChannel(currentChat) || currentChat != null && currentChat.megagroup) {
            mentionsAdapter.setBotInfo(botInfo);
        }
        mentionsAdapter.setParentFragment(this);
        mentionsAdapter.setChatInfo(info);
        mentionsAdapter.setNeedUsernames(currentChat != null);
        mentionsAdapter.setNeedBotContext(currentEncryptedChat == null
                || AndroidUtilities.getPeerLayerVersion(currentEncryptedChat.layer) >= 46);
        mentionsAdapter.setBotsCount(currentChat != null ? botsCount : 1);
        mentionListView.setOnItemClickListener(
                mentionsOnItemClickListener = new RecyclerListView.OnItemClickListener() {
                    @Override
                    public void onItemClick(View view, int position) {
                        Object object = mentionsAdapter.getItem(position);
                        int start = mentionsAdapter.getResultStartPosition();
                        int len = mentionsAdapter.getResultLength();
                        if (object instanceof TLRPC.User) {
                            TLRPC.User user = (TLRPC.User) object;
                            if (user != null) {
                                if (user.username != null) {
                                    chatActivityEnterView.replaceWithText(start, len,
                                            "@" + user.username + " ");
                                } else {
                                    String name = user.first_name;
                                    if (name == null || name.length() == 0) {
                                        name = user.last_name;
                                    }
                                    Spannable spannable = new SpannableString(name + " ");
                                    spannable.setSpan(new URLSpanUserMention("" + user.id), 0,
                                            spannable.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                                    chatActivityEnterView.replaceWithText(start, len, spannable);
                                }
                            }
                        } else if (object instanceof String) {
                            if (mentionsAdapter.isBotCommands()) {
                                SendMessagesHelper.getInstance().sendMessage((String) object, dialog_id, null,
                                        null, false, null, null, null);
                                chatActivityEnterView.setFieldText("");
                            } else {
                                chatActivityEnterView.replaceWithText(start, len, object + " ");
                            }
                        } else if (object instanceof TLRPC.BotInlineResult) {
                            if (chatActivityEnterView.getFieldText() == null) {
                                return;
                            }
                            TLRPC.BotInlineResult result = (TLRPC.BotInlineResult) object;
                            if (Build.VERSION.SDK_INT >= 16 && (result.type.equals("photo")
                                    && (result.photo != null || result.content_url != null)
                                    || result.type.equals("gif")
                                            && (result.document != null || result.content_url != null)
                                    || result.type.equals("video")
                                            && (result.document != null/* || result.content_url != null*/))) {
                                ArrayList<Object> arrayList = botContextResults = new ArrayList<Object>(
                                        mentionsAdapter.getSearchResultBotContext());
                                PhotoViewer.getInstance().setParentActivity(getParentActivity());
                                PhotoViewer.getInstance().openPhotoForSelect(arrayList,
                                        mentionsAdapter.getItemPosition(position), 3, botContextProvider, null);
                            } else {
                                sendBotInlineResult(result);
                            }
                        } else if (object instanceof TLRPC.TL_inlineBotSwitchPM) {
                            processInlineBotContextPM((TLRPC.TL_inlineBotSwitchPM) object);
                        }
                    }
                });

        mentionListView.setOnItemLongClickListener(new RecyclerListView.OnItemLongClickListener() {
            @Override
            public boolean onItemClick(View view, int position) {
                if (getParentActivity() == null || !mentionsAdapter.isLongClickEnabled()) {
                    return false;
                }
                Object object = mentionsAdapter.getItem(position);
                if (object instanceof String) {
                    if (mentionsAdapter.isBotCommands()) {
                        if (URLSpanBotCommand.enabled) {
                            chatActivityEnterView.setFieldText("");
                            chatActivityEnterView.setCommand(null, (String) object, true,
                                    currentChat != null && currentChat.megagroup);
                            return true;
                        }
                        return false;
                    } else {
                        AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity());
                        builder.setTitle(LocaleController.getString("AppName", R.string.AppName));
                        builder.setMessage(LocaleController.getString("ClearSearch", R.string.ClearSearch));
                        builder.setPositiveButton(
                                LocaleController.getString("ClearButton", R.string.ClearButton).toUpperCase(),
                                new DialogInterface.OnClickListener() {
                                    @Override
                                    public void onClick(DialogInterface dialogInterface, int i) {
                                        mentionsAdapter.clearRecentHashtags();
                                    }
                                });
                        builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null);
                        showDialog(builder.create());
                        return true;
                    }
                }
                return false;
            }
        });

        mentionListView.setOnScrollListener(new RecyclerView.OnScrollListener() {

            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                mentionListViewIsScrolling = newState == RecyclerView.SCROLL_STATE_DRAGGING;
            }

            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                int lastVisibleItem;
                if (mentionsAdapter.isBotContext() && mentionsAdapter.isMediaLayout()) {
                    lastVisibleItem = mentionGridLayoutManager.findLastVisibleItemPosition();
                } else {
                    lastVisibleItem = mentionLayoutManager.findLastVisibleItemPosition();
                }
                int visibleItemCount = lastVisibleItem == RecyclerView.NO_POSITION ? 0 : lastVisibleItem;
                if (visibleItemCount > 0 && lastVisibleItem > mentionsAdapter.getItemCount() - 5) {
                    mentionsAdapter.searchForContextBotForNextOffset();
                }
                mentionListViewUpdateLayout();
            }
        });
    }

    pagedownButton = new FrameLayout(context);
    pagedownButton.setVisibility(View.INVISIBLE);
    contentView.addView(pagedownButton,
            LayoutHelper.createFrame(46, 59, Gravity.RIGHT | Gravity.BOTTOM, 0, 0, 7, 5));
    pagedownButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            if (returnToMessageId > 0) {
                scrollToMessageId(returnToMessageId, 0, true, returnToLoadIndex);
            } else {
                scrollToLastMessage(true);
            }
        }
    });

    ImageView pagedownButtonImage = new ImageView(context);
    pagedownButtonImage.setImageResource(R.drawable.pagedown);
    pagedownButton.addView(pagedownButtonImage,
            LayoutHelper.createFrame(46, 46, Gravity.LEFT | Gravity.BOTTOM));

    pagedownButtonCounter = new TextView(context);
    pagedownButtonCounter.setVisibility(View.INVISIBLE);
    pagedownButtonCounter.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
    pagedownButtonCounter.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 13);
    pagedownButtonCounter.setTextColor(0xffffffff);
    pagedownButtonCounter.setGravity(Gravity.CENTER);
    pagedownButtonCounter.setBackgroundResource(R.drawable.chat_badge);
    pagedownButtonCounter.setMinWidth(AndroidUtilities.dp(23));
    pagedownButtonCounter.setPadding(AndroidUtilities.dp(8), 0, AndroidUtilities.dp(8), AndroidUtilities.dp(1));
    pagedownButton.addView(pagedownButtonCounter,
            LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, 23, Gravity.TOP | Gravity.CENTER_HORIZONTAL));

    chatActivityEnterView = new ChatActivityEnterView(getParentActivity(), contentView, this, true);
    chatActivityEnterView.setDialogId(dialog_id);
    chatActivityEnterView.addToAttachLayout(menuItem);
    chatActivityEnterView.setId(id_chat_compose_panel);
    chatActivityEnterView.setBotsCount(botsCount, hasBotsCommands);
    chatActivityEnterView.setAllowStickersAndGifs(
            currentEncryptedChat == null
                    || AndroidUtilities.getPeerLayerVersion(currentEncryptedChat.layer) >= 23,
            currentEncryptedChat == null
                    || AndroidUtilities.getPeerLayerVersion(currentEncryptedChat.layer) >= 46);
    contentView.addView(chatActivityEnterView, contentView.getChildCount() - 1, LayoutHelper
            .createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.BOTTOM));
    chatActivityEnterView.setDelegate(new ChatActivityEnterView.ChatActivityEnterViewDelegate() {
        @Override
        public void onMessageSend(CharSequence message) {
            moveScrollToLastMessage();
            showReplyPanel(false, null, null, null, false, true);
            if (mentionsAdapter != null) {
                mentionsAdapter.addHashtagsFromMessage(message);
            }
        }

        @Override
        public void onTextChanged(final CharSequence text, boolean bigChange) {
            MediaController.getInstance().setInputFieldHasText(
                    text != null && text.length() != 0 || chatActivityEnterView.isEditingMessage());
            if (stickersAdapter != null && !chatActivityEnterView.isEditingMessage()) {
                stickersAdapter.loadStikersForEmoji(text);
            }
            if (mentionsAdapter != null) {
                mentionsAdapter.searchUsernameOrHashtag(text.toString(),
                        chatActivityEnterView.getCursorPosition(), messages);
            }
            if (waitingForCharaterEnterRunnable != null) {
                AndroidUtilities.cancelRunOnUIThread(waitingForCharaterEnterRunnable);
                waitingForCharaterEnterRunnable = null;
            }
            if (chatActivityEnterView.isMessageWebPageSearchEnabled()
                    && (!chatActivityEnterView.isEditingMessage()
                            || !chatActivityEnterView.isEditingCaption())) {
                if (bigChange) {
                    searchLinks(text, true);
                } else {
                    waitingForCharaterEnterRunnable = new Runnable() {
                        @Override
                        public void run() {
                            if (this == waitingForCharaterEnterRunnable) {
                                searchLinks(text, false);
                                waitingForCharaterEnterRunnable = null;
                            }
                        }
                    };
                    AndroidUtilities.runOnUIThread(waitingForCharaterEnterRunnable,
                            AndroidUtilities.WEB_URL == null ? 3000 : 1000);
                }
            }
        }

        @Override
        public void needSendTyping() {
            MessagesController.getInstance().sendTyping(dialog_id, 0, classGuid);
        }

        @Override
        public void onAttachButtonHidden() {
            if (actionBar.isSearchFieldVisible()) {
                return;
            }
            if (attachItem != null) {
                attachItem.setVisibility(View.VISIBLE);
            }
            if (headerItem != null) {
                headerItem.setVisibility(View.GONE);
            }
        }

        @Override
        public void onAttachButtonShow() {
            if (actionBar.isSearchFieldVisible()) {
                return;
            }
            if (attachItem != null) {
                attachItem.setVisibility(View.GONE);
            }
            if (headerItem != null) {
                headerItem.setVisibility(View.VISIBLE);
            }
        }

        @Override
        public void onMessageEditEnd(boolean loading) {
            if (loading) {
                showEditDoneProgress(true, true);
            } else {
                mentionsAdapter.setNeedBotContext(currentEncryptedChat == null
                        || AndroidUtilities.getPeerLayerVersion(currentEncryptedChat.layer) >= 46);
                chatListView.setOnItemLongClickListener(onItemLongClickListener);
                chatListView.setOnItemClickListener(onItemClickListener);
                chatListView.setClickable(true);
                chatListView.setLongClickable(true);
                mentionsAdapter.setAllowNewMentions(true);
                actionModeTitleContainer.setVisibility(View.GONE);
                selectedMessagesCountTextView.setVisibility(View.VISIBLE);
                chatActivityEnterView.setAllowStickersAndGifs(
                        currentEncryptedChat == null
                                || AndroidUtilities.getPeerLayerVersion(currentEncryptedChat.layer) >= 23,
                        currentEncryptedChat == null
                                || AndroidUtilities.getPeerLayerVersion(currentEncryptedChat.layer) >= 46);
                if (editingMessageObjectReqId != 0) {
                    ConnectionsManager.getInstance().cancelRequest(editingMessageObjectReqId, true);
                    editingMessageObjectReqId = 0;
                }
                actionBar.hideActionMode();
                updatePinnedMessageView(true);
                updateVisibleRows();
            }
        }

        @Override
        public void onWindowSizeChanged(int size) {
            if (size < AndroidUtilities.dp(72) + ActionBar.getCurrentActionBarHeight()) {
                allowStickersPanel = false;
                if (stickersPanel.getVisibility() == View.VISIBLE) {
                    stickersPanel.setVisibility(View.INVISIBLE);
                }
                if (mentionContainer != null && mentionContainer.getVisibility() == View.VISIBLE) {
                    mentionContainer.setVisibility(View.INVISIBLE);
                }
            } else {
                allowStickersPanel = true;
                if (stickersPanel.getVisibility() == View.INVISIBLE) {
                    stickersPanel.setVisibility(View.VISIBLE);
                }
                if (mentionContainer != null && mentionContainer.getVisibility() == View.INVISIBLE
                        && (!mentionsAdapter.isBotContext()
                                || (allowContextBotPanel || allowContextBotPanelSecond))) {
                    mentionContainer.setVisibility(View.VISIBLE);
                    mentionContainer.setTag(null);
                }
            }

            allowContextBotPanel = !chatActivityEnterView.isPopupShowing();
            checkContextBotPanel();
        }

        @Override
        public void onStickersTab(boolean opened) {
            if (emojiButtonRed != null) {
                emojiButtonRed.setVisibility(View.GONE);
            }
            allowContextBotPanelSecond = !opened;
            checkContextBotPanel();
        }
    });

    FrameLayout replyLayout = new FrameLayout(context) {
        @Override
        public void setTranslationY(float translationY) {
            super.setTranslationY(translationY);
            if (chatActivityEnterView != null) {
                chatActivityEnterView.invalidate();
            }
            if (getVisibility() != GONE) {
                int height = getLayoutParams().height;
                if (chatListView != null) {
                    chatListView.setTranslationY(translationY);
                }
                if (progressView != null) {
                    progressView.setTranslationY(translationY);
                }
                if (mentionContainer != null) {
                    mentionContainer.setTranslationY(translationY);
                }
                if (pagedownButton != null) {
                    pagedownButton.setTranslationY(translationY);
                }
            }
        }

        @Override
        public boolean hasOverlappingRendering() {
            return false;
        }

        @Override
        public void setVisibility(int visibility) {
            super.setVisibility(visibility);
            if (visibility == GONE) {
                if (chatListView != null) {
                    chatListView.setTranslationY(0);
                }
                if (progressView != null) {
                    progressView.setTranslationY(0);
                }
                if (mentionContainer != null) {
                    mentionContainer.setTranslationY(0);
                }
                if (pagedownButton != null) {
                    pagedownButton
                            .setTranslationY(pagedownButton.getTag() == null ? AndroidUtilities.dp(100) : 0);
                }
            }
        }
    };
    replyLayout.setClickable(true);
    chatActivityEnterView.addTopView(replyLayout, 48);

    View lineView = new View(context);
    lineView.setBackgroundColor(0xffe8e8e8);
    replyLayout.addView(lineView,
            LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 1, Gravity.BOTTOM | Gravity.LEFT));

    replyIconImageView = new ImageView(context);
    replyIconImageView.setScaleType(ImageView.ScaleType.CENTER);
    replyLayout.addView(replyIconImageView, LayoutHelper.createFrame(52, 46, Gravity.TOP | Gravity.LEFT));

    ImageView imageView = new ImageView(context);
    imageView.setImageResource(R.drawable.delete_reply);
    imageView.setScaleType(ImageView.ScaleType.CENTER);
    replyLayout.addView(imageView,
            LayoutHelper.createFrame(52, 46, Gravity.RIGHT | Gravity.TOP, 0, 0.5f, 0, 0));
    imageView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (forwardingMessages != null) {
                forwardingMessages.clear();
            }
            showReplyPanel(false, null, null, foundWebPage, true, true);
        }
    });

    replyNameTextView = new SimpleTextView(context);
    replyNameTextView.setTextSize(14);
    replyNameTextView.setTextColor(Theme.REPLY_PANEL_NAME_TEXT_COLOR);
    replyNameTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
    replyLayout.addView(replyNameTextView,
            LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 18, Gravity.TOP | Gravity.LEFT, 52, 6, 52, 0));

    replyObjectTextView = new SimpleTextView(context);
    replyObjectTextView.setTextSize(14);
    replyObjectTextView.setTextColor(Theme.REPLY_PANEL_MESSAGE_TEXT_COLOR);
    replyLayout.addView(replyObjectTextView,
            LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 18, Gravity.TOP | Gravity.LEFT, 52, 24, 52, 0));

    replyImageView = new BackupImageView(context);
    replyLayout.addView(replyImageView,
            LayoutHelper.createFrame(34, 34, Gravity.TOP | Gravity.LEFT, 52, 6, 0, 0));

    stickersPanel = new FrameLayout(context);
    stickersPanel.setVisibility(View.GONE);
    contentView.addView(stickersPanel, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, 81.5f,
            Gravity.LEFT | Gravity.BOTTOM, 0, 0, 0, 38));

    stickersListView = new RecyclerListView(context) {
        @Override
        public boolean onInterceptTouchEvent(MotionEvent event) {
            boolean result = StickerPreviewViewer.getInstance().onInterceptTouchEvent(event, stickersListView,
                    0);
            return super.onInterceptTouchEvent(event) || result;
        }
    };
    stickersListView.setTag(3);
    stickersListView.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            return StickerPreviewViewer.getInstance().onTouch(event, stickersListView, 0,
                    stickersOnItemClickListener);
        }
    });
    stickersListView.setDisallowInterceptTouchEvents(true);
    LinearLayoutManager layoutManager = new LinearLayoutManager(context);
    layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
    stickersListView.setLayoutManager(layoutManager);
    stickersListView.setClipToPadding(false);
    stickersListView.setOverScrollMode(RecyclerListView.OVER_SCROLL_NEVER);
    stickersPanel.addView(stickersListView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 78));
    initStickers();

    imageView = new ImageView(context);
    imageView.setImageResource(R.drawable.stickers_back_arrow);
    stickersPanel.addView(imageView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT,
            LayoutHelper.WRAP_CONTENT, Gravity.BOTTOM | Gravity.LEFT, 53, 0, 0, 0));

    searchContainer = new FrameLayout(context);
    searchContainer.setBackgroundResource(R.drawable.compose_panel);
    searchContainer.setVisibility(View.INVISIBLE);
    searchContainer.setFocusable(true);
    searchContainer.setFocusableInTouchMode(true);
    searchContainer.setClickable(true);
    searchContainer.setBackgroundResource(R.drawable.compose_panel);
    searchContainer.setPadding(0, AndroidUtilities.dp(3), 0, 0);
    contentView.addView(searchContainer,
            LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 51, Gravity.BOTTOM));

    searchUpButton = new ImageView(context);
    searchUpButton.setScaleType(ImageView.ScaleType.CENTER);
    searchUpButton.setImageResource(R.drawable.search_up);
    searchContainer.addView(searchUpButton, LayoutHelper.createFrame(48, 48));
    searchUpButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            MessagesSearchQuery.searchMessagesInChat(null, dialog_id, mergeDialogId, classGuid, 1);
        }
    });

    searchDownButton = new ImageView(context);
    searchDownButton.setScaleType(ImageView.ScaleType.CENTER);
    searchDownButton.setImageResource(R.drawable.search_down);
    searchContainer.addView(searchDownButton,
            LayoutHelper.createFrame(48, 48, Gravity.LEFT | Gravity.TOP, 48, 0, 0, 0));
    searchDownButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            MessagesSearchQuery.searchMessagesInChat(null, dialog_id, mergeDialogId, classGuid, 2);
        }
    });

    searchCountText = new SimpleTextView(context);
    searchCountText.setTextColor(Theme.CHAT_SEARCH_COUNT_TEXT_COLOR);
    searchCountText.setTextSize(15);
    searchCountText.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
    searchContainer.addView(searchCountText, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT,
            LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.CENTER_VERTICAL, 108, 0, 0, 0));

    bottomOverlay = new FrameLayout(context);
    bottomOverlay.setVisibility(View.INVISIBLE);
    bottomOverlay.setFocusable(true);
    bottomOverlay.setFocusableInTouchMode(true);
    bottomOverlay.setClickable(true);
    bottomOverlay.setBackgroundResource(R.drawable.compose_panel);
    bottomOverlay.setPadding(0, AndroidUtilities.dp(3), 0, 0);
    contentView.addView(bottomOverlay, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 51, Gravity.BOTTOM));

    bottomOverlayText = new TextView(context);
    bottomOverlayText.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
    bottomOverlayText.setTextColor(Theme.CHAT_BOTTOM_OVERLAY_TEXT_COLOR);
    bottomOverlay.addView(bottomOverlayText,
            LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER));

    bottomOverlayChat = new FrameLayout(context);
    bottomOverlayChat.setBackgroundResource(R.drawable.compose_panel);
    bottomOverlayChat.setPadding(0, AndroidUtilities.dp(3), 0, 0);
    bottomOverlayChat.setVisibility(View.INVISIBLE);
    contentView.addView(bottomOverlayChat,
            LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 51, Gravity.BOTTOM));
    bottomOverlayChat.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            if (getParentActivity() == null) {
                return;
            }
            AlertDialog.Builder builder = null;
            if (currentUser != null && userBlocked) {
                if (currentUser.bot) {
                    String botUserLast = botUser;
                    botUser = null;
                    MessagesController.getInstance().unblockUser(currentUser.id);
                    if (botUserLast != null && botUserLast.length() != 0) {
                        MessagesController.getInstance().sendBotStart(currentUser, botUserLast);
                    } else {
                        SendMessagesHelper.getInstance().sendMessage("/start", dialog_id, null, null, false,
                                null, null, null);
                    }
                } else {
                    builder = new AlertDialog.Builder(getParentActivity());
                    builder.setMessage(LocaleController.getString("AreYouSureUnblockContact",
                            R.string.AreYouSureUnblockContact));
                    builder.setPositiveButton(LocaleController.getString("OK", R.string.OK),
                            new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialogInterface, int i) {
                                    MessagesController.getInstance().unblockUser(currentUser.id);
                                }
                            });
                }
            } else if (currentUser != null && currentUser.bot && botUser != null) {
                if (botUser.length() != 0) {
                    MessagesController.getInstance().sendBotStart(currentUser, botUser);
                } else {
                    SendMessagesHelper.getInstance().sendMessage("/start", dialog_id, null, null, false, null,
                            null, null);
                }
                botUser = null;
                updateBottomOverlay();
            } else {
                if (ChatObject.isChannel(currentChat) && !(currentChat instanceof TLRPC.TL_channelForbidden)) {
                    if (ChatObject.isNotInChat(currentChat)) {
                        MessagesController.getInstance().addUserToChat(currentChat.id,
                                UserConfig.getCurrentUser(), null, 0, null, null);
                    } else {
                        toggleMute(true);
                    }
                } else {
                    builder = new AlertDialog.Builder(getParentActivity());
                    builder.setMessage(LocaleController.getString("AreYouSureDeleteThisChat",
                            R.string.AreYouSureDeleteThisChat));
                    builder.setPositiveButton(LocaleController.getString("OK", R.string.OK),
                            new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialogInterface, int i) {
                                    MessagesController.getInstance().deleteDialog(dialog_id, 0);
                                    finishFragment();
                                }
                            });
                }
            }
            if (builder != null) {
                builder.setTitle(LocaleController.getString("AppName", R.string.AppName));
                builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null);
                showDialog(builder.create());
            }
        }
    });

    bottomOverlayChatText = new TextView(context);
    bottomOverlayChatText.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
    bottomOverlayChatText.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
    bottomOverlayChatText.setTextColor(Theme.CHAT_BOTTOM_CHAT_OVERLAY_TEXT_COLOR);
    bottomOverlayChat.addView(bottomOverlayChatText,
            LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER));

    chatAdapter.updateRows();
    if (loading && messages.isEmpty()) {
        progressView.setVisibility(chatAdapter.botInfoRow == -1 ? View.VISIBLE : View.INVISIBLE);
        chatListView.setEmptyView(null);
    } else {
        progressView.setVisibility(View.INVISIBLE);
        chatListView.setEmptyView(emptyViewContainer);
    }

    chatActivityEnterView.setButtons(userBlocked ? null : botButtons);

    if (!AndroidUtilities.isTablet() || AndroidUtilities.isSmallTablet()) {
        contentView.addView(playerView = new PlayerView(context, this), LayoutHelper
                .createFrame(LayoutHelper.MATCH_PARENT, 39, Gravity.TOP | Gravity.LEFT, 0, -36, 0, 0));
    }

    updateContactStatus();
    updateBottomOverlay();
    updateSecretStatus();
    updateSpamView();
    updatePinnedMessageView(true);

    try {
        if (currentEncryptedChat != null && Build.VERSION.SDK_INT >= 23) {
            getParentActivity().getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE,
                    WindowManager.LayoutParams.FLAG_SECURE);
        }
    } catch (Throwable e) {
        FileLog.e("tmessages", e);
    }
    fixLayoutInternal();

    contentView.addView(actionBar);

    return fragmentView;
}

From source file:kr.wdream.ui.ChatActivity.java

@Override
public View createView(Context context) {

    Log.d(LOG_TAG, "createView");

    if (chatMessageCellsCache.isEmpty()) {
        for (int a = 0; a < 8; a++) {
            chatMessageCellsCache.add(new ChatMessageCell(context));
        }//from   www.ja  v  a  2 s .c  o m
    }
    for (int a = 1; a >= 0; a--) {
        selectedMessagesIds[a].clear();
        selectedMessagesCanCopyIds[a].clear();
    }
    cantDeleteMessagesCount = 0;

    hasOwnBackground = true;
    if (chatAttachAlert != null) {
        chatAttachAlert.onDestroy();
        chatAttachAlert = null;
    }

    Theme.loadRecources(context);
    Theme.loadChatResources(context);

    actionBar.setAddToContainer(false);
    actionBar.setBackButtonDrawable(new BackDrawable(false));
    actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() {
        @Override
        public void onItemClick(final int id) {
            if (id == -1) {
                if (actionBar.isActionModeShowed()) {
                    for (int a = 1; a >= 0; a--) {
                        selectedMessagesIds[a].clear();
                        selectedMessagesCanCopyIds[a].clear();
                    }
                    cantDeleteMessagesCount = 0;
                    if (chatActivityEnterView.isEditingMessage()) {
                        chatActivityEnterView.setEditingMessageObject(null, false);
                    } else {
                        actionBar.hideActionMode();
                        updatePinnedMessageView(true);
                    }
                    updateVisibleRows();
                } else {
                    finishFragment();
                }
            } else if (id == copy) {
                String str = "";
                int previousUid = 0;
                for (int a = 1; a >= 0; a--) {
                    ArrayList<Integer> ids = new ArrayList<>(selectedMessagesCanCopyIds[a].keySet());
                    if (currentEncryptedChat == null) {
                        Collections.sort(ids);
                    } else {
                        Collections.sort(ids, Collections.reverseOrder());
                    }
                    for (int b = 0; b < ids.size(); b++) {
                        Integer messageId = ids.get(b);
                        MessageObject messageObject = selectedMessagesCanCopyIds[a].get(messageId);
                        if (str.length() != 0) {
                            str += "\n\n";
                        }
                        str += getMessageContent(messageObject, previousUid, true);
                        previousUid = messageObject.messageOwner.from_id;
                    }
                }
                if (str.length() != 0) {
                    AndroidUtilities.addToClipboard(str);
                }
                for (int a = 1; a >= 0; a--) {
                    selectedMessagesIds[a].clear();
                    selectedMessagesCanCopyIds[a].clear();
                }
                cantDeleteMessagesCount = 0;
                actionBar.hideActionMode();
                updatePinnedMessageView(true);
                updateVisibleRows();
            } else if (id == edit_done) {
                if (chatActivityEnterView != null
                        && (chatActivityEnterView.isEditingCaption() || chatActivityEnterView.hasText())) {
                    chatActivityEnterView.doneEditingMessage();
                }
            } else if (id == delete) {
                if (getParentActivity() == null) {
                    return;
                }
                createDeleteMessagesAlert(null);
            } else if (id == forward) {
                Bundle args = new Bundle();
                args.putBoolean("onlySelect", true);
                args.putInt("dialogsType", 1);
                DialogsActivity fragment = new DialogsActivity(args);
                fragment.setDelegate(ChatActivity.this);
                presentFragment(fragment);
            } else if (id == chat_enc_timer) {
                if (getParentActivity() == null) {
                    return;
                }
                showDialog(AndroidUtilities.buildTTLAlert(getParentActivity(), currentEncryptedChat).create());
            } else if (id == clear_history || id == delete_chat) {
                if (getParentActivity() == null) {
                    return;
                }
                final boolean isChat = (int) dialog_id < 0 && (int) (dialog_id >> 32) != 1;
                AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity());
                builder.setTitle(LocaleController.getString("AppName", kr.wdream.storyshop.R.string.AppName));
                if (id == clear_history) {
                    builder.setMessage(LocaleController.getString("AreYouSureClearHistory",
                            kr.wdream.storyshop.R.string.AreYouSureClearHistory));
                } else {
                    if (isChat) {
                        builder.setMessage(LocaleController.getString("AreYouSureDeleteAndExit",
                                kr.wdream.storyshop.R.string.AreYouSureDeleteAndExit));
                    } else {
                        builder.setMessage(LocaleController.getString("AreYouSureDeleteThisChat",
                                kr.wdream.storyshop.R.string.AreYouSureDeleteThisChat));
                    }
                }
                builder.setPositiveButton(LocaleController.getString("OK", kr.wdream.storyshop.R.string.OK),
                        new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialogInterface, int i) {
                                if (id != clear_history) {
                                    if (isChat) {
                                        if (ChatObject.isNotInChat(currentChat)) {
                                            MessagesController.getInstance().deleteDialog(dialog_id, 0);
                                        } else {
                                            MessagesController.getInstance()
                                                    .deleteUserFromChat(
                                                            (int) -dialog_id, MessagesController.getInstance()
                                                                    .getUser(UserConfig.getClientUserId()),
                                                            null);
                                        }
                                    } else {
                                        MessagesController.getInstance().deleteDialog(dialog_id, 0);
                                    }
                                    finishFragment();
                                } else {
                                    MessagesController.getInstance().deleteDialog(dialog_id, 1);
                                }
                            }
                        });
                builder.setNegativeButton(
                        LocaleController.getString("Cancel", kr.wdream.storyshop.R.string.Cancel), null);
                showDialog(builder.create());
            } else if (id == share_contact) {
                if (currentUser == null || getParentActivity() == null) {
                    return;
                }
                if (currentUser.phone != null && currentUser.phone.length() != 0) {
                    Bundle args = new Bundle();
                    args.putInt("user_id", currentUser.id);
                    args.putBoolean("addContact", true);
                    presentFragment(new ContactAddActivity(args));
                } else {
                    shareMyContact(replyingMessageObject);
                }
            } else if (id == mute) {
                toggleMute(false);
            } else if (id == report) {
                showDialog(AlertsCreator.createReportAlert(getParentActivity(), dialog_id, ChatActivity.this));
            } else if (id == reply) {
                MessageObject messageObject = null;
                for (int a = 1; a >= 0; a--) {
                    if (messageObject == null && selectedMessagesIds[a].size() == 1) {
                        ArrayList<Integer> ids = new ArrayList<>(selectedMessagesIds[a].keySet());
                        messageObject = messagesDict[a].get(ids.get(0));
                    }
                    selectedMessagesIds[a].clear();
                    selectedMessagesCanCopyIds[a].clear();
                }
                if (messageObject != null && (messageObject.messageOwner.id > 0
                        || messageObject.messageOwner.id < 0 && currentEncryptedChat != null)) {
                    showReplyPanel(true, messageObject, null, null, false, true);
                }
                cantDeleteMessagesCount = 0;
                actionBar.hideActionMode();
                updatePinnedMessageView(true);
                updateVisibleRows();
            } else if (id == chat_menu_attach) {
                if (getParentActivity() == null) {
                    return;
                }

                createChatAttachView();
                chatAttachAlert.loadGalleryPhotos();
                if (Build.VERSION.SDK_INT == 21 || Build.VERSION.SDK_INT == 22) {
                    chatActivityEnterView.closeKeyboard();
                }
                chatAttachAlert.init();
                showDialog(chatAttachAlert);
            } else if (id == bot_help) {
                SendMessagesHelper.getInstance().sendMessage("/help", dialog_id, null, null, false, null, null,
                        null);
            } else if (id == bot_settings) {
                SendMessagesHelper.getInstance().sendMessage("/settings", dialog_id, null, null, false, null,
                        null, null);
            } else if (id == search) {
                openSearchWithText(null);
            }
        }
    });

    avatarContainer = new ChatAvatarContainer(context, this, currentEncryptedChat != null);
    actionBar.addView(avatarContainer, 0, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT,
            LayoutHelper.MATCH_PARENT, Gravity.TOP | Gravity.LEFT, 56, 0, 40, 0));

    if (currentChat != null) {
        if (!ChatObject.isChannel(currentChat)) {
            int count = currentChat.participants_count;
            if (info != null) {
                count = info.participants.participants.size();
            }
            if (count == 0 || currentChat.deactivated || currentChat.left
                    || currentChat instanceof TLRPC.TL_chatForbidden
                    || info != null && info.participants instanceof TLRPC.TL_chatParticipantsForbidden) {
                avatarContainer.setEnabled(false);
            }
        }
    }

    ActionBarMenu menu = actionBar.createMenu();

    if (currentEncryptedChat == null && !isBroadcast) {
        searchItem = menu.addItem(0, kr.wdream.storyshop.R.drawable.ic_ab_search).setIsSearchField(true)
                .setActionBarMenuItemSearchListener(new ActionBarMenuItem.ActionBarMenuItemSearchListener() {

                    @Override
                    public void onSearchCollapse() {
                        avatarContainer.setVisibility(View.VISIBLE);
                        if (chatActivityEnterView.hasText()) {
                            if (headerItem != null) {
                                headerItem.setVisibility(View.GONE);
                            }
                            if (attachItem != null) {
                                attachItem.setVisibility(View.VISIBLE);
                            }
                        } else {
                            if (headerItem != null) {
                                headerItem.setVisibility(View.VISIBLE);
                            }
                            if (attachItem != null) {
                                attachItem.setVisibility(View.GONE);
                            }
                        }
                        searchItem.setVisibility(View.GONE);
                        highlightMessageId = Integer.MAX_VALUE;
                        updateVisibleRows();
                        scrollToLastMessage(false);
                        updateBottomOverlay();
                    }

                    @Override
                    public void onSearchExpand() {
                        if (!openSearchKeyboard) {
                            return;
                        }
                        AndroidUtilities.runOnUIThread(new Runnable() {
                            @Override
                            public void run() {
                                searchItem.getSearchField().requestFocus();
                                AndroidUtilities.showKeyboard(searchItem.getSearchField());
                            }
                        }, 300);
                    }

                    @Override
                    public void onSearchPressed(EditText editText) {
                        updateSearchButtons(0, 0, 0);
                        MessagesSearchQuery.searchMessagesInChat(editText.getText().toString(), dialog_id,
                                mergeDialogId, classGuid, 0);
                    }
                });
        searchItem.getSearchField()
                .setHint(LocaleController.getString("Search", kr.wdream.storyshop.R.string.Search));
        searchItem.setVisibility(View.GONE);
    }

    headerItem = menu.addItem(0, kr.wdream.storyshop.R.drawable.ic_ab_other);
    if (searchItem != null) {
        headerItem.addSubItem(search, LocaleController.getString("Search", kr.wdream.storyshop.R.string.Search),
                0);
    }
    if (ChatObject.isChannel(currentChat) && !currentChat.creator
            && (!currentChat.megagroup || currentChat.username != null && currentChat.username.length() > 0)) {
        headerItem.addSubItem(report,
                LocaleController.getString("ReportChat", kr.wdream.storyshop.R.string.ReportChat), 0);
    }
    if (currentUser != null) {
        addContactItem = headerItem.addSubItem(share_contact, "", 0);
    }
    if (currentEncryptedChat != null) {
        timeItem2 = headerItem.addSubItem(chat_enc_timer,
                LocaleController.getString("SetTimer", kr.wdream.storyshop.R.string.SetTimer), 0);
    }
    if (!ChatObject.isChannel(currentChat)) {
        headerItem.addSubItem(clear_history,
                LocaleController.getString("ClearHistory", kr.wdream.storyshop.R.string.ClearHistory), 0);
        if (currentChat != null && !isBroadcast) {
            headerItem.addSubItem(delete_chat,
                    LocaleController.getString("DeleteAndExit", kr.wdream.storyshop.R.string.DeleteAndExit), 0);
        } else {
            headerItem.addSubItem(delete_chat,
                    LocaleController.getString("DeleteChatUser", kr.wdream.storyshop.R.string.DeleteChatUser),
                    0);
        }
    }
    if (currentUser == null || !currentUser.self) {
        muteItem = headerItem.addSubItem(mute, null, 0);
    }
    if (currentUser != null && currentEncryptedChat == null && currentUser.bot) {
        headerItem.addSubItem(bot_settings,
                LocaleController.getString("BotSettings", kr.wdream.storyshop.R.string.BotSettings), 0);
        headerItem.addSubItem(bot_help,
                LocaleController.getString("BotHelp", kr.wdream.storyshop.R.string.BotHelp), 0);
        updateBotButtons();
    }

    updateTitle();
    avatarContainer.updateOnlineCount();
    avatarContainer.updateSubtitle();
    updateTitleIcons();

    attachItem = menu.addItem(chat_menu_attach, kr.wdream.storyshop.R.drawable.ic_ab_other)
            .setOverrideMenuClick(true).setAllowCloseAnimation(false);
    attachItem.setVisibility(View.GONE);
    menuItem = menu.addItem(chat_menu_attach, kr.wdream.storyshop.R.drawable.ic_ab_attach)
            .setAllowCloseAnimation(false);
    menuItem.setBackgroundDrawable(null);

    actionModeViews.clear();

    final ActionBarMenu actionMode = actionBar.createActionMode();

    selectedMessagesCountTextView = new NumberTextView(actionMode.getContext());
    selectedMessagesCountTextView.setTextSize(18);
    selectedMessagesCountTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
    selectedMessagesCountTextView.setTextColor(Theme.ACTION_BAR_ACTION_MODE_TEXT_COLOR);
    actionMode.addView(selectedMessagesCountTextView,
            LayoutHelper.createLinear(0, LayoutHelper.MATCH_PARENT, 1.0f, 65, 0, 0, 0));
    selectedMessagesCountTextView.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            return true;
        }
    });

    actionModeTitleContainer = new FrameLayout(context) {

        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            int width = MeasureSpec.getSize(widthMeasureSpec);
            int height = MeasureSpec.getSize(heightMeasureSpec);

            setMeasuredDimension(width, height);

            actionModeTextView.setTextSize(!AndroidUtilities.isTablet()
                    && getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE ? 18
                            : 20);
            actionModeTextView.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST),
                    MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(24), MeasureSpec.AT_MOST));

            if (actionModeSubTextView.getVisibility() != GONE) {
                actionModeSubTextView.setTextSize(!AndroidUtilities.isTablet()
                        && getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE
                                ? 14
                                : 16);
                actionModeSubTextView.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST),
                        MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(20), MeasureSpec.AT_MOST));
            }
        }

        @Override
        protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
            int height = bottom - top;

            int textTop;
            if (actionModeSubTextView.getVisibility() != GONE) {
                textTop = (height / 2 - actionModeTextView.getTextHeight()) / 2
                        + AndroidUtilities.dp(!AndroidUtilities.isTablet() && getResources()
                                .getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE ? 2 : 3);
            } else {
                textTop = (height - actionModeTextView.getTextHeight()) / 2;
            }
            actionModeTextView.layout(0, textTop, actionModeTextView.getMeasuredWidth(),
                    textTop + actionModeTextView.getTextHeight());

            if (actionModeSubTextView.getVisibility() != GONE) {
                textTop = height / 2 + (height / 2 - actionModeSubTextView.getTextHeight()) / 2
                        - AndroidUtilities.dp(!AndroidUtilities.isTablet() && getResources()
                                .getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE ? 1 : 1);
                actionModeSubTextView.layout(0, textTop, actionModeSubTextView.getMeasuredWidth(),
                        textTop + actionModeSubTextView.getTextHeight());
            }
        }
    };
    actionMode.addView(actionModeTitleContainer,
            LayoutHelper.createLinear(0, LayoutHelper.MATCH_PARENT, 1.0f, 65, 0, 0, 0));
    actionModeTitleContainer.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            return true;
        }
    });
    actionModeTitleContainer.setVisibility(View.GONE);

    actionModeTextView = new SimpleTextView(context);
    actionModeTextView.setTextSize(18);
    actionModeTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
    actionModeTextView.setTextColor(Theme.ACTION_BAR_ACTION_MODE_TEXT_COLOR);
    actionModeTextView.setText(LocaleController.getString("Edit", kr.wdream.storyshop.R.string.Edit));
    actionModeTitleContainer.addView(actionModeTextView,
            LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));

    actionModeSubTextView = new SimpleTextView(context);
    actionModeSubTextView.setGravity(Gravity.LEFT);
    actionModeSubTextView.setTextColor(Theme.ACTION_BAR_ACTION_MODE_TEXT_COLOR);
    actionModeTitleContainer.addView(actionModeSubTextView,
            LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));

    if (currentEncryptedChat == null) {
        if (!isBroadcast) {
            actionModeViews.add(actionMode.addItem(reply, kr.wdream.storyshop.R.drawable.ic_ab_reply,
                    Theme.ACTION_BAR_MODE_SELECTOR_COLOR, null, AndroidUtilities.dp(54)));
        }
        actionModeViews.add(actionMode.addItem(copy, kr.wdream.storyshop.R.drawable.ic_ab_fwd_copy,
                Theme.ACTION_BAR_MODE_SELECTOR_COLOR, null, AndroidUtilities.dp(54)));
        actionModeViews.add(actionMode.addItem(forward, kr.wdream.storyshop.R.drawable.ic_ab_fwd_forward,
                Theme.ACTION_BAR_MODE_SELECTOR_COLOR, null, AndroidUtilities.dp(54)));
        actionModeViews.add(actionMode.addItem(delete, kr.wdream.storyshop.R.drawable.ic_ab_fwd_delete,
                Theme.ACTION_BAR_MODE_SELECTOR_COLOR, null, AndroidUtilities.dp(54)));
        actionModeViews
                .add(editDoneItem = actionMode.addItem(edit_done, kr.wdream.storyshop.R.drawable.check_blue,
                        Theme.ACTION_BAR_MODE_SELECTOR_COLOR, null, AndroidUtilities.dp(54)));
        editDoneItem.setVisibility(View.GONE);
        editDoneItemProgress = new ContextProgressView(context, 0);
        editDoneItem.addView(editDoneItemProgress,
                LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
        editDoneItemProgress.setVisibility(View.INVISIBLE);
    } else {
        actionModeViews.add(actionMode.addItem(reply, kr.wdream.storyshop.R.drawable.ic_ab_reply,
                Theme.ACTION_BAR_MODE_SELECTOR_COLOR, null, AndroidUtilities.dp(54)));
        actionModeViews.add(actionMode.addItem(copy, kr.wdream.storyshop.R.drawable.ic_ab_fwd_copy,
                Theme.ACTION_BAR_MODE_SELECTOR_COLOR, null, AndroidUtilities.dp(54)));
        actionModeViews.add(actionMode.addItem(delete, kr.wdream.storyshop.R.drawable.ic_ab_fwd_delete,
                Theme.ACTION_BAR_MODE_SELECTOR_COLOR, null, AndroidUtilities.dp(54)));
    }
    actionMode.getItem(copy)
            .setVisibility(selectedMessagesCanCopyIds[0].size() + selectedMessagesCanCopyIds[1].size() != 0
                    ? View.VISIBLE
                    : View.GONE);
    actionMode.getItem(delete).setVisibility(cantDeleteMessagesCount == 0 ? View.VISIBLE : View.GONE);
    checkActionBarMenu();

    fragmentView = new SizeNotifierFrameLayout(context) {

        int inputFieldHeight = 0;

        @Override
        protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
            boolean result = super.drawChild(canvas, child, drawingTime);
            if (child == actionBar) {
                parentLayout.drawHeaderShadow(canvas, actionBar.getMeasuredHeight());
            }
            return result;
        }

        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            int widthSize = MeasureSpec.getSize(widthMeasureSpec);
            int heightSize = MeasureSpec.getSize(heightMeasureSpec);

            setMeasuredDimension(widthSize, heightSize);
            heightSize -= getPaddingTop();

            measureChildWithMargins(actionBar, widthMeasureSpec, 0, heightMeasureSpec, 0);
            int actionBarHeight = actionBar.getMeasuredHeight();
            heightSize -= actionBarHeight;

            int keyboardSize = getKeyboardHeight();

            if (keyboardSize <= AndroidUtilities.dp(20) && !AndroidUtilities.isInMultiwindow) {
                heightSize -= chatActivityEnterView.getEmojiPadding();
            }

            int childCount = getChildCount();

            measureChildWithMargins(chatActivityEnterView, widthMeasureSpec, 0, heightMeasureSpec, 0);
            inputFieldHeight = chatActivityEnterView.getMeasuredHeight();

            for (int i = 0; i < childCount; i++) {
                View child = getChildAt(i);
                if (child == null || child.getVisibility() == GONE || child == chatActivityEnterView
                        || child == actionBar) {
                    continue;
                }
                if (child == chatListView || child == progressView) {
                    int contentWidthSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY);
                    int contentHeightSpec = MeasureSpec
                            .makeMeasureSpec(
                                    Math.max(AndroidUtilities.dp(10),
                                            heightSize - inputFieldHeight + AndroidUtilities.dp(
                                                    2 + (chatActivityEnterView.isTopViewVisible() ? 48 : 0))),
                                    MeasureSpec.EXACTLY);
                    child.measure(contentWidthSpec, contentHeightSpec);
                } else if (child == emptyViewContainer) {
                    int contentWidthSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY);
                    int contentHeightSpec = MeasureSpec.makeMeasureSpec(heightSize, MeasureSpec.EXACTLY);
                    child.measure(contentWidthSpec, contentHeightSpec);
                } else if (chatActivityEnterView.isPopupView(child)) {
                    if (AndroidUtilities.isInMultiwindow) {
                        if (AndroidUtilities.isTablet()) {
                            child.measure(MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY),
                                    MeasureSpec.makeMeasureSpec(Math.min(AndroidUtilities.dp(320),
                                            heightSize - inputFieldHeight + actionBarHeight
                                                    - AndroidUtilities.statusBarHeight + getPaddingTop()),
                                            MeasureSpec.EXACTLY));
                        } else {
                            child.measure(MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY),
                                    MeasureSpec.makeMeasureSpec(
                                            heightSize - inputFieldHeight + actionBarHeight
                                                    - AndroidUtilities.statusBarHeight + getPaddingTop(),
                                            MeasureSpec.EXACTLY));
                        }
                    } else {
                        child.measure(MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY), MeasureSpec
                                .makeMeasureSpec(child.getLayoutParams().height, MeasureSpec.EXACTLY));
                    }
                } else if (child == mentionContainer) {
                    FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) mentionContainer
                            .getLayoutParams();
                    int height;
                    mentionListViewIgnoreLayout = true;

                    if (mentionsAdapter.isBotContext() && mentionsAdapter.isMediaLayout()) {
                        int size = mentionGridLayoutManager.getRowsCount(widthSize);
                        int maxHeight = size * 102;
                        if (mentionsAdapter.isBotContext()) {
                            if (mentionsAdapter.getBotContextSwitch() != null) {
                                maxHeight += 34;
                            }
                        }
                        height = heightSize - chatActivityEnterView.getMeasuredHeight()
                                + (maxHeight != 0 ? AndroidUtilities.dp(2) : 0);
                        mentionListView.setPadding(0,
                                Math.max(0, height - AndroidUtilities.dp(Math.min(maxHeight, 68 * 1.8f))), 0,
                                0);
                    } else {
                        int size = mentionsAdapter.getItemCount();
                        int maxHeight = 0;
                        if (mentionsAdapter.isBotContext()) {
                            if (mentionsAdapter.getBotContextSwitch() != null) {
                                maxHeight += 36;
                                size -= 1;
                            }
                            maxHeight += size * 68;
                        } else {
                            maxHeight += size * 36;
                        }
                        height = heightSize - chatActivityEnterView.getMeasuredHeight()
                                + (maxHeight != 0 ? AndroidUtilities.dp(2) : 0);
                        mentionListView.setPadding(0,
                                Math.max(0, height - AndroidUtilities.dp(Math.min(maxHeight, 68 * 1.8f))), 0,
                                0);
                    }

                    layoutParams.height = height;
                    layoutParams.topMargin = 0;

                    mentionListViewIgnoreLayout = false;
                    child.measure(MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY),
                            MeasureSpec.makeMeasureSpec(layoutParams.height, MeasureSpec.EXACTLY));
                } else {
                    measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, 0);
                }
            }
        }

        @Override
        protected void onLayout(boolean changed, int l, int t, int r, int b) {
            final int count = getChildCount();

            int paddingBottom = getKeyboardHeight() <= AndroidUtilities.dp(20)
                    && !AndroidUtilities.isInMultiwindow ? chatActivityEnterView.getEmojiPadding() : 0;
            setBottomClip(paddingBottom);

            for (int i = 0; i < count; i++) {
                final View child = getChildAt(i);
                if (child.getVisibility() == GONE) {
                    continue;
                }
                final LayoutParams lp = (LayoutParams) child.getLayoutParams();

                final int width = child.getMeasuredWidth();
                final int height = child.getMeasuredHeight();

                int childLeft;
                int childTop;

                int gravity = lp.gravity;
                if (gravity == -1) {
                    gravity = Gravity.TOP | Gravity.LEFT;
                }

                final int absoluteGravity = gravity & Gravity.HORIZONTAL_GRAVITY_MASK;
                final int verticalGravity = gravity & Gravity.VERTICAL_GRAVITY_MASK;

                switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
                case Gravity.CENTER_HORIZONTAL:
                    childLeft = (r - l - width) / 2 + lp.leftMargin - lp.rightMargin;
                    break;
                case Gravity.RIGHT:
                    childLeft = r - width - lp.rightMargin;
                    break;
                case Gravity.LEFT:
                default:
                    childLeft = lp.leftMargin;
                }

                switch (verticalGravity) {
                case Gravity.TOP:
                    childTop = lp.topMargin + getPaddingTop();
                    if (child != actionBar) {
                        childTop += actionBar.getMeasuredHeight();
                    }
                    break;
                case Gravity.CENTER_VERTICAL:
                    childTop = ((b - paddingBottom) - t - height) / 2 + lp.topMargin - lp.bottomMargin;
                    break;
                case Gravity.BOTTOM:
                    childTop = ((b - paddingBottom) - t) - height - lp.bottomMargin;
                    break;
                default:
                    childTop = lp.topMargin;
                }

                if (child == mentionContainer) {
                    childTop -= chatActivityEnterView.getMeasuredHeight() - AndroidUtilities.dp(2);
                } else if (child == pagedownButton) {
                    childTop -= chatActivityEnterView.getMeasuredHeight();
                } else if (child == emptyViewContainer) {
                    childTop -= inputFieldHeight / 2 - actionBar.getMeasuredHeight() / 2;
                } else if (chatActivityEnterView.isPopupView(child)) {
                    if (AndroidUtilities.isInMultiwindow) {
                        childTop = chatActivityEnterView.getTop() - child.getMeasuredHeight()
                                + AndroidUtilities.dp(1);
                    } else {
                        childTop = chatActivityEnterView.getBottom();
                    }
                } else if (child == gifHintTextView) {
                    childTop -= inputFieldHeight;
                } else if (child == chatListView || child == progressView) {
                    if (chatActivityEnterView.isTopViewVisible()) {
                        childTop -= AndroidUtilities.dp(48);
                    }
                } else if (child == actionBar) {
                    childTop -= getPaddingTop();
                }
                child.layout(childLeft, childTop, childLeft + width, childTop + height);
            }

            updateMessagesVisisblePart();
            notifyHeightChanged();
        }
    };

    SizeNotifierFrameLayout contentView = (SizeNotifierFrameLayout) fragmentView;

    contentView.setBackgroundImage(ApplicationLoader.getCachedWallpaper());

    emptyViewContainer = new FrameLayout(context);
    emptyViewContainer.setVisibility(View.INVISIBLE);
    contentView.addView(emptyViewContainer,
            LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER));
    emptyViewContainer.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            return true;
        }
    });

    if (currentEncryptedChat == null) {
        if (currentUser != null && currentUser.self) {
            bigEmptyView = new ChatBigEmptyView(context, false);
            emptyViewContainer.addView(bigEmptyView, new FrameLayout.LayoutParams(LayoutHelper.WRAP_CONTENT,
                    LayoutHelper.WRAP_CONTENT, Gravity.CENTER));
        } else {
            TextView emptyView = new TextView(context);
            if (currentUser != null && currentUser.id != 777000 && currentUser.id != 429000
                    && (currentUser.id / 1000 == 333 || currentUser.id % 1000 == 0)) {
                emptyView.setText(
                        LocaleController.getString("GotAQuestion", kr.wdream.storyshop.R.string.GotAQuestion));
            } else {
                emptyView.setText(
                        LocaleController.getString("NoMessages", kr.wdream.storyshop.R.string.NoMessages));
            }
            emptyView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
            emptyView.setGravity(Gravity.CENTER);
            emptyView.setTextColor(Theme.CHAT_EMPTY_VIEW_TEXT_COLOR);
            emptyView.setBackgroundResource(kr.wdream.storyshop.R.drawable.system);
            emptyView.getBackground().setColorFilter(Theme.colorFilter);
            emptyView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
            emptyView.setPadding(AndroidUtilities.dp(10), AndroidUtilities.dp(2), AndroidUtilities.dp(10),
                    AndroidUtilities.dp(3));
            emptyViewContainer.addView(emptyView, new FrameLayout.LayoutParams(LayoutHelper.WRAP_CONTENT,
                    LayoutHelper.WRAP_CONTENT, Gravity.CENTER));
        }
    } else {
        bigEmptyView = new ChatBigEmptyView(context, true);
        if (currentEncryptedChat.admin_id == UserConfig.getClientUserId()) {
            bigEmptyView.setSecretText(LocaleController.formatString("EncryptedPlaceholderTitleOutgoing",
                    kr.wdream.storyshop.R.string.EncryptedPlaceholderTitleOutgoing,
                    UserObject.getFirstName(currentUser)));
        } else {
            bigEmptyView.setSecretText(LocaleController.formatString("EncryptedPlaceholderTitleIncoming",
                    kr.wdream.storyshop.R.string.EncryptedPlaceholderTitleIncoming,
                    UserObject.getFirstName(currentUser)));
        }
        emptyViewContainer.addView(bigEmptyView, new FrameLayout.LayoutParams(LayoutHelper.WRAP_CONTENT,
                LayoutHelper.WRAP_CONTENT, Gravity.CENTER));
    }

    if (chatActivityEnterView != null) {
        chatActivityEnterView.onDestroy();
    }
    if (mentionsAdapter != null) {
        mentionsAdapter.onDestroy();
    }

    chatListView = new RecyclerListView(context) {
        @Override
        protected void onLayout(boolean changed, int l, int t, int r, int b) {
            super.onLayout(changed, l, t, r, b);
            forceScrollToTop = false;
            if (chatAdapter.isBot) {
                int childCount = getChildCount();
                for (int a = 0; a < childCount; a++) {
                    View child = getChildAt(a);
                    if (child instanceof BotHelpCell) {
                        int height = b - t;
                        int top = height / 2 - child.getMeasuredHeight() / 2;
                        if (child.getTop() > top) {
                            child.layout(0, top, r - l, top + child.getMeasuredHeight());
                        }
                        break;
                    }
                }
            }
        }
    };
    chatListView.setTag(1);
    chatListView.setVerticalScrollBarEnabled(true);
    chatListView.setAdapter(chatAdapter = new ChatActivityAdapter(context));
    chatListView.setClipToPadding(false);
    chatListView.setPadding(0, AndroidUtilities.dp(4), 0, AndroidUtilities.dp(3));
    chatListView.setItemAnimator(null);
    chatListView.setLayoutAnimation(null);
    chatLayoutManager = new LinearLayoutManager(context) {
        @Override
        public boolean supportsPredictiveItemAnimations() {
            return false;
        }
    };
    chatLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
    chatLayoutManager.setStackFromEnd(true);
    chatListView.setLayoutManager(chatLayoutManager);
    contentView.addView(chatListView,
            LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
    chatListView.setOnItemLongClickListener(onItemLongClickListener);
    chatListView.setOnItemClickListener(onItemClickListener);
    chatListView.setOnScrollListener(new RecyclerView.OnScrollListener() {

        private float totalDy = 0;
        private final int scrollValue = AndroidUtilities.dp(100);

        @Override
        public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
            if (newState == RecyclerView.SCROLL_STATE_DRAGGING && highlightMessageId != Integer.MAX_VALUE) {
                highlightMessageId = Integer.MAX_VALUE;
                updateVisibleRows();
            }
        }

        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            checkScrollForLoad(true);
            int firstVisibleItem = chatLayoutManager.findFirstVisibleItemPosition();
            int visibleItemCount = firstVisibleItem == RecyclerView.NO_POSITION ? 0
                    : Math.abs(chatLayoutManager.findLastVisibleItemPosition() - firstVisibleItem) + 1;
            if (visibleItemCount > 0) {
                int totalItemCount = chatAdapter.getItemCount();
                if (firstVisibleItem + visibleItemCount == totalItemCount && forwardEndReached[0]) {
                    showPagedownButton(false, true);
                } else {
                    if (dy > 0) {
                        if (pagedownButton.getTag() == null) {
                            totalDy += dy;
                            if (totalDy > scrollValue) {
                                totalDy = 0;
                                showPagedownButton(true, true);
                                pagedownButtonShowedByScroll = true;
                            }
                        }
                    } else {
                        if (pagedownButtonShowedByScroll && pagedownButton.getTag() != null) {
                            totalDy += dy;
                            if (totalDy < -scrollValue) {
                                showPagedownButton(false, true);
                                totalDy = 0;
                            }
                        }
                    }
                }
            }
            updateMessagesVisisblePart();
        }
    });
    chatListView.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if (openSecretPhotoRunnable != null || SecretPhotoViewer.getInstance().isVisible()) {
                if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL
                        || event.getAction() == MotionEvent.ACTION_POINTER_UP) {
                    AndroidUtilities.runOnUIThread(new Runnable() {
                        @Override
                        public void run() {
                            chatListView.setOnItemClickListener(onItemClickListener);
                        }
                    }, 150);
                    if (openSecretPhotoRunnable != null) {
                        AndroidUtilities.cancelRunOnUIThread(openSecretPhotoRunnable);
                        openSecretPhotoRunnable = null;
                        try {
                            Toast.makeText(v.getContext(), LocaleController.getString("PhotoTip",
                                    kr.wdream.storyshop.R.string.PhotoTip), Toast.LENGTH_SHORT).show();
                        } catch (Exception e) {
                            FileLog.e("tmessages", e);
                        }
                    } else if (SecretPhotoViewer.getInstance().isVisible()) {
                        AndroidUtilities.runOnUIThread(new Runnable() {
                            @Override
                            public void run() {
                                chatListView.setOnItemLongClickListener(onItemLongClickListener);
                                chatListView.setLongClickable(true);
                            }
                        });
                        SecretPhotoViewer.getInstance().closePhoto();
                    }
                } else if (event.getAction() != MotionEvent.ACTION_DOWN) {
                    if (SecretPhotoViewer.getInstance().isVisible()) {
                        return true;
                    } else if (openSecretPhotoRunnable != null) {
                        if (event.getAction() == MotionEvent.ACTION_MOVE) {
                            if (Math.hypot(startX - event.getX(), startY - event.getY()) > AndroidUtilities
                                    .dp(5)) {
                                AndroidUtilities.cancelRunOnUIThread(openSecretPhotoRunnable);
                                openSecretPhotoRunnable = null;
                            }
                        } else {
                            AndroidUtilities.cancelRunOnUIThread(openSecretPhotoRunnable);
                            openSecretPhotoRunnable = null;
                        }
                        chatListView.setOnItemClickListener(onItemClickListener);
                        chatListView.setOnItemLongClickListener(onItemLongClickListener);
                        chatListView.setLongClickable(true);
                    }
                }
            }
            return false;
        }
    });
    chatListView.setOnInterceptTouchListener(new RecyclerListView.OnInterceptTouchListener() {
        @Override
        public boolean onInterceptTouchEvent(MotionEvent event) {
            if (chatActivityEnterView != null && chatActivityEnterView.isEditingMessage()) {
                return true;
            }
            if (actionBar.isActionModeShowed()) {
                return false;
            }
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                int x = (int) event.getX();
                int y = (int) event.getY();
                int count = chatListView.getChildCount();
                for (int a = 0; a < count; a++) {
                    View view = chatListView.getChildAt(a);
                    int top = view.getTop();
                    int bottom = view.getBottom();
                    if (top > y || bottom < y) {
                        continue;
                    }
                    if (!(view instanceof ChatMessageCell)) {
                        break;
                    }
                    final ChatMessageCell cell = (ChatMessageCell) view;
                    final MessageObject messageObject = cell.getMessageObject();
                    if (messageObject == null || messageObject.isSending() || !messageObject.isSecretPhoto()
                            || !cell.getPhotoImage().isInsideImage(x, y - top)) {
                        break;
                    }
                    File file = FileLoader.getPathToMessage(messageObject.messageOwner);
                    if (!file.exists()) {
                        break;
                    }
                    startX = x;
                    startY = y;
                    chatListView.setOnItemClickListener(null);
                    openSecretPhotoRunnable = new Runnable() {
                        @Override
                        public void run() {
                            if (openSecretPhotoRunnable == null) {
                                return;
                            }
                            chatListView.requestDisallowInterceptTouchEvent(true);
                            chatListView.setOnItemLongClickListener(null);
                            chatListView.setLongClickable(false);
                            openSecretPhotoRunnable = null;
                            if (sendSecretMessageRead(messageObject)) {
                                cell.invalidate();
                            }
                            SecretPhotoViewer.getInstance().setParentActivity(getParentActivity());
                            SecretPhotoViewer.getInstance().openPhoto(messageObject);
                        }
                    };
                    AndroidUtilities.runOnUIThread(openSecretPhotoRunnable, 100);
                    return true;
                }
            }
            return false;
        }
    });

    progressView = new FrameLayout(context);
    progressView.setVisibility(View.INVISIBLE);
    contentView.addView(progressView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT,
            LayoutHelper.MATCH_PARENT, Gravity.TOP | Gravity.LEFT));

    View view = new View(context);
    view.setBackgroundResource(kr.wdream.storyshop.R.drawable.system_loader);
    view.getBackground().setColorFilter(Theme.colorFilter);
    progressView.addView(view, LayoutHelper.createFrame(36, 36, Gravity.CENTER));

    ProgressBar progressBar = new ProgressBar(context);
    try {
        progressBar.setIndeterminateDrawable(
                context.getResources().getDrawable(kr.wdream.storyshop.R.drawable.loading_animation));
    } catch (Exception e) {
        //don't promt
    }
    progressBar.setIndeterminate(true);
    AndroidUtilities.setProgressBarAnimationDuration(progressBar, 1500);
    progressView.addView(progressBar, LayoutHelper.createFrame(32, 32, Gravity.CENTER));

    if (ChatObject.isChannel(currentChat)) {
        pinnedMessageView = new FrameLayout(context);
        pinnedMessageView.setTag(1);
        pinnedMessageView.setTranslationY(-AndroidUtilities.dp(50));
        pinnedMessageView.setVisibility(View.GONE);
        pinnedMessageView.setBackgroundResource(kr.wdream.storyshop.R.drawable.blockpanel);
        contentView.addView(pinnedMessageView,
                LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 50, Gravity.TOP | Gravity.LEFT));
        pinnedMessageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                scrollToMessageId(info.pinned_msg_id, 0, true, 0);
            }
        });

        View lineView = new View(context);
        lineView.setBackgroundColor(0xff6c9fd2);
        pinnedMessageView.addView(lineView,
                LayoutHelper.createFrame(2, 32, Gravity.LEFT | Gravity.TOP, 8, 8, 0, 0));

        pinnedMessageImageView = new BackupImageView(context);
        pinnedMessageView.addView(pinnedMessageImageView,
                LayoutHelper.createFrame(32, 32, Gravity.TOP | Gravity.LEFT, 17, 8, 0, 0));

        pinnedMessageNameTextView = new SimpleTextView(context);
        pinnedMessageNameTextView.setTextSize(14);
        pinnedMessageNameTextView.setTextColor(Theme.PINNED_PANEL_NAME_TEXT_COLOR);
        pinnedMessageNameTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
        pinnedMessageView.addView(pinnedMessageNameTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT,
                AndroidUtilities.dp(18), Gravity.TOP | Gravity.LEFT, 18, 7.3f, 52, 0));

        pinnedMessageTextView = new SimpleTextView(context);
        pinnedMessageTextView.setTextSize(14);
        pinnedMessageTextView.setTextColor(Theme.PINNED_PANEL_MESSAGE_TEXT_COLOR);
        pinnedMessageView.addView(pinnedMessageTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT,
                AndroidUtilities.dp(18), Gravity.TOP | Gravity.LEFT, 18, 25.3f, 52, 0));

        ImageView closePinned = new ImageView(context);
        closePinned.setImageResource(kr.wdream.storyshop.R.drawable.miniplayer_close);
        closePinned.setScaleType(ImageView.ScaleType.CENTER);
        pinnedMessageView.addView(closePinned, LayoutHelper.createFrame(48, 48, Gravity.RIGHT | Gravity.TOP));
        closePinned.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (getParentActivity() == null) {
                    return;
                }
                if (currentChat.creator || currentChat.editor) {
                    AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity());
                    builder.setMessage(LocaleController.getString("UnpinMessageAlert",
                            kr.wdream.storyshop.R.string.UnpinMessageAlert));
                    builder.setPositiveButton(LocaleController.getString("OK", kr.wdream.storyshop.R.string.OK),
                            new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialogInterface, int i) {
                                    MessagesController.getInstance().pinChannelMessage(currentChat, 0, false);
                                }
                            });
                    builder.setTitle(
                            LocaleController.getString("AppName", kr.wdream.storyshop.R.string.AppName));
                    builder.setNegativeButton(
                            LocaleController.getString("Cancel", kr.wdream.storyshop.R.string.Cancel), null);
                    showDialog(builder.create());
                } else {
                    SharedPreferences preferences = ApplicationLoader.applicationContext
                            .getSharedPreferences("Notifications", Activity.MODE_PRIVATE);
                    preferences.edit().putInt("pin_" + dialog_id, info.pinned_msg_id).commit();
                    updatePinnedMessageView(true);
                }
            }
        });
    }

    reportSpamView = new LinearLayout(context);
    reportSpamView.setTag(1);
    reportSpamView.setTranslationY(-AndroidUtilities.dp(50));
    reportSpamView.setVisibility(View.GONE);
    reportSpamView.setBackgroundResource(kr.wdream.storyshop.R.drawable.blockpanel);
    contentView.addView(reportSpamView,
            LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 50, Gravity.TOP | Gravity.LEFT));

    addToContactsButton = new TextView(context);
    addToContactsButton.setTextColor(Theme.CHAT_ADD_CONTACT_TEXT_COLOR);
    addToContactsButton.setVisibility(View.GONE);
    addToContactsButton.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
    addToContactsButton.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
    addToContactsButton.setSingleLine(true);
    addToContactsButton.setMaxLines(1);
    addToContactsButton.setPadding(AndroidUtilities.dp(4), 0, AndroidUtilities.dp(4), 0);
    addToContactsButton.setGravity(Gravity.CENTER);
    addToContactsButton
            .setText(LocaleController.getString("AddContactChat", kr.wdream.storyshop.R.string.AddContactChat));
    reportSpamView.addView(addToContactsButton, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT,
            LayoutHelper.MATCH_PARENT, 0.5f, Gravity.LEFT | Gravity.TOP, 0, 0, 0, AndroidUtilities.dp(1)));
    addToContactsButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Bundle args = new Bundle();
            args.putInt("user_id", currentUser.id);
            args.putBoolean("addContact", true);
            presentFragment(new ContactAddActivity(args));
        }
    });

    reportSpamContainer = new FrameLayout(context);
    reportSpamView.addView(reportSpamContainer, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT,
            LayoutHelper.MATCH_PARENT, 1.0f, Gravity.LEFT | Gravity.TOP, 0, 0, 0, AndroidUtilities.dp(1)));

    reportSpamButton = new TextView(context);
    reportSpamButton.setTextColor(Theme.CHAT_REPORT_SPAM_TEXT_COLOR);
    reportSpamButton.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
    reportSpamButton.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
    reportSpamButton.setSingleLine(true);
    reportSpamButton.setMaxLines(1);
    if (currentChat != null) {
        reportSpamButton.setText(LocaleController.getString("ReportSpamAndLeave",
                kr.wdream.storyshop.R.string.ReportSpamAndLeave));
    } else {
        reportSpamButton
                .setText(LocaleController.getString("ReportSpam", kr.wdream.storyshop.R.string.ReportSpam));
    }
    reportSpamButton.setGravity(Gravity.CENTER);
    reportSpamButton.setPadding(AndroidUtilities.dp(50), 0, AndroidUtilities.dp(50), 0);
    reportSpamContainer.addView(reportSpamButton, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT,
            LayoutHelper.MATCH_PARENT, Gravity.LEFT | Gravity.TOP));
    reportSpamButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (getParentActivity() == null) {
                return;
            }
            AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity());
            if (ChatObject.isChannel(currentChat) && !currentChat.megagroup) {
                builder.setMessage(LocaleController.getString("ReportSpamAlertChannel",
                        kr.wdream.storyshop.R.string.ReportSpamAlertChannel));
            } else if (currentChat != null) {
                builder.setMessage(LocaleController.getString("ReportSpamAlertGroup",
                        kr.wdream.storyshop.R.string.ReportSpamAlertGroup));
            } else {
                builder.setMessage(LocaleController.getString("ReportSpamAlert",
                        kr.wdream.storyshop.R.string.ReportSpamAlert));
            }
            builder.setTitle(LocaleController.getString("AppName", kr.wdream.storyshop.R.string.AppName));
            builder.setPositiveButton(LocaleController.getString("OK", kr.wdream.storyshop.R.string.OK),
                    new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {
                            if (currentUser != null) {
                                MessagesController.getInstance().blockUser(currentUser.id);
                            }
                            MessagesController.getInstance().reportSpam(dialog_id, currentUser, currentChat);
                            updateSpamView();
                            if (currentChat != null) {
                                if (ChatObject.isNotInChat(currentChat)) {
                                    MessagesController.getInstance().deleteDialog(dialog_id, 0);
                                } else {
                                    MessagesController.getInstance().deleteUserFromChat((int) -dialog_id,
                                            MessagesController.getInstance()
                                                    .getUser(UserConfig.getClientUserId()),
                                            null);
                                }
                            } else {
                                MessagesController.getInstance().deleteDialog(dialog_id, 0);
                            }
                            finishFragment();
                        }
                    });
            builder.setNegativeButton(LocaleController.getString("Cancel", kr.wdream.storyshop.R.string.Cancel),
                    null);
            showDialog(builder.create());
        }
    });

    ImageView closeReportSpam = new ImageView(context);
    closeReportSpam.setImageResource(kr.wdream.storyshop.R.drawable.miniplayer_close);
    closeReportSpam.setScaleType(ImageView.ScaleType.CENTER);
    reportSpamContainer.addView(closeReportSpam, LayoutHelper.createFrame(48, 48, Gravity.RIGHT | Gravity.TOP));
    closeReportSpam.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            MessagesController.getInstance().hideReportSpam(dialog_id, currentUser, currentChat);
            updateSpamView();
        }
    });

    alertView = new FrameLayout(context);
    alertView.setTag(1);
    alertView.setTranslationY(-AndroidUtilities.dp(50));
    alertView.setVisibility(View.GONE);
    alertView.setBackgroundResource(kr.wdream.storyshop.R.drawable.blockpanel);
    contentView.addView(alertView,
            LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 50, Gravity.TOP | Gravity.LEFT));

    alertNameTextView = new TextView(context);
    alertNameTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
    alertNameTextView.setTextColor(Theme.ALERT_PANEL_NAME_TEXT_COLOR);
    alertNameTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
    alertNameTextView.setSingleLine(true);
    alertNameTextView.setEllipsize(TextUtils.TruncateAt.END);
    alertNameTextView.setMaxLines(1);
    alertView.addView(alertNameTextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT,
            LayoutHelper.WRAP_CONTENT, Gravity.TOP | Gravity.LEFT, 8, 5, 8, 0));

    alertTextView = new TextView(context);
    alertTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
    alertTextView.setTextColor(Theme.ALERT_PANEL_MESSAGE_TEXT_COLOR);
    alertTextView.setSingleLine(true);
    alertTextView.setEllipsize(TextUtils.TruncateAt.END);
    alertTextView.setMaxLines(1);
    alertView.addView(alertTextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT,
            LayoutHelper.WRAP_CONTENT, Gravity.TOP | Gravity.LEFT, 8, 23, 8, 0));

    if (!isBroadcast) {
        mentionContainer = new FrameLayout(context) {

            private Drawable background;

            @Override
            public void onDraw(Canvas canvas) {
                if (mentionListView.getChildCount() <= 0) {
                    return;
                }
                if (mentionsAdapter.isBotContext() && mentionsAdapter.isMediaLayout()
                        && mentionsAdapter.getBotContextSwitch() == null) {
                    background.setBounds(0, mentionListViewScrollOffsetY - AndroidUtilities.dp(4),
                            getMeasuredWidth(), getMeasuredHeight());
                } else {
                    background.setBounds(0, mentionListViewScrollOffsetY - AndroidUtilities.dp(2),
                            getMeasuredWidth(), getMeasuredHeight());
                }
                background.draw(canvas);
            }

            @Override
            public void setBackgroundResource(int resid) {
                background = getContext().getResources().getDrawable(resid);
            }

            @Override
            public void requestLayout() {
                if (mentionListViewIgnoreLayout) {
                    return;
                }
                super.requestLayout();
            }
        };
        mentionContainer.setBackgroundResource(kr.wdream.storyshop.R.drawable.compose_panel);
        mentionContainer.setVisibility(View.GONE);
        mentionContainer.setWillNotDraw(false);
        contentView.addView(mentionContainer,
                LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 110, Gravity.LEFT | Gravity.BOTTOM));

        mentionListView = new RecyclerListView(context) {

            private int lastWidth;
            private int lastHeight;

            @Override
            public boolean onInterceptTouchEvent(MotionEvent event) {
                if (!mentionListViewIsScrolling && mentionListViewScrollOffsetY != 0
                        && event.getY() < mentionListViewScrollOffsetY) {
                    return false;
                }
                boolean result = StickerPreviewViewer.getInstance().onInterceptTouchEvent(event,
                        mentionListView, 0);
                return super.onInterceptTouchEvent(event) || result;
            }

            @Override
            public boolean onTouchEvent(MotionEvent event) {
                if (!mentionListViewIsScrolling && mentionListViewScrollOffsetY != 0
                        && event.getY() < mentionListViewScrollOffsetY) {
                    return false;
                }
                //supress warning
                return super.onTouchEvent(event);
            }

            @Override
            public void requestLayout() {
                if (mentionListViewIgnoreLayout) {
                    return;
                }
                super.requestLayout();
            }

            @Override
            protected void onLayout(boolean changed, int l, int t, int r, int b) {
                int width = r - l;
                int height = b - t;

                int newPosition = -1;
                int newTop = 0;
                if (mentionListView != null && mentionListViewLastViewPosition >= 0 && width == lastWidth
                        && height - lastHeight != 0) {
                    newPosition = mentionListViewLastViewPosition;
                    newTop = mentionListViewLastViewTop + height - lastHeight - getPaddingTop();
                }

                super.onLayout(changed, l, t, r, b);

                if (newPosition != -1) {
                    mentionListViewIgnoreLayout = true;
                    if (mentionsAdapter.isBotContext() && mentionsAdapter.isMediaLayout()) {
                        mentionGridLayoutManager.scrollToPositionWithOffset(newPosition, newTop);
                    } else {
                        mentionLayoutManager.scrollToPositionWithOffset(newPosition, newTop);
                    }
                    super.onLayout(false, l, t, r, b);
                    mentionListViewIgnoreLayout = false;
                }

                lastHeight = height;
                lastWidth = width;
                mentionListViewUpdateLayout();
            }
        };
        mentionListView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return StickerPreviewViewer.getInstance().onTouch(event, mentionListView, 0,
                        mentionsOnItemClickListener);
            }
        });
        mentionListView.setTag(2);
        mentionLayoutManager = new LinearLayoutManager(context) {
            @Override
            public boolean supportsPredictiveItemAnimations() {
                return false;
            }
        };
        mentionLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        mentionGridLayoutManager = new ExtendedGridLayoutManager(context, 100) {

            private Size size = new Size();

            @Override
            protected Size getSizeForItem(int i) {
                if (mentionsAdapter.getBotContextSwitch() != null) {
                    i++;
                }
                Object object = mentionsAdapter.getItem(i);
                if (object instanceof TLRPC.BotInlineResult) {
                    TLRPC.BotInlineResult inlineResult = (TLRPC.BotInlineResult) object;
                    if (inlineResult.document != null) {
                        size.width = inlineResult.document.thumb != null ? inlineResult.document.thumb.w : 100;
                        size.height = inlineResult.document.thumb != null ? inlineResult.document.thumb.h : 100;
                        for (int b = 0; b < inlineResult.document.attributes.size(); b++) {
                            TLRPC.DocumentAttribute attribute = inlineResult.document.attributes.get(b);
                            if (attribute instanceof TLRPC.TL_documentAttributeImageSize
                                    || attribute instanceof TLRPC.TL_documentAttributeVideo) {
                                size.width = attribute.w;
                                size.height = attribute.h;
                                break;
                            }
                        }
                    } else {
                        size.width = inlineResult.w;
                        size.height = inlineResult.h;
                    }
                }
                return size;
            }

            @Override
            protected int getFlowItemCount() {
                if (mentionsAdapter.getBotContextSwitch() != null) {
                    return getItemCount() - 1;
                }
                return super.getFlowItemCount();
            }
        };
        mentionGridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
            @Override
            public int getSpanSize(int position) {
                Object object = mentionsAdapter.getItem(position);
                if (object instanceof TLRPC.TL_inlineBotSwitchPM) {
                    return 100;
                } else {
                    if (mentionsAdapter.getBotContextSwitch() != null) {
                        position--;
                    }
                    return mentionGridLayoutManager.getSpanSizeForItem(position);
                }
            }
        });
        mentionListView.addItemDecoration(new RecyclerView.ItemDecoration() {
            @Override
            public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
                outRect.left = 0;
                outRect.right = 0;
                outRect.top = 0;
                outRect.bottom = 0;
                if (parent.getLayoutManager() == mentionGridLayoutManager) {
                    int position = parent.getChildAdapterPosition(view);
                    if (mentionsAdapter.getBotContextSwitch() != null) {
                        if (position == 0) {
                            return;
                        }
                        position--;
                        if (!mentionGridLayoutManager.isFirstRow(position)) {
                            outRect.top = AndroidUtilities.dp(2);
                        }
                    } else {
                        outRect.top = AndroidUtilities.dp(2);
                    }
                    outRect.right = mentionGridLayoutManager.isLastInRow(position) ? 0 : AndroidUtilities.dp(2);
                }
            }
        });
        mentionListView.setItemAnimator(null);
        mentionListView.setLayoutAnimation(null);
        mentionListView.setClipToPadding(false);
        mentionListView.setLayoutManager(mentionLayoutManager);
        mentionListView.setOverScrollMode(ListView.OVER_SCROLL_NEVER);
        mentionContainer.addView(mentionListView,
                LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));

        mentionListView.setAdapter(mentionsAdapter = new MentionsAdapter(context, false, dialog_id,
                new MentionsAdapter.MentionsAdapterDelegate() {
                    @Override
                    public void needChangePanelVisibility(boolean show) {
                        if (mentionsAdapter.isBotContext() && mentionsAdapter.isMediaLayout()) {
                            mentionListView.setLayoutManager(mentionGridLayoutManager);
                        } else {
                            mentionListView.setLayoutManager(mentionLayoutManager);
                        }
                        if (show) {
                            if (mentionListAnimation != null) {
                                mentionListAnimation.cancel();
                                mentionListAnimation = null;
                            }

                            if (mentionContainer.getVisibility() == View.VISIBLE) {
                                mentionContainer.setAlpha(1.0f);
                                return;
                            }
                            if (mentionsAdapter.isBotContext() && mentionsAdapter.isMediaLayout()) {
                                mentionGridLayoutManager.scrollToPositionWithOffset(0, 10000);
                            } else {
                                mentionLayoutManager.scrollToPositionWithOffset(0, 10000);
                            }
                            if (allowStickersPanel && (!mentionsAdapter.isBotContext()
                                    || (allowContextBotPanel || allowContextBotPanelSecond))) {
                                if (currentEncryptedChat != null && mentionsAdapter.isBotContext()) {
                                    SharedPreferences preferences = ApplicationLoader.applicationContext
                                            .getSharedPreferences("mainconfig", Activity.MODE_PRIVATE);
                                    if (!preferences.getBoolean("secretbot", false)) {
                                        AlertDialog.Builder builder = new AlertDialog.Builder(
                                                getParentActivity());
                                        builder.setTitle(LocaleController.getString("AppName",
                                                kr.wdream.storyshop.R.string.AppName));
                                        builder.setMessage(LocaleController.getString(
                                                "SecretChatContextBotAlert",
                                                kr.wdream.storyshop.R.string.SecretChatContextBotAlert));
                                        builder.setPositiveButton(LocaleController.getString("OK",
                                                kr.wdream.storyshop.R.string.OK), null);
                                        showDialog(builder.create());
                                        preferences.edit().putBoolean("secretbot", true).commit();
                                    }
                                }
                                mentionContainer.setVisibility(View.VISIBLE);
                                mentionContainer.setTag(null);
                                mentionListAnimation = new AnimatorSet();
                                mentionListAnimation.playTogether(
                                        ObjectAnimator.ofFloat(mentionContainer, "alpha", 0.0f, 1.0f));
                                mentionListAnimation.addListener(new AnimatorListenerAdapterProxy() {
                                    @Override
                                    public void onAnimationEnd(Animator animation) {
                                        if (mentionListAnimation != null
                                                && mentionListAnimation.equals(animation)) {
                                            mentionListAnimation = null;
                                        }
                                    }

                                    @Override
                                    public void onAnimationCancel(Animator animation) {
                                        if (mentionListAnimation != null
                                                && mentionListAnimation.equals(animation)) {
                                            mentionListAnimation = null;
                                        }
                                    }
                                });
                                mentionListAnimation.setDuration(200);
                                mentionListAnimation.start();
                            } else {
                                mentionContainer.setAlpha(1.0f);
                                mentionContainer.setVisibility(View.INVISIBLE);
                            }
                        } else {
                            if (mentionListAnimation != null) {
                                mentionListAnimation.cancel();
                                mentionListAnimation = null;
                            }

                            if (mentionContainer.getVisibility() == View.GONE) {
                                return;
                            }
                            if (allowStickersPanel) {
                                mentionListAnimation = new AnimatorSet();
                                mentionListAnimation
                                        .playTogether(ObjectAnimator.ofFloat(mentionContainer, "alpha", 0.0f));
                                mentionListAnimation.addListener(new AnimatorListenerAdapterProxy() {
                                    @Override
                                    public void onAnimationEnd(Animator animation) {
                                        if (mentionListAnimation != null
                                                && mentionListAnimation.equals(animation)) {
                                            mentionContainer.setVisibility(View.GONE);
                                            mentionContainer.setTag(null);
                                            mentionListAnimation = null;
                                        }
                                    }

                                    @Override
                                    public void onAnimationCancel(Animator animation) {
                                        if (mentionListAnimation != null
                                                && mentionListAnimation.equals(animation)) {
                                            mentionListAnimation = null;
                                        }
                                    }
                                });
                                mentionListAnimation.setDuration(200);
                                mentionListAnimation.start();
                            } else {
                                mentionContainer.setTag(null);
                                mentionContainer.setVisibility(View.GONE);
                            }
                        }
                    }

                    @Override
                    public void onContextSearch(boolean searching) {
                        if (chatActivityEnterView != null) {
                            chatActivityEnterView.setCaption(mentionsAdapter.getBotCaption());
                            chatActivityEnterView.showContextProgress(searching);
                        }
                    }

                    @Override
                    public void onContextClick(TLRPC.BotInlineResult result) {
                        if (getParentActivity() == null || result.content_url == null) {
                            return;
                        }
                        if (result.type.equals("video") || result.type.equals("web_player_video")) {
                            BottomSheet.Builder builder = new BottomSheet.Builder(getParentActivity());
                            builder.setCustomView(new WebFrameLayout(getParentActivity(), builder.create(),
                                    result.title != null ? result.title : "", result.description,
                                    result.content_url, result.content_url, result.w, result.h));
                            builder.setUseFullWidth(true);
                            showDialog(builder.create());
                        } else {
                            Browser.openUrl(getParentActivity(), result.content_url);
                        }
                    }
                }));
        if (!ChatObject.isChannel(currentChat) || currentChat != null && currentChat.megagroup) {
            mentionsAdapter.setBotInfo(botInfo);
        }
        mentionsAdapter.setParentFragment(this);
        mentionsAdapter.setChatInfo(info);
        mentionsAdapter.setNeedUsernames(currentChat != null);
        mentionsAdapter.setNeedBotContext(currentEncryptedChat == null
                || AndroidUtilities.getPeerLayerVersion(currentEncryptedChat.layer) >= 46);
        mentionsAdapter.setBotsCount(currentChat != null ? botsCount : 1);
        mentionListView.setOnItemClickListener(
                mentionsOnItemClickListener = new RecyclerListView.OnItemClickListener() {
                    @Override
                    public void onItemClick(View view, int position) {
                        Object object = mentionsAdapter.getItem(position);
                        int start = mentionsAdapter.getResultStartPosition();
                        int len = mentionsAdapter.getResultLength();
                        if (object instanceof TLRPC.User) {
                            TLRPC.User user = (TLRPC.User) object;
                            if (user != null) {
                                if (user.username != null) {
                                    chatActivityEnterView.replaceWithText(start, len,
                                            "@" + user.username + " ");
                                } else {
                                    String name = user.first_name;
                                    if (name == null || name.length() == 0) {
                                        name = user.last_name;
                                    }
                                    Spannable spannable = new SpannableString(name + " ");
                                    spannable.setSpan(new URLSpanUserMention("" + user.id), 0,
                                            spannable.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                                    chatActivityEnterView.replaceWithText(start, len, spannable);
                                }
                            }
                        } else if (object instanceof String) {
                            if (mentionsAdapter.isBotCommands()) {
                                SendMessagesHelper.getInstance().sendMessage((String) object, dialog_id, null,
                                        null, false, null, null, null);
                                chatActivityEnterView.setFieldText("");
                            } else {
                                chatActivityEnterView.replaceWithText(start, len, object + " ");
                            }
                        } else if (object instanceof TLRPC.BotInlineResult) {
                            if (chatActivityEnterView.getFieldText() == null) {
                                return;
                            }
                            TLRPC.BotInlineResult result = (TLRPC.BotInlineResult) object;
                            if (Build.VERSION.SDK_INT >= 16 && (result.type.equals("photo")
                                    && (result.photo != null || result.content_url != null)
                                    || result.type.equals("gif")
                                            && (result.document != null || result.content_url != null)
                                    || result.type.equals("video")
                                            && (result.document != null/* || result.content_url != null*/))) {
                                ArrayList<Object> arrayList = botContextResults = new ArrayList<Object>(
                                        mentionsAdapter.getSearchResultBotContext());
                                PhotoViewer.getInstance().setParentActivity(getParentActivity());
                                PhotoViewer.getInstance().openPhotoForSelect(arrayList,
                                        mentionsAdapter.getItemPosition(position), 3, botContextProvider, null);
                            } else {
                                sendBotInlineResult(result);
                            }
                        } else if (object instanceof TLRPC.TL_inlineBotSwitchPM) {
                            processInlineBotContextPM((TLRPC.TL_inlineBotSwitchPM) object);
                        }
                    }
                });

        mentionListView.setOnItemLongClickListener(new RecyclerListView.OnItemLongClickListener() {
            @Override
            public boolean onItemClick(View view, int position) {
                if (getParentActivity() == null || !mentionsAdapter.isLongClickEnabled()) {
                    return false;
                }
                Object object = mentionsAdapter.getItem(position);
                if (object instanceof String) {
                    if (mentionsAdapter.isBotCommands()) {
                        if (URLSpanBotCommand.enabled) {
                            chatActivityEnterView.setFieldText("");
                            chatActivityEnterView.setCommand(null, (String) object, true,
                                    currentChat != null && currentChat.megagroup);
                            return true;
                        }
                        return false;
                    } else {
                        AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity());
                        builder.setTitle(
                                LocaleController.getString("AppName", kr.wdream.storyshop.R.string.AppName));
                        builder.setMessage(LocaleController.getString("ClearSearch",
                                kr.wdream.storyshop.R.string.ClearSearch));
                        builder.setPositiveButton(LocaleController
                                .getString("ClearButton", kr.wdream.storyshop.R.string.ClearButton)
                                .toUpperCase(), new DialogInterface.OnClickListener() {
                                    @Override
                                    public void onClick(DialogInterface dialogInterface, int i) {
                                        mentionsAdapter.clearRecentHashtags();
                                    }
                                });
                        builder.setNegativeButton(
                                LocaleController.getString("Cancel", kr.wdream.storyshop.R.string.Cancel),
                                null);
                        showDialog(builder.create());
                        return true;
                    }
                }
                return false;
            }
        });

        mentionListView.setOnScrollListener(new RecyclerView.OnScrollListener() {

            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                mentionListViewIsScrolling = newState == RecyclerView.SCROLL_STATE_DRAGGING;
            }

            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                int lastVisibleItem;
                if (mentionsAdapter.isBotContext() && mentionsAdapter.isMediaLayout()) {
                    lastVisibleItem = mentionGridLayoutManager.findLastVisibleItemPosition();
                } else {
                    lastVisibleItem = mentionLayoutManager.findLastVisibleItemPosition();
                }
                int visibleItemCount = lastVisibleItem == RecyclerView.NO_POSITION ? 0 : lastVisibleItem;
                if (visibleItemCount > 0 && lastVisibleItem > mentionsAdapter.getItemCount() - 5) {
                    mentionsAdapter.searchForContextBotForNextOffset();
                }
                mentionListViewUpdateLayout();
            }
        });
    }

    pagedownButton = new FrameLayout(context);
    pagedownButton.setVisibility(View.INVISIBLE);
    contentView.addView(pagedownButton,
            LayoutHelper.createFrame(46, 59, Gravity.RIGHT | Gravity.BOTTOM, 0, 0, 7, 5));
    pagedownButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            if (returnToMessageId > 0) {
                scrollToMessageId(returnToMessageId, 0, true, returnToLoadIndex);
            } else {
                scrollToLastMessage(true);
            }
        }
    });

    ImageView pagedownButtonImage = new ImageView(context);
    pagedownButtonImage.setImageResource(kr.wdream.storyshop.R.drawable.pagedown);
    pagedownButton.addView(pagedownButtonImage,
            LayoutHelper.createFrame(46, 46, Gravity.LEFT | Gravity.BOTTOM));

    pagedownButtonCounter = new TextView(context);
    pagedownButtonCounter.setVisibility(View.INVISIBLE);
    pagedownButtonCounter.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
    pagedownButtonCounter.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 13);
    pagedownButtonCounter.setTextColor(0xffffffff);
    pagedownButtonCounter.setGravity(Gravity.CENTER);
    pagedownButtonCounter.setBackgroundResource(kr.wdream.storyshop.R.drawable.chat_badge);
    pagedownButtonCounter.setMinWidth(AndroidUtilities.dp(23));
    pagedownButtonCounter.setPadding(AndroidUtilities.dp(8), 0, AndroidUtilities.dp(8), AndroidUtilities.dp(1));
    pagedownButton.addView(pagedownButtonCounter,
            LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, 23, Gravity.TOP | Gravity.CENTER_HORIZONTAL));

    chatActivityEnterView = new ChatActivityEnterView(getParentActivity(), contentView, this, true);
    chatActivityEnterView.setDialogId(dialog_id);
    chatActivityEnterView.addToAttachLayout(menuItem);
    chatActivityEnterView.setId(id_chat_compose_panel);
    chatActivityEnterView.setBotsCount(botsCount, hasBotsCommands);
    chatActivityEnterView.setAllowStickersAndGifs(
            currentEncryptedChat == null
                    || AndroidUtilities.getPeerLayerVersion(currentEncryptedChat.layer) >= 23,
            currentEncryptedChat == null
                    || AndroidUtilities.getPeerLayerVersion(currentEncryptedChat.layer) >= 46);
    contentView.addView(chatActivityEnterView, contentView.getChildCount() - 1, LayoutHelper
            .createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.BOTTOM));
    chatActivityEnterView.setDelegate(new ChatActivityEnterView.ChatActivityEnterViewDelegate() {
        @Override
        public void onMessageSend(CharSequence message) {
            moveScrollToLastMessage();
            showReplyPanel(false, null, null, null, false, true);
            if (mentionsAdapter != null) {
                mentionsAdapter.addHashtagsFromMessage(message);
            }
        }

        @Override
        public void onTextChanged(final CharSequence text, boolean bigChange) {
            MediaController.getInstance().setInputFieldHasText(
                    text != null && text.length() != 0 || chatActivityEnterView.isEditingMessage());
            if (stickersAdapter != null && !chatActivityEnterView.isEditingMessage()) {
                stickersAdapter.loadStikersForEmoji(text);
            }
            if (mentionsAdapter != null) {
                mentionsAdapter.searchUsernameOrHashtag(text.toString(),
                        chatActivityEnterView.getCursorPosition(), messages);
            }
            if (waitingForCharaterEnterRunnable != null) {
                AndroidUtilities.cancelRunOnUIThread(waitingForCharaterEnterRunnable);
                waitingForCharaterEnterRunnable = null;
            }
            if (chatActivityEnterView.isMessageWebPageSearchEnabled()
                    && (!chatActivityEnterView.isEditingMessage()
                            || !chatActivityEnterView.isEditingCaption())) {
                if (bigChange) {
                    searchLinks(text, true);
                } else {
                    waitingForCharaterEnterRunnable = new Runnable() {
                        @Override
                        public void run() {
                            if (this == waitingForCharaterEnterRunnable) {
                                searchLinks(text, false);
                                waitingForCharaterEnterRunnable = null;
                            }
                        }
                    };
                    AndroidUtilities.runOnUIThread(waitingForCharaterEnterRunnable,
                            AndroidUtilities.WEB_URL == null ? 3000 : 1000);
                }
            }
        }

        @Override
        public void needSendTyping() {
            MessagesController.getInstance().sendTyping(dialog_id, 0, classGuid);
        }

        @Override
        public void onAttachButtonHidden() {
            if (actionBar.isSearchFieldVisible()) {
                return;
            }
            if (attachItem != null) {
                attachItem.setVisibility(View.VISIBLE);
            }
            if (headerItem != null) {
                headerItem.setVisibility(View.GONE);
            }
        }

        @Override
        public void onAttachButtonShow() {
            if (actionBar.isSearchFieldVisible()) {
                return;
            }
            if (attachItem != null) {
                attachItem.setVisibility(View.GONE);
            }
            if (headerItem != null) {
                headerItem.setVisibility(View.VISIBLE);
            }
        }

        @Override
        public void onMessageEditEnd(boolean loading) {
            if (loading) {
                showEditDoneProgress(true, true);
            } else {
                mentionsAdapter.setNeedBotContext(currentEncryptedChat == null
                        || AndroidUtilities.getPeerLayerVersion(currentEncryptedChat.layer) >= 46);
                chatListView.setOnItemLongClickListener(onItemLongClickListener);
                chatListView.setOnItemClickListener(onItemClickListener);
                chatListView.setClickable(true);
                chatListView.setLongClickable(true);
                mentionsAdapter.setAllowNewMentions(true);
                actionModeTitleContainer.setVisibility(View.GONE);
                selectedMessagesCountTextView.setVisibility(View.VISIBLE);
                chatActivityEnterView.setAllowStickersAndGifs(
                        currentEncryptedChat == null
                                || AndroidUtilities.getPeerLayerVersion(currentEncryptedChat.layer) >= 23,
                        currentEncryptedChat == null
                                || AndroidUtilities.getPeerLayerVersion(currentEncryptedChat.layer) >= 46);
                if (editingMessageObjectReqId != 0) {
                    ConnectionsManager.getInstance().cancelRequest(editingMessageObjectReqId, true);
                    editingMessageObjectReqId = 0;
                }
                actionBar.hideActionMode();
                updatePinnedMessageView(true);
                updateVisibleRows();
            }
        }

        @Override
        public void onWindowSizeChanged(int size) {
            if (size < AndroidUtilities.dp(72) + ActionBar.getCurrentActionBarHeight()) {
                allowStickersPanel = false;
                if (stickersPanel.getVisibility() == View.VISIBLE) {
                    stickersPanel.setVisibility(View.INVISIBLE);
                }
                if (mentionContainer != null && mentionContainer.getVisibility() == View.VISIBLE) {
                    mentionContainer.setVisibility(View.INVISIBLE);
                }
            } else {
                allowStickersPanel = true;
                if (stickersPanel.getVisibility() == View.INVISIBLE) {
                    stickersPanel.setVisibility(View.VISIBLE);
                }
                if (mentionContainer != null && mentionContainer.getVisibility() == View.INVISIBLE
                        && (!mentionsAdapter.isBotContext()
                                || (allowContextBotPanel || allowContextBotPanelSecond))) {
                    mentionContainer.setVisibility(View.VISIBLE);
                    mentionContainer.setTag(null);
                }
            }

            allowContextBotPanel = !chatActivityEnterView.isPopupShowing();
            checkContextBotPanel();
        }

        @Override
        public void onStickersTab(boolean opened) {
            if (emojiButtonRed != null) {
                emojiButtonRed.setVisibility(View.GONE);
            }
            allowContextBotPanelSecond = !opened;
            checkContextBotPanel();
        }
    });

    FrameLayout replyLayout = new FrameLayout(context) {
        @Override
        public void setTranslationY(float translationY) {
            super.setTranslationY(translationY);
            if (chatActivityEnterView != null) {
                chatActivityEnterView.invalidate();
            }
            if (getVisibility() != GONE) {
                int height = getLayoutParams().height;
                if (chatListView != null) {
                    chatListView.setTranslationY(translationY);
                }
                if (progressView != null) {
                    progressView.setTranslationY(translationY);
                }
                if (mentionContainer != null) {
                    mentionContainer.setTranslationY(translationY);
                }
                if (pagedownButton != null) {
                    pagedownButton.setTranslationY(translationY);
                }
            }
        }

        @Override
        public boolean hasOverlappingRendering() {
            return false;
        }

        @Override
        public void setVisibility(int visibility) {
            super.setVisibility(visibility);
            if (visibility == GONE) {
                if (chatListView != null) {
                    chatListView.setTranslationY(0);
                }
                if (progressView != null) {
                    progressView.setTranslationY(0);
                }
                if (mentionContainer != null) {
                    mentionContainer.setTranslationY(0);
                }
                if (pagedownButton != null) {
                    pagedownButton
                            .setTranslationY(pagedownButton.getTag() == null ? AndroidUtilities.dp(100) : 0);
                }
            }
        }
    };
    replyLayout.setClickable(true);
    chatActivityEnterView.addTopView(replyLayout, 48);

    View lineView = new View(context);
    lineView.setBackgroundColor(0xffe8e8e8);
    replyLayout.addView(lineView,
            LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 1, Gravity.BOTTOM | Gravity.LEFT));

    replyIconImageView = new ImageView(context);
    replyIconImageView.setScaleType(ImageView.ScaleType.CENTER);
    replyLayout.addView(replyIconImageView, LayoutHelper.createFrame(52, 46, Gravity.TOP | Gravity.LEFT));

    ImageView imageView = new ImageView(context);
    imageView.setImageResource(kr.wdream.storyshop.R.drawable.delete_reply);
    imageView.setScaleType(ImageView.ScaleType.CENTER);
    replyLayout.addView(imageView,
            LayoutHelper.createFrame(52, 46, Gravity.RIGHT | Gravity.TOP, 0, 0.5f, 0, 0));
    imageView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (forwardingMessages != null) {
                forwardingMessages.clear();
            }
            showReplyPanel(false, null, null, foundWebPage, true, true);
        }
    });

    replyNameTextView = new SimpleTextView(context);
    replyNameTextView.setTextSize(14);
    replyNameTextView.setTextColor(Theme.REPLY_PANEL_NAME_TEXT_COLOR);
    replyNameTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
    replyLayout.addView(replyNameTextView,
            LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 18, Gravity.TOP | Gravity.LEFT, 52, 6, 52, 0));

    replyObjectTextView = new SimpleTextView(context);
    replyObjectTextView.setTextSize(14);
    replyObjectTextView.setTextColor(Theme.REPLY_PANEL_MESSAGE_TEXT_COLOR);
    replyLayout.addView(replyObjectTextView,
            LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 18, Gravity.TOP | Gravity.LEFT, 52, 24, 52, 0));

    replyImageView = new BackupImageView(context);
    replyLayout.addView(replyImageView,
            LayoutHelper.createFrame(34, 34, Gravity.TOP | Gravity.LEFT, 52, 6, 0, 0));

    stickersPanel = new FrameLayout(context);
    stickersPanel.setVisibility(View.GONE);
    contentView.addView(stickersPanel, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, 81.5f,
            Gravity.LEFT | Gravity.BOTTOM, 0, 0, 0, 38));

    stickersListView = new RecyclerListView(context) {
        @Override
        public boolean onInterceptTouchEvent(MotionEvent event) {
            boolean result = StickerPreviewViewer.getInstance().onInterceptTouchEvent(event, stickersListView,
                    0);
            return super.onInterceptTouchEvent(event) || result;
        }
    };
    stickersListView.setTag(3);
    stickersListView.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            return StickerPreviewViewer.getInstance().onTouch(event, stickersListView, 0,
                    stickersOnItemClickListener);
        }
    });
    stickersListView.setDisallowInterceptTouchEvents(true);
    LinearLayoutManager layoutManager = new LinearLayoutManager(context);
    layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
    stickersListView.setLayoutManager(layoutManager);
    stickersListView.setClipToPadding(false);
    stickersListView.setOverScrollMode(RecyclerListView.OVER_SCROLL_NEVER);
    stickersPanel.addView(stickersListView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 78));
    initStickers();

    imageView = new ImageView(context);
    imageView.setImageResource(kr.wdream.storyshop.R.drawable.stickers_back_arrow);
    stickersPanel.addView(imageView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT,
            LayoutHelper.WRAP_CONTENT, Gravity.BOTTOM | Gravity.LEFT, 53, 0, 0, 0));

    searchContainer = new FrameLayout(context);
    searchContainer.setBackgroundResource(kr.wdream.storyshop.R.drawable.compose_panel);
    searchContainer.setVisibility(View.INVISIBLE);
    searchContainer.setFocusable(true);
    searchContainer.setFocusableInTouchMode(true);
    searchContainer.setClickable(true);
    searchContainer.setBackgroundResource(kr.wdream.storyshop.R.drawable.compose_panel);
    searchContainer.setPadding(0, AndroidUtilities.dp(3), 0, 0);
    contentView.addView(searchContainer,
            LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 51, Gravity.BOTTOM));

    searchUpButton = new ImageView(context);
    searchUpButton.setScaleType(ImageView.ScaleType.CENTER);
    searchUpButton.setImageResource(kr.wdream.storyshop.R.drawable.search_up);
    searchContainer.addView(searchUpButton, LayoutHelper.createFrame(48, 48));
    searchUpButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            MessagesSearchQuery.searchMessagesInChat(null, dialog_id, mergeDialogId, classGuid, 1);
        }
    });

    searchDownButton = new ImageView(context);
    searchDownButton.setScaleType(ImageView.ScaleType.CENTER);
    searchDownButton.setImageResource(kr.wdream.storyshop.R.drawable.search_down);
    searchContainer.addView(searchDownButton,
            LayoutHelper.createFrame(48, 48, Gravity.LEFT | Gravity.TOP, 48, 0, 0, 0));
    searchDownButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            MessagesSearchQuery.searchMessagesInChat(null, dialog_id, mergeDialogId, classGuid, 2);
        }
    });

    searchCountText = new SimpleTextView(context);
    searchCountText.setTextColor(Theme.CHAT_SEARCH_COUNT_TEXT_COLOR);
    searchCountText.setTextSize(15);
    searchCountText.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
    searchContainer.addView(searchCountText, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT,
            LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.CENTER_VERTICAL, 108, 0, 0, 0));

    bottomOverlay = new FrameLayout(context);
    bottomOverlay.setVisibility(View.INVISIBLE);
    bottomOverlay.setFocusable(true);
    bottomOverlay.setFocusableInTouchMode(true);
    bottomOverlay.setClickable(true);
    bottomOverlay.setBackgroundResource(kr.wdream.storyshop.R.drawable.compose_panel);
    bottomOverlay.setPadding(0, AndroidUtilities.dp(3), 0, 0);
    contentView.addView(bottomOverlay, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 51, Gravity.BOTTOM));

    bottomOverlayText = new TextView(context);
    bottomOverlayText.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
    bottomOverlayText.setTextColor(Theme.CHAT_BOTTOM_OVERLAY_TEXT_COLOR);
    bottomOverlay.addView(bottomOverlayText,
            LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER));

    bottomOverlayChat = new FrameLayout(context);
    bottomOverlayChat.setBackgroundResource(kr.wdream.storyshop.R.drawable.compose_panel);
    bottomOverlayChat.setPadding(0, AndroidUtilities.dp(3), 0, 0);
    bottomOverlayChat.setVisibility(View.INVISIBLE);
    contentView.addView(bottomOverlayChat,
            LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 51, Gravity.BOTTOM));
    bottomOverlayChat.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            if (getParentActivity() == null) {
                return;
            }
            AlertDialog.Builder builder = null;
            if (currentUser != null && userBlocked) {
                if (currentUser.bot) {
                    String botUserLast = botUser;
                    botUser = null;
                    MessagesController.getInstance().unblockUser(currentUser.id);
                    if (botUserLast != null && botUserLast.length() != 0) {
                        MessagesController.getInstance().sendBotStart(currentUser, botUserLast);
                    } else {
                        SendMessagesHelper.getInstance().sendMessage("/start", dialog_id, null, null, false,
                                null, null, null);
                    }
                } else {
                    builder = new AlertDialog.Builder(getParentActivity());
                    builder.setMessage(LocaleController.getString("AreYouSureUnblockContact",
                            kr.wdream.storyshop.R.string.AreYouSureUnblockContact));
                    builder.setPositiveButton(LocaleController.getString("OK", kr.wdream.storyshop.R.string.OK),
                            new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialogInterface, int i) {
                                    MessagesController.getInstance().unblockUser(currentUser.id);
                                }
                            });
                }
            } else if (currentUser != null && currentUser.bot && botUser != null) {
                if (botUser.length() != 0) {
                    MessagesController.getInstance().sendBotStart(currentUser, botUser);
                } else {
                    SendMessagesHelper.getInstance().sendMessage("/start", dialog_id, null, null, false, null,
                            null, null);
                }
                botUser = null;
                updateBottomOverlay();
            } else {
                if (ChatObject.isChannel(currentChat) && !(currentChat instanceof TLRPC.TL_channelForbidden)) {
                    if (ChatObject.isNotInChat(currentChat)) {
                        MessagesController.getInstance().addUserToChat(currentChat.id,
                                UserConfig.getCurrentUser(), null, 0, null, null);
                    } else {
                        toggleMute(true);
                    }
                } else {
                    builder = new AlertDialog.Builder(getParentActivity());
                    builder.setMessage(LocaleController.getString("AreYouSureDeleteThisChat",
                            kr.wdream.storyshop.R.string.AreYouSureDeleteThisChat));
                    builder.setPositiveButton(LocaleController.getString("OK", kr.wdream.storyshop.R.string.OK),
                            new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialogInterface, int i) {
                                    MessagesController.getInstance().deleteDialog(dialog_id, 0);
                                    finishFragment();
                                }
                            });
                }
            }
            if (builder != null) {
                builder.setTitle(LocaleController.getString("AppName", kr.wdream.storyshop.R.string.AppName));
                builder.setNegativeButton(
                        LocaleController.getString("Cancel", kr.wdream.storyshop.R.string.Cancel), null);
                showDialog(builder.create());
            }
        }
    });

    bottomOverlayChatText = new TextView(context);
    bottomOverlayChatText.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
    bottomOverlayChatText.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
    bottomOverlayChatText.setTextColor(Theme.CHAT_BOTTOM_CHAT_OVERLAY_TEXT_COLOR);
    bottomOverlayChat.addView(bottomOverlayChatText,
            LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER));

    chatAdapter.updateRows();
    if (loading && messages.isEmpty()) {
        progressView.setVisibility(chatAdapter.botInfoRow == -1 ? View.VISIBLE : View.INVISIBLE);
        chatListView.setEmptyView(null);
    } else {
        progressView.setVisibility(View.INVISIBLE);
        chatListView.setEmptyView(emptyViewContainer);
    }

    chatActivityEnterView.setButtons(userBlocked ? null : botButtons);

    if (!AndroidUtilities.isTablet() || AndroidUtilities.isSmallTablet()) {
        contentView.addView(playerView = new PlayerView(context, this), LayoutHelper
                .createFrame(LayoutHelper.MATCH_PARENT, 39, Gravity.TOP | Gravity.LEFT, 0, -36, 0, 0));
    }

    updateContactStatus();
    updateBottomOverlay();
    updateSecretStatus();
    updateSpamView();
    updatePinnedMessageView(true);

    try {
        if (currentEncryptedChat != null && Build.VERSION.SDK_INT >= 23) {
            getParentActivity().getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE,
                    WindowManager.LayoutParams.FLAG_SECURE);
        }
    } catch (Throwable e) {
        FileLog.e("tmessages", e);
    }
    fixLayoutInternal();

    contentView.addView(actionBar);

    return fragmentView;
}