Merge "Remove more unused resources" into jb-ub-mail-ur10
diff --git a/assets/script.js b/assets/script.js
index b30305a..0449d00 100644
--- a/assets/script.js
+++ b/assets/script.js
@@ -592,7 +592,7 @@
}
// add an extra one to mark the top/bottom of the last message footer spacer
overlayTops[i] = "" + prevBodyBottom;
- overlayBottoms[i] = "" + document.body.offsetHeight;
+ overlayBottoms[i] = "" + document.documentElement.scrollHeight;
window.mail.onWebContentGeometryChange(overlayTops, overlayBottoms);
}
diff --git a/res/drawable-hdpi/snap_header_gradient.9.png b/res/drawable-hdpi/snap_header_gradient.9.png
index 08d4ff1..1216021 100644
--- a/res/drawable-hdpi/snap_header_gradient.9.png
+++ b/res/drawable-hdpi/snap_header_gradient.9.png
Binary files differ
diff --git a/res/drawable-mdpi/snap_header_gradient.9.png b/res/drawable-mdpi/snap_header_gradient.9.png
index f847fb7..288e677 100644
--- a/res/drawable-mdpi/snap_header_gradient.9.png
+++ b/res/drawable-mdpi/snap_header_gradient.9.png
Binary files differ
diff --git a/res/drawable-xhdpi/snap_header_gradient.9.png b/res/drawable-xhdpi/snap_header_gradient.9.png
index 05a2af8..135c10d 100644
--- a/res/drawable-xhdpi/snap_header_gradient.9.png
+++ b/res/drawable-xhdpi/snap_header_gradient.9.png
Binary files differ
diff --git a/res/layout/conversation_outbox_tip_view.xml b/res/layout/conversation_outbox_tip_view.xml
new file mode 100644
index 0000000..8a1951f
--- /dev/null
+++ b/res/layout/conversation_outbox_tip_view.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) 2013 Google Inc. -->
+<com.android.mail.ui.ConversationsInOutboxTipView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="@color/swiped_bg_color" >
+
+ <LinearLayout
+ android:id="@+id/swipeable_content"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="@drawable/conversation_read_selector"
+ android:orientation="horizontal" >
+
+ <TextView
+ android:id="@+id/outbox"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:layout_marginBottom="12dp"
+ android:layout_marginTop="12dp"
+ android:layout_marginLeft="16dp"
+ android:layout_marginStart="16dp"
+ android:layout_weight="1"
+ android:duplicateParentState="true"
+ android:fontFamily="sans-serif-light"
+ android:textColor="@color/teaser_main_text"
+ android:textSize="16sp" />
+
+ <View
+ android:id="@+id/dismiss_separator"
+ android:layout_width="1dip"
+ android:layout_height="match_parent"
+ android:background="@color/teaser_main_text"
+ android:layout_marginTop="16dp"
+ android:layout_marginBottom="16dp"
+ android:layout_marginLeft="16dp"
+ android:layout_marginStart="16dp" />
+
+ <ImageButton
+ android:id="@+id/dismiss_button"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:background="?android:attr/selectableItemBackground"
+ android:clickable="true"
+ android:paddingLeft="20dip"
+ android:paddingStart="20dip"
+ android:paddingRight="28dip"
+ android:paddingEnd="28dip"
+ android:scaleType="center"
+ android:contentDescription="@string/dismiss_tip_hover_text"
+ android:src="@drawable/ic_cancel_holo_light" />
+ </LinearLayout>
+
+</com.android.mail.ui.ConversationsInOutboxTipView>
diff --git a/res/layout/conversation_pager.xml b/res/layout/conversation_pager.xml
index 623d35d..a85ece6 100644
--- a/res/layout/conversation_pager.xml
+++ b/res/layout/conversation_pager.xml
@@ -22,14 +22,4 @@
android:layout_height="match_parent"
android:visibility="gone">
- <android.support.v4.view.PagerTitleStrip
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="bottom"
- android:paddingLeft="16dp"
- android:paddingRight="16dp"
- android:textAppearance="?android:attr/textAppearanceSmallInverse"
- android:includeFontPadding="false"
- android:background="@color/position_bar_background" />
-
</com.android.mail.browse.ConversationPager>
\ No newline at end of file
diff --git a/res/values/dimen.xml b/res/values/dimen.xml
index 0ca763c..28fe4f4 100644
--- a/res/values/dimen.xml
+++ b/res/values/dimen.xml
@@ -90,8 +90,6 @@
<dimen name="widget_margin_right">0dip</dimen>
<dimen name="widget_margin_bottom">0dip</dimen>
<dimen name="search_view_width">400dip</dimen>
- <dimen name="toast_bar_bottom_margin">4dip</dimen>
- <dimen name="toast_bar_bottom_margin_in_conversation">24dip</dimen>
<dimen name="wait_padding">16dp</dimen>
<integer name="chips_max_lines">2</integer>
<dimen name="tile_letter_font_size">33dp</dimen>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 20c2108..0128e4f 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -939,4 +939,9 @@
<!-- This is used as a parameter to another string and combined reads
"Turn on in Account settings." [CHAR LIMIT=250] -->
<string name="account_settings_param">Account settings</string>
+
+ <!-- Hint text that there are X number of unsent messages users
+ Outbox. [CHAR LIMIT=250] -->
+ <string name="unsent_messages_in_outbox"><xliff:g id="number">%1$s</xliff:g>
+ unsent in <xliff:g id="outbox">%2$s</xliff:g></string>
</resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index f33247a..c354d3a 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -396,6 +396,7 @@
<item name="android:layout_gravity">bottom</item>
<item name="android:layout_marginLeft">4dip</item>
<item name="android:layout_marginRight">4dip</item>
+ <item name="android:layout_marginBottom">4dip</item>
<item name="android:orientation">horizontal</item>
<item name="android:gravity">center_vertical</item>
<item name="android:background">@drawable/panel_undo_holo</item>
diff --git a/src/com/android/mail/browse/ConversationItemView.java b/src/com/android/mail/browse/ConversationItemView.java
index 7ae9534..b6e8af4 100644
--- a/src/com/android/mail/browse/ConversationItemView.java
+++ b/src/com/android/mail/browse/ConversationItemView.java
@@ -590,6 +590,11 @@
// reset the grid, as the newly bound item may have a different attachment count
mAttachmentsView.setCount(0);
}
+
+ if (header.conversation.id != mHeader.conversation.id) {
+ // Stop the photo flip animation
+ mPhotoFlipAnimator.stopAnimation();
+ }
}
mCoordinates = null;
mHeader = header;
diff --git a/src/com/android/mail/browse/ConversationPagerAdapter.java b/src/com/android/mail/browse/ConversationPagerAdapter.java
index e3b5712..70620b4 100644
--- a/src/com/android/mail/browse/ConversationPagerAdapter.java
+++ b/src/com/android/mail/browse/ConversationPagerAdapter.java
@@ -27,7 +27,6 @@
import android.support.v4.view.ViewPager;
import android.view.ViewGroup;
-import com.android.mail.R;
import com.android.mail.providers.Account;
import com.android.mail.providers.Conversation;
import com.android.mail.providers.Folder;
@@ -242,29 +241,6 @@
}
@Override
- public CharSequence getPageTitle(int position) {
- final String title;
- final int currentPosition = mPager.getCurrentItem();
- final Cursor cursor = getCursor();
- if (isPagingDisabled(cursor)) {
- title = null;
- } else if (position == currentPosition) {
- int total = getCount();
- if (mController != null) {
- final Folder f = mController.getFolder();
- if (f != null && f.totalCount > total) {
- total = f.totalCount;
- }
- }
- title = mResources.getString(R.string.conversation_count, position + 1, total);
- } else {
- title = mResources.getString(position < currentPosition ?
- R.string.conversation_newer : R.string.conversation_older);
- }
- return title;
- }
-
- @Override
public Parcelable saveState() {
LogUtils.d(LOG_TAG, "IN PagerAdapter.saveState. this=%s", this);
Bundle state = (Bundle) super.saveState(); // superclass uses a Bundle
diff --git a/src/com/android/mail/preferences/AccountPreferences.java b/src/com/android/mail/preferences/AccountPreferences.java
index 7746330..b71b212 100644
--- a/src/com/android/mail/preferences/AccountPreferences.java
+++ b/src/com/android/mail/preferences/AccountPreferences.java
@@ -48,6 +48,11 @@
*/
public static final String ACCOUNT_SYNC_OFF_DISMISSES = "num-of-dismisses-account-sync-off";
+ /**
+ * The count reported last time the "X unseen in Outbox" tip was displayed.
+ */
+ public static final String LAST_SEEN_OUTBOX_COUNT = "last-seen-outbox-count";
+
public static final ImmutableSet<String> BACKUP_KEYS =
new ImmutableSet.Builder<String>().add(NOTIFICATIONS_ENABLED).build();
}
@@ -128,4 +133,12 @@
PreferenceKeys.ACCOUNT_SYNC_OFF_DISMISSES, 0);
getEditor().putInt(PreferenceKeys.ACCOUNT_SYNC_OFF_DISMISSES, value + 1).apply();
}
+
+ public int getLastSeenOutboxCount() {
+ return getSharedPreferences().getInt(PreferenceKeys.LAST_SEEN_OUTBOX_COUNT, 0);
+ }
+
+ public void setLastSeenOutboxCount(final int count) {
+ getEditor().putInt(PreferenceKeys.LAST_SEEN_OUTBOX_COUNT, count).apply();
+ }
}
diff --git a/src/com/android/mail/ui/AbstractActivityController.java b/src/com/android/mail/ui/AbstractActivityController.java
index 43bcd74..edc1e33 100644
--- a/src/com/android/mail/ui/AbstractActivityController.java
+++ b/src/com/android/mail/ui/AbstractActivityController.java
@@ -3850,7 +3850,6 @@
* @param replaceVisibleToast if true, this should replace any currently visible toast.
*/
protected final void showErrorToast(final Folder folder, boolean replaceVisibleToast) {
- mToastBar.setConversationMode(false);
final ActionClickedListener listener;
final int actionTextResourceId;
diff --git a/src/com/android/mail/ui/ActionableToastBar.java b/src/com/android/mail/ui/ActionableToastBar.java
index 4cdcd20..5beade7 100644
--- a/src/com/android/mail/ui/ActionableToastBar.java
+++ b/src/com/android/mail/ui/ActionableToastBar.java
@@ -23,7 +23,6 @@
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
-import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
@@ -39,8 +38,6 @@
private Animator mHideAnimation;
private final Runnable mRunnable;
private final Handler mFadeOutHandler;
- private final int mBottomMarginSizeInConversation;
- private final int mBottomMarginSize;
/** How long toast will last in ms */
private static final long TOAST_LIFETIME = 15*1000L;
@@ -76,10 +73,6 @@
}
}
};
- mBottomMarginSize = context.getResources()
- .getDimensionPixelSize(R.dimen.toast_bar_bottom_margin);
- mBottomMarginSizeInConversation = context.getResources().getDimensionPixelSize(
- R.dimen.toast_bar_bottom_margin_in_conversation);
LayoutInflater.from(context).inflate(R.layout.actionable_toast_row, this, true);
}
@@ -95,18 +88,6 @@
}
/**
- * Tells the view that it will be appearing in the conversation pane
- * and should adjust its layout parameters accordingly.
- * @param isInConversationMode true if the view will be shown in the conversation view
- */
- public void setConversationMode(boolean isInConversationMode) {
- final FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) getLayoutParams();
- params.bottomMargin = isInConversationMode ? mBottomMarginSizeInConversation
- : mBottomMarginSize;
- setLayoutParams(params);
- }
-
- /**
* Displays the toast bar and makes it visible. Allows the setting of
* parameters to customize the display.
* @param listener Performs some action when the action button is clicked.
diff --git a/src/com/android/mail/ui/ConversationListHelper.java b/src/com/android/mail/ui/ConversationListHelper.java
index 6f93f4e..aa2a122 100644
--- a/src/com/android/mail/ui/ConversationListHelper.java
+++ b/src/com/android/mail/ui/ConversationListHelper.java
@@ -33,27 +33,35 @@
*/
public ArrayList<ConversationSpecialItemView> makeConversationListSpecialViews(
final Context context, final ControllableActivity activity, final Account account) {
+ final ConversationSyncDisabledTipView conversationSyncDisabledTipView =
+ (ConversationSyncDisabledTipView) LayoutInflater.from(context)
+ .inflate(R.layout.conversation_sync_disabled_tip_view, null);
+ conversationSyncDisabledTipView.bindAccount(account);
+
+ final ConversationsInOutboxTipView conversationsInOutboxTipView =
+ (ConversationsInOutboxTipView) LayoutInflater.from(context)
+ .inflate(R.layout.conversation_outbox_tip_view, null);
+ conversationsInOutboxTipView.bind(account, activity.getFolderSelector());
+
// Conversation photo teaser view
final ConversationPhotoTeaserView conversationPhotoTeaser =
(ConversationPhotoTeaserView) LayoutInflater.from(context)
.inflate(R.layout.conversation_photo_teaser_view, null);
-
// Long press to select tip
final ConversationLongPressTipView conversationLongPressTipView =
(ConversationLongPressTipView) LayoutInflater.from(context)
.inflate(R.layout.conversation_long_press_to_select_tip_view, null);
- // Sync is off warning tip
- final ConversationSyncDisabledTipView conversationSyncDisabledTipView =
- (ConversationSyncDisabledTipView) LayoutInflater.from(context)
- .inflate(R.layout.conversation_sync_disabled_tip_view, null);
- conversationSyncDisabledTipView.bindAccount(account);
-
+ // Order matters. If a and b are added in order itemViews.add(a), itemViews.add(b),
+ // they will appear in conversation list as:
+ // b
+ // a
final ArrayList<ConversationSpecialItemView> itemViews = Lists.newArrayList();
itemViews.add(conversationPhotoTeaser);
itemViews.add(conversationLongPressTipView);
itemViews.add(conversationSyncDisabledTipView);
+ itemViews.add(conversationsInOutboxTipView);
return itemViews;
}
}
diff --git a/src/com/android/mail/ui/ConversationLongPressTipView.java b/src/com/android/mail/ui/ConversationLongPressTipView.java
index a6f5f7b..ee7d67c 100644
--- a/src/com/android/mail/ui/ConversationLongPressTipView.java
+++ b/src/com/android/mail/ui/ConversationLongPressTipView.java
@@ -22,7 +22,9 @@
import com.android.mail.preferences.MailPrefs;
import com.android.mail.providers.Folder;
+import android.animation.Animator;
import android.animation.ObjectAnimator;
+import android.animation.Animator.AnimatorListener;
import android.app.LoaderManager;
import android.content.Context;
import android.content.res.Resources;
@@ -112,8 +114,7 @@
@Override
public int getPosition() {
// We want this teaser to go before the first real conversation
- // If another teaser wants position 0, we will want position 1
- return mAdapter.getPositionOffset(0);
+ return 0;
}
@Override
@@ -191,6 +192,28 @@
ObjectAnimator.ofInt(this, "animatedHeight", start, end);
heightAnimator.setInterpolator(new DecelerateInterpolator(2.0f));
heightAnimator.setDuration(sShrinkAnimationDuration);
+ heightAnimator.addListener(new AnimatorListener() {
+ @Override
+ public void onAnimationStart(final Animator animation) {
+ // Do nothing
+ }
+
+ @Override
+ public void onAnimationRepeat(final Animator animation) {
+ // Do nothing
+ }
+
+ @Override
+ public void onAnimationEnd(final Animator animation) {
+ // We should no longer exist, so notify the adapter
+ mAdapter.notifyDataSetChanged();
+ }
+
+ @Override
+ public void onAnimationCancel(final Animator animation) {
+ // Do nothing
+ }
+ });
heightAnimator.start();
}
diff --git a/src/com/android/mail/ui/ConversationPhotoTeaserView.java b/src/com/android/mail/ui/ConversationPhotoTeaserView.java
index 84e6bc1..c358028 100644
--- a/src/com/android/mail/ui/ConversationPhotoTeaserView.java
+++ b/src/com/android/mail/ui/ConversationPhotoTeaserView.java
@@ -1,6 +1,8 @@
package com.android.mail.ui;
+import android.animation.Animator;
import android.animation.ObjectAnimator;
+import android.animation.Animator.AnimatorListener;
import android.app.LoaderManager;
import android.content.Context;
import android.content.res.Resources;
@@ -203,6 +205,28 @@
ObjectAnimator.ofInt(this, "animatedHeight", start, end);
heightAnimator.setInterpolator(new DecelerateInterpolator(2.0f));
heightAnimator.setDuration(sShrinkAnimationDuration);
+ heightAnimator.addListener(new AnimatorListener() {
+ @Override
+ public void onAnimationStart(final Animator animation) {
+ // Do nothing
+ }
+
+ @Override
+ public void onAnimationRepeat(final Animator animation) {
+ // Do nothing
+ }
+
+ @Override
+ public void onAnimationEnd(final Animator animation) {
+ // We should no longer exist, so notify the adapter
+ mAdapter.notifyDataSetChanged();
+ }
+
+ @Override
+ public void onAnimationCancel(final Animator animation) {
+ // Do nothing
+ }
+ });
heightAnimator.start();
}
diff --git a/src/com/android/mail/ui/ConversationSyncDisabledTipView.java b/src/com/android/mail/ui/ConversationSyncDisabledTipView.java
index f462b06..1203e4e 100644
--- a/src/com/android/mail/ui/ConversationSyncDisabledTipView.java
+++ b/src/com/android/mail/ui/ConversationSyncDisabledTipView.java
@@ -16,7 +16,9 @@
package com.android.mail.ui;
+import android.animation.Animator;
import android.animation.ObjectAnimator;
+import android.animation.Animator.AnimatorListener;
import android.app.LoaderManager;
import android.content.ContentResolver;
import android.content.Context;
@@ -267,8 +269,7 @@
@Override
public int getPosition() {
// We want this teaser to go before the first real conversation
- // If another teaser wants position 0, we will want position 1
- return mAdapter.getPositionOffset(0);
+ return 0;
}
@Override
@@ -291,7 +292,6 @@
@Override
public void onCabModeEntered() {
- dismiss();
}
@Override
@@ -351,6 +351,28 @@
ObjectAnimator.ofInt(this, "animatedHeight", start, end);
heightAnimator.setInterpolator(new DecelerateInterpolator(2.0f));
heightAnimator.setDuration(sShrinkAnimationDuration);
+ heightAnimator.addListener(new AnimatorListener() {
+ @Override
+ public void onAnimationStart(final Animator animation) {
+ // Do nothing
+ }
+
+ @Override
+ public void onAnimationRepeat(final Animator animation) {
+ // Do nothing
+ }
+
+ @Override
+ public void onAnimationEnd(final Animator animation) {
+ // We should no longer exist, so notify the adapter
+ mAdapter.notifyDataSetChanged();
+ }
+
+ @Override
+ public void onAnimationCancel(final Animator animation) {
+ // Do nothing
+ }
+ });
heightAnimator.start();
}
diff --git a/src/com/android/mail/ui/ConversationsInOutboxTipView.java b/src/com/android/mail/ui/ConversationsInOutboxTipView.java
new file mode 100644
index 0000000..fb492c1
--- /dev/null
+++ b/src/com/android/mail/ui/ConversationsInOutboxTipView.java
@@ -0,0 +1,330 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.mail.ui;
+
+import android.animation.Animator;
+import android.animation.ObjectAnimator;
+import android.animation.Animator.AnimatorListener;
+import android.app.LoaderManager;
+import android.app.LoaderManager.LoaderCallbacks;
+import android.content.Context;
+import android.content.Loader;
+import android.content.res.Resources;
+import android.os.Bundle;
+import android.text.SpannableString;
+import android.text.style.TextAppearanceSpan;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.animation.DecelerateInterpolator;
+import android.widget.FrameLayout;
+import android.widget.TextView;
+
+import com.android.mail.R;
+import com.android.mail.browse.ConversationCursor;
+import com.android.mail.content.ObjectCursor;
+import com.android.mail.content.ObjectCursorLoader;
+import com.android.mail.preferences.AccountPreferences;
+import com.android.mail.providers.Account;
+import com.android.mail.providers.Folder;
+import com.android.mail.providers.UIProvider;
+
+/**
+ * Tip that is displayed in conversation list of 'Sent' folder whenever there are
+ * one or more messages in the Outbox.
+ */
+public class ConversationsInOutboxTipView extends FrameLayout
+ implements ConversationSpecialItemView, SwipeableItemView {
+
+ private static int sScrollSlop = 0;
+ private static int sShrinkAnimationDuration;
+
+ private Account mAccount = null;
+ private AccountPreferences mAccountPreferences;
+ private AnimatedAdapter mAdapter;
+ private LoaderManager mLoaderManager;
+ private FolderSelector mFolderSelector;
+ private Folder mOutbox;
+ private int mOutboxCount = -1;
+
+ private View mSwipeableContent;
+ private TextView mText;
+
+ private int mAnimatedHeight = -1;
+
+ private static final int LOADER_FOLDER_LIST =
+ AbstractActivityController.LAST_FRAGMENT_LOADER_ID + 100;
+
+ public ConversationsInOutboxTipView(final Context context) {
+ this(context, null);
+ }
+
+ public ConversationsInOutboxTipView(final Context context, final AttributeSet attrs) {
+ this(context, attrs, -1);
+ }
+
+ public ConversationsInOutboxTipView(
+ final Context context, final AttributeSet attrs, final int defStyle) {
+ super(context, attrs, defStyle);
+
+ final Resources resources = context.getResources();
+
+ if (sScrollSlop == 0) {
+ sScrollSlop = resources.getInteger(R.integer.swipeScrollSlop);
+ sShrinkAnimationDuration = resources.getInteger(
+ R.integer.shrink_animation_duration);
+ }
+ }
+
+ public void bind(final Account account, final FolderSelector folderSelector) {
+ mAccount = account;
+ mAccountPreferences = AccountPreferences.get(getContext(), account.name);
+ mFolderSelector = folderSelector;
+ }
+
+ @Override
+ public void onGetView() {
+ // Do nothing
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ mSwipeableContent = findViewById(R.id.swipeable_content);
+
+ mText = (TextView) findViewById(R.id.outbox);
+
+ findViewById(R.id.outbox).setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ goToOutbox();
+ }
+ });
+
+ findViewById(R.id.dismiss_button).setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ dismiss();
+ }
+ });
+ }
+
+ private void goToOutbox() {
+ if (mOutbox != null) {
+ mFolderSelector.onFolderSelected(mOutbox);
+ }
+ }
+
+ @Override
+ public void onUpdate(String account, Folder folder, ConversationCursor cursor) {
+ if (mLoaderManager != null && folder != null) {
+ if ((folder.type & UIProvider.FolderType.SENT) > 0) {
+ // Only display this tip if user is viewing the Sent folder
+ mLoaderManager.initLoader(LOADER_FOLDER_LIST, null, mFolderListLoaderCallbacks);
+ }
+ }
+ }
+
+ private final LoaderCallbacks<ObjectCursor<Folder>> mFolderListLoaderCallbacks =
+ new LoaderManager.LoaderCallbacks<ObjectCursor<Folder>>() {
+ @Override
+ public void onLoaderReset(final Loader<ObjectCursor<Folder>> loader) {
+ // Do nothing
+ }
+
+ @Override
+ public void onLoadFinished(final Loader<ObjectCursor<Folder>> loader,
+ final ObjectCursor<Folder> data) {
+ if (data != null && data.moveToFirst()) {
+ do {
+ final Folder folder = data.getModel();
+ if ((folder.type & UIProvider.FolderType.OUTBOX) > 0) {
+ mOutbox = folder;
+ onOutboxTotalCount(folder.totalCount);
+ }
+ } while (data.moveToNext());
+ }
+ }
+
+ @Override
+ public Loader<ObjectCursor<Folder>> onCreateLoader(final int id, final Bundle args) {
+ // This loads all folders in order to find 'Outbox'. We could consider adding a new
+ // query to load folders of a given type to make this more efficient, but should be
+ // okay for now since this is triggered infrequently (only when user visits the
+ // 'Sent' folder).
+ final ObjectCursorLoader<Folder> loader = new ObjectCursorLoader<Folder>(getContext(),
+ mAccount.folderListUri, UIProvider.FOLDERS_PROJECTION, Folder.FACTORY);
+ return loader;
+ }
+ };
+
+ private void onOutboxTotalCount(int outboxCount) {
+ if (mOutboxCount != outboxCount) {
+ mOutboxCount = outboxCount;
+ if (outboxCount > 0) {
+ if (mText != null) {
+ updateText();
+ }
+ }
+ }
+ if (outboxCount == 0) {
+ // Clear the last seen count, so that new messages in Outbox will always cause this
+ // tip to appear again.
+ mAccountPreferences.setLastSeenOutboxCount(0);
+ }
+ }
+
+ private void updateText() {
+ // Update the display text to reflect current mOutboxCount
+ final Resources resources = getContext().getResources();
+ final String subString = mOutbox.name;
+ final String entireString = resources.getString(
+ R.string.unsent_messages_in_outbox,
+ String.valueOf(mOutboxCount), subString);
+ final SpannableString text = new SpannableString(entireString);
+ final int index = entireString.indexOf(subString);
+ text.setSpan(
+ new TextAppearanceSpan(getContext(), R.style.LinksInTipTextAppearance),
+ index,
+ index + subString.length(),
+ 0);
+ mText.setText(text);
+ }
+
+ @Override
+ public boolean getShouldDisplayInList() {
+ return (mOutboxCount > 0 && mOutboxCount != mAccountPreferences.getLastSeenOutboxCount());
+ }
+
+ @Override
+ public int getPosition() {
+ // We want this teaser to go before the first real conversation
+ return 0;
+ }
+
+ @Override
+ public void setAdapter(AnimatedAdapter adapter) {
+ mAdapter = adapter;
+ }
+
+ @Override
+ public void bindLoaderManager(LoaderManager loaderManager) {
+ mLoaderManager = loaderManager;
+ }
+
+ @Override
+ public void cleanup() {
+ }
+
+ @Override
+ public void onConversationSelected() {
+ // DO NOTHING
+ }
+
+ @Override
+ public void onCabModeEntered() {
+ }
+
+ @Override
+ public void onCabModeExited() {
+ }
+
+ @Override
+ public boolean acceptsUserTaps() {
+ return true;
+ }
+
+ @Override
+ public void dismiss() {
+ // Do not show this tip again until we have a new count. Note this is not quite
+ // ideal behavior since after a user dismisses an "1 unsent in outbox" tip,
+ // the message stuck in Outbox could get sent, and a new one gets stuck.
+ // If the user checks back on on Sent folder then, we don't reshow the message since count
+ // itself hasn't changed, but ideally we should since it's a different message than before.
+ // However if user checks the Sent folder in between (when there were 0 messages
+ // in Outbox), the preference is cleared (see {@link onOutboxTotalCount}).
+ mAccountPreferences.setLastSeenOutboxCount(mOutboxCount);
+
+ startDestroyAnimation();
+ }
+
+ @Override
+ public SwipeableView getSwipeableView() {
+ return SwipeableView.from(mSwipeableContent);
+ }
+
+ @Override
+ public boolean canChildBeDismissed() {
+ return true;
+ }
+
+ @Override
+ public float getMinAllowScrollDistance() {
+ return sScrollSlop;
+ }
+
+ private void startDestroyAnimation() {
+ final int start = getHeight();
+ final int end = 0;
+ mAnimatedHeight = start;
+ final ObjectAnimator heightAnimator =
+ ObjectAnimator.ofInt(this, "animatedHeight", start, end);
+ heightAnimator.setInterpolator(new DecelerateInterpolator(2.0f));
+ heightAnimator.setDuration(sShrinkAnimationDuration);
+ heightAnimator.addListener(new AnimatorListener() {
+ @Override
+ public void onAnimationStart(final Animator animation) {
+ // Do nothing
+ }
+
+ @Override
+ public void onAnimationRepeat(final Animator animation) {
+ // Do nothing
+ }
+
+ @Override
+ public void onAnimationEnd(final Animator animation) {
+ // We should no longer exist, so notify the adapter
+ mAdapter.notifyDataSetChanged();
+ }
+
+ @Override
+ public void onAnimationCancel(final Animator animation) {
+ // Do nothing
+ }
+ });
+ heightAnimator.start();
+ }
+
+ /**
+ * This method is used by the animator. It is explicitly kept in proguard.flags to prevent it
+ * from being removed, inlined, or obfuscated.
+ * Edit ./vendor/unbundled/packages/apps/UnifiedGmail/proguard.flags
+ * In the future, we want to use @Keep
+ */
+ public void setAnimatedHeight(final int height) {
+ mAnimatedHeight = height;
+ requestLayout();
+ }
+
+ @Override
+ protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
+ if (mAnimatedHeight == -1) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ } else {
+ setMeasuredDimension(View.MeasureSpec.getSize(widthMeasureSpec), mAnimatedHeight);
+ }
+ }
+}
diff --git a/src/com/android/mail/ui/MailActionBarView.java b/src/com/android/mail/ui/MailActionBarView.java
index c952010..2d4f7cd 100644
--- a/src/com/android/mail/ui/MailActionBarView.java
+++ b/src/com/android/mail/ui/MailActionBarView.java
@@ -364,10 +364,6 @@
// that are possible.
LogUtils.d(LOG_TAG, "ActionBarView.onPrepareOptionsMenu().");
- if (mController.shouldHideMenuItems()) {
- setMenuItemsToHiddenForOpenDrawer(menu);
- return false;
- }
if (mHelpItem != null) {
mHelpItem.setVisible(mAccount != null
&& mAccount.supportsCapability(AccountCapabilities.HELP_CONTENT));
@@ -376,6 +372,21 @@
mSendFeedbackItem.setVisible(mAccount != null
&& mAccount.supportsCapability(AccountCapabilities.SEND_FEEDBACK));
}
+ if (mController.shouldHideMenuItems()) {
+ // Shortcut: hide all remaining menu items if the drawer is shown
+ final int size = menu.size();
+
+ for (int i = 0; i < size; i++) {
+ final MenuItem item = menu.getItem(i);
+ final int id = item.getItemId();
+ if (id != R.id.settings
+ && id != R.id.feedback_menu_item
+ && id != R.id.help_info_menu_item) {
+ item.setVisible(false);
+ }
+ }
+ return false;
+ }
if (mFolderSettingsItem != null) {
mFolderSettingsItem.setVisible(mFolder != null
&& mFolder.supportsCapability(FolderCapabilities.SUPPORTS_SETTINGS));
@@ -520,22 +531,6 @@
}
/**
- * Hides menu items while the drawer is open.
- */
- private static void setMenuItemsToHiddenForOpenDrawer(Menu menu) {
- final int size = menu.size();
-
- for (int i = 0; i < size; i++) {
- final MenuItem item = menu.getItem(i);
-
- final int id = item.getItemId();
- item.setVisible(id == R.id.settings ||
- id == R.id.feedback_menu_item ||
- id == R.id.help_info_menu_item);
- }
- }
-
- /**
* Put the ActionBar in List navigation mode.
*/
private void showNavList() {
diff --git a/src/com/android/mail/ui/OnePaneController.java b/src/com/android/mail/ui/OnePaneController.java
index 51a91d4..ffd1a04 100644
--- a/src/com/android/mail/ui/OnePaneController.java
+++ b/src/com/android/mail/ui/OnePaneController.java
@@ -510,7 +510,6 @@
switch (mode) {
case ViewMode.SEARCH_RESULTS_CONVERSATION:
case ViewMode.CONVERSATION:
- mToastBar.setConversationMode(true);
mToastBar.show(getUndoClickedListener(
convList != null ? convList.getAnimatedAdapter() : null),
0,
@@ -524,7 +523,6 @@
case ViewMode.SEARCH_RESULTS_LIST:
case ViewMode.CONVERSATION_LIST:
if (convList != null) {
- mToastBar.setConversationMode(false);
mToastBar.show(
getUndoClickedListener(convList.getAnimatedAdapter()),
0,
diff --git a/src/com/android/mail/ui/TwoPaneController.java b/src/com/android/mail/ui/TwoPaneController.java
index e71ec7b..1127956 100644
--- a/src/com/android/mail/ui/TwoPaneController.java
+++ b/src/com/android/mail/ui/TwoPaneController.java
@@ -508,7 +508,6 @@
- params.rightMargin;
params.gravity = Gravity.BOTTOM | Gravity.RIGHT;
mToastBar.setLayoutParams(params);
- mToastBar.setConversationMode(false);
break;
case ViewMode.SEARCH_RESULTS_CONVERSATION:
case ViewMode.CONVERSATION:
@@ -518,14 +517,12 @@
params.width = mLayout.computeConversationListWidth() - params.leftMargin
- params.rightMargin;
mToastBar.setLayoutParams(params);
- mToastBar.setConversationMode(false);
} else {
// Show undo bar in the conversation.
params.gravity = Gravity.BOTTOM | Gravity.RIGHT;
params.width = mLayout.computeConversationWidth() - params.leftMargin
- params.rightMargin;
mToastBar.setLayoutParams(params);
- mToastBar.setConversationMode(true);
}
break;
}
diff --git a/src/org/apache/commons/io/FileUtils.java b/src/org/apache/commons/io/FileUtils.java
index d5de771..8715eea 100644
--- a/src/org/apache/commons/io/FileUtils.java
+++ b/src/org/apache/commons/io/FileUtils.java
@@ -16,6 +16,8 @@
*/
package org.apache.commons.io;
+import com.google.common.annotations.VisibleForTesting;
+
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
@@ -77,6 +79,7 @@
* @author Sandy McArthur
* @version $Id: FileUtils.java 610810 2008-01-10 15:04:49Z niallp $
*/
+@VisibleForTesting
public class FileUtils {
/**
@@ -741,6 +744,7 @@
* @throws IOException if an IO error occurs during copying
* @since Commons IO 1.1
*/
+ @VisibleForTesting
public static void copyDirectory(File srcDir, File destDir) throws IOException {
copyDirectory(srcDir, destDir, true);
}