Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 37533d28 authored by Mady Mellor's avatar Mady Mellor
Browse files

Modify the default start position of app bubbles on tablet

It's a bit tricky to pipe the current top bubble through all the
places we getDefaultPosition / getRestingPosition / isStackOnLeft.
These are used by Stack/ExpandedAnimationControllers when the views
are  initialized, before we know which bubble is getting added.

So instead of piping that info to those methods, I'm overriding
that info when an app bubble is added (and the resting position
hasn't been set previously).

Test: atest BubblePositionerTest BubbleDataTest
Test: manual - reboot the device so we don't have a previous resting
               location for bubbles
             - get an app bubble
             => observe in LTR the app bubble appears on the right
             => observe in RTL the app bubble appears on the left
             - test with a normal chat bubble and it should be the
               opposite (left in RTL, right in RTL).
Bug: 283910436
Change-Id: I4d32608dfd726384237e3963d469a4ad4db1e43d
parent 250f036d
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -852,7 +852,10 @@ public class Bubble implements BubbleViewProvider {
        return mAppIntent;
    }

    boolean isAppBubble() {
    /**
     * Returns whether this bubble is from an app versus a notification.
     */
    public boolean isAppBubble() {
        return mIsAppBubble;
    }

+30 −6
Original line number Diff line number Diff line
@@ -653,14 +653,38 @@ public class BubblePositioner {
    }

    /**
     * @return the stack position to use if we don't have a saved location or if user education
     * is being shown.
     * Returns whether the {@link #getRestingPosition()} is equal to the default start position
     * initialized for bubbles, if {@code true} this means the user hasn't moved the bubble
     * from the initial start position (or they haven't received a bubble yet).
     */
    public boolean hasUserModifiedDefaultPosition() {
        PointF defaultStart = getDefaultStartPosition();
        return mRestingStackPosition != null
                && !mRestingStackPosition.equals(defaultStart);
    }

    /**
     * Returns the stack position to use if we don't have a saved location or if user education
     * is being shown, for a normal bubble.
     */
    public PointF getDefaultStartPosition() {
        // Start on the left if we're in LTR, right otherwise.
        final boolean startOnLeft =
                mContext.getResources().getConfiguration().getLayoutDirection()
                        != LAYOUT_DIRECTION_RTL;
        return getDefaultStartPosition(false /* isAppBubble */);
    }

    /**
     * The stack position to use if we don't have a saved location or if user education
     * is being shown.
     *
     * @param isAppBubble whether this start position is for an app bubble or not.
     */
    public PointF getDefaultStartPosition(boolean isAppBubble) {
        final int layoutDirection = mContext.getResources().getConfiguration().getLayoutDirection();
        // Normal bubbles start on the left if we're in LTR, right otherwise.
        // TODO (b/294284894): update language around "app bubble" here
        // App bubbles start on the right in RTL, left otherwise.
        final boolean startOnLeft = isAppBubble
                ? layoutDirection == LAYOUT_DIRECTION_RTL
                : layoutDirection != LAYOUT_DIRECTION_RTL;
        final RectF allowableStackPositionRegion = getAllowableStackPositionRegion(
                1 /* default starts with 1 bubble */);
        if (isLargeScreen()) {
+16 −3
Original line number Diff line number Diff line
@@ -1770,13 +1770,26 @@ public class BubbleStackView extends FrameLayout
            return;
        }

        if (firstBubble && bubble.isAppBubble() && !mPositioner.hasUserModifiedDefaultPosition()) {
            // TODO (b/294284894): update language around "app bubble" here
            // If it's an app bubble and we don't have a previous resting position, update the
            // controllers to use the default position for the app bubble (it'd be different from
            // the position initialized with the controllers originally).
            PointF startPosition =  mPositioner.getDefaultStartPosition(true /* isAppBubble */);
            mStackOnLeftOrWillBe = mPositioner.isStackOnLeft(startPosition);
            mStackAnimationController.setStackPosition(startPosition);
            mExpandedAnimationController.setCollapsePoint(startPosition);
            // Set the translation x so that this bubble will animate in from the same side they
            // expand / collapse on.
            bubble.getIconView().setTranslationX(startPosition.x);
        } else if (firstBubble) {
            mStackOnLeftOrWillBe = mStackAnimationController.isStackOnLeftSide();
        }

        mBubbleContainer.addView(bubble.getIconView(), 0,
                new FrameLayout.LayoutParams(mPositioner.getBubbleSize(),
                        mPositioner.getBubbleSize()));

        if (firstBubble) {
            mStackOnLeftOrWillBe = mStackAnimationController.isStackOnLeftSide();
        }
        // Set the dot position to the opposite of the side the stack is resting on, since the stack
        // resting slightly off-screen would result in the dot also being off-screen.
        bubble.getIconView().setDotBadgeOnLeft(!mStackOnLeftOrWillBe /* onLeft */);
+15 −7
Original line number Diff line number Diff line
@@ -132,6 +132,16 @@ public class ExpandedAnimationController

    private BubbleStackView mBubbleStackView;

    /**
     * Whether the individual bubble has been dragged out of the row of bubbles far enough to cause
     * the rest of the bubbles to animate to fill the gap.
     */
    private boolean mBubbleDraggedOutEnough = false;

    /** End action to run when the lead bubble's expansion animation completes. */
    @Nullable
    private Runnable mLeadBubbleEndAction;

    public ExpandedAnimationController(BubblePositioner positioner,
            Runnable onBubbleAnimatedOutAction, BubbleStackView stackView) {
        mPositioner = positioner;
@@ -142,14 +152,12 @@ public class ExpandedAnimationController
    }

    /**
     * Whether the individual bubble has been dragged out of the row of bubbles far enough to cause
     * the rest of the bubbles to animate to fill the gap.
     * Overrides the collapse location without actually collapsing the stack.
     * @param point the new collapse location.
     */
    private boolean mBubbleDraggedOutEnough = false;

    /** End action to run when the lead bubble's expansion animation completes. */
    @Nullable
    private Runnable mLeadBubbleEndAction;
    public void setCollapsePoint(PointF point) {
        mCollapsePoint = point;
    }

    /**
     * Animates expanding the bubbles into a row along the top of the screen, optionally running an
+0 −3
Original line number Diff line number Diff line
@@ -298,9 +298,6 @@ public class StackAnimationController extends

    /** Whether the stack is on the left side of the screen. */
    public boolean isStackOnLeftSide() {
        if (mLayout == null || !isStackPositionSet()) {
            return true; // Default to left, which is where it starts by default.
        }
        return mPositioner.isStackOnLeft(mStackPosition);
    }

Loading