diff --git a/res/values/strings.xml b/res/values/strings.xml index 0fb3f3c..3bb1c54 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -7,6 +7,11 @@ Open nav Close nav + Enter password: + Password was incorrect + Could not read password verification file + Not authenticated + Inbox Outbox Sent diff --git a/src/i2p/bote/EmailListFragment.java b/src/i2p/bote/EmailListFragment.java index 5e8aa7a..7e906c8 100644 --- a/src/i2p/bote/EmailListFragment.java +++ b/src/i2p/bote/EmailListFragment.java @@ -1,7 +1,12 @@ package i2p.bote; +import java.io.IOException; +import java.security.GeneralSecurityException; import java.util.List; +import net.i2p.I2PAppContext; +import net.i2p.util.Log; + import i2p.bote.email.Email; import i2p.bote.fileencryption.PasswordException; import i2p.bote.folder.EmailFolder; @@ -9,12 +14,16 @@ import i2p.bote.folder.FolderListener; import i2p.bote.util.BetterAsyncTaskLoader; import i2p.bote.util.BoteHelper; import android.app.Activity; +import android.app.AlertDialog; import android.content.Context; +import android.content.DialogInterface; import android.os.Bundle; import android.support.v4.app.ListFragment; import android.support.v4.app.LoaderManager; import android.support.v4.content.Loader; +import android.view.LayoutInflater; import android.view.View; +import android.widget.EditText; import android.widget.ListView; public class EmailListFragment extends ListFragment implements @@ -69,20 +78,70 @@ public class EmailListFragment extends ListFragment implements R.string.folder_does_not_exist)); getActivity().setTitle(getResources().getString(R.string.app_name)); } else { - setListShown(false); - setEmptyText(getResources().getString( - R.string.folder_empty)); - try { - getActivity().setTitle( - BoteHelper.getFolderDisplayName(getActivity(), mFolder, false)); - } catch (PasswordException e) { - // TODO: Get password from user and retry - getActivity().setTitle("ERROR: " + e.getMessage()); + getActivity().setTitle( + BoteHelper.getFolderDisplayName(getActivity(), mFolder)); + if (I2PBote.getInstance().isPasswordRequired()) { + // Request a password from the user. + requestPassword(); + } else { + // Password is cached, or not set. + initializeList(); } - getLoaderManager().initLoader(EMAIL_LIST_LOADER, null, this); } } + /** + * Request the password from the user, and try it. + */ + private void requestPassword() { + LayoutInflater li = LayoutInflater.from(getActivity()); + View promptView = li.inflate(R.layout.dialog_password, null); + AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + builder.setView(promptView); + final EditText input = (EditText) promptView.findViewById(R.id.passwordInput); + + builder.setPositiveButton("OK", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int id) { + try { + if (BoteHelper.tryPassword(input.getText().toString())) + initializeList(); + else + setEmptyText(getResources().getString( + R.string.password_incorrect)); + } catch (IOException e) { + setEmptyText(getResources().getString( + R.string.password_file_error)); + } catch (GeneralSecurityException e) { + setEmptyText(getResources().getString( + R.string.password_file_error)); + } + dialog.dismiss(); + } + }).setNegativeButton("Cancel", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int id) { + setEmptyText(getResources().getString( + R.string.not_authed)); + dialog.cancel(); + } + }); + AlertDialog passwordDialog = builder.create(); + passwordDialog.show(); + } + + /** + * Start loading the list of emails from this folder. + * Only called when we have a password cached, or no + * password is required. + */ + private void initializeList() { + setListShown(false); + setEmptyText(getResources().getString( + R.string.folder_empty)); + getLoaderManager().initLoader(EMAIL_LIST_LOADER, null, this); + } + @Override public void onListItemClick(ListView parent, View view, int pos, long id) { super.onListItemClick(parent, view, pos, id); @@ -111,7 +170,7 @@ public class EmailListFragment extends ListFragment implements try { emails = BoteHelper.getEmails(mFolder, null, true); } catch (PasswordException pe) { - // TODO: Handle this error properly (get user to log in) + // XXX: Should not get here. } return emails; } @@ -145,10 +204,12 @@ public class EmailListFragment extends ListFragment implements mAdapter.setData(data); try { getActivity().setTitle( - BoteHelper.getFolderDisplayName(getActivity(), mFolder, true)); + BoteHelper.getFolderDisplayNameWithNew(getActivity(), mFolder)); } catch (PasswordException e) { - // TODO: Get password from user and retry - getActivity().setTitle("ERROR: " + e.getMessage()); + // Should not get here. + Log log = I2PAppContext.getGlobalContext().logManager().getLog(EmailListFragment.class); + if (log.shouldLog(Log.WARN)) + log.warn("Email list loader finished, but password is no longer cached", e); } if (isResumed()) { @@ -160,12 +221,7 @@ public class EmailListFragment extends ListFragment implements public void onLoaderReset(Loader> loader) { mAdapter.setData(null); - try { - getActivity().setTitle( - BoteHelper.getFolderDisplayName(getActivity(), mFolder, false)); - } catch (PasswordException e) { - // TODO: Get password from user and retry - getActivity().setTitle("ERROR: " + e.getMessage()); - } + getActivity().setTitle( + BoteHelper.getFolderDisplayName(getActivity(), mFolder)); } } diff --git a/src/i2p/bote/FolderListAdapter.java b/src/i2p/bote/FolderListAdapter.java index ee2b66e..f4bdc5a 100644 --- a/src/i2p/bote/FolderListAdapter.java +++ b/src/i2p/bote/FolderListAdapter.java @@ -37,10 +37,10 @@ public class FolderListAdapter extends ArrayAdapter { TextView name = (TextView) v.findViewById(R.id.folder_name); // TODO: This needs to be updated when emails change. try { - name.setText(BoteHelper.getFolderDisplayName(getContext(), folder, true)); + name.setText(BoteHelper.getFolderDisplayNameWithNew(getContext(), folder)); } catch (PasswordException e) { - // TODO: Get password from user and retry - name.setText("ERROR: " + e.getMessage()); + // Password fetching is handled in EmailListFragment + name.setText(BoteHelper.getFolderDisplayName(getContext(), folder)); } return v; diff --git a/src/i2p/bote/util/BoteHelper.java b/src/i2p/bote/util/BoteHelper.java index 8eec0eb..d417da8 100644 --- a/src/i2p/bote/util/BoteHelper.java +++ b/src/i2p/bote/util/BoteHelper.java @@ -22,26 +22,34 @@ public class BoteHelper extends GeneralHelper { * @return The name of the folder. * @throws PasswordException */ - public static String getFolderDisplayName(Context ctx, EmailFolder folder, boolean showNew) throws PasswordException { - String displayName = ""; - + public static String getFolderDisplayName(Context ctx, EmailFolder folder) { String name = folder.getName(); if ("inbox".equals(name)) - displayName = ctx.getResources().getString(R.string.folder_inbox); + return ctx.getResources().getString(R.string.folder_inbox); else if ("outbox".equals(name)) - displayName = ctx.getResources().getString(R.string.folder_outbox); + return ctx.getResources().getString(R.string.folder_outbox); else if ("sent".equals(name)) - displayName = ctx.getResources().getString(R.string.folder_sent); + return ctx.getResources().getString(R.string.folder_sent); else if ("trash".equals(name)) - displayName = ctx.getResources().getString(R.string.folder_trash); + return ctx.getResources().getString(R.string.folder_trash); else - displayName = name; + return name; + } - if (showNew) { - int numNew = folder.getNumNewEmails(); - if (numNew > 0) - displayName = displayName + " (" + numNew + ")"; - } + /** + * Get the translated name of the folder with the number of + * new messages it contains appended. + * @param ctx Android Context to get strings from. + * @param folder The folder. + * @return The name of the folder. + * @throws PasswordException + */ + public static String getFolderDisplayNameWithNew(Context ctx, EmailFolder folder) throws PasswordException { + String displayName = getFolderDisplayName(ctx, folder); + + int numNew = folder.getNumNewEmails(); + if (numNew > 0) + displayName = displayName + " (" + numNew + ")"; return displayName; }