2010-07-21 21:29:49 +00:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2010 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.email.activity;
|
|
|
|
|
2010-08-27 17:25:03 +00:00
|
|
|
import com.android.email.Clock;
|
2010-12-07 23:17:52 +00:00
|
|
|
import com.android.email.Controller;
|
|
|
|
import com.android.email.ControllerResultUiThreadWrapper;
|
2010-07-21 21:29:49 +00:00
|
|
|
import com.android.email.Email;
|
2010-09-10 00:23:53 +00:00
|
|
|
import com.android.email.Preferences;
|
2010-07-21 21:29:49 +00:00
|
|
|
import com.android.email.R;
|
2010-08-18 23:47:42 +00:00
|
|
|
import com.android.email.RefreshManager;
|
2010-08-06 21:49:57 +00:00
|
|
|
import com.android.email.Utility;
|
2010-09-09 21:13:47 +00:00
|
|
|
import com.android.email.activity.setup.AccountSecurity;
|
2010-08-18 23:47:42 +00:00
|
|
|
import com.android.email.activity.setup.AccountSettingsXL;
|
2010-08-27 17:25:03 +00:00
|
|
|
import com.android.email.provider.EmailContent.Account;
|
2010-08-25 02:09:34 +00:00
|
|
|
import com.android.email.provider.EmailContent.Mailbox;
|
2011-02-10 02:47:43 +00:00
|
|
|
import com.android.emailcommon.mail.MessagingException;
|
2010-07-21 21:29:49 +00:00
|
|
|
|
2010-07-28 18:42:37 +00:00
|
|
|
import android.app.ActionBar;
|
2010-07-21 21:29:49 +00:00
|
|
|
import android.app.Activity;
|
|
|
|
import android.app.LoaderManager.LoaderCallbacks;
|
|
|
|
import android.content.Context;
|
2010-08-04 22:38:25 +00:00
|
|
|
import android.content.Intent;
|
2010-07-21 21:29:49 +00:00
|
|
|
import android.content.Loader;
|
2010-07-28 18:42:37 +00:00
|
|
|
import android.database.Cursor;
|
2010-08-27 17:25:03 +00:00
|
|
|
import android.os.AsyncTask;
|
2010-07-21 21:29:49 +00:00
|
|
|
import android.os.Bundle;
|
2010-12-07 23:17:52 +00:00
|
|
|
import android.os.Handler;
|
2011-01-25 19:07:42 +00:00
|
|
|
import android.text.TextUtils;
|
2010-07-21 21:29:49 +00:00
|
|
|
import android.util.Log;
|
2010-08-04 23:54:08 +00:00
|
|
|
import android.view.Menu;
|
|
|
|
import android.view.MenuItem;
|
2010-11-29 19:42:13 +00:00
|
|
|
import android.view.View;
|
|
|
|
import android.widget.TextView;
|
2010-07-21 21:29:49 +00:00
|
|
|
|
2010-08-25 02:09:34 +00:00
|
|
|
import java.security.InvalidParameterException;
|
|
|
|
|
2010-07-21 21:29:49 +00:00
|
|
|
/**
|
Refactoring MessageListXL
I always thought our Activities are way too fat, meaning we've put too many
things into activities without any structure.
The major problems with this are:
- They have too many fields, which are not final and not even orthogonal.
This makes them very hard to understand/maintain. Changing one tiny bit
can always cause unanticipated side-effects.
- Very hard, or almost impossible to test.
I really think we should break them into independent and self-contained
subcomponents which can be tested separately.
Introducing MessageListXLStateManager, which manages the current account,
mailbox and message, and show/hide/update fragments accordingly
for MessageListXL.
With this class, MessageListXL will be able to switch accounts/mailboxes/
messages by just calling the methods such as selectAccount(), without
worrying about when to show/hide what fragment and how to initialize them.
(In other words, MessageListXLStateManager encapsulates the two-pane screen
transition. It's not intended to be reused for the phone UI.)
I didn't make it a nested class in MessageListXL, because nested classes can't
have real private members (private member are accessible from outer classes and
even brother classes!!), and I wanted it to be really self-contained anyway.
Change-Id: I1c121e99e30f12cc118e1c35abc9b30f49939a4a
2010-07-22 22:01:31 +00:00
|
|
|
* The main (two-pane) activity for XL devices.
|
2010-08-04 22:43:55 +00:00
|
|
|
*
|
Let MessageViewFragment own bottom buttons.
Create a custom view containing the bottons below MVF
(delete, move, reply, etc) and let MVF own this.
These buttons used to be owned by the XL activity itself, because
the UI for these commands will most likely be totally different
from the tablet UI, so the fragment having them looked wrong.
However, this made it harder to make changes suggested by the latest
mock, such as "put reply/forward in the message header".
I think the buttons are semantically part of the message view anyway,
so the fragment owning UI for these commands is probably the way to go.
(And let's worry about the phone UI later.)
Reason for the use of a custom view is that it will make it easier
to make non-trivial UI changes, e.g. "combine reply, reply-all and
forward and make it dropdown."
Also removed obsolete TODOs from MessageListXL.
Change-Id: Ibf93f4c70fe07bdbbe33d2adb6bbd2b96812830d
2010-09-16 18:16:46 +00:00
|
|
|
* TODO Refine "move to".
|
2010-07-21 21:29:49 +00:00
|
|
|
*/
|
Let MessageViewFragment own bottom buttons.
Create a custom view containing the bottons below MVF
(delete, move, reply, etc) and let MVF own this.
These buttons used to be owned by the XL activity itself, because
the UI for these commands will most likely be totally different
from the tablet UI, so the fragment having them looked wrong.
However, this made it harder to make changes suggested by the latest
mock, such as "put reply/forward in the message header".
I think the buttons are semantically part of the message view anyway,
so the fragment owning UI for these commands is probably the way to go.
(And let's worry about the phone UI later.)
Reason for the use of a custom view is that it will make it easier
to make non-trivial UI changes, e.g. "combine reply, reply-all and
forward and make it dropdown."
Also removed obsolete TODOs from MessageListXL.
Change-Id: Ibf93f4c70fe07bdbbe33d2adb6bbd2b96812830d
2010-09-16 18:16:46 +00:00
|
|
|
public class MessageListXL extends Activity implements
|
2010-11-29 19:42:13 +00:00
|
|
|
MessageListXLFragmentManager.TargetActivity, MoveMessageToDialog.Callback,
|
|
|
|
View.OnClickListener {
|
2010-08-25 02:09:34 +00:00
|
|
|
private static final String EXTRA_ACCOUNT_ID = "ACCOUNT_ID";
|
|
|
|
private static final String EXTRA_MAILBOX_ID = "MAILBOX_ID";
|
2010-12-04 00:28:25 +00:00
|
|
|
private static final String EXTRA_MESSAGE_ID = "MESSAGE_ID";
|
2010-07-28 18:42:37 +00:00
|
|
|
private static final int LOADER_ID_ACCOUNT_LIST = 0;
|
2010-08-27 17:25:03 +00:00
|
|
|
/* package */ static final int MAILBOX_REFRESH_MIN_INTERVAL = 30 * 1000; // in milliseconds
|
|
|
|
/* package */ static final int INBOX_AUTO_REFRESH_MIN_INTERVAL = 10 * 1000; // in milliseconds
|
2010-07-21 21:29:49 +00:00
|
|
|
|
|
|
|
private Context mContext;
|
2010-12-07 23:17:52 +00:00
|
|
|
private Controller mController;
|
2010-08-16 21:14:40 +00:00
|
|
|
private RefreshManager mRefreshManager;
|
|
|
|
private final RefreshListener mMailRefreshManagerListener
|
|
|
|
= new RefreshListener();
|
2010-12-07 23:17:52 +00:00
|
|
|
private Controller.Result mControllerResult;
|
2010-07-21 21:29:49 +00:00
|
|
|
|
2011-01-25 19:07:42 +00:00
|
|
|
/** True between onCreate() to onDestroy() */
|
|
|
|
private boolean mIsCreated;
|
|
|
|
|
2010-07-28 18:42:37 +00:00
|
|
|
private AccountSelectorAdapter mAccountsSelectorAdapter;
|
|
|
|
private final ActionBarNavigationCallback mActionBarNavigationCallback
|
|
|
|
= new ActionBarNavigationCallback();
|
|
|
|
|
Refactoring MessageListXL
I always thought our Activities are way too fat, meaning we've put too many
things into activities without any structure.
The major problems with this are:
- They have too many fields, which are not final and not even orthogonal.
This makes them very hard to understand/maintain. Changing one tiny bit
can always cause unanticipated side-effects.
- Very hard, or almost impossible to test.
I really think we should break them into independent and self-contained
subcomponents which can be tested separately.
Introducing MessageListXLStateManager, which manages the current account,
mailbox and message, and show/hide/update fragments accordingly
for MessageListXL.
With this class, MessageListXL will be able to switch accounts/mailboxes/
messages by just calling the methods such as selectAccount(), without
worrying about when to show/hide what fragment and how to initialize them.
(In other words, MessageListXLStateManager encapsulates the two-pane screen
transition. It's not intended to be reused for the phone UI.)
I didn't make it a nested class in MessageListXL, because nested classes can't
have real private members (private member are accessible from outer classes and
even brother classes!!), and I wanted it to be really self-contained anyway.
Change-Id: I1c121e99e30f12cc118e1c35abc9b30f49939a4a
2010-07-22 22:01:31 +00:00
|
|
|
private MessageOrderManager mOrderManager;
|
2010-07-21 21:29:49 +00:00
|
|
|
|
Refactoring MessageListXL
I always thought our Activities are way too fat, meaning we've put too many
things into activities without any structure.
The major problems with this are:
- They have too many fields, which are not final and not even orthogonal.
This makes them very hard to understand/maintain. Changing one tiny bit
can always cause unanticipated side-effects.
- Very hard, or almost impossible to test.
I really think we should break them into independent and self-contained
subcomponents which can be tested separately.
Introducing MessageListXLStateManager, which manages the current account,
mailbox and message, and show/hide/update fragments accordingly
for MessageListXL.
With this class, MessageListXL will be able to switch accounts/mailboxes/
messages by just calling the methods such as selectAccount(), without
worrying about when to show/hide what fragment and how to initialize them.
(In other words, MessageListXLStateManager encapsulates the two-pane screen
transition. It's not intended to be reused for the phone UI.)
I didn't make it a nested class in MessageListXL, because nested classes can't
have real private members (private member are accessible from outer classes and
even brother classes!!), and I wanted it to be really self-contained anyway.
Change-Id: I1c121e99e30f12cc118e1c35abc9b30f49939a4a
2010-07-22 22:01:31 +00:00
|
|
|
private final MessageListXLFragmentManager mFragmentManager
|
|
|
|
= new MessageListXLFragmentManager(this);
|
2010-07-21 21:29:49 +00:00
|
|
|
|
Refactoring MessageListXL
I always thought our Activities are way too fat, meaning we've put too many
things into activities without any structure.
The major problems with this are:
- They have too many fields, which are not final and not even orthogonal.
This makes them very hard to understand/maintain. Changing one tiny bit
can always cause unanticipated side-effects.
- Very hard, or almost impossible to test.
I really think we should break them into independent and self-contained
subcomponents which can be tested separately.
Introducing MessageListXLStateManager, which manages the current account,
mailbox and message, and show/hide/update fragments accordingly
for MessageListXL.
With this class, MessageListXL will be able to switch accounts/mailboxes/
messages by just calling the methods such as selectAccount(), without
worrying about when to show/hide what fragment and how to initialize them.
(In other words, MessageListXLStateManager encapsulates the two-pane screen
transition. It's not intended to be reused for the phone UI.)
I didn't make it a nested class in MessageListXL, because nested classes can't
have real private members (private member are accessible from outer classes and
even brother classes!!), and I wanted it to be really self-contained anyway.
Change-Id: I1c121e99e30f12cc118e1c35abc9b30f49939a4a
2010-07-22 22:01:31 +00:00
|
|
|
private final MessageOrderManagerCallback mMessageOrderManagerCallback
|
|
|
|
= new MessageOrderManagerCallback();
|
2010-07-21 21:29:49 +00:00
|
|
|
|
2010-08-27 17:25:03 +00:00
|
|
|
private RefreshTask mRefreshTask;
|
|
|
|
|
2010-12-07 23:17:52 +00:00
|
|
|
private BannerController mBannerController;
|
2010-11-29 19:42:13 +00:00
|
|
|
private TextView mErrorMessageView;
|
2010-12-07 23:17:52 +00:00
|
|
|
/**
|
|
|
|
* Id of the account that had a messaging exception most recently.
|
|
|
|
*/
|
|
|
|
private long mLastErrorAccountId;
|
2010-11-29 19:42:13 +00:00
|
|
|
|
2010-08-09 23:17:53 +00:00
|
|
|
/**
|
|
|
|
* Launch and open account's inbox.
|
2010-08-25 02:09:34 +00:00
|
|
|
*
|
|
|
|
* @param accountId If -1, default account will be used.
|
2010-08-09 23:17:53 +00:00
|
|
|
*/
|
2010-08-25 02:09:34 +00:00
|
|
|
public static void actionOpenAccount(Activity fromActivity, long accountId) {
|
2011-01-20 00:25:26 +00:00
|
|
|
Intent i = Utility.createRestartAppIntent(fromActivity, MessageListXL.class);
|
2010-08-09 23:17:53 +00:00
|
|
|
if (accountId != -1) {
|
|
|
|
i.putExtra(EXTRA_ACCOUNT_ID, accountId);
|
|
|
|
}
|
2010-08-25 02:09:34 +00:00
|
|
|
fromActivity.startActivity(i);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Launch and open a mailbox.
|
|
|
|
*
|
|
|
|
* @param accountId must not be -1.
|
2010-11-03 00:38:29 +00:00
|
|
|
* @param mailboxId must not be -1. Magic mailboxes IDs (such as
|
|
|
|
* {@link Mailbox#QUERY_ALL_INBOXES}) don't work.
|
2010-08-25 02:09:34 +00:00
|
|
|
*/
|
|
|
|
public static void actionOpenMailbox(Activity fromActivity, long accountId, long mailboxId) {
|
|
|
|
if (accountId == -1 || mailboxId == -1) {
|
|
|
|
throw new InvalidParameterException();
|
|
|
|
}
|
2011-01-20 00:25:26 +00:00
|
|
|
Intent i = Utility.createRestartAppIntent(fromActivity, MessageListXL.class);
|
2010-08-25 02:09:34 +00:00
|
|
|
i.putExtra(EXTRA_ACCOUNT_ID, accountId);
|
2010-11-03 00:38:29 +00:00
|
|
|
i.putExtra(EXTRA_MAILBOX_ID, mailboxId);
|
2010-08-09 23:17:53 +00:00
|
|
|
fromActivity.startActivity(i);
|
2010-08-04 22:38:25 +00:00
|
|
|
}
|
|
|
|
|
2010-12-04 00:28:25 +00:00
|
|
|
/**
|
|
|
|
* Launch and open a message.
|
|
|
|
*
|
|
|
|
* @param accountId must not be -1.
|
|
|
|
* @param mailboxId must not be -1. Magic mailboxes IDs (such as
|
|
|
|
* {@link Mailbox#QUERY_ALL_INBOXES}) don't work.
|
|
|
|
* @param messageId must not be -1.
|
|
|
|
*/
|
|
|
|
public static void actionOpenMessage(Activity fromActivity, long accountId, long mailboxId,
|
|
|
|
long messageId) {
|
|
|
|
if (accountId == -1 || mailboxId == -1 || messageId == -1) {
|
|
|
|
throw new InvalidParameterException();
|
|
|
|
}
|
2011-01-20 00:25:26 +00:00
|
|
|
Intent i = Utility.createRestartAppIntent(fromActivity, MessageListXL.class);
|
2010-12-04 00:28:25 +00:00
|
|
|
i.putExtra(EXTRA_ACCOUNT_ID, accountId);
|
|
|
|
i.putExtra(EXTRA_MAILBOX_ID, mailboxId);
|
|
|
|
i.putExtra(EXTRA_MESSAGE_ID, messageId);
|
|
|
|
fromActivity.startActivity(i);
|
|
|
|
}
|
|
|
|
|
2010-07-21 21:29:49 +00:00
|
|
|
@Override
|
|
|
|
protected void onCreate(Bundle savedInstanceState) {
|
Refactoring MessageListXL
I always thought our Activities are way too fat, meaning we've put too many
things into activities without any structure.
The major problems with this are:
- They have too many fields, which are not final and not even orthogonal.
This makes them very hard to understand/maintain. Changing one tiny bit
can always cause unanticipated side-effects.
- Very hard, or almost impossible to test.
I really think we should break them into independent and self-contained
subcomponents which can be tested separately.
Introducing MessageListXLStateManager, which manages the current account,
mailbox and message, and show/hide/update fragments accordingly
for MessageListXL.
With this class, MessageListXL will be able to switch accounts/mailboxes/
messages by just calling the methods such as selectAccount(), without
worrying about when to show/hide what fragment and how to initialize them.
(In other words, MessageListXLStateManager encapsulates the two-pane screen
transition. It's not intended to be reused for the phone UI.)
I didn't make it a nested class in MessageListXL, because nested classes can't
have real private members (private member are accessible from outer classes and
even brother classes!!), and I wanted it to be really self-contained anyway.
Change-Id: I1c121e99e30f12cc118e1c35abc9b30f49939a4a
2010-07-22 22:01:31 +00:00
|
|
|
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) Log.d(Email.LOG_TAG, "MessageListXL onCreate");
|
2010-07-21 21:29:49 +00:00
|
|
|
super.onCreate(savedInstanceState);
|
2010-11-01 23:15:15 +00:00
|
|
|
ActivityHelper.debugSetWindowFlags(this);
|
2010-07-21 21:29:49 +00:00
|
|
|
setContentView(R.layout.message_list_xl);
|
|
|
|
|
2010-11-19 20:45:34 +00:00
|
|
|
ActionBar ab = getActionBar();
|
|
|
|
ab.setDisplayOptions(ActionBar.DISPLAY_SHOW_TITLE | ActionBar.DISPLAY_SHOW_HOME);
|
|
|
|
|
|
|
|
mFragmentManager.onActivityViewReady();
|
2010-07-21 21:29:49 +00:00
|
|
|
|
|
|
|
mContext = getApplicationContext();
|
2010-12-07 23:17:52 +00:00
|
|
|
mController = Controller.getInstance(this);
|
2010-08-16 21:14:40 +00:00
|
|
|
mRefreshManager = RefreshManager.getInstance(this);
|
|
|
|
mRefreshManager.registerListener(mMailRefreshManagerListener);
|
2010-07-21 21:29:49 +00:00
|
|
|
|
Refactoring MessageListXL
I always thought our Activities are way too fat, meaning we've put too many
things into activities without any structure.
The major problems with this are:
- They have too many fields, which are not final and not even orthogonal.
This makes them very hard to understand/maintain. Changing one tiny bit
can always cause unanticipated side-effects.
- Very hard, or almost impossible to test.
I really think we should break them into independent and self-contained
subcomponents which can be tested separately.
Introducing MessageListXLStateManager, which manages the current account,
mailbox and message, and show/hide/update fragments accordingly
for MessageListXL.
With this class, MessageListXL will be able to switch accounts/mailboxes/
messages by just calling the methods such as selectAccount(), without
worrying about when to show/hide what fragment and how to initialize them.
(In other words, MessageListXLStateManager encapsulates the two-pane screen
transition. It's not intended to be reused for the phone UI.)
I didn't make it a nested class in MessageListXL, because nested classes can't
have real private members (private member are accessible from outer classes and
even brother classes!!), and I wanted it to be really self-contained anyway.
Change-Id: I1c121e99e30f12cc118e1c35abc9b30f49939a4a
2010-07-22 22:01:31 +00:00
|
|
|
mFragmentManager.setMailboxListFragmentCallback(new MailboxListFragmentCallback());
|
|
|
|
mFragmentManager.setMessageListFragmentCallback(new MessageListFragmentCallback());
|
|
|
|
mFragmentManager.setMessageViewFragmentCallback(new MessageViewFragmentCallback());
|
2010-07-21 21:29:49 +00:00
|
|
|
|
2010-11-05 19:05:40 +00:00
|
|
|
mAccountsSelectorAdapter = new AccountSelectorAdapter(this, null);
|
2010-07-28 18:42:37 +00:00
|
|
|
|
2010-11-19 20:45:34 +00:00
|
|
|
if (savedInstanceState != null) {
|
Refactoring MessageListXL
I always thought our Activities are way too fat, meaning we've put too many
things into activities without any structure.
The major problems with this are:
- They have too many fields, which are not final and not even orthogonal.
This makes them very hard to understand/maintain. Changing one tiny bit
can always cause unanticipated side-effects.
- Very hard, or almost impossible to test.
I really think we should break them into independent and self-contained
subcomponents which can be tested separately.
Introducing MessageListXLStateManager, which manages the current account,
mailbox and message, and show/hide/update fragments accordingly
for MessageListXL.
With this class, MessageListXL will be able to switch accounts/mailboxes/
messages by just calling the methods such as selectAccount(), without
worrying about when to show/hide what fragment and how to initialize them.
(In other words, MessageListXLStateManager encapsulates the two-pane screen
transition. It's not intended to be reused for the phone UI.)
I didn't make it a nested class in MessageListXL, because nested classes can't
have real private members (private member are accessible from outer classes and
even brother classes!!), and I wanted it to be really self-contained anyway.
Change-Id: I1c121e99e30f12cc118e1c35abc9b30f49939a4a
2010-07-22 22:01:31 +00:00
|
|
|
mFragmentManager.loadState(savedInstanceState);
|
2010-08-09 23:17:53 +00:00
|
|
|
} else {
|
|
|
|
initFromIntent();
|
2010-07-21 21:29:49 +00:00
|
|
|
}
|
2010-07-28 18:42:37 +00:00
|
|
|
loadAccounts();
|
2010-11-12 00:28:21 +00:00
|
|
|
|
2010-11-29 19:42:13 +00:00
|
|
|
// Set up views
|
|
|
|
// TODO Probably better to extract mErrorMessageView related code into a separate class,
|
|
|
|
// so that it'll be easy to reuse for the phone activities.
|
|
|
|
mErrorMessageView = (TextView) findViewById(R.id.error_message);
|
|
|
|
mErrorMessageView.setOnClickListener(this);
|
2010-12-07 23:17:52 +00:00
|
|
|
mBannerController = new BannerController(this, mErrorMessageView,
|
|
|
|
getResources().getDimensionPixelSize(R.dimen.error_message_height));
|
2010-11-29 19:42:13 +00:00
|
|
|
|
2010-11-18 07:19:36 +00:00
|
|
|
// Halt the progress indicator (we'll display it later when needed)
|
|
|
|
setProgressBarIndeterminate(true);
|
|
|
|
setProgressBarIndeterminateVisibility(false);
|
2010-12-07 23:17:52 +00:00
|
|
|
|
|
|
|
mControllerResult = new ControllerResultUiThreadWrapper<ControllerResult>(new Handler(),
|
|
|
|
new ControllerResult());
|
|
|
|
mController.addResultCallback(mControllerResult);
|
2011-01-25 19:07:42 +00:00
|
|
|
|
|
|
|
mIsCreated = true;
|
2010-07-21 21:29:49 +00:00
|
|
|
}
|
|
|
|
|
2010-08-09 23:17:53 +00:00
|
|
|
private void initFromIntent() {
|
|
|
|
final Intent i = getIntent();
|
|
|
|
final long accountId = i.getLongExtra(EXTRA_ACCOUNT_ID, -1);
|
2010-08-25 02:09:34 +00:00
|
|
|
final long mailboxId = i.getLongExtra(EXTRA_MAILBOX_ID, -1);
|
2010-12-04 00:28:25 +00:00
|
|
|
final long messageId = i.getLongExtra(EXTRA_MESSAGE_ID, -1);
|
2010-12-14 00:32:02 +00:00
|
|
|
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
|
2010-11-03 00:38:29 +00:00
|
|
|
Log.d(Email.LOG_TAG, String.format("initFromIntent: %d %d", accountId, mailboxId));
|
2010-08-25 02:09:34 +00:00
|
|
|
}
|
|
|
|
|
2010-08-09 23:17:53 +00:00
|
|
|
if (accountId != -1) {
|
2010-12-04 00:28:25 +00:00
|
|
|
mFragmentManager.selectAccount(accountId, mailboxId, messageId, true);
|
2010-08-09 23:17:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-07-21 21:29:49 +00:00
|
|
|
@Override
|
|
|
|
protected void onSaveInstanceState(Bundle outState) {
|
Refactoring MessageListXL
I always thought our Activities are way too fat, meaning we've put too many
things into activities without any structure.
The major problems with this are:
- They have too many fields, which are not final and not even orthogonal.
This makes them very hard to understand/maintain. Changing one tiny bit
can always cause unanticipated side-effects.
- Very hard, or almost impossible to test.
I really think we should break them into independent and self-contained
subcomponents which can be tested separately.
Introducing MessageListXLStateManager, which manages the current account,
mailbox and message, and show/hide/update fragments accordingly
for MessageListXL.
With this class, MessageListXL will be able to switch accounts/mailboxes/
messages by just calling the methods such as selectAccount(), without
worrying about when to show/hide what fragment and how to initialize them.
(In other words, MessageListXLStateManager encapsulates the two-pane screen
transition. It's not intended to be reused for the phone UI.)
I didn't make it a nested class in MessageListXL, because nested classes can't
have real private members (private member are accessible from outer classes and
even brother classes!!), and I wanted it to be really self-contained anyway.
Change-Id: I1c121e99e30f12cc118e1c35abc9b30f49939a4a
2010-07-22 22:01:31 +00:00
|
|
|
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
|
|
|
|
Log.d(Email.LOG_TAG, "MessageListXL onSaveInstanceState");
|
|
|
|
}
|
2010-07-21 21:29:49 +00:00
|
|
|
super.onSaveInstanceState(outState);
|
Refactoring MessageListXL
I always thought our Activities are way too fat, meaning we've put too many
things into activities without any structure.
The major problems with this are:
- They have too many fields, which are not final and not even orthogonal.
This makes them very hard to understand/maintain. Changing one tiny bit
can always cause unanticipated side-effects.
- Very hard, or almost impossible to test.
I really think we should break them into independent and self-contained
subcomponents which can be tested separately.
Introducing MessageListXLStateManager, which manages the current account,
mailbox and message, and show/hide/update fragments accordingly
for MessageListXL.
With this class, MessageListXL will be able to switch accounts/mailboxes/
messages by just calling the methods such as selectAccount(), without
worrying about when to show/hide what fragment and how to initialize them.
(In other words, MessageListXLStateManager encapsulates the two-pane screen
transition. It's not intended to be reused for the phone UI.)
I didn't make it a nested class in MessageListXL, because nested classes can't
have real private members (private member are accessible from outer classes and
even brother classes!!), and I wanted it to be really self-contained anyway.
Change-Id: I1c121e99e30f12cc118e1c35abc9b30f49939a4a
2010-07-22 22:01:31 +00:00
|
|
|
mFragmentManager.onSaveInstanceState(outState);
|
2010-07-21 21:29:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onStart() {
|
Refactoring MessageListXL
I always thought our Activities are way too fat, meaning we've put too many
things into activities without any structure.
The major problems with this are:
- They have too many fields, which are not final and not even orthogonal.
This makes them very hard to understand/maintain. Changing one tiny bit
can always cause unanticipated side-effects.
- Very hard, or almost impossible to test.
I really think we should break them into independent and self-contained
subcomponents which can be tested separately.
Introducing MessageListXLStateManager, which manages the current account,
mailbox and message, and show/hide/update fragments accordingly
for MessageListXL.
With this class, MessageListXL will be able to switch accounts/mailboxes/
messages by just calling the methods such as selectAccount(), without
worrying about when to show/hide what fragment and how to initialize them.
(In other words, MessageListXLStateManager encapsulates the two-pane screen
transition. It's not intended to be reused for the phone UI.)
I didn't make it a nested class in MessageListXL, because nested classes can't
have real private members (private member are accessible from outer classes and
even brother classes!!), and I wanted it to be really self-contained anyway.
Change-Id: I1c121e99e30f12cc118e1c35abc9b30f49939a4a
2010-07-22 22:01:31 +00:00
|
|
|
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) Log.d(Email.LOG_TAG, "MessageListXL onStart");
|
2010-07-21 21:29:49 +00:00
|
|
|
super.onStart();
|
Refactoring MessageListXL
I always thought our Activities are way too fat, meaning we've put too many
things into activities without any structure.
The major problems with this are:
- They have too many fields, which are not final and not even orthogonal.
This makes them very hard to understand/maintain. Changing one tiny bit
can always cause unanticipated side-effects.
- Very hard, or almost impossible to test.
I really think we should break them into independent and self-contained
subcomponents which can be tested separately.
Introducing MessageListXLStateManager, which manages the current account,
mailbox and message, and show/hide/update fragments accordingly
for MessageListXL.
With this class, MessageListXL will be able to switch accounts/mailboxes/
messages by just calling the methods such as selectAccount(), without
worrying about when to show/hide what fragment and how to initialize them.
(In other words, MessageListXLStateManager encapsulates the two-pane screen
transition. It's not intended to be reused for the phone UI.)
I didn't make it a nested class in MessageListXL, because nested classes can't
have real private members (private member are accessible from outer classes and
even brother classes!!), and I wanted it to be really self-contained anyway.
Change-Id: I1c121e99e30f12cc118e1c35abc9b30f49939a4a
2010-07-22 22:01:31 +00:00
|
|
|
|
2010-07-28 18:42:37 +00:00
|
|
|
mFragmentManager.onStart();
|
Refactoring MessageListXL
I always thought our Activities are way too fat, meaning we've put too many
things into activities without any structure.
The major problems with this are:
- They have too many fields, which are not final and not even orthogonal.
This makes them very hard to understand/maintain. Changing one tiny bit
can always cause unanticipated side-effects.
- Very hard, or almost impossible to test.
I really think we should break them into independent and self-contained
subcomponents which can be tested separately.
Introducing MessageListXLStateManager, which manages the current account,
mailbox and message, and show/hide/update fragments accordingly
for MessageListXL.
With this class, MessageListXL will be able to switch accounts/mailboxes/
messages by just calling the methods such as selectAccount(), without
worrying about when to show/hide what fragment and how to initialize them.
(In other words, MessageListXLStateManager encapsulates the two-pane screen
transition. It's not intended to be reused for the phone UI.)
I didn't make it a nested class in MessageListXL, because nested classes can't
have real private members (private member are accessible from outer classes and
even brother classes!!), and I wanted it to be really self-contained anyway.
Change-Id: I1c121e99e30f12cc118e1c35abc9b30f49939a4a
2010-07-22 22:01:31 +00:00
|
|
|
if (mFragmentManager.isMessageSelected()) {
|
|
|
|
updateMessageOrderManager();
|
|
|
|
}
|
2010-07-21 21:29:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onResume() {
|
Refactoring MessageListXL
I always thought our Activities are way too fat, meaning we've put too many
things into activities without any structure.
The major problems with this are:
- They have too many fields, which are not final and not even orthogonal.
This makes them very hard to understand/maintain. Changing one tiny bit
can always cause unanticipated side-effects.
- Very hard, or almost impossible to test.
I really think we should break them into independent and self-contained
subcomponents which can be tested separately.
Introducing MessageListXLStateManager, which manages the current account,
mailbox and message, and show/hide/update fragments accordingly
for MessageListXL.
With this class, MessageListXL will be able to switch accounts/mailboxes/
messages by just calling the methods such as selectAccount(), without
worrying about when to show/hide what fragment and how to initialize them.
(In other words, MessageListXLStateManager encapsulates the two-pane screen
transition. It's not intended to be reused for the phone UI.)
I didn't make it a nested class in MessageListXL, because nested classes can't
have real private members (private member are accessible from outer classes and
even brother classes!!), and I wanted it to be really self-contained anyway.
Change-Id: I1c121e99e30f12cc118e1c35abc9b30f49939a4a
2010-07-22 22:01:31 +00:00
|
|
|
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) Log.d(Email.LOG_TAG, "MessageListXL onResume");
|
2010-07-21 21:29:49 +00:00
|
|
|
super.onResume();
|
2010-11-16 19:11:22 +00:00
|
|
|
mFragmentManager.onResume();
|
2010-08-25 02:09:34 +00:00
|
|
|
|
2010-09-08 18:05:25 +00:00
|
|
|
// On MessageList.onResume, we go back to Welcome if an account has been added/removed.
|
|
|
|
// We don't need to do that here, because when the activity resumes, the account list loader
|
|
|
|
// will load the latest list.
|
2010-10-08 18:29:57 +00:00
|
|
|
// And if all the accounts have been removed, the loader will detect it and do
|
|
|
|
// appropriate things.
|
2010-07-21 21:29:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onPause() {
|
Refactoring MessageListXL
I always thought our Activities are way too fat, meaning we've put too many
things into activities without any structure.
The major problems with this are:
- They have too many fields, which are not final and not even orthogonal.
This makes them very hard to understand/maintain. Changing one tiny bit
can always cause unanticipated side-effects.
- Very hard, or almost impossible to test.
I really think we should break them into independent and self-contained
subcomponents which can be tested separately.
Introducing MessageListXLStateManager, which manages the current account,
mailbox and message, and show/hide/update fragments accordingly
for MessageListXL.
With this class, MessageListXL will be able to switch accounts/mailboxes/
messages by just calling the methods such as selectAccount(), without
worrying about when to show/hide what fragment and how to initialize them.
(In other words, MessageListXLStateManager encapsulates the two-pane screen
transition. It's not intended to be reused for the phone UI.)
I didn't make it a nested class in MessageListXL, because nested classes can't
have real private members (private member are accessible from outer classes and
even brother classes!!), and I wanted it to be really self-contained anyway.
Change-Id: I1c121e99e30f12cc118e1c35abc9b30f49939a4a
2010-07-22 22:01:31 +00:00
|
|
|
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) Log.d(Email.LOG_TAG, "MessageListXL onPause");
|
2010-07-21 21:29:49 +00:00
|
|
|
super.onPause();
|
2010-09-30 01:44:05 +00:00
|
|
|
mFragmentManager.onPause();
|
2010-07-21 21:29:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onStop() {
|
Refactoring MessageListXL
I always thought our Activities are way too fat, meaning we've put too many
things into activities without any structure.
The major problems with this are:
- They have too many fields, which are not final and not even orthogonal.
This makes them very hard to understand/maintain. Changing one tiny bit
can always cause unanticipated side-effects.
- Very hard, or almost impossible to test.
I really think we should break them into independent and self-contained
subcomponents which can be tested separately.
Introducing MessageListXLStateManager, which manages the current account,
mailbox and message, and show/hide/update fragments accordingly
for MessageListXL.
With this class, MessageListXL will be able to switch accounts/mailboxes/
messages by just calling the methods such as selectAccount(), without
worrying about when to show/hide what fragment and how to initialize them.
(In other words, MessageListXLStateManager encapsulates the two-pane screen
transition. It's not intended to be reused for the phone UI.)
I didn't make it a nested class in MessageListXL, because nested classes can't
have real private members (private member are accessible from outer classes and
even brother classes!!), and I wanted it to be really self-contained anyway.
Change-Id: I1c121e99e30f12cc118e1c35abc9b30f49939a4a
2010-07-22 22:01:31 +00:00
|
|
|
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) Log.d(Email.LOG_TAG, "MessageListXL onStop");
|
2010-07-21 21:29:49 +00:00
|
|
|
super.onStop();
|
Refactoring MessageListXL
I always thought our Activities are way too fat, meaning we've put too many
things into activities without any structure.
The major problems with this are:
- They have too many fields, which are not final and not even orthogonal.
This makes them very hard to understand/maintain. Changing one tiny bit
can always cause unanticipated side-effects.
- Very hard, or almost impossible to test.
I really think we should break them into independent and self-contained
subcomponents which can be tested separately.
Introducing MessageListXLStateManager, which manages the current account,
mailbox and message, and show/hide/update fragments accordingly
for MessageListXL.
With this class, MessageListXL will be able to switch accounts/mailboxes/
messages by just calling the methods such as selectAccount(), without
worrying about when to show/hide what fragment and how to initialize them.
(In other words, MessageListXLStateManager encapsulates the two-pane screen
transition. It's not intended to be reused for the phone UI.)
I didn't make it a nested class in MessageListXL, because nested classes can't
have real private members (private member are accessible from outer classes and
even brother classes!!), and I wanted it to be really self-contained anyway.
Change-Id: I1c121e99e30f12cc118e1c35abc9b30f49939a4a
2010-07-22 22:01:31 +00:00
|
|
|
|
|
|
|
mFragmentManager.onStop();
|
2010-07-21 21:29:49 +00:00
|
|
|
stopMessageOrderManager();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onDestroy() {
|
Refactoring MessageListXL
I always thought our Activities are way too fat, meaning we've put too many
things into activities without any structure.
The major problems with this are:
- They have too many fields, which are not final and not even orthogonal.
This makes them very hard to understand/maintain. Changing one tiny bit
can always cause unanticipated side-effects.
- Very hard, or almost impossible to test.
I really think we should break them into independent and self-contained
subcomponents which can be tested separately.
Introducing MessageListXLStateManager, which manages the current account,
mailbox and message, and show/hide/update fragments accordingly
for MessageListXL.
With this class, MessageListXL will be able to switch accounts/mailboxes/
messages by just calling the methods such as selectAccount(), without
worrying about when to show/hide what fragment and how to initialize them.
(In other words, MessageListXLStateManager encapsulates the two-pane screen
transition. It's not intended to be reused for the phone UI.)
I didn't make it a nested class in MessageListXL, because nested classes can't
have real private members (private member are accessible from outer classes and
even brother classes!!), and I wanted it to be really self-contained anyway.
Change-Id: I1c121e99e30f12cc118e1c35abc9b30f49939a4a
2010-07-22 22:01:31 +00:00
|
|
|
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) Log.d(Email.LOG_TAG, "MessageListXL onDestroy");
|
2011-01-25 19:07:42 +00:00
|
|
|
mIsCreated = false;
|
2010-12-07 23:17:52 +00:00
|
|
|
mController.removeResultCallback(mControllerResult);
|
2010-08-27 17:25:03 +00:00
|
|
|
Utility.cancelTaskInterrupt(mRefreshTask);
|
2010-08-16 21:14:40 +00:00
|
|
|
mRefreshManager.unregisterListener(mMailRefreshManagerListener);
|
2010-09-30 01:44:05 +00:00
|
|
|
mFragmentManager.onDestroy();
|
2010-07-21 21:29:49 +00:00
|
|
|
super.onDestroy();
|
|
|
|
}
|
|
|
|
|
Refactoring MessageListXL
I always thought our Activities are way too fat, meaning we've put too many
things into activities without any structure.
The major problems with this are:
- They have too many fields, which are not final and not even orthogonal.
This makes them very hard to understand/maintain. Changing one tiny bit
can always cause unanticipated side-effects.
- Very hard, or almost impossible to test.
I really think we should break them into independent and self-contained
subcomponents which can be tested separately.
Introducing MessageListXLStateManager, which manages the current account,
mailbox and message, and show/hide/update fragments accordingly
for MessageListXL.
With this class, MessageListXL will be able to switch accounts/mailboxes/
messages by just calling the methods such as selectAccount(), without
worrying about when to show/hide what fragment and how to initialize them.
(In other words, MessageListXLStateManager encapsulates the two-pane screen
transition. It's not intended to be reused for the phone UI.)
I didn't make it a nested class in MessageListXL, because nested classes can't
have real private members (private member are accessible from outer classes and
even brother classes!!), and I wanted it to be really self-contained anyway.
Change-Id: I1c121e99e30f12cc118e1c35abc9b30f49939a4a
2010-07-22 22:01:31 +00:00
|
|
|
@Override
|
|
|
|
public void onBackPressed() {
|
|
|
|
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
|
|
|
|
Log.d(Email.LOG_TAG, "MessageListXL onBackPressed");
|
|
|
|
}
|
2010-11-16 19:11:22 +00:00
|
|
|
onBackPressed(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Performs the back action.
|
|
|
|
*
|
2010-11-24 22:39:49 +00:00
|
|
|
* @param isSystemBackKey set true if the system back key is pressed, rather than the home
|
|
|
|
* icon on action bar.
|
2010-11-16 19:11:22 +00:00
|
|
|
*/
|
2010-11-24 22:39:49 +00:00
|
|
|
private boolean onBackPressed(boolean isSystemBackKey) {
|
|
|
|
if (mFragmentManager.onBackPressed(isSystemBackKey)) {
|
2010-11-16 19:11:22 +00:00
|
|
|
return true;
|
2010-07-21 21:29:49 +00:00
|
|
|
}
|
2010-11-24 22:39:49 +00:00
|
|
|
if (isSystemBackKey) {
|
2010-11-16 19:11:22 +00:00
|
|
|
// Perform the default behavior.
|
|
|
|
super.onBackPressed();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
2010-07-21 21:29:49 +00:00
|
|
|
}
|
Refactoring MessageListXL
I always thought our Activities are way too fat, meaning we've put too many
things into activities without any structure.
The major problems with this are:
- They have too many fields, which are not final and not even orthogonal.
This makes them very hard to understand/maintain. Changing one tiny bit
can always cause unanticipated side-effects.
- Very hard, or almost impossible to test.
I really think we should break them into independent and self-contained
subcomponents which can be tested separately.
Introducing MessageListXLStateManager, which manages the current account,
mailbox and message, and show/hide/update fragments accordingly
for MessageListXL.
With this class, MessageListXL will be able to switch accounts/mailboxes/
messages by just calling the methods such as selectAccount(), without
worrying about when to show/hide what fragment and how to initialize them.
(In other words, MessageListXLStateManager encapsulates the two-pane screen
transition. It's not intended to be reused for the phone UI.)
I didn't make it a nested class in MessageListXL, because nested classes can't
have real private members (private member are accessible from outer classes and
even brother classes!!), and I wanted it to be really self-contained anyway.
Change-Id: I1c121e99e30f12cc118e1c35abc9b30f49939a4a
2010-07-22 22:01:31 +00:00
|
|
|
|
2010-11-29 19:42:13 +00:00
|
|
|
@Override
|
|
|
|
public void onClick(View v) {
|
|
|
|
switch (v.getId()) {
|
|
|
|
case R.id.error_message:
|
|
|
|
dismissErrorMessage();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-09-10 00:23:53 +00:00
|
|
|
private void onCurrentMessageGone() {
|
|
|
|
switch (Preferences.getPreferences(this).getAutoAdvanceDirection()) {
|
|
|
|
case Preferences.AUTO_ADVANCE_NEWER:
|
|
|
|
if (moveToNewer()) return;
|
|
|
|
if (moveToOlder()) return;
|
|
|
|
break;
|
|
|
|
case Preferences.AUTO_ADVANCE_OLDER:
|
|
|
|
if (moveToOlder()) return;
|
|
|
|
if (moveToNewer()) return;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
// Last message in the box or AUTO_ADVANCE_MESSAGE_LIST. Go back to message list.
|
|
|
|
mFragmentManager.goBackToMailbox();
|
2010-08-17 22:07:28 +00:00
|
|
|
}
|
|
|
|
|
2010-08-25 16:53:19 +00:00
|
|
|
private void onMoveMessage() {
|
|
|
|
long messageId = mFragmentManager.getMessageId();
|
2010-09-02 21:49:36 +00:00
|
|
|
MoveMessageToDialog dialog = MoveMessageToDialog.newInstance(this, new long[] {messageId},
|
|
|
|
null);
|
2010-08-25 16:53:19 +00:00
|
|
|
dialog.show(getFragmentManager(), "dialog");
|
|
|
|
}
|
|
|
|
|
2010-09-02 21:49:36 +00:00
|
|
|
@Override
|
|
|
|
public void onMoveToMailboxSelected(long newMailboxId, long[] messageIds) {
|
|
|
|
ActivityHelper.moveMessages(this, newMailboxId, messageIds);
|
2010-09-13 21:27:13 +00:00
|
|
|
onCurrentMessageGone();
|
2010-09-02 21:49:36 +00:00
|
|
|
}
|
|
|
|
|
Refactoring MessageListXL
I always thought our Activities are way too fat, meaning we've put too many
things into activities without any structure.
The major problems with this are:
- They have too many fields, which are not final and not even orthogonal.
This makes them very hard to understand/maintain. Changing one tiny bit
can always cause unanticipated side-effects.
- Very hard, or almost impossible to test.
I really think we should break them into independent and self-contained
subcomponents which can be tested separately.
Introducing MessageListXLStateManager, which manages the current account,
mailbox and message, and show/hide/update fragments accordingly
for MessageListXL.
With this class, MessageListXL will be able to switch accounts/mailboxes/
messages by just calling the methods such as selectAccount(), without
worrying about when to show/hide what fragment and how to initialize them.
(In other words, MessageListXLStateManager encapsulates the two-pane screen
transition. It's not intended to be reused for the phone UI.)
I didn't make it a nested class in MessageListXL, because nested classes can't
have real private members (private member are accessible from outer classes and
even brother classes!!), and I wanted it to be really self-contained anyway.
Change-Id: I1c121e99e30f12cc118e1c35abc9b30f49939a4a
2010-07-22 22:01:31 +00:00
|
|
|
/**
|
|
|
|
* Start {@link MessageOrderManager} if not started, and sync it to the current message.
|
|
|
|
*/
|
|
|
|
private void updateMessageOrderManager() {
|
|
|
|
if (!mFragmentManager.isMailboxSelected()) {
|
2010-07-21 21:29:49 +00:00
|
|
|
return;
|
|
|
|
}
|
Refactoring MessageListXL
I always thought our Activities are way too fat, meaning we've put too many
things into activities without any structure.
The major problems with this are:
- They have too many fields, which are not final and not even orthogonal.
This makes them very hard to understand/maintain. Changing one tiny bit
can always cause unanticipated side-effects.
- Very hard, or almost impossible to test.
I really think we should break them into independent and self-contained
subcomponents which can be tested separately.
Introducing MessageListXLStateManager, which manages the current account,
mailbox and message, and show/hide/update fragments accordingly
for MessageListXL.
With this class, MessageListXL will be able to switch accounts/mailboxes/
messages by just calling the methods such as selectAccount(), without
worrying about when to show/hide what fragment and how to initialize them.
(In other words, MessageListXLStateManager encapsulates the two-pane screen
transition. It's not intended to be reused for the phone UI.)
I didn't make it a nested class in MessageListXL, because nested classes can't
have real private members (private member are accessible from outer classes and
even brother classes!!), and I wanted it to be really self-contained anyway.
Change-Id: I1c121e99e30f12cc118e1c35abc9b30f49939a4a
2010-07-22 22:01:31 +00:00
|
|
|
final long mailboxId = mFragmentManager.getMailboxId();
|
|
|
|
if (mOrderManager == null || mOrderManager.getMailboxId() != mailboxId) {
|
|
|
|
stopMessageOrderManager();
|
|
|
|
mOrderManager = new MessageOrderManager(this, mailboxId, mMessageOrderManagerCallback);
|
2010-07-21 21:29:49 +00:00
|
|
|
}
|
Refactoring MessageListXL
I always thought our Activities are way too fat, meaning we've put too many
things into activities without any structure.
The major problems with this are:
- They have too many fields, which are not final and not even orthogonal.
This makes them very hard to understand/maintain. Changing one tiny bit
can always cause unanticipated side-effects.
- Very hard, or almost impossible to test.
I really think we should break them into independent and self-contained
subcomponents which can be tested separately.
Introducing MessageListXLStateManager, which manages the current account,
mailbox and message, and show/hide/update fragments accordingly
for MessageListXL.
With this class, MessageListXL will be able to switch accounts/mailboxes/
messages by just calling the methods such as selectAccount(), without
worrying about when to show/hide what fragment and how to initialize them.
(In other words, MessageListXLStateManager encapsulates the two-pane screen
transition. It's not intended to be reused for the phone UI.)
I didn't make it a nested class in MessageListXL, because nested classes can't
have real private members (private member are accessible from outer classes and
even brother classes!!), and I wanted it to be really self-contained anyway.
Change-Id: I1c121e99e30f12cc118e1c35abc9b30f49939a4a
2010-07-22 22:01:31 +00:00
|
|
|
if (mFragmentManager.isMessageSelected()) {
|
|
|
|
mOrderManager.moveTo(mFragmentManager.getMessageId());
|
|
|
|
}
|
|
|
|
}
|
2010-07-21 21:29:49 +00:00
|
|
|
|
Refactoring MessageListXL
I always thought our Activities are way too fat, meaning we've put too many
things into activities without any structure.
The major problems with this are:
- They have too many fields, which are not final and not even orthogonal.
This makes them very hard to understand/maintain. Changing one tiny bit
can always cause unanticipated side-effects.
- Very hard, or almost impossible to test.
I really think we should break them into independent and self-contained
subcomponents which can be tested separately.
Introducing MessageListXLStateManager, which manages the current account,
mailbox and message, and show/hide/update fragments accordingly
for MessageListXL.
With this class, MessageListXL will be able to switch accounts/mailboxes/
messages by just calling the methods such as selectAccount(), without
worrying about when to show/hide what fragment and how to initialize them.
(In other words, MessageListXLStateManager encapsulates the two-pane screen
transition. It's not intended to be reused for the phone UI.)
I didn't make it a nested class in MessageListXL, because nested classes can't
have real private members (private member are accessible from outer classes and
even brother classes!!), and I wanted it to be really self-contained anyway.
Change-Id: I1c121e99e30f12cc118e1c35abc9b30f49939a4a
2010-07-22 22:01:31 +00:00
|
|
|
private class MessageOrderManagerCallback implements MessageOrderManager.Callback {
|
|
|
|
@Override
|
|
|
|
public void onMessagesChanged() {
|
|
|
|
updateNavigationArrows();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onMessageNotFound() {
|
2010-08-17 22:07:28 +00:00
|
|
|
// Current message gone.
|
2010-08-31 20:13:44 +00:00
|
|
|
mFragmentManager.goBackToMailbox();
|
Refactoring MessageListXL
I always thought our Activities are way too fat, meaning we've put too many
things into activities without any structure.
The major problems with this are:
- They have too many fields, which are not final and not even orthogonal.
This makes them very hard to understand/maintain. Changing one tiny bit
can always cause unanticipated side-effects.
- Very hard, or almost impossible to test.
I really think we should break them into independent and self-contained
subcomponents which can be tested separately.
Introducing MessageListXLStateManager, which manages the current account,
mailbox and message, and show/hide/update fragments accordingly
for MessageListXL.
With this class, MessageListXL will be able to switch accounts/mailboxes/
messages by just calling the methods such as selectAccount(), without
worrying about when to show/hide what fragment and how to initialize them.
(In other words, MessageListXLStateManager encapsulates the two-pane screen
transition. It's not intended to be reused for the phone UI.)
I didn't make it a nested class in MessageListXL, because nested classes can't
have real private members (private member are accessible from outer classes and
even brother classes!!), and I wanted it to be really self-contained anyway.
Change-Id: I1c121e99e30f12cc118e1c35abc9b30f49939a4a
2010-07-22 22:01:31 +00:00
|
|
|
}
|
2010-07-21 21:29:49 +00:00
|
|
|
}
|
|
|
|
|
Refactoring MessageListXL
I always thought our Activities are way too fat, meaning we've put too many
things into activities without any structure.
The major problems with this are:
- They have too many fields, which are not final and not even orthogonal.
This makes them very hard to understand/maintain. Changing one tiny bit
can always cause unanticipated side-effects.
- Very hard, or almost impossible to test.
I really think we should break them into independent and self-contained
subcomponents which can be tested separately.
Introducing MessageListXLStateManager, which manages the current account,
mailbox and message, and show/hide/update fragments accordingly
for MessageListXL.
With this class, MessageListXL will be able to switch accounts/mailboxes/
messages by just calling the methods such as selectAccount(), without
worrying about when to show/hide what fragment and how to initialize them.
(In other words, MessageListXLStateManager encapsulates the two-pane screen
transition. It's not intended to be reused for the phone UI.)
I didn't make it a nested class in MessageListXL, because nested classes can't
have real private members (private member are accessible from outer classes and
even brother classes!!), and I wanted it to be really self-contained anyway.
Change-Id: I1c121e99e30f12cc118e1c35abc9b30f49939a4a
2010-07-22 22:01:31 +00:00
|
|
|
/**
|
|
|
|
* Stop {@link MessageOrderManager}.
|
|
|
|
*/
|
2010-07-21 21:29:49 +00:00
|
|
|
private void stopMessageOrderManager() {
|
|
|
|
if (mOrderManager != null) {
|
|
|
|
mOrderManager.close();
|
|
|
|
mOrderManager = null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Refactoring MessageListXL
I always thought our Activities are way too fat, meaning we've put too many
things into activities without any structure.
The major problems with this are:
- They have too many fields, which are not final and not even orthogonal.
This makes them very hard to understand/maintain. Changing one tiny bit
can always cause unanticipated side-effects.
- Very hard, or almost impossible to test.
I really think we should break them into independent and self-contained
subcomponents which can be tested separately.
Introducing MessageListXLStateManager, which manages the current account,
mailbox and message, and show/hide/update fragments accordingly
for MessageListXL.
With this class, MessageListXL will be able to switch accounts/mailboxes/
messages by just calling the methods such as selectAccount(), without
worrying about when to show/hide what fragment and how to initialize them.
(In other words, MessageListXLStateManager encapsulates the two-pane screen
transition. It's not intended to be reused for the phone UI.)
I didn't make it a nested class in MessageListXL, because nested classes can't
have real private members (private member are accessible from outer classes and
even brother classes!!), and I wanted it to be really self-contained anyway.
Change-Id: I1c121e99e30f12cc118e1c35abc9b30f49939a4a
2010-07-22 22:01:31 +00:00
|
|
|
/**
|
|
|
|
* Called when the default account is not found, i.e. there's no account set up.
|
|
|
|
*/
|
2010-07-21 21:29:49 +00:00
|
|
|
private void onNoAccountFound() {
|
|
|
|
// Open Welcome, which in turn shows the adding a new account screen.
|
|
|
|
Welcome.actionStart(this);
|
|
|
|
finish();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
Refactoring MessageListXL
I always thought our Activities are way too fat, meaning we've put too many
things into activities without any structure.
The major problems with this are:
- They have too many fields, which are not final and not even orthogonal.
This makes them very hard to understand/maintain. Changing one tiny bit
can always cause unanticipated side-effects.
- Very hard, or almost impossible to test.
I really think we should break them into independent and self-contained
subcomponents which can be tested separately.
Introducing MessageListXLStateManager, which manages the current account,
mailbox and message, and show/hide/update fragments accordingly
for MessageListXL.
With this class, MessageListXL will be able to switch accounts/mailboxes/
messages by just calling the methods such as selectAccount(), without
worrying about when to show/hide what fragment and how to initialize them.
(In other words, MessageListXLStateManager encapsulates the two-pane screen
transition. It's not intended to be reused for the phone UI.)
I didn't make it a nested class in MessageListXL, because nested classes can't
have real private members (private member are accessible from outer classes and
even brother classes!!), and I wanted it to be really self-contained anyway.
Change-Id: I1c121e99e30f12cc118e1c35abc9b30f49939a4a
2010-07-22 22:01:31 +00:00
|
|
|
/**
|
Let MessageViewFragment own bottom buttons.
Create a custom view containing the bottons below MVF
(delete, move, reply, etc) and let MVF own this.
These buttons used to be owned by the XL activity itself, because
the UI for these commands will most likely be totally different
from the tablet UI, so the fragment having them looked wrong.
However, this made it harder to make changes suggested by the latest
mock, such as "put reply/forward in the message header".
I think the buttons are semantically part of the message view anyway,
so the fragment owning UI for these commands is probably the way to go.
(And let's worry about the phone UI later.)
Reason for the use of a custom view is that it will make it easier
to make non-trivial UI changes, e.g. "combine reply, reply-all and
forward and make it dropdown."
Also removed obsolete TODOs from MessageListXL.
Change-Id: Ibf93f4c70fe07bdbbe33d2adb6bbd2b96812830d
2010-09-16 18:16:46 +00:00
|
|
|
* Disable/enable the move-to-newer/older buttons.
|
Refactoring MessageListXL
I always thought our Activities are way too fat, meaning we've put too many
things into activities without any structure.
The major problems with this are:
- They have too many fields, which are not final and not even orthogonal.
This makes them very hard to understand/maintain. Changing one tiny bit
can always cause unanticipated side-effects.
- Very hard, or almost impossible to test.
I really think we should break them into independent and self-contained
subcomponents which can be tested separately.
Introducing MessageListXLStateManager, which manages the current account,
mailbox and message, and show/hide/update fragments accordingly
for MessageListXL.
With this class, MessageListXL will be able to switch accounts/mailboxes/
messages by just calling the methods such as selectAccount(), without
worrying about when to show/hide what fragment and how to initialize them.
(In other words, MessageListXLStateManager encapsulates the two-pane screen
transition. It's not intended to be reused for the phone UI.)
I didn't make it a nested class in MessageListXL, because nested classes can't
have real private members (private member are accessible from outer classes and
even brother classes!!), and I wanted it to be really self-contained anyway.
Change-Id: I1c121e99e30f12cc118e1c35abc9b30f49939a4a
2010-07-22 22:01:31 +00:00
|
|
|
*/
|
|
|
|
private void updateNavigationArrows() {
|
Let MessageViewFragment own bottom buttons.
Create a custom view containing the bottons below MVF
(delete, move, reply, etc) and let MVF own this.
These buttons used to be owned by the XL activity itself, because
the UI for these commands will most likely be totally different
from the tablet UI, so the fragment having them looked wrong.
However, this made it harder to make changes suggested by the latest
mock, such as "put reply/forward in the message header".
I think the buttons are semantically part of the message view anyway,
so the fragment owning UI for these commands is probably the way to go.
(And let's worry about the phone UI later.)
Reason for the use of a custom view is that it will make it easier
to make non-trivial UI changes, e.g. "combine reply, reply-all and
forward and make it dropdown."
Also removed obsolete TODOs from MessageListXL.
Change-Id: Ibf93f4c70fe07bdbbe33d2adb6bbd2b96812830d
2010-09-16 18:16:46 +00:00
|
|
|
if (mOrderManager == null) {
|
2011-01-11 22:36:00 +00:00
|
|
|
// shouldn't happen, but just in case
|
|
|
|
mFragmentManager.updateMessageCommandButtons(false, false, 0, 0);
|
Let MessageViewFragment own bottom buttons.
Create a custom view containing the bottons below MVF
(delete, move, reply, etc) and let MVF own this.
These buttons used to be owned by the XL activity itself, because
the UI for these commands will most likely be totally different
from the tablet UI, so the fragment having them looked wrong.
However, this made it harder to make changes suggested by the latest
mock, such as "put reply/forward in the message header".
I think the buttons are semantically part of the message view anyway,
so the fragment owning UI for these commands is probably the way to go.
(And let's worry about the phone UI later.)
Reason for the use of a custom view is that it will make it easier
to make non-trivial UI changes, e.g. "combine reply, reply-all and
forward and make it dropdown."
Also removed obsolete TODOs from MessageListXL.
Change-Id: Ibf93f4c70fe07bdbbe33d2adb6bbd2b96812830d
2010-09-16 18:16:46 +00:00
|
|
|
} else {
|
2011-01-11 22:36:00 +00:00
|
|
|
mFragmentManager.updateMessageCommandButtons(
|
|
|
|
mOrderManager.canMoveToNewer(), mOrderManager.canMoveToOlder(),
|
2010-11-08 23:04:10 +00:00
|
|
|
mOrderManager.getCurrentPosition(), mOrderManager.getTotalMessageCount());
|
Let MessageViewFragment own bottom buttons.
Create a custom view containing the bottons below MVF
(delete, move, reply, etc) and let MVF own this.
These buttons used to be owned by the XL activity itself, because
the UI for these commands will most likely be totally different
from the tablet UI, so the fragment having them looked wrong.
However, this made it harder to make changes suggested by the latest
mock, such as "put reply/forward in the message header".
I think the buttons are semantically part of the message view anyway,
so the fragment owning UI for these commands is probably the way to go.
(And let's worry about the phone UI later.)
Reason for the use of a custom view is that it will make it easier
to make non-trivial UI changes, e.g. "combine reply, reply-all and
forward and make it dropdown."
Also removed obsolete TODOs from MessageListXL.
Change-Id: Ibf93f4c70fe07bdbbe33d2adb6bbd2b96812830d
2010-09-16 18:16:46 +00:00
|
|
|
}
|
Refactoring MessageListXL
I always thought our Activities are way too fat, meaning we've put too many
things into activities without any structure.
The major problems with this are:
- They have too many fields, which are not final and not even orthogonal.
This makes them very hard to understand/maintain. Changing one tiny bit
can always cause unanticipated side-effects.
- Very hard, or almost impossible to test.
I really think we should break them into independent and self-contained
subcomponents which can be tested separately.
Introducing MessageListXLStateManager, which manages the current account,
mailbox and message, and show/hide/update fragments accordingly
for MessageListXL.
With this class, MessageListXL will be able to switch accounts/mailboxes/
messages by just calling the methods such as selectAccount(), without
worrying about when to show/hide what fragment and how to initialize them.
(In other words, MessageListXLStateManager encapsulates the two-pane screen
transition. It's not intended to be reused for the phone UI.)
I didn't make it a nested class in MessageListXL, because nested classes can't
have real private members (private member are accessible from outer classes and
even brother classes!!), and I wanted it to be really self-contained anyway.
Change-Id: I1c121e99e30f12cc118e1c35abc9b30f49939a4a
2010-07-22 22:01:31 +00:00
|
|
|
}
|
2010-07-21 21:29:49 +00:00
|
|
|
|
Refactoring MessageListXL
I always thought our Activities are way too fat, meaning we've put too many
things into activities without any structure.
The major problems with this are:
- They have too many fields, which are not final and not even orthogonal.
This makes them very hard to understand/maintain. Changing one tiny bit
can always cause unanticipated side-effects.
- Very hard, or almost impossible to test.
I really think we should break them into independent and self-contained
subcomponents which can be tested separately.
Introducing MessageListXLStateManager, which manages the current account,
mailbox and message, and show/hide/update fragments accordingly
for MessageListXL.
With this class, MessageListXL will be able to switch accounts/mailboxes/
messages by just calling the methods such as selectAccount(), without
worrying about when to show/hide what fragment and how to initialize them.
(In other words, MessageListXLStateManager encapsulates the two-pane screen
transition. It's not intended to be reused for the phone UI.)
I didn't make it a nested class in MessageListXL, because nested classes can't
have real private members (private member are accessible from outer classes and
even brother classes!!), and I wanted it to be really self-contained anyway.
Change-Id: I1c121e99e30f12cc118e1c35abc9b30f49939a4a
2010-07-22 22:01:31 +00:00
|
|
|
private boolean moveToOlder() {
|
|
|
|
if (mFragmentManager.isMessageSelected() && (mOrderManager != null)
|
|
|
|
&& mOrderManager.moveToOlder()) {
|
|
|
|
mFragmentManager.selectMessage(mOrderManager.getCurrentMessageId());
|
|
|
|
return true;
|
2010-07-21 21:29:49 +00:00
|
|
|
}
|
Refactoring MessageListXL
I always thought our Activities are way too fat, meaning we've put too many
things into activities without any structure.
The major problems with this are:
- They have too many fields, which are not final and not even orthogonal.
This makes them very hard to understand/maintain. Changing one tiny bit
can always cause unanticipated side-effects.
- Very hard, or almost impossible to test.
I really think we should break them into independent and self-contained
subcomponents which can be tested separately.
Introducing MessageListXLStateManager, which manages the current account,
mailbox and message, and show/hide/update fragments accordingly
for MessageListXL.
With this class, MessageListXL will be able to switch accounts/mailboxes/
messages by just calling the methods such as selectAccount(), without
worrying about when to show/hide what fragment and how to initialize them.
(In other words, MessageListXLStateManager encapsulates the two-pane screen
transition. It's not intended to be reused for the phone UI.)
I didn't make it a nested class in MessageListXL, because nested classes can't
have real private members (private member are accessible from outer classes and
even brother classes!!), and I wanted it to be really self-contained anyway.
Change-Id: I1c121e99e30f12cc118e1c35abc9b30f49939a4a
2010-07-22 22:01:31 +00:00
|
|
|
return false;
|
2010-07-21 21:29:49 +00:00
|
|
|
}
|
|
|
|
|
Refactoring MessageListXL
I always thought our Activities are way too fat, meaning we've put too many
things into activities without any structure.
The major problems with this are:
- They have too many fields, which are not final and not even orthogonal.
This makes them very hard to understand/maintain. Changing one tiny bit
can always cause unanticipated side-effects.
- Very hard, or almost impossible to test.
I really think we should break them into independent and self-contained
subcomponents which can be tested separately.
Introducing MessageListXLStateManager, which manages the current account,
mailbox and message, and show/hide/update fragments accordingly
for MessageListXL.
With this class, MessageListXL will be able to switch accounts/mailboxes/
messages by just calling the methods such as selectAccount(), without
worrying about when to show/hide what fragment and how to initialize them.
(In other words, MessageListXLStateManager encapsulates the two-pane screen
transition. It's not intended to be reused for the phone UI.)
I didn't make it a nested class in MessageListXL, because nested classes can't
have real private members (private member are accessible from outer classes and
even brother classes!!), and I wanted it to be really self-contained anyway.
Change-Id: I1c121e99e30f12cc118e1c35abc9b30f49939a4a
2010-07-22 22:01:31 +00:00
|
|
|
private boolean moveToNewer() {
|
|
|
|
if (mFragmentManager.isMessageSelected() && (mOrderManager != null)
|
|
|
|
&& mOrderManager.moveToNewer()) {
|
|
|
|
mFragmentManager.selectMessage(mOrderManager.getCurrentMessageId());
|
|
|
|
return true;
|
2010-07-21 21:29:49 +00:00
|
|
|
}
|
Refactoring MessageListXL
I always thought our Activities are way too fat, meaning we've put too many
things into activities without any structure.
The major problems with this are:
- They have too many fields, which are not final and not even orthogonal.
This makes them very hard to understand/maintain. Changing one tiny bit
can always cause unanticipated side-effects.
- Very hard, or almost impossible to test.
I really think we should break them into independent and self-contained
subcomponents which can be tested separately.
Introducing MessageListXLStateManager, which manages the current account,
mailbox and message, and show/hide/update fragments accordingly
for MessageListXL.
With this class, MessageListXL will be able to switch accounts/mailboxes/
messages by just calling the methods such as selectAccount(), without
worrying about when to show/hide what fragment and how to initialize them.
(In other words, MessageListXLStateManager encapsulates the two-pane screen
transition. It's not intended to be reused for the phone UI.)
I didn't make it a nested class in MessageListXL, because nested classes can't
have real private members (private member are accessible from outer classes and
even brother classes!!), and I wanted it to be really self-contained anyway.
Change-Id: I1c121e99e30f12cc118e1c35abc9b30f49939a4a
2010-07-22 22:01:31 +00:00
|
|
|
return false;
|
2010-07-21 21:29:49 +00:00
|
|
|
}
|
|
|
|
|
Refactoring MessageListXL
I always thought our Activities are way too fat, meaning we've put too many
things into activities without any structure.
The major problems with this are:
- They have too many fields, which are not final and not even orthogonal.
This makes them very hard to understand/maintain. Changing one tiny bit
can always cause unanticipated side-effects.
- Very hard, or almost impossible to test.
I really think we should break them into independent and self-contained
subcomponents which can be tested separately.
Introducing MessageListXLStateManager, which manages the current account,
mailbox and message, and show/hide/update fragments accordingly
for MessageListXL.
With this class, MessageListXL will be able to switch accounts/mailboxes/
messages by just calling the methods such as selectAccount(), without
worrying about when to show/hide what fragment and how to initialize them.
(In other words, MessageListXLStateManager encapsulates the two-pane screen
transition. It's not intended to be reused for the phone UI.)
I didn't make it a nested class in MessageListXL, because nested classes can't
have real private members (private member are accessible from outer classes and
even brother classes!!), and I wanted it to be really self-contained anyway.
Change-Id: I1c121e99e30f12cc118e1c35abc9b30f49939a4a
2010-07-22 22:01:31 +00:00
|
|
|
private class MailboxListFragmentCallback implements MailboxListFragment.Callback {
|
|
|
|
@Override
|
|
|
|
public void onMailboxSelected(long accountId, long mailboxId) {
|
2010-12-04 00:28:25 +00:00
|
|
|
mFragmentManager.selectMailbox(mailboxId, -1, true);
|
2010-07-21 21:29:49 +00:00
|
|
|
}
|
2010-10-26 00:51:56 +00:00
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onAccountSelected(long accountId) {
|
2010-12-04 00:28:25 +00:00
|
|
|
mFragmentManager.selectAccount(accountId, -1, -1, true);
|
2010-10-26 00:51:56 +00:00
|
|
|
loadAccounts(); // This will update the account spinner, and select the account.
|
|
|
|
}
|
2010-11-19 20:45:34 +00:00
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onCurrentMailboxUpdated(long mailboxId, String mailboxName, int unreadCount) {
|
|
|
|
mFragmentManager.setCurrentMailboxName(mailboxName, unreadCount);
|
|
|
|
}
|
2010-07-21 21:29:49 +00:00
|
|
|
}
|
|
|
|
|
Refactoring MessageListXL
I always thought our Activities are way too fat, meaning we've put too many
things into activities without any structure.
The major problems with this are:
- They have too many fields, which are not final and not even orthogonal.
This makes them very hard to understand/maintain. Changing one tiny bit
can always cause unanticipated side-effects.
- Very hard, or almost impossible to test.
I really think we should break them into independent and self-contained
subcomponents which can be tested separately.
Introducing MessageListXLStateManager, which manages the current account,
mailbox and message, and show/hide/update fragments accordingly
for MessageListXL.
With this class, MessageListXL will be able to switch accounts/mailboxes/
messages by just calling the methods such as selectAccount(), without
worrying about when to show/hide what fragment and how to initialize them.
(In other words, MessageListXLStateManager encapsulates the two-pane screen
transition. It's not intended to be reused for the phone UI.)
I didn't make it a nested class in MessageListXL, because nested classes can't
have real private members (private member are accessible from outer classes and
even brother classes!!), and I wanted it to be really self-contained anyway.
Change-Id: I1c121e99e30f12cc118e1c35abc9b30f49939a4a
2010-07-22 22:01:31 +00:00
|
|
|
private class MessageListFragmentCallback implements MessageListFragment.Callback {
|
|
|
|
@Override
|
2010-08-10 01:36:44 +00:00
|
|
|
public void onMessageOpen(long messageId, long messageMailboxId, long listMailboxId,
|
|
|
|
int type) {
|
|
|
|
if (type == MessageListFragment.Callback.TYPE_DRAFT) {
|
|
|
|
MessageCompose.actionEditDraft(MessageListXL.this, messageId);
|
|
|
|
} else {
|
|
|
|
mFragmentManager.selectMessage(messageId);
|
|
|
|
}
|
2010-07-21 21:29:49 +00:00
|
|
|
}
|
|
|
|
|
Refactoring MessageListXL
I always thought our Activities are way too fat, meaning we've put too many
things into activities without any structure.
The major problems with this are:
- They have too many fields, which are not final and not even orthogonal.
This makes them very hard to understand/maintain. Changing one tiny bit
can always cause unanticipated side-effects.
- Very hard, or almost impossible to test.
I really think we should break them into independent and self-contained
subcomponents which can be tested separately.
Introducing MessageListXLStateManager, which manages the current account,
mailbox and message, and show/hide/update fragments accordingly
for MessageListXL.
With this class, MessageListXL will be able to switch accounts/mailboxes/
messages by just calling the methods such as selectAccount(), without
worrying about when to show/hide what fragment and how to initialize them.
(In other words, MessageListXLStateManager encapsulates the two-pane screen
transition. It's not intended to be reused for the phone UI.)
I didn't make it a nested class in MessageListXL, because nested classes can't
have real private members (private member are accessible from outer classes and
even brother classes!!), and I wanted it to be really self-contained anyway.
Change-Id: I1c121e99e30f12cc118e1c35abc9b30f49939a4a
2010-07-22 22:01:31 +00:00
|
|
|
@Override
|
2010-08-17 22:07:28 +00:00
|
|
|
public void onMailboxNotFound() {
|
Refactoring MessageListXL
I always thought our Activities are way too fat, meaning we've put too many
things into activities without any structure.
The major problems with this are:
- They have too many fields, which are not final and not even orthogonal.
This makes them very hard to understand/maintain. Changing one tiny bit
can always cause unanticipated side-effects.
- Very hard, or almost impossible to test.
I really think we should break them into independent and self-contained
subcomponents which can be tested separately.
Introducing MessageListXLStateManager, which manages the current account,
mailbox and message, and show/hide/update fragments accordingly
for MessageListXL.
With this class, MessageListXL will be able to switch accounts/mailboxes/
messages by just calling the methods such as selectAccount(), without
worrying about when to show/hide what fragment and how to initialize them.
(In other words, MessageListXLStateManager encapsulates the two-pane screen
transition. It's not intended to be reused for the phone UI.)
I didn't make it a nested class in MessageListXL, because nested classes can't
have real private members (private member are accessible from outer classes and
even brother classes!!), and I wanted it to be really self-contained anyway.
Change-Id: I1c121e99e30f12cc118e1c35abc9b30f49939a4a
2010-07-22 22:01:31 +00:00
|
|
|
// TODO: What to do??
|
|
|
|
}
|
2010-09-22 23:17:53 +00:00
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onEnterSelectionMode(boolean enter) {
|
|
|
|
}
|
2010-07-21 21:29:49 +00:00
|
|
|
}
|
|
|
|
|
2010-07-30 22:41:40 +00:00
|
|
|
private class MessageViewFragmentCallback implements MessageViewFragment.Callback {
|
2010-09-02 01:40:10 +00:00
|
|
|
@Override
|
|
|
|
public void onMessageViewShown(int mailboxType) {
|
|
|
|
updateMessageOrderManager();
|
|
|
|
updateNavigationArrows();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onMessageViewGone() {
|
|
|
|
stopMessageOrderManager();
|
|
|
|
}
|
|
|
|
|
Refactoring MessageListXL
I always thought our Activities are way too fat, meaning we've put too many
things into activities without any structure.
The major problems with this are:
- They have too many fields, which are not final and not even orthogonal.
This makes them very hard to understand/maintain. Changing one tiny bit
can always cause unanticipated side-effects.
- Very hard, or almost impossible to test.
I really think we should break them into independent and self-contained
subcomponents which can be tested separately.
Introducing MessageListXLStateManager, which manages the current account,
mailbox and message, and show/hide/update fragments accordingly
for MessageListXL.
With this class, MessageListXL will be able to switch accounts/mailboxes/
messages by just calling the methods such as selectAccount(), without
worrying about when to show/hide what fragment and how to initialize them.
(In other words, MessageListXLStateManager encapsulates the two-pane screen
transition. It's not intended to be reused for the phone UI.)
I didn't make it a nested class in MessageListXL, because nested classes can't
have real private members (private member are accessible from outer classes and
even brother classes!!), and I wanted it to be really self-contained anyway.
Change-Id: I1c121e99e30f12cc118e1c35abc9b30f49939a4a
2010-07-22 22:01:31 +00:00
|
|
|
@Override
|
|
|
|
public boolean onUrlInMessageClicked(String url) {
|
2010-08-17 22:07:28 +00:00
|
|
|
return ActivityHelper.openUrlInMessage(MessageListXL.this, url,
|
2011-01-07 22:49:05 +00:00
|
|
|
mFragmentManager.getActualAccountId());
|
2010-07-21 21:29:49 +00:00
|
|
|
}
|
Refactoring MessageListXL
I always thought our Activities are way too fat, meaning we've put too many
things into activities without any structure.
The major problems with this are:
- They have too many fields, which are not final and not even orthogonal.
This makes them very hard to understand/maintain. Changing one tiny bit
can always cause unanticipated side-effects.
- Very hard, or almost impossible to test.
I really think we should break them into independent and self-contained
subcomponents which can be tested separately.
Introducing MessageListXLStateManager, which manages the current account,
mailbox and message, and show/hide/update fragments accordingly
for MessageListXL.
With this class, MessageListXL will be able to switch accounts/mailboxes/
messages by just calling the methods such as selectAccount(), without
worrying about when to show/hide what fragment and how to initialize them.
(In other words, MessageListXLStateManager encapsulates the two-pane screen
transition. It's not intended to be reused for the phone UI.)
I didn't make it a nested class in MessageListXL, because nested classes can't
have real private members (private member are accessible from outer classes and
even brother classes!!), and I wanted it to be really self-contained anyway.
Change-Id: I1c121e99e30f12cc118e1c35abc9b30f49939a4a
2010-07-22 22:01:31 +00:00
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onMessageSetUnread() {
|
2010-08-31 20:13:44 +00:00
|
|
|
mFragmentManager.goBackToMailbox();
|
2010-07-21 21:29:49 +00:00
|
|
|
}
|
|
|
|
|
Refactoring MessageListXL
I always thought our Activities are way too fat, meaning we've put too many
things into activities without any structure.
The major problems with this are:
- They have too many fields, which are not final and not even orthogonal.
This makes them very hard to understand/maintain. Changing one tiny bit
can always cause unanticipated side-effects.
- Very hard, or almost impossible to test.
I really think we should break them into independent and self-contained
subcomponents which can be tested separately.
Introducing MessageListXLStateManager, which manages the current account,
mailbox and message, and show/hide/update fragments accordingly
for MessageListXL.
With this class, MessageListXL will be able to switch accounts/mailboxes/
messages by just calling the methods such as selectAccount(), without
worrying about when to show/hide what fragment and how to initialize them.
(In other words, MessageListXLStateManager encapsulates the two-pane screen
transition. It's not intended to be reused for the phone UI.)
I didn't make it a nested class in MessageListXL, because nested classes can't
have real private members (private member are accessible from outer classes and
even brother classes!!), and I wanted it to be really self-contained anyway.
Change-Id: I1c121e99e30f12cc118e1c35abc9b30f49939a4a
2010-07-22 22:01:31 +00:00
|
|
|
@Override
|
|
|
|
public void onMessageNotExists() {
|
2010-08-31 20:13:44 +00:00
|
|
|
mFragmentManager.goBackToMailbox();
|
Refactoring MessageListXL
I always thought our Activities are way too fat, meaning we've put too many
things into activities without any structure.
The major problems with this are:
- They have too many fields, which are not final and not even orthogonal.
This makes them very hard to understand/maintain. Changing one tiny bit
can always cause unanticipated side-effects.
- Very hard, or almost impossible to test.
I really think we should break them into independent and self-contained
subcomponents which can be tested separately.
Introducing MessageListXLStateManager, which manages the current account,
mailbox and message, and show/hide/update fragments accordingly
for MessageListXL.
With this class, MessageListXL will be able to switch accounts/mailboxes/
messages by just calling the methods such as selectAccount(), without
worrying about when to show/hide what fragment and how to initialize them.
(In other words, MessageListXLStateManager encapsulates the two-pane screen
transition. It's not intended to be reused for the phone UI.)
I didn't make it a nested class in MessageListXL, because nested classes can't
have real private members (private member are accessible from outer classes and
even brother classes!!), and I wanted it to be really self-contained anyway.
Change-Id: I1c121e99e30f12cc118e1c35abc9b30f49939a4a
2010-07-22 22:01:31 +00:00
|
|
|
}
|
2010-07-21 21:29:49 +00:00
|
|
|
|
Refactoring MessageListXL
I always thought our Activities are way too fat, meaning we've put too many
things into activities without any structure.
The major problems with this are:
- They have too many fields, which are not final and not even orthogonal.
This makes them very hard to understand/maintain. Changing one tiny bit
can always cause unanticipated side-effects.
- Very hard, or almost impossible to test.
I really think we should break them into independent and self-contained
subcomponents which can be tested separately.
Introducing MessageListXLStateManager, which manages the current account,
mailbox and message, and show/hide/update fragments accordingly
for MessageListXL.
With this class, MessageListXL will be able to switch accounts/mailboxes/
messages by just calling the methods such as selectAccount(), without
worrying about when to show/hide what fragment and how to initialize them.
(In other words, MessageListXLStateManager encapsulates the two-pane screen
transition. It's not intended to be reused for the phone UI.)
I didn't make it a nested class in MessageListXL, because nested classes can't
have real private members (private member are accessible from outer classes and
even brother classes!!), and I wanted it to be really self-contained anyway.
Change-Id: I1c121e99e30f12cc118e1c35abc9b30f49939a4a
2010-07-22 22:01:31 +00:00
|
|
|
@Override
|
|
|
|
public void onLoadMessageStarted() {
|
2010-08-17 22:07:28 +00:00
|
|
|
// TODO Any nice UI for this?
|
Refactoring MessageListXL
I always thought our Activities are way too fat, meaning we've put too many
things into activities without any structure.
The major problems with this are:
- They have too many fields, which are not final and not even orthogonal.
This makes them very hard to understand/maintain. Changing one tiny bit
can always cause unanticipated side-effects.
- Very hard, or almost impossible to test.
I really think we should break them into independent and self-contained
subcomponents which can be tested separately.
Introducing MessageListXLStateManager, which manages the current account,
mailbox and message, and show/hide/update fragments accordingly
for MessageListXL.
With this class, MessageListXL will be able to switch accounts/mailboxes/
messages by just calling the methods such as selectAccount(), without
worrying about when to show/hide what fragment and how to initialize them.
(In other words, MessageListXLStateManager encapsulates the two-pane screen
transition. It's not intended to be reused for the phone UI.)
I didn't make it a nested class in MessageListXL, because nested classes can't
have real private members (private member are accessible from outer classes and
even brother classes!!), and I wanted it to be really self-contained anyway.
Change-Id: I1c121e99e30f12cc118e1c35abc9b30f49939a4a
2010-07-22 22:01:31 +00:00
|
|
|
}
|
2010-07-21 21:29:49 +00:00
|
|
|
|
Refactoring MessageListXL
I always thought our Activities are way too fat, meaning we've put too many
things into activities without any structure.
The major problems with this are:
- They have too many fields, which are not final and not even orthogonal.
This makes them very hard to understand/maintain. Changing one tiny bit
can always cause unanticipated side-effects.
- Very hard, or almost impossible to test.
I really think we should break them into independent and self-contained
subcomponents which can be tested separately.
Introducing MessageListXLStateManager, which manages the current account,
mailbox and message, and show/hide/update fragments accordingly
for MessageListXL.
With this class, MessageListXL will be able to switch accounts/mailboxes/
messages by just calling the methods such as selectAccount(), without
worrying about when to show/hide what fragment and how to initialize them.
(In other words, MessageListXLStateManager encapsulates the two-pane screen
transition. It's not intended to be reused for the phone UI.)
I didn't make it a nested class in MessageListXL, because nested classes can't
have real private members (private member are accessible from outer classes and
even brother classes!!), and I wanted it to be really self-contained anyway.
Change-Id: I1c121e99e30f12cc118e1c35abc9b30f49939a4a
2010-07-22 22:01:31 +00:00
|
|
|
@Override
|
|
|
|
public void onLoadMessageFinished() {
|
2010-08-17 22:07:28 +00:00
|
|
|
// TODO Any nice UI for this?
|
Refactoring MessageListXL
I always thought our Activities are way too fat, meaning we've put too many
things into activities without any structure.
The major problems with this are:
- They have too many fields, which are not final and not even orthogonal.
This makes them very hard to understand/maintain. Changing one tiny bit
can always cause unanticipated side-effects.
- Very hard, or almost impossible to test.
I really think we should break them into independent and self-contained
subcomponents which can be tested separately.
Introducing MessageListXLStateManager, which manages the current account,
mailbox and message, and show/hide/update fragments accordingly
for MessageListXL.
With this class, MessageListXL will be able to switch accounts/mailboxes/
messages by just calling the methods such as selectAccount(), without
worrying about when to show/hide what fragment and how to initialize them.
(In other words, MessageListXLStateManager encapsulates the two-pane screen
transition. It's not intended to be reused for the phone UI.)
I didn't make it a nested class in MessageListXL, because nested classes can't
have real private members (private member are accessible from outer classes and
even brother classes!!), and I wanted it to be really self-contained anyway.
Change-Id: I1c121e99e30f12cc118e1c35abc9b30f49939a4a
2010-07-22 22:01:31 +00:00
|
|
|
}
|
2010-07-21 21:29:49 +00:00
|
|
|
|
Refactoring MessageListXL
I always thought our Activities are way too fat, meaning we've put too many
things into activities without any structure.
The major problems with this are:
- They have too many fields, which are not final and not even orthogonal.
This makes them very hard to understand/maintain. Changing one tiny bit
can always cause unanticipated side-effects.
- Very hard, or almost impossible to test.
I really think we should break them into independent and self-contained
subcomponents which can be tested separately.
Introducing MessageListXLStateManager, which manages the current account,
mailbox and message, and show/hide/update fragments accordingly
for MessageListXL.
With this class, MessageListXL will be able to switch accounts/mailboxes/
messages by just calling the methods such as selectAccount(), without
worrying about when to show/hide what fragment and how to initialize them.
(In other words, MessageListXLStateManager encapsulates the two-pane screen
transition. It's not intended to be reused for the phone UI.)
I didn't make it a nested class in MessageListXL, because nested classes can't
have real private members (private member are accessible from outer classes and
even brother classes!!), and I wanted it to be really self-contained anyway.
Change-Id: I1c121e99e30f12cc118e1c35abc9b30f49939a4a
2010-07-22 22:01:31 +00:00
|
|
|
@Override
|
2010-11-29 19:42:13 +00:00
|
|
|
public void onLoadMessageError(String errorMessage) {
|
Refactoring MessageListXL
I always thought our Activities are way too fat, meaning we've put too many
things into activities without any structure.
The major problems with this are:
- They have too many fields, which are not final and not even orthogonal.
This makes them very hard to understand/maintain. Changing one tiny bit
can always cause unanticipated side-effects.
- Very hard, or almost impossible to test.
I really think we should break them into independent and self-contained
subcomponents which can be tested separately.
Introducing MessageListXLStateManager, which manages the current account,
mailbox and message, and show/hide/update fragments accordingly
for MessageListXL.
With this class, MessageListXL will be able to switch accounts/mailboxes/
messages by just calling the methods such as selectAccount(), without
worrying about when to show/hide what fragment and how to initialize them.
(In other words, MessageListXLStateManager encapsulates the two-pane screen
transition. It's not intended to be reused for the phone UI.)
I didn't make it a nested class in MessageListXL, because nested classes can't
have real private members (private member are accessible from outer classes and
even brother classes!!), and I wanted it to be really self-contained anyway.
Change-Id: I1c121e99e30f12cc118e1c35abc9b30f49939a4a
2010-07-22 22:01:31 +00:00
|
|
|
}
|
2010-07-21 21:29:49 +00:00
|
|
|
|
2010-08-17 22:07:28 +00:00
|
|
|
@Override
|
|
|
|
public void onRespondedToInvite(int response) {
|
2010-09-10 00:23:53 +00:00
|
|
|
onCurrentMessageGone();
|
Refactoring MessageListXL
I always thought our Activities are way too fat, meaning we've put too many
things into activities without any structure.
The major problems with this are:
- They have too many fields, which are not final and not even orthogonal.
This makes them very hard to understand/maintain. Changing one tiny bit
can always cause unanticipated side-effects.
- Very hard, or almost impossible to test.
I really think we should break them into independent and self-contained
subcomponents which can be tested separately.
Introducing MessageListXLStateManager, which manages the current account,
mailbox and message, and show/hide/update fragments accordingly
for MessageListXL.
With this class, MessageListXL will be able to switch accounts/mailboxes/
messages by just calling the methods such as selectAccount(), without
worrying about when to show/hide what fragment and how to initialize them.
(In other words, MessageListXLStateManager encapsulates the two-pane screen
transition. It's not intended to be reused for the phone UI.)
I didn't make it a nested class in MessageListXL, because nested classes can't
have real private members (private member are accessible from outer classes and
even brother classes!!), and I wanted it to be really self-contained anyway.
Change-Id: I1c121e99e30f12cc118e1c35abc9b30f49939a4a
2010-07-22 22:01:31 +00:00
|
|
|
}
|
2010-07-21 21:29:49 +00:00
|
|
|
|
Refactoring MessageListXL
I always thought our Activities are way too fat, meaning we've put too many
things into activities without any structure.
The major problems with this are:
- They have too many fields, which are not final and not even orthogonal.
This makes them very hard to understand/maintain. Changing one tiny bit
can always cause unanticipated side-effects.
- Very hard, or almost impossible to test.
I really think we should break them into independent and self-contained
subcomponents which can be tested separately.
Introducing MessageListXLStateManager, which manages the current account,
mailbox and message, and show/hide/update fragments accordingly
for MessageListXL.
With this class, MessageListXL will be able to switch accounts/mailboxes/
messages by just calling the methods such as selectAccount(), without
worrying about when to show/hide what fragment and how to initialize them.
(In other words, MessageListXLStateManager encapsulates the two-pane screen
transition. It's not intended to be reused for the phone UI.)
I didn't make it a nested class in MessageListXL, because nested classes can't
have real private members (private member are accessible from outer classes and
even brother classes!!), and I wanted it to be really self-contained anyway.
Change-Id: I1c121e99e30f12cc118e1c35abc9b30f49939a4a
2010-07-22 22:01:31 +00:00
|
|
|
@Override
|
|
|
|
public void onCalendarLinkClicked(long epochEventStartTime) {
|
2010-08-17 22:07:28 +00:00
|
|
|
ActivityHelper.openCalendar(MessageListXL.this, epochEventStartTime);
|
Refactoring MessageListXL
I always thought our Activities are way too fat, meaning we've put too many
things into activities without any structure.
The major problems with this are:
- They have too many fields, which are not final and not even orthogonal.
This makes them very hard to understand/maintain. Changing one tiny bit
can always cause unanticipated side-effects.
- Very hard, or almost impossible to test.
I really think we should break them into independent and self-contained
subcomponents which can be tested separately.
Introducing MessageListXLStateManager, which manages the current account,
mailbox and message, and show/hide/update fragments accordingly
for MessageListXL.
With this class, MessageListXL will be able to switch accounts/mailboxes/
messages by just calling the methods such as selectAccount(), without
worrying about when to show/hide what fragment and how to initialize them.
(In other words, MessageListXLStateManager encapsulates the two-pane screen
transition. It's not intended to be reused for the phone UI.)
I didn't make it a nested class in MessageListXL, because nested classes can't
have real private members (private member are accessible from outer classes and
even brother classes!!), and I wanted it to be really self-contained anyway.
Change-Id: I1c121e99e30f12cc118e1c35abc9b30f49939a4a
2010-07-22 22:01:31 +00:00
|
|
|
}
|
2010-07-21 21:29:49 +00:00
|
|
|
|
Let MessageViewFragment own bottom buttons.
Create a custom view containing the bottons below MVF
(delete, move, reply, etc) and let MVF own this.
These buttons used to be owned by the XL activity itself, because
the UI for these commands will most likely be totally different
from the tablet UI, so the fragment having them looked wrong.
However, this made it harder to make changes suggested by the latest
mock, such as "put reply/forward in the message header".
I think the buttons are semantically part of the message view anyway,
so the fragment owning UI for these commands is probably the way to go.
(And let's worry about the phone UI later.)
Reason for the use of a custom view is that it will make it easier
to make non-trivial UI changes, e.g. "combine reply, reply-all and
forward and make it dropdown."
Also removed obsolete TODOs from MessageListXL.
Change-Id: Ibf93f4c70fe07bdbbe33d2adb6bbd2b96812830d
2010-09-16 18:16:46 +00:00
|
|
|
@Override
|
|
|
|
public void onBeforeMessageDelete() {
|
|
|
|
onCurrentMessageGone();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onMoveMessage() {
|
|
|
|
MessageListXL.this.onMoveMessage();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onForward() {
|
|
|
|
MessageCompose.actionForward(MessageListXL.this, mFragmentManager.getMessageId());
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onReply() {
|
|
|
|
MessageCompose.actionReply(MessageListXL.this, mFragmentManager.getMessageId(), false);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onReplyAll() {
|
|
|
|
MessageCompose.actionReply(MessageListXL.this, mFragmentManager.getMessageId(), true);
|
|
|
|
}
|
2010-07-21 21:29:49 +00:00
|
|
|
}
|
2010-07-26 18:14:09 +00:00
|
|
|
|
2010-08-04 23:23:26 +00:00
|
|
|
@Override
|
2010-09-09 21:13:47 +00:00
|
|
|
public void onAccountSecurityHold(long accountId) {
|
|
|
|
startActivity(AccountSecurity.actionUpdateSecurityIntent(this, accountId));
|
2010-08-04 23:23:26 +00:00
|
|
|
}
|
|
|
|
|
2011-01-04 22:02:09 +00:00
|
|
|
@Override
|
|
|
|
public void onAccountChanged(long accountId) {
|
|
|
|
invalidateOptionsMenu(); // Update the refresh button
|
|
|
|
}
|
|
|
|
|
2010-09-13 23:35:58 +00:00
|
|
|
@Override
|
|
|
|
public void onMailboxChanged(long accountId, long newMailboxId) {
|
|
|
|
updateProgressIcon();
|
|
|
|
}
|
|
|
|
|
2011-01-11 22:36:00 +00:00
|
|
|
@Override
|
|
|
|
public void onMoveToNewer() {
|
|
|
|
moveToNewer();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onMoveToOlder() {
|
|
|
|
moveToOlder();
|
|
|
|
}
|
|
|
|
|
2010-12-07 23:17:52 +00:00
|
|
|
/**
|
|
|
|
* Call this when getting a connection error.
|
|
|
|
*/
|
2011-01-25 19:07:42 +00:00
|
|
|
private void showErrorMessage(final String rawMessage, final long accountId) {
|
|
|
|
new AsyncTask<Void, Void, String>() {
|
|
|
|
@Override
|
|
|
|
protected String doInBackground(Void... params) {
|
|
|
|
Account account = Account.restoreAccountWithId(MessageListXL.this, accountId);
|
|
|
|
return (account == null) ? null : account.mDisplayName;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onPostExecute(String accountName) {
|
|
|
|
if (!mIsCreated) {
|
|
|
|
return; // activity destroyed.
|
|
|
|
}
|
|
|
|
final String message;
|
|
|
|
if (TextUtils.isEmpty(accountName)) {
|
|
|
|
message = rawMessage;
|
|
|
|
} else {
|
|
|
|
// TODO Use properly designed layout. Don't just concat strings, which isn't
|
|
|
|
// good for I18N either.
|
|
|
|
message = rawMessage + " (" + accountName + ")";
|
|
|
|
}
|
|
|
|
if (mBannerController.show(message)) {
|
|
|
|
mLastErrorAccountId = accountId;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}.execute();
|
|
|
|
|
2010-12-07 23:17:52 +00:00
|
|
|
}
|
2010-11-29 19:42:13 +00:00
|
|
|
|
2010-12-07 23:17:52 +00:00
|
|
|
/**
|
|
|
|
* Call this when the connection for an account is considered working.
|
|
|
|
*/
|
|
|
|
private void clearErrorMessage(long accountId) {
|
|
|
|
if (mLastErrorAccountId == accountId) {
|
|
|
|
dismissErrorMessage();
|
2010-11-29 19:42:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-12-07 23:17:52 +00:00
|
|
|
/**
|
|
|
|
* Force dismiss the error banner.
|
|
|
|
*/
|
2010-11-29 19:42:13 +00:00
|
|
|
private void dismissErrorMessage() {
|
2010-12-07 23:17:52 +00:00
|
|
|
mBannerController.dismiss();
|
2010-11-29 19:42:13 +00:00
|
|
|
}
|
|
|
|
|
2010-10-26 00:51:56 +00:00
|
|
|
/**
|
|
|
|
* Load account list for the action bar.
|
|
|
|
*
|
|
|
|
* If there's only one account configured, show the account name in the action bar.
|
|
|
|
* If more than one account are configured, show a spinner in the action bar, and select the
|
|
|
|
* current account.
|
|
|
|
*/
|
2010-07-28 18:42:37 +00:00
|
|
|
private void loadAccounts() {
|
|
|
|
getLoaderManager().initLoader(LOADER_ID_ACCOUNT_LIST, null, new LoaderCallbacks<Cursor>() {
|
|
|
|
@Override
|
|
|
|
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
|
|
|
|
return AccountSelectorAdapter.createLoader(mContext);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
|
|
|
|
updateAccountList(data);
|
|
|
|
}
|
2010-12-16 08:44:50 +00:00
|
|
|
|
2010-12-17 21:31:25 +00:00
|
|
|
@Override
|
2010-12-16 08:44:50 +00:00
|
|
|
public void onLoaderReset(Loader<Cursor> loader) {
|
2010-12-17 21:31:25 +00:00
|
|
|
mAccountsSelectorAdapter.swapCursor(null);
|
2010-12-16 08:44:50 +00:00
|
|
|
}
|
2010-07-28 18:42:37 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
private void updateAccountList(Cursor accountsCursor) {
|
2010-08-25 23:04:55 +00:00
|
|
|
final int count = accountsCursor.getCount();
|
|
|
|
if (count == 0) {
|
2010-07-28 18:42:37 +00:00
|
|
|
onNoAccountFound();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2010-08-25 23:04:55 +00:00
|
|
|
// If ony one acount, don't show dropdown.
|
|
|
|
final ActionBar ab = getActionBar();
|
|
|
|
if (count == 1) {
|
|
|
|
accountsCursor.moveToFirst();
|
2010-12-16 19:32:28 +00:00
|
|
|
|
|
|
|
// Show the account name as the title.
|
|
|
|
ab.setDisplayOptions(ActionBar.DISPLAY_SHOW_TITLE, ActionBar.DISPLAY_SHOW_TITLE);
|
2010-11-05 19:05:40 +00:00
|
|
|
ab.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
|
2010-09-15 23:20:01 +00:00
|
|
|
ab.setTitle(AccountSelectorAdapter.getAccountDisplayName(accountsCursor));
|
2010-08-25 23:04:55 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2010-07-28 18:42:37 +00:00
|
|
|
// Find the currently selected account, and select it.
|
|
|
|
int defaultSelection = 0;
|
|
|
|
if (mFragmentManager.isAccountSelected()) {
|
2010-08-04 18:33:52 +00:00
|
|
|
accountsCursor.moveToPosition(-1);
|
2010-07-28 18:42:37 +00:00
|
|
|
int i = 0;
|
|
|
|
while (accountsCursor.moveToNext()) {
|
|
|
|
final long accountId = AccountSelectorAdapter.getAccountId(accountsCursor);
|
2011-01-07 22:49:05 +00:00
|
|
|
if (accountId == mFragmentManager.getUIAccountId()) {
|
2010-07-28 18:42:37 +00:00
|
|
|
defaultSelection = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Update the dropdown list.
|
2010-12-17 21:31:25 +00:00
|
|
|
mAccountsSelectorAdapter.swapCursor(accountsCursor);
|
2010-12-16 19:32:28 +00:00
|
|
|
|
|
|
|
// Don't show the title.
|
|
|
|
ab.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE);
|
2010-11-05 19:05:40 +00:00
|
|
|
ab.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
|
|
|
|
ab.setListNavigationCallbacks(mAccountsSelectorAdapter, mActionBarNavigationCallback);
|
|
|
|
ab.setSelectedNavigationItem(defaultSelection);
|
2010-07-28 18:42:37 +00:00
|
|
|
}
|
|
|
|
|
2010-12-01 21:12:58 +00:00
|
|
|
private class ActionBarNavigationCallback implements ActionBar.OnNavigationListener {
|
2010-07-28 18:42:37 +00:00
|
|
|
@Override
|
|
|
|
public boolean onNavigationItemSelected(int itemPosition, long accountId) {
|
2010-12-14 00:32:02 +00:00
|
|
|
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
|
|
|
|
Log.d(Email.LOG_TAG, "Account selected: accountId=" + accountId);
|
|
|
|
}
|
2010-12-04 00:28:25 +00:00
|
|
|
mFragmentManager.selectAccount(accountId, -1, -1, true);
|
2010-07-28 18:42:37 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-08-16 21:14:40 +00:00
|
|
|
private class RefreshListener
|
|
|
|
implements RefreshManager.Listener {
|
|
|
|
@Override
|
2010-10-19 21:27:21 +00:00
|
|
|
public void onMessagingError(final long accountId, long mailboxId, final String message) {
|
2010-09-13 23:35:58 +00:00
|
|
|
updateProgressIcon();
|
2010-08-16 21:14:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onRefreshStatusChanged(long accountId, long mailboxId) {
|
2010-09-13 23:35:58 +00:00
|
|
|
updateProgressIcon();
|
2010-08-16 21:14:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-09-13 23:35:58 +00:00
|
|
|
/**
|
|
|
|
* If we're refreshing the current mailbox, animate the "mailbox refreshing" progress icon.
|
|
|
|
*/
|
|
|
|
private void updateProgressIcon() {
|
2011-01-25 22:46:11 +00:00
|
|
|
invalidateOptionsMenu();
|
2010-09-13 23:35:58 +00:00
|
|
|
}
|
|
|
|
|
2010-08-16 21:14:40 +00:00
|
|
|
private boolean isProgressActive() {
|
|
|
|
final long mailboxId = mFragmentManager.getMailboxId();
|
|
|
|
return (mailboxId >= 0) && mRefreshManager.isMessageListRefreshing(mailboxId);
|
|
|
|
}
|
|
|
|
|
2010-08-04 23:54:08 +00:00
|
|
|
@Override
|
|
|
|
public boolean onCreateOptionsMenu(Menu menu) {
|
|
|
|
super.onCreateOptionsMenu(menu);
|
|
|
|
getMenuInflater().inflate(R.menu.message_list_xl_option, menu);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2011-01-04 22:02:09 +00:00
|
|
|
@Override
|
|
|
|
public boolean onPrepareOptionsMenu(Menu menu) {
|
|
|
|
MenuItem item = menu.findItem(R.id.refresh);
|
|
|
|
if (item != null) {
|
|
|
|
item.setVisible(shouldShowRefreshButton());
|
2011-01-25 22:46:11 +00:00
|
|
|
if (isProgressActive()) {
|
|
|
|
// Turn it into a progress icon.
|
|
|
|
item.setActionView(R.layout.action_bar_indeterminate_progress);
|
|
|
|
} else {
|
|
|
|
item.setActionView(null);
|
|
|
|
}
|
2011-01-04 22:02:09 +00:00
|
|
|
}
|
|
|
|
return super.onPrepareOptionsMenu(menu);
|
|
|
|
}
|
|
|
|
|
|
|
|
private boolean shouldShowRefreshButton() {
|
2011-01-07 22:49:05 +00:00
|
|
|
return -1 != mFragmentManager.getActualAccountId();
|
2011-01-04 22:02:09 +00:00
|
|
|
}
|
|
|
|
|
2010-08-04 23:54:08 +00:00
|
|
|
@Override
|
|
|
|
public boolean onOptionsItemSelected(MenuItem item) {
|
|
|
|
switch (item.getItemId()) {
|
2010-11-12 00:28:21 +00:00
|
|
|
case android.R.id.home:
|
|
|
|
// Comes from the action bar when the app icon on the left is pressed.
|
2010-11-16 19:11:22 +00:00
|
|
|
// It works like a back press, but it won't close the activity.
|
|
|
|
return onBackPressed(false);
|
2010-08-04 23:54:08 +00:00
|
|
|
case R.id.compose:
|
|
|
|
return onCompose();
|
|
|
|
case R.id.refresh:
|
2010-08-16 21:14:40 +00:00
|
|
|
onRefresh();
|
2010-08-04 23:54:08 +00:00
|
|
|
return true;
|
|
|
|
case R.id.account_settings:
|
2010-08-10 00:25:42 +00:00
|
|
|
return onAccountSettings();
|
2010-08-04 23:54:08 +00:00
|
|
|
}
|
|
|
|
return super.onOptionsItemSelected(item);
|
|
|
|
}
|
|
|
|
|
|
|
|
private boolean onCompose() {
|
|
|
|
if (!mFragmentManager.isAccountSelected()) {
|
|
|
|
return false; // this shouldn't really happen
|
|
|
|
}
|
2011-01-07 22:49:05 +00:00
|
|
|
MessageCompose.actionCompose(this, mFragmentManager.getActualAccountId());
|
2010-08-04 23:54:08 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2010-08-10 00:25:42 +00:00
|
|
|
private boolean onAccountSettings() {
|
2011-01-07 22:49:05 +00:00
|
|
|
AccountSettingsXL.actionSettings(this, mFragmentManager.getActualAccountId());
|
2010-08-10 00:25:42 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2010-08-16 21:14:40 +00:00
|
|
|
private void onRefresh() {
|
2010-08-27 17:25:03 +00:00
|
|
|
// Cancel previously running instance if any.
|
|
|
|
Utility.cancelTaskInterrupt(mRefreshTask);
|
2011-01-07 22:49:05 +00:00
|
|
|
mRefreshTask = new RefreshTask(this, mFragmentManager.getActualAccountId(),
|
2010-08-27 17:25:03 +00:00
|
|
|
mFragmentManager.getMailboxId());
|
|
|
|
mRefreshTask.execute();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Class to handle refresh.
|
|
|
|
*
|
|
|
|
* When the user press "refresh",
|
|
|
|
* <ul>
|
|
|
|
* <li>Refresh the current mailbox, if it's refreshable. (e.g. don't refresh combined inbox,
|
|
|
|
* drafts, etc.
|
|
|
|
* <li>Refresh the mailbox list, if it hasn't been refreshed in the last
|
|
|
|
* {@link #MAILBOX_REFRESH_MIN_INTERVAL}.
|
|
|
|
* <li>Refresh inbox, if it's not the current mailbox and it hasn't been refreshed in the last
|
|
|
|
* {@link #INBOX_AUTO_REFRESH_MIN_INTERVAL}.
|
|
|
|
* </ul>
|
|
|
|
*/
|
|
|
|
/* package */ static class RefreshTask extends AsyncTask<Void, Void, Boolean> {
|
|
|
|
private final Clock mClock;
|
|
|
|
private final Context mContext;
|
|
|
|
private final long mAccountId;
|
|
|
|
private final long mMailboxId;
|
|
|
|
private final RefreshManager mRefreshManager;
|
|
|
|
/* package */ long mInboxId;
|
|
|
|
|
|
|
|
public RefreshTask(Context context, long accountId, long mailboxId) {
|
|
|
|
this(context, accountId, mailboxId, Clock.INSTANCE,
|
|
|
|
RefreshManager.getInstance(context));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* package */ RefreshTask(Context context, long accountId, long mailboxId, Clock clock,
|
|
|
|
RefreshManager refreshManager) {
|
|
|
|
mClock = clock;
|
|
|
|
mContext = context;
|
|
|
|
mRefreshManager = refreshManager;
|
|
|
|
mAccountId = accountId;
|
|
|
|
mMailboxId = mailboxId;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Do DB access on a worker thread.
|
|
|
|
*/
|
|
|
|
@Override
|
|
|
|
protected Boolean doInBackground(Void... params) {
|
|
|
|
mInboxId = Account.getInboxId(mContext, mAccountId);
|
|
|
|
return Mailbox.isRefreshable(mContext, mMailboxId);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Do the actual refresh.
|
|
|
|
*/
|
|
|
|
@Override
|
|
|
|
protected void onPostExecute(Boolean isCurrentMailboxRefreshable) {
|
|
|
|
if (isCancelled() || isCurrentMailboxRefreshable == null) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (isCurrentMailboxRefreshable) {
|
2010-12-21 03:00:20 +00:00
|
|
|
mRefreshManager.refreshMessageList(mAccountId, mMailboxId, false);
|
2010-08-27 17:25:03 +00:00
|
|
|
}
|
|
|
|
// Refresh mailbox list
|
|
|
|
if (mAccountId != -1) {
|
|
|
|
if (shouldRefreshMailboxList()) {
|
|
|
|
mRefreshManager.refreshMailboxList(mAccountId);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Refresh inbox
|
|
|
|
if (shouldAutoRefreshInbox()) {
|
2010-12-21 03:00:20 +00:00
|
|
|
mRefreshManager.refreshMessageList(mAccountId, mInboxId, false);
|
2010-08-18 22:39:55 +00:00
|
|
|
}
|
2010-08-16 21:14:40 +00:00
|
|
|
}
|
|
|
|
|
2010-08-27 17:25:03 +00:00
|
|
|
/**
|
|
|
|
* @return true if the mailbox list of the current account hasn't been refreshed
|
|
|
|
* in the last {@link #MAILBOX_REFRESH_MIN_INTERVAL}.
|
|
|
|
*/
|
|
|
|
/* package */ boolean shouldRefreshMailboxList() {
|
|
|
|
if (mRefreshManager.isMailboxListRefreshing(mAccountId)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
final long nextRefreshTime = mRefreshManager.getLastMailboxListRefreshTime(mAccountId)
|
|
|
|
+ MAILBOX_REFRESH_MIN_INTERVAL;
|
|
|
|
if (nextRefreshTime > mClock.getTime()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
2010-08-16 21:14:40 +00:00
|
|
|
|
2010-08-27 17:25:03 +00:00
|
|
|
/**
|
|
|
|
* @return true if the inbox of the current account hasn't been refreshed
|
|
|
|
* in the last {@link #INBOX_AUTO_REFRESH_MIN_INTERVAL}.
|
|
|
|
*/
|
|
|
|
/* package */ boolean shouldAutoRefreshInbox() {
|
|
|
|
if (mInboxId == mMailboxId) {
|
|
|
|
return false; // Current ID == inbox. No need to auto-refresh.
|
|
|
|
}
|
|
|
|
if (mRefreshManager.isMessageListRefreshing(mInboxId)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
final long nextRefreshTime = mRefreshManager.getLastMessageListRefreshTime(mInboxId)
|
|
|
|
+ INBOX_AUTO_REFRESH_MIN_INTERVAL;
|
|
|
|
if (nextRefreshTime > mClock.getTime()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
2010-08-16 21:14:40 +00:00
|
|
|
}
|
2010-12-07 23:17:52 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* A {@link Controller.Result} to detect connection status.
|
|
|
|
*/
|
|
|
|
private class ControllerResult extends Controller.Result {
|
|
|
|
@Override
|
|
|
|
public void sendMailCallback(
|
|
|
|
MessagingException result, long accountId, long messageId, int progress) {
|
|
|
|
handleError(result, accountId, progress);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void serviceCheckMailCallback(
|
|
|
|
MessagingException result, long accountId, long mailboxId, int progress, long tag) {
|
|
|
|
handleError(result, accountId, progress);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void updateMailboxCallback(MessagingException result, long accountId, long mailboxId,
|
|
|
|
int progress, int numNewMessages) {
|
|
|
|
handleError(result, accountId, progress);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void updateMailboxListCallback(
|
|
|
|
MessagingException result, long accountId, int progress) {
|
|
|
|
handleError(result, accountId, progress);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2010-12-10 21:36:18 +00:00
|
|
|
public void loadAttachmentCallback(MessagingException result, long accountId,
|
|
|
|
long messageId, long attachmentId, int progress) {
|
|
|
|
handleError(result, accountId, progress);
|
2010-12-07 23:17:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2010-12-10 21:36:18 +00:00
|
|
|
public void loadMessageForViewCallback(MessagingException result, long accountId,
|
|
|
|
long messageId, int progress) {
|
|
|
|
handleError(result, accountId, progress);
|
2010-12-07 23:17:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private void handleError(MessagingException result, long accountId, int progress) {
|
|
|
|
if (accountId == -1) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (result == null) {
|
|
|
|
if (progress > 0) {
|
|
|
|
// Connection now working.
|
|
|
|
clearErrorMessage(accountId);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// Connection error.
|
|
|
|
showErrorMessage(result.getUiErrorMessage(MessageListXL.this), accountId);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2010-07-21 21:29:49 +00:00
|
|
|
}
|