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;
}