1 /* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.mail.ui; 18 19 import android.app.LoaderManager; 20 import android.app.LoaderManager.LoaderCallbacks; 21 import android.content.Context; 22 import android.content.Loader; 23 import android.content.res.Resources; 24 import android.os.Bundle; 25 import android.text.SpannableString; 26 import android.text.Spanned; 27 import android.text.style.TextAppearanceSpan; 28 import android.view.View; 29 30 import com.android.mail.R; 31 import com.android.mail.browse.ConversationCursor; 32 import com.android.mail.content.ObjectCursor; 33 import com.android.mail.content.ObjectCursorLoader; 34 import com.android.mail.preferences.AccountPreferences; 35 import com.android.mail.providers.Account; 36 import com.android.mail.providers.Folder; 37 import com.android.mail.providers.UIProvider; 38 39 /** 40 * Tip that is displayed in conversation list of 'Sent' folder whenever there are 41 * one or more messages in the Outbox. 42 */ 43 public class ConversationsInOutboxTipView extends ConversationTipView { 44 private Account mAccount = null; 45 private AccountPreferences mAccountPreferences; 46 private LoaderManager mLoaderManager; 47 private FolderSelector mFolderSelector; 48 private Folder mOutbox; 49 private int mOutboxCount = -1; 50 51 private static final int LOADER_FOLDER_LIST = 52 AbstractActivityController.LAST_FRAGMENT_LOADER_ID + 100; 53 ConversationsInOutboxTipView(Context context)54 public ConversationsInOutboxTipView(Context context) { 55 super(context); 56 } 57 bind(final Account account, final FolderSelector folderSelector)58 public void bind(final Account account, final FolderSelector folderSelector) { 59 mAccount = account; 60 mAccountPreferences = AccountPreferences.get(getContext(), account); 61 mFolderSelector = folderSelector; 62 } 63 64 @Override getTextAreaOnClickListener()65 protected OnClickListener getTextAreaOnClickListener() { 66 return new OnClickListener() { 67 @Override 68 public void onClick(View view) { 69 if (mOutbox != null) { 70 mFolderSelector.onFolderSelected(mOutbox); 71 } 72 } 73 }; 74 } 75 76 @Override 77 public void onUpdate(Folder folder, ConversationCursor cursor) { 78 if (mLoaderManager != null && folder != null) { 79 if ((folder.type & UIProvider.FolderType.SENT) > 0) { 80 // Only display this tip if user is viewing the Sent folder 81 mLoaderManager.initLoader(LOADER_FOLDER_LIST, null, mFolderListLoaderCallbacks); 82 } 83 } 84 } 85 86 private final LoaderCallbacks<ObjectCursor<Folder>> mFolderListLoaderCallbacks = 87 new LoaderManager.LoaderCallbacks<ObjectCursor<Folder>>() { 88 @Override 89 public void onLoaderReset(final Loader<ObjectCursor<Folder>> loader) { 90 // Do nothing 91 } 92 93 @Override 94 public void onLoadFinished(final Loader<ObjectCursor<Folder>> loader, 95 final ObjectCursor<Folder> data) { 96 if (data != null && data.moveToFirst()) { 97 do { 98 final Folder folder = data.getModel(); 99 if ((folder.type & UIProvider.FolderType.OUTBOX) > 0) { 100 mOutbox = folder; 101 onOutboxTotalCount(folder.totalCount); 102 } 103 } while (data.moveToNext()); 104 } 105 } 106 107 @Override 108 public Loader<ObjectCursor<Folder>> onCreateLoader(final int id, final Bundle args) { 109 // This loads all folders in order to find 'Outbox'. We could consider adding a new 110 // query to load folders of a given type to make this more efficient, but should be 111 // okay for now since this is triggered infrequently (only when user visits the 112 // 'Sent' folder). 113 return new ObjectCursorLoader<Folder>(getContext(), 114 mAccount.folderListUri, UIProvider.FOLDERS_PROJECTION, Folder.FACTORY); 115 } 116 }; 117 118 private void onOutboxTotalCount(int outboxCount) { 119 if (mOutboxCount != outboxCount) { 120 mOutboxCount = outboxCount; 121 if (outboxCount > 0) { 122 updateText(); 123 } 124 } 125 if (outboxCount == 0) { 126 // Clear the last seen count, so that new messages in Outbox will always cause this 127 // tip to appear again. 128 mAccountPreferences.setLastSeenOutboxCount(0); 129 } 130 } 131 132 private void updateText() { 133 // Update the display text to reflect current mOutboxCount 134 final Resources resources = getContext().getResources(); 135 final String subString = mOutbox.name; 136 final String entireString = resources.getString(R.string.unsent_messages_in_outbox, 137 String.valueOf(mOutboxCount), subString); 138 final SpannableString text = new SpannableString(entireString); 139 final int index = entireString.indexOf(subString); 140 text.setSpan(new TextAppearanceSpan(getContext(), R.style.LinksInTipTextAppearance), index, 141 index + subString.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); 142 setText(text); 143 } 144 145 @Override 146 public boolean getShouldDisplayInList() { 147 return (mOutboxCount > 0 && mOutboxCount != mAccountPreferences.getLastSeenOutboxCount()); 148 } 149 150 @Override 151 public void bindFragment(final LoaderManager loaderManager, final Bundle savedInstanceState) { 152 mLoaderManager = loaderManager; 153 } 154 155 @Override 156 public void dismiss() { 157 // Do not show this tip again until we have a new count. Note this is not quite 158 // ideal behavior since after a user dismisses an "1 unsent in outbox" tip, 159 // the message stuck in Outbox could get sent, and a new one gets stuck. 160 // If the user checks back on on Sent folder then, we don't reshow the message since count 161 // itself hasn't changed, but ideally we should since it's a different message than before. 162 // However if user checks the Sent folder in between (when there were 0 messages 163 // in Outbox), the preference is cleared (see {@link onOutboxTotalCount}). 164 mAccountPreferences.setLastSeenOutboxCount(mOutboxCount); 165 super.dismiss(); 166 } 167 } 168