16c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira/*
26c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira * Copyright (C) 2012 Google Inc.
36c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira * Licensed to The Android Open Source Project.
46c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira *
56c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira * Licensed under the Apache License, Version 2.0 (the "License");
66c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira * you may not use this file except in compliance with the License.
76c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira * You may obtain a copy of the License at
86c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira *
96c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira *      http://www.apache.org/licenses/LICENSE-2.0
106c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira *
116c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira * Unless required by applicable law or agreed to in writing, software
126c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira * distributed under the License is distributed on an "AS IS" BASIS,
136c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
146c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira * See the License for the specific language governing permissions and
156c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira * limitations under the License.
166c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira */
176c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira
186c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereirapackage com.android.mail.ui;
196c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira
20067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereiraimport android.animation.Animator.AnimatorListener;
21370f868c834861e7732faaa9bdd07a0fa0105596Andy Huangimport android.animation.ObjectAnimator;
226c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereiraimport android.content.Context;
23d064972c4a032f3c5cfcb236aa470273f7ac2ce0mindypimport android.content.res.Resources;
246c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereiraimport android.util.AttributeSet;
25bf232c3735f65b1a4746943e4a134e59e36f0bdePaul Westbrookimport android.view.View;
26bf232c3735f65b1a4746943e4a134e59e36f0bdePaul Westbrookimport android.view.View.OnClickListener;
27067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereiraimport android.view.animation.DecelerateInterpolator;
28a538984fcc19e7624f2650b119ede39bf1f35846mindypimport android.widget.FrameLayout;
296c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereiraimport android.widget.TextView;
306c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira
316c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereiraimport com.android.mail.R;
32042a530b2296487fa5899a3e871214ac4a47e3d8Andy Huangimport com.android.mail.analytics.Analytics;
33bf232c3735f65b1a4746943e4a134e59e36f0bdePaul Westbrookimport com.android.mail.browse.ConversationCursor;
34370f868c834861e7732faaa9bdd07a0fa0105596Andy Huangimport com.android.mail.browse.ConversationItemView;
356c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereiraimport com.android.mail.providers.Account;
366c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereiraimport com.android.mail.providers.Conversation;
37bcd784c09f649785a3dda1d6d9a6d5f58ba41770Mindy Pereiraimport com.android.mail.providers.Folder;
38c59dd8270215f97d39697dae9e69976bcfe3642bmindypimport com.android.mail.utils.Utils;
396c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereiraimport com.google.common.collect.ImmutableList;
406c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira
416a6deb20dbbea543ccf093487d26dea4ac4f9cd4mindyppublic class LeaveBehindItem extends FrameLayout implements OnClickListener, SwipeableItemView {
426c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira
43d3367499e56116854ed637b1036fd71057ac0f49Mindy Pereira    private ToastBarOperation mUndoOp;
446c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira    private Account mAccount;
456c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira    private AnimatedAdapter mAdapter;
4684f9b5c60dc023570202859ba1d30cf9cb5e6e7aMindy Pereira    private TextView mText;
47a538984fcc19e7624f2650b119ede39bf1f35846mindyp    private View mSwipeableContent;
48eb88ececd0a53c4e956240b7b619da6410e2d356mindyp    public int position;
49370f868c834861e7732faaa9bdd07a0fa0105596Andy Huang    private Conversation mData;
50370f868c834861e7732faaa9bdd07a0fa0105596Andy Huang    private int mWidth;
51370f868c834861e7732faaa9bdd07a0fa0105596Andy Huang    /**
52370f868c834861e7732faaa9bdd07a0fa0105596Andy Huang     * The height of this view. Typically, this matches the height of the originating
53370f868c834861e7732faaa9bdd07a0fa0105596Andy Huang     * {@link ConversationItemView}.
54370f868c834861e7732faaa9bdd07a0fa0105596Andy Huang     */
55370f868c834861e7732faaa9bdd07a0fa0105596Andy Huang    private int mHeight;
56370f868c834861e7732faaa9bdd07a0fa0105596Andy Huang    private int mAnimatedHeight = -1;
57370f868c834861e7732faaa9bdd07a0fa0105596Andy Huang    private boolean mAnimating;
58370f868c834861e7732faaa9bdd07a0fa0105596Andy Huang    private boolean mFadingInText;
59370f868c834861e7732faaa9bdd07a0fa0105596Andy Huang    private boolean mInert = false;
60370f868c834861e7732faaa9bdd07a0fa0105596Andy Huang    private ObjectAnimator mFadeIn;
61370f868c834861e7732faaa9bdd07a0fa0105596Andy Huang
62db58fcbfb9ddba5cc85b5af20b490bfe7ad028d5Mindy Pereira    private static int sShrinkAnimationDuration = -1;
6384f9b5c60dc023570202859ba1d30cf9cb5e6e7aMindy Pereira    private static int sFadeInAnimationDuration = -1;
64d064972c4a032f3c5cfcb236aa470273f7ac2ce0mindyp    private static float sScrollSlop;
65e5707f86f340797d5ee1535bff86d331715cbce9Scott Kennedy    private static final float OPAQUE = 1.0f;
66e5707f86f340797d5ee1535bff86d331715cbce9Scott Kennedy    private static final float TRANSPARENT = 0.0f;
676c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira
686c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira    public LeaveBehindItem(Context context) {
696c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira        this(context, null);
706c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira    }
716c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira
726c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira    public LeaveBehindItem(Context context, AttributeSet attrs) {
736c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira        this(context, attrs, -1);
746c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira    }
756c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira
766c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira    public LeaveBehindItem(Context context, AttributeSet attrs, int defStyle) {
776c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira        super(context, attrs, defStyle);
78e5707f86f340797d5ee1535bff86d331715cbce9Scott Kennedy        loadStatics(context);
79e5707f86f340797d5ee1535bff86d331715cbce9Scott Kennedy    }
80e5707f86f340797d5ee1535bff86d331715cbce9Scott Kennedy
81e5707f86f340797d5ee1535bff86d331715cbce9Scott Kennedy    private static void loadStatics(final Context context) {
82db58fcbfb9ddba5cc85b5af20b490bfe7ad028d5Mindy Pereira        if (sShrinkAnimationDuration == -1) {
83d064972c4a032f3c5cfcb236aa470273f7ac2ce0mindyp            Resources res = context.getResources();
84d064972c4a032f3c5cfcb236aa470273f7ac2ce0mindyp            sShrinkAnimationDuration = res.getInteger(R.integer.shrink_animation_duration);
85d064972c4a032f3c5cfcb236aa470273f7ac2ce0mindyp            sFadeInAnimationDuration = res.getInteger(R.integer.fade_in_animation_duration);
86d064972c4a032f3c5cfcb236aa470273f7ac2ce0mindyp            sScrollSlop = res.getInteger(R.integer.leaveBehindSwipeScrollSlop);
87db58fcbfb9ddba5cc85b5af20b490bfe7ad028d5Mindy Pereira        }
886c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira    }
896c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira
906c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira    @Override
916c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira    public void onClick(View v) {
922b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy        final int id = v.getId();
932b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy        if (id == R.id.swipeable_content) {
942b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy            if (mAccount.undoUri != null && !mInert) {
952b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy                // NOTE: We might want undo to return the messages affected,
962b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy                // in which case the resulting cursor might be interesting...
972b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy                // TODO: Use UIProvider.SEQUENCE_QUERY_PARAMETER to indicate
982b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy                // the set of commands to undo
992b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy                mAdapter.setSwipeUndo(true);
1002b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy                mAdapter.clearLeaveBehind(getConversationId());
1012b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy                ConversationCursor cursor = mAdapter.getConversationCursor();
1022b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy                if (cursor != null) {
1032b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy                    cursor.undo(getContext(), mAccount.undoUri);
1046c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira                }
1052b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy            }
1066c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira        }
1076c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira    }
1086c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira
109370f868c834861e7732faaa9bdd07a0fa0105596Andy Huang    public void bind(int pos, Account account, AnimatedAdapter adapter,
110370f868c834861e7732faaa9bdd07a0fa0105596Andy Huang            ToastBarOperation undoOp, Conversation target, Folder folder, int height) {
111eb88ececd0a53c4e956240b7b619da6410e2d356mindyp        position = pos;
1126c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira        mUndoOp = undoOp;
1136c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira        mAccount = account;
1146c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira        mAdapter = adapter;
115370f868c834861e7732faaa9bdd07a0fa0105596Andy Huang        mHeight = height;
11662d7962b2b4d73f8414bbab1f42952442ac25be0Andy Huang        setData(target);
117a538984fcc19e7624f2650b119ede39bf1f35846mindyp        mSwipeableContent = findViewById(R.id.swipeable_content);
11820e75dc2738ef22bda10e50df265fd5526a82676mindyp        // Listen on swipeable content so that we can show both the undo icon
11920e75dc2738ef22bda10e50df265fd5526a82676mindyp        // and button text as selected since they set duplicateParentState to true
12020e75dc2738ef22bda10e50df265fd5526a82676mindyp        mSwipeableContent.setOnClickListener(this);
121e5707f86f340797d5ee1535bff86d331715cbce9Scott Kennedy        mSwipeableContent.setAlpha(TRANSPARENT);
122160f8a7166daa4e300157527bc3e65ffcd7a0c1cAndrew Sapperstein        mText = ((TextView) findViewById(R.id.undo_description_text));
123c59dd8270215f97d39697dae9e69976bcfe3642bmindyp        mText.setText(Utils.convertHtmlToPlainText(mUndoOp
124bcd784c09f649785a3dda1d6d9a6d5f58ba41770Mindy Pereira                .getSingularDescription(getContext(), folder)));
12520e75dc2738ef22bda10e50df265fd5526a82676mindyp        mText.setOnClickListener(this);
1266c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira    }
1276c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira
1286c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira    public void commit() {
129215d2a465dd17139d4c8cce426ae8c8ff556746emindyp        ConversationCursor cursor = mAdapter.getConversationCursor();
130215d2a465dd17139d4c8cce426ae8c8ff556746emindyp        if (cursor != null) {
1319e2d407fdafeb874e640eb84017feaf784309075Scott Kennedy            cursor.delete(ImmutableList.of(getData()));
132c3180e021cdf6aa13545682b7eda4f38a6baf51aMindy Pereira        }
13362d7962b2b4d73f8414bbab1f42952442ac25be0Andy Huang    }
13462d7962b2b4d73f8414bbab1f42952442ac25be0Andy Huang
135a538984fcc19e7624f2650b119ede39bf1f35846mindyp    @Override
1369a604d0a4bbf41e9c287c5138b3f10db4b60f6c2Mindy Pereira    public void dismiss() {
1379a604d0a4bbf41e9c287c5138b3f10db4b60f6c2Mindy Pereira        if (mAdapter != null) {
138042a530b2296487fa5899a3e871214ac4a47e3d8Andy Huang            Analytics.getInstance().sendEvent("list_swipe", "leave_behind", null, 0);
1396a6deb20dbbea543ccf093487d26dea4ac4f9cd4mindyp            mAdapter.fadeOutSpecificLeaveBehindItem(mData.id);
1409a604d0a4bbf41e9c287c5138b3f10db4b60f6c2Mindy Pereira            mAdapter.notifyDataSetChanged();
1419a604d0a4bbf41e9c287c5138b3f10db4b60f6c2Mindy Pereira        }
1429a604d0a4bbf41e9c287c5138b3f10db4b60f6c2Mindy Pereira    }
1439a604d0a4bbf41e9c287c5138b3f10db4b60f6c2Mindy Pereira
14462d7962b2b4d73f8414bbab1f42952442ac25be0Andy Huang    public long getConversationId() {
14562d7962b2b4d73f8414bbab1f42952442ac25be0Andy Huang        return getData().id;
1466c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira    }
1476c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira
148bf232c3735f65b1a4746943e4a134e59e36f0bdePaul Westbrook    @Override
1492102b2c87a6cb39bc63fb7eff13dda64da56b72eMark Wei    public SwipeableView getSwipeableView() {
1502102b2c87a6cb39bc63fb7eff13dda64da56b72eMark Wei        return SwipeableView.from(mSwipeableContent);
1516c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira    }
1526c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira
1536c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira    @Override
154a538984fcc19e7624f2650b119ede39bf1f35846mindyp    public boolean canChildBeDismissed() {
1553b5e82b06a0af3f5ddf3667de9a2aa26eeb5f24bmindyp        return !mInert;
1566c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira    }
15779e6a0830cc23deb9ba7be07d4ec5b5235a3398bMindy Pereira
15879e6a0830cc23deb9ba7be07d4ec5b5235a3398bMindy Pereira    public LeaveBehindData getLeaveBehindData() {
159370f868c834861e7732faaa9bdd07a0fa0105596Andy Huang        return new LeaveBehindData(getData(), mUndoOp, mHeight);
16079e6a0830cc23deb9ba7be07d4ec5b5235a3398bMindy Pereira    }
16179e6a0830cc23deb9ba7be07d4ec5b5235a3398bMindy Pereira
162067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira    /**
1634d4531a63cff536d2ee1a2929d0820981df8516amindyp     * Animate shrinking the height of this view.
164067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira     * @param listener the method to call when the animation is done
165067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira     */
1663b965d78774a42358ce6bbdcc43b4c8df130a60eScott Kennedy    public void startShrinkAnimation(AnimatorListener listener) {
1678f39702ca9f9bea23d27a46a288cd6f6660de447Mindy Pereira        if (!mAnimating) {
1688f39702ca9f9bea23d27a46a288cd6f6660de447Mindy Pereira            mAnimating = true;
169370f868c834861e7732faaa9bdd07a0fa0105596Andy Huang            final ObjectAnimator height = ObjectAnimator.ofInt(this, "animatedHeight", mHeight, 0);
170370f868c834861e7732faaa9bdd07a0fa0105596Andy Huang            setMinimumHeight(mHeight);
171370f868c834861e7732faaa9bdd07a0fa0105596Andy Huang            mWidth = getWidth();
1727af43c93d4ca90bb0a43ec790a434c95128cc99fmindyp            height.setInterpolator(new DecelerateInterpolator(1.75f));
1738f39702ca9f9bea23d27a46a288cd6f6660de447Mindy Pereira            height.setDuration(sShrinkAnimationDuration);
1743b5e82b06a0af3f5ddf3667de9a2aa26eeb5f24bmindyp            height.addListener(listener);
1758f39702ca9f9bea23d27a46a288cd6f6660de447Mindy Pereira            height.start();
1768f39702ca9f9bea23d27a46a288cd6f6660de447Mindy Pereira        }
177067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira    }
178067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira
1794d4531a63cff536d2ee1a2929d0820981df8516amindyp    /**
1804d4531a63cff536d2ee1a2929d0820981df8516amindyp     * Set the alpha value for the text displayed by this item.
1814d4531a63cff536d2ee1a2929d0820981df8516amindyp     */
1824d4531a63cff536d2ee1a2929d0820981df8516amindyp    public void setTextAlpha(float alpha) {
183e5707f86f340797d5ee1535bff86d331715cbce9Scott Kennedy        if (mSwipeableContent.getAlpha() > TRANSPARENT) {
1844d4531a63cff536d2ee1a2929d0820981df8516amindyp            mSwipeableContent.setAlpha(alpha);
1854d4531a63cff536d2ee1a2929d0820981df8516amindyp        }
1867af43c93d4ca90bb0a43ec790a434c95128cc99fmindyp    }
1877af43c93d4ca90bb0a43ec790a434c95128cc99fmindyp
188ac2ef8104955233d0f2854fa20bc285ba1ea1043mindyp    /**
189ac2ef8104955233d0f2854fa20bc285ba1ea1043mindyp     * Kick off the animation to fade in the leave behind text.
190ac2ef8104955233d0f2854fa20bc285ba1ea1043mindyp     * @param delay Whether to delay the start of the animation or not.
191ac2ef8104955233d0f2854fa20bc285ba1ea1043mindyp     */
192a44babdac4e070034f35d984d06c675af8fee81fmindyp    public void startFadeInTextAnimation(int delay) {
1934d4531a63cff536d2ee1a2929d0820981df8516amindyp        // If this thing isn't already fully visible AND its not already animating...
1944d4531a63cff536d2ee1a2929d0820981df8516amindyp        if (!mFadingInText && mSwipeableContent.getAlpha() != OPAQUE) {
19584f9b5c60dc023570202859ba1d30cf9cb5e6e7aMindy Pereira            mFadingInText = true;
196e5707f86f340797d5ee1535bff86d331715cbce9Scott Kennedy            mFadeIn = startFadeInTextAnimation(mSwipeableContent, delay);
1977af43c93d4ca90bb0a43ec790a434c95128cc99fmindyp        }
1987af43c93d4ca90bb0a43ec790a434c95128cc99fmindyp    }
1997af43c93d4ca90bb0a43ec790a434c95128cc99fmindyp
200a44babdac4e070034f35d984d06c675af8fee81fmindyp    /**
201e5707f86f340797d5ee1535bff86d331715cbce9Scott Kennedy     * Creates and starts the animator for the fade-in text
202e5707f86f340797d5ee1535bff86d331715cbce9Scott Kennedy     * @param delay The delay, in milliseconds, before starting the animation
203e5707f86f340797d5ee1535bff86d331715cbce9Scott Kennedy     * @return The {@link ObjectAnimator}
204e5707f86f340797d5ee1535bff86d331715cbce9Scott Kennedy     */
205e5707f86f340797d5ee1535bff86d331715cbce9Scott Kennedy    public static ObjectAnimator startFadeInTextAnimation(final View view, final int delay) {
206e5707f86f340797d5ee1535bff86d331715cbce9Scott Kennedy        loadStatics(view.getContext());
207e5707f86f340797d5ee1535bff86d331715cbce9Scott Kennedy
208e5707f86f340797d5ee1535bff86d331715cbce9Scott Kennedy        final float start = TRANSPARENT;
209e5707f86f340797d5ee1535bff86d331715cbce9Scott Kennedy        final float end = OPAQUE;
210e5707f86f340797d5ee1535bff86d331715cbce9Scott Kennedy        final ObjectAnimator fadeIn = ObjectAnimator.ofFloat(view, "alpha", start, end);
211e5707f86f340797d5ee1535bff86d331715cbce9Scott Kennedy        view.setAlpha(TRANSPARENT);
212e5707f86f340797d5ee1535bff86d331715cbce9Scott Kennedy        if (delay != 0) {
213e5707f86f340797d5ee1535bff86d331715cbce9Scott Kennedy            fadeIn.setStartDelay(delay);
214e5707f86f340797d5ee1535bff86d331715cbce9Scott Kennedy        }
215e5707f86f340797d5ee1535bff86d331715cbce9Scott Kennedy        fadeIn.setInterpolator(new DecelerateInterpolator(OPAQUE));
216e5707f86f340797d5ee1535bff86d331715cbce9Scott Kennedy        fadeIn.setDuration(sFadeInAnimationDuration / 2);
217e5707f86f340797d5ee1535bff86d331715cbce9Scott Kennedy        fadeIn.start();
218e5707f86f340797d5ee1535bff86d331715cbce9Scott Kennedy
219e5707f86f340797d5ee1535bff86d331715cbce9Scott Kennedy        return fadeIn;
220e5707f86f340797d5ee1535bff86d331715cbce9Scott Kennedy    }
221e5707f86f340797d5ee1535bff86d331715cbce9Scott Kennedy
222e5707f86f340797d5ee1535bff86d331715cbce9Scott Kennedy    /**
223a44babdac4e070034f35d984d06c675af8fee81fmindyp     * Increase the overall time before fading in a the text description this view.
224a44babdac4e070034f35d984d06c675af8fee81fmindyp     * @param newDelay Amount of total delay the user should see
225a44babdac4e070034f35d984d06c675af8fee81fmindyp     */
226a44babdac4e070034f35d984d06c675af8fee81fmindyp    public void increaseFadeInDelay(int newDelay) {
227a44babdac4e070034f35d984d06c675af8fee81fmindyp        // If this thing isn't already fully visible AND its not already animating...
228a44babdac4e070034f35d984d06c675af8fee81fmindyp        if (!mFadingInText && mSwipeableContent.getAlpha() != OPAQUE) {
229a44babdac4e070034f35d984d06c675af8fee81fmindyp            mFadingInText = true;
230a44babdac4e070034f35d984d06c675af8fee81fmindyp            long delay = mFadeIn.getStartDelay();
231a44babdac4e070034f35d984d06c675af8fee81fmindyp            if (newDelay == delay || mFadeIn.isRunning()) {
232a44babdac4e070034f35d984d06c675af8fee81fmindyp                return;
233a44babdac4e070034f35d984d06c675af8fee81fmindyp            }
234a44babdac4e070034f35d984d06c675af8fee81fmindyp            mFadeIn.cancel();
235a44babdac4e070034f35d984d06c675af8fee81fmindyp            mFadeIn.setStartDelay(newDelay - delay);
236a44babdac4e070034f35d984d06c675af8fee81fmindyp            mFadeIn.start();
237a44babdac4e070034f35d984d06c675af8fee81fmindyp        }
238a44babdac4e070034f35d984d06c675af8fee81fmindyp    }
239a44babdac4e070034f35d984d06c675af8fee81fmindyp
240a44babdac4e070034f35d984d06c675af8fee81fmindyp    /**
241a44babdac4e070034f35d984d06c675af8fee81fmindyp     * Cancel fading in the text description for this view.
242a44babdac4e070034f35d984d06c675af8fee81fmindyp     */
2434d4531a63cff536d2ee1a2929d0820981df8516amindyp    public void cancelFadeInTextAnimation() {
2447af43c93d4ca90bb0a43ec790a434c95128cc99fmindyp        if (mFadeIn != null) {
2454d4531a63cff536d2ee1a2929d0820981df8516amindyp            mFadingInText = false;
2467af43c93d4ca90bb0a43ec790a434c95128cc99fmindyp            mFadeIn.cancel();
24784f9b5c60dc023570202859ba1d30cf9cb5e6e7aMindy Pereira        }
24884f9b5c60dc023570202859ba1d30cf9cb5e6e7aMindy Pereira    }
24984f9b5c60dc023570202859ba1d30cf9cb5e6e7aMindy Pereira
250a44babdac4e070034f35d984d06c675af8fee81fmindyp    /**
251a44babdac4e070034f35d984d06c675af8fee81fmindyp     * Cancel fading in the text description for this view only if it the
252a44babdac4e070034f35d984d06c675af8fee81fmindyp     * animation hasn't already started.
253a44babdac4e070034f35d984d06c675af8fee81fmindyp     * @return whether the animation was cancelled
254a44babdac4e070034f35d984d06c675af8fee81fmindyp     */
255a44babdac4e070034f35d984d06c675af8fee81fmindyp    public boolean cancelFadeInTextAnimationIfNotStarted() {
256a44babdac4e070034f35d984d06c675af8fee81fmindyp        // The animation was started, so don't cancel and restart it.
257a44babdac4e070034f35d984d06c675af8fee81fmindyp        if (mFadeIn != null && !mFadeIn.isRunning()) {
258a44babdac4e070034f35d984d06c675af8fee81fmindyp            cancelFadeInTextAnimation();
259a44babdac4e070034f35d984d06c675af8fee81fmindyp            return true;
260a44babdac4e070034f35d984d06c675af8fee81fmindyp        }
261a44babdac4e070034f35d984d06c675af8fee81fmindyp        return false;
262a44babdac4e070034f35d984d06c675af8fee81fmindyp    }
263a44babdac4e070034f35d984d06c675af8fee81fmindyp
264067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira    public void setData(Conversation conversation) {
265067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira        mData = conversation;
266067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira    }
267067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira
268067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira    public Conversation getData() {
269067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira        return mData;
270067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira    }
271067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira
272067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira    @Override
273067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
274067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira        if (mAnimatedHeight != -1) {
275db58fcbfb9ddba5cc85b5af20b490bfe7ad028d5Mindy Pereira            setMeasuredDimension(mWidth, mAnimatedHeight);
276067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira        } else {
277370f868c834861e7732faaa9bdd07a0fa0105596Andy Huang            // override the height MeasureSpec to ensure this is sized up at the desired height
278370f868c834861e7732faaa9bdd07a0fa0105596Andy Huang            super.onMeasure(widthMeasureSpec,
279370f868c834861e7732faaa9bdd07a0fa0105596Andy Huang                    MeasureSpec.makeMeasureSpec(mHeight, MeasureSpec.EXACTLY));
280067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira        }
281067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira    }
282067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira
283067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira    // Used by animator
284067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira    @SuppressWarnings("unused")
285067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira    public void setAnimatedHeight(int height) {
286067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira        mAnimatedHeight = height;
287067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira        requestLayout();
288067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira    }
289b66c010296d35e111f4c5952ff826ddcf1cbe444mindyp
290d064972c4a032f3c5cfcb236aa470273f7ac2ce0mindyp    @Override
291d064972c4a032f3c5cfcb236aa470273f7ac2ce0mindyp    public float getMinAllowScrollDistance() {
292d064972c4a032f3c5cfcb236aa470273f7ac2ce0mindyp        return sScrollSlop;
293d064972c4a032f3c5cfcb236aa470273f7ac2ce0mindyp    }
294e358ed5c4ed1b172f5eae98f97919a8e471c98dcmindyp
2956a6deb20dbbea543ccf093487d26dea4ac4f9cd4mindyp    public void makeInert() {
2967af43c93d4ca90bb0a43ec790a434c95128cc99fmindyp        if (mFadeIn != null) {
2977af43c93d4ca90bb0a43ec790a434c95128cc99fmindyp            mFadeIn.cancel();
2987af43c93d4ca90bb0a43ec790a434c95128cc99fmindyp        }
2996a6deb20dbbea543ccf093487d26dea4ac4f9cd4mindyp        mSwipeableContent.setVisibility(View.GONE);
3003b5e82b06a0af3f5ddf3667de9a2aa26eeb5f24bmindyp        mInert = true;
301e358ed5c4ed1b172f5eae98f97919a8e471c98dcmindyp    }
3024d4531a63cff536d2ee1a2929d0820981df8516amindyp
3034d4531a63cff536d2ee1a2929d0820981df8516amindyp    public void cancelFadeOutText() {
3044d4531a63cff536d2ee1a2929d0820981df8516amindyp        mSwipeableContent.setAlpha(OPAQUE);
3054d4531a63cff536d2ee1a2929d0820981df8516amindyp    }
306a44babdac4e070034f35d984d06c675af8fee81fmindyp
307a44babdac4e070034f35d984d06c675af8fee81fmindyp    public boolean isAnimating() {
308a44babdac4e070034f35d984d06c675af8fee81fmindyp        return this.mFadingInText;
309a44babdac4e070034f35d984d06c675af8fee81fmindyp    }
3104d4531a63cff536d2ee1a2929d0820981df8516amindyp}