Added edit page for identities
This commit is contained in:
@@ -32,6 +32,9 @@
|
||||
<activity
|
||||
android:name="i2p.bote.SetPasswordActivity"
|
||||
android:parentActivityName="i2p.bote.SettingsActivity" />
|
||||
<activity
|
||||
android:name="i2p.bote.EditIdentityActivity"
|
||||
android:parentActivityName="i2p.bote.SettingsActivity" />
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
|
||||
23
res/layout/activity_edit_identity.xml
Normal file
23
res/layout/activity_edit_identity.xml
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" >
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/edit_identity_frag"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/identity_waiter_frag"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
||||
57
res/layout/fragment_edit_identity.xml
Normal file
57
res/layout/fragment_edit_identity.xml
Normal file
@@ -0,0 +1,57 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/identity_picture"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@drawable/ic_launcher" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/public_name"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/public_name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ems="10"
|
||||
android:inputType="text" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/description"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/description"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ems="10"
|
||||
android:inputType="text" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal" >
|
||||
|
||||
<Button
|
||||
android:id="@+id/submit_identity"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="OK" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/error"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/error_color" />
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -53,4 +53,9 @@
|
||||
<string name="new_password">New password:</string>
|
||||
<string name="confirm_new_password">Confirm new password:</string>
|
||||
<string name="password_changed">Password changed successfully</string>
|
||||
|
||||
<string name="pref_title_identities">Identities</string>
|
||||
<string name="public_name">Public name:</string>
|
||||
<string name="description">Description:</string>
|
||||
<string name="identity_saved">Identity saved</string>
|
||||
</resources>
|
||||
|
||||
@@ -16,6 +16,6 @@
|
||||
</header>
|
||||
<header
|
||||
android:id="@+id/identity_settings"
|
||||
android:title="Identities" />
|
||||
android:title="@string/pref_title_identities" />
|
||||
|
||||
</preference-headers>
|
||||
32
src/i2p/bote/EditIdentityActivity.java
Normal file
32
src/i2p/bote/EditIdentityActivity.java
Normal file
@@ -0,0 +1,32 @@
|
||||
package i2p.bote;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.app.ActionBarActivity;
|
||||
import android.widget.Toast;
|
||||
|
||||
public class EditIdentityActivity extends ActionBarActivity implements
|
||||
EditIdentityFragment.Callbacks {
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_edit_identity);
|
||||
|
||||
// Enable ActionBar app icon to behave as action to go back
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
if (savedInstanceState == null) {
|
||||
EditIdentityFragment f = EditIdentityFragment.newInstance(
|
||||
getIntent().getExtras().getString(EditIdentityFragment.IDENTITY_KEY));
|
||||
getSupportFragmentManager().beginTransaction()
|
||||
.add(R.id.edit_identity_frag, f).commit();
|
||||
}
|
||||
}
|
||||
|
||||
// EditIdentityFragment.Callbacks
|
||||
|
||||
public void onTaskFinished() {
|
||||
Toast.makeText(this, R.string.identity_saved,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
finish();
|
||||
}
|
||||
}
|
||||
266
src/i2p/bote/EditIdentityFragment.java
Normal file
266
src/i2p/bote/EditIdentityFragment.java
Normal file
@@ -0,0 +1,266 @@
|
||||
package i2p.bote;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.GeneralSecurityException;
|
||||
|
||||
import i2p.bote.email.EmailIdentity;
|
||||
import i2p.bote.fileencryption.PasswordException;
|
||||
import i2p.bote.util.BoteHelper;
|
||||
import i2p.bote.util.RobustAsyncTask;
|
||||
import i2p.bote.util.TaskFragment;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
|
||||
public class EditIdentityFragment extends Fragment {
|
||||
private Callbacks mCallbacks = sDummyCallbacks;
|
||||
|
||||
public interface Callbacks {
|
||||
public void onTaskFinished();
|
||||
}
|
||||
private static Callbacks sDummyCallbacks = new Callbacks() {
|
||||
public void onTaskFinished() {};
|
||||
};
|
||||
|
||||
@Override
|
||||
public void onAttach(Activity activity) {
|
||||
super.onAttach(activity);
|
||||
if (!(activity instanceof Callbacks))
|
||||
throw new IllegalStateException("Activity must implement fragment's callbacks.");
|
||||
mCallbacks = (Callbacks) activity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetach() {
|
||||
super.onDetach();
|
||||
mCallbacks = sDummyCallbacks;
|
||||
}
|
||||
|
||||
public static final String IDENTITY_KEY = "identity_key";
|
||||
|
||||
// Code to identify the fragment that is calling onActivityResult().
|
||||
static final int IDENTITY_WAITER = 0;
|
||||
// Tag so we can find the task fragment again, in another
|
||||
// instance of this fragment after rotation.
|
||||
static final String IDENTITY_WAITER_TAG = "identityWaiterTask";
|
||||
|
||||
private String mKey;
|
||||
private FragmentManager mFM;
|
||||
Button mSubmit;
|
||||
TextView mError;
|
||||
|
||||
public static EditIdentityFragment newInstance(String key) {
|
||||
EditIdentityFragment f = new EditIdentityFragment();
|
||||
Bundle args = new Bundle();
|
||||
args.putString(IDENTITY_KEY, key);
|
||||
f.setArguments(args);
|
||||
return f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
mFM = getFragmentManager();
|
||||
IdentityWaiterFrag f = (IdentityWaiterFrag) mFM.findFragmentByTag(IDENTITY_WAITER_TAG);
|
||||
if (f != null)
|
||||
f.setTargetFragment(this, IDENTITY_WAITER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
return inflater.inflate(R.layout.fragment_edit_identity, container, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
|
||||
mKey = getArguments().getString(IDENTITY_KEY);
|
||||
|
||||
final EditText nameField = (EditText) view.findViewById(R.id.public_name);
|
||||
final EditText descField = (EditText) view.findViewById(R.id.description);
|
||||
mSubmit = (Button) view.findViewById(R.id.submit_identity);
|
||||
mError = (TextView) view.findViewById(R.id.error);
|
||||
|
||||
try {
|
||||
EmailIdentity identity = BoteHelper.getIdentity(mKey);
|
||||
nameField.setText(identity.getPublicName());
|
||||
descField.setText(identity.getDescription());
|
||||
} catch (PasswordException e) {
|
||||
// TODO Handle
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
// TODO Handle
|
||||
e.printStackTrace();
|
||||
} catch (GeneralSecurityException e) {
|
||||
// TODO Handle
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
IdentityWaiterFrag f = (IdentityWaiterFrag) mFM.findFragmentByTag(IDENTITY_WAITER_TAG);
|
||||
if (f != null)
|
||||
mSubmit.setEnabled(false);
|
||||
|
||||
mSubmit.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
String publicName = nameField.getText().toString();
|
||||
String description = descField.getText().toString();
|
||||
|
||||
InputMethodManager imm = (InputMethodManager)getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
imm.hideSoftInputFromWindow(nameField.getWindowToken(), 0);
|
||||
|
||||
mSubmit.setEnabled(false);
|
||||
mError.setText("");
|
||||
|
||||
IdentityWaiterFrag f = IdentityWaiterFrag.newInstance(
|
||||
false,
|
||||
-1,
|
||||
mKey,
|
||||
publicName,
|
||||
description,
|
||||
null,
|
||||
false);
|
||||
f.setTask(new IdentityWaiter());
|
||||
f.setTargetFragment(EditIdentityFragment.this, IDENTITY_WAITER);
|
||||
mFM.beginTransaction()
|
||||
.replace(R.id.identity_waiter_frag, f, IDENTITY_WAITER_TAG)
|
||||
.commit();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
if (requestCode == IDENTITY_WAITER) {
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
mCallbacks.onTaskFinished();
|
||||
} else if (resultCode == Activity.RESULT_CANCELED) {
|
||||
mSubmit.setEnabled(true);
|
||||
mError.setText(data.getStringExtra("error"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class IdentityWaiterFrag extends TaskFragment<Object, String, String> {
|
||||
static final String CREATE_NEW = "create_new";
|
||||
static final String CRYPTO_IMPL_ID = "crypto_impl_id";
|
||||
static final String KEY = "key";
|
||||
static final String PUBLIC_NAME = "public_name";
|
||||
static final String DESCRIPTION = "description";
|
||||
static final String EMAIL_ADDRESS = "email_address";
|
||||
static final String SET_DEFAULT = "set_default";
|
||||
|
||||
String currentStatus;
|
||||
TextView mStatus;
|
||||
|
||||
public static IdentityWaiterFrag newInstance(
|
||||
boolean createNew, int cryptoImplId, String key, String publicName, String description, String emailAddress, boolean setDefault) {
|
||||
IdentityWaiterFrag f = new IdentityWaiterFrag();
|
||||
Bundle args = new Bundle();
|
||||
args.putBoolean(CREATE_NEW, createNew);
|
||||
args.putInt(CRYPTO_IMPL_ID, cryptoImplId);
|
||||
args.putString(KEY, key);
|
||||
args.putString(PUBLIC_NAME, publicName);
|
||||
args.putString(DESCRIPTION, description);
|
||||
args.putString(EMAIL_ADDRESS, emailAddress);
|
||||
args.putBoolean(SET_DEFAULT, setDefault);
|
||||
f.setArguments(args);
|
||||
return f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
View v = inflater.inflate(R.layout.dialog_status, container, false);
|
||||
mStatus = (TextView) v.findViewById(R.id.status);
|
||||
|
||||
if (currentStatus != null && !currentStatus.isEmpty())
|
||||
mStatus.setText(currentStatus);
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getParams() {
|
||||
Bundle args = getArguments();
|
||||
return new Object[] {
|
||||
Boolean.valueOf(args.getBoolean(CREATE_NEW)),
|
||||
Integer.valueOf(args.getInt(CRYPTO_IMPL_ID)),
|
||||
args.getString(KEY),
|
||||
args.getString(PUBLIC_NAME),
|
||||
args.getString(DESCRIPTION),
|
||||
args.getString(EMAIL_ADDRESS),
|
||||
Boolean.valueOf(args.getBoolean(SET_DEFAULT)),
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateProgress(String... values) {
|
||||
currentStatus = values[0];
|
||||
mStatus.setText(currentStatus);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void taskFinished(String result) {
|
||||
super.taskFinished(result);
|
||||
|
||||
if (getTargetFragment() != null) {
|
||||
Intent i = new Intent();
|
||||
i.putExtra("result", result);
|
||||
getTargetFragment().onActivityResult(
|
||||
getTargetRequestCode(), Activity.RESULT_OK, i);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void taskCancelled(String error) {
|
||||
super.taskCancelled(error);
|
||||
|
||||
if (getTargetFragment() != null) {
|
||||
Intent i = new Intent();
|
||||
i.putExtra("error", error);
|
||||
getTargetFragment().onActivityResult(
|
||||
getTargetRequestCode(), Activity.RESULT_CANCELED, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class IdentityWaiter extends RobustAsyncTask<Object, String, String> {
|
||||
protected String doInBackground(Object... params) {
|
||||
StatusListener lsnr = new StatusListener() {
|
||||
public void updateStatus(String status) {
|
||||
publishProgress(status);
|
||||
}
|
||||
};
|
||||
lsnr.updateStatus("Saving identity");
|
||||
try {
|
||||
BoteHelper.createOrModifyIdentity(
|
||||
(Boolean) params[0],
|
||||
(Integer) params[1],
|
||||
(String) params[2],
|
||||
(String) params[3],
|
||||
(String) params[4],
|
||||
(String) params[5],
|
||||
(Boolean) params[6]);
|
||||
I2PBote.getInstance().getIdentities().save();
|
||||
return null;
|
||||
} catch (Throwable e) {
|
||||
cancel(false);
|
||||
return e.getMessage();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,7 @@ import java.util.Map;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
@@ -33,8 +34,8 @@ public class SettingsActivity extends PreferenceActivity {
|
||||
private Header[] mIdentityListHeaders;
|
||||
private List<Header> mGeneratedHeaders;
|
||||
|
||||
private String mRequestedIdentityHash;
|
||||
private String mDeletingIdentityHash;
|
||||
private String mRequestedIdentityKey;
|
||||
private String mDeletingIdentityKey;
|
||||
|
||||
// Async tasks
|
||||
private LoadIdentityListTask mLoadIdentityListTask;
|
||||
@@ -130,11 +131,12 @@ public class SettingsActivity extends PreferenceActivity {
|
||||
for (int index = 0; index < headerCount; index++) {
|
||||
Header header = mIdentityListHeaders[index];
|
||||
if (header != null && header.id != HEADER_ID_UNDEFINED) {
|
||||
String hash = header.fragmentArguments.getString("hash");
|
||||
if (hash != mDeletingIdentityHash) {
|
||||
String key = header.extras.getString(
|
||||
EditIdentityFragment.IDENTITY_KEY);
|
||||
if (key != mDeletingIdentityKey) {
|
||||
target.add(header);
|
||||
if (hash == mRequestedIdentityHash) {
|
||||
mRequestedIdentityHash = null;
|
||||
if (key == mRequestedIdentityKey) {
|
||||
mRequestedIdentityKey = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -154,7 +156,7 @@ public class SettingsActivity extends PreferenceActivity {
|
||||
private void loadLegacySettings(String action) {
|
||||
if (ACTION_PREFS_GENERAL.equals(action)) {
|
||||
addPreferencesFromResource(R.xml.settings_general);
|
||||
} // TODO: implement identity settings
|
||||
}
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
|
||||
@@ -166,7 +168,7 @@ public class SettingsActivity extends PreferenceActivity {
|
||||
String settings = getArguments().getString("settings");
|
||||
if ("general".equals(settings)) {
|
||||
addPreferencesFromResource(R.xml.settings_general);
|
||||
} // TODO: implement identity settings
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -241,16 +243,19 @@ public class SettingsActivity extends PreferenceActivity {
|
||||
for (EmailIdentity identity : identities) {
|
||||
final long id = identity.getHash().hashCode();
|
||||
final String name = identity.getPublicName();
|
||||
final String desc = identity.getKey();
|
||||
final String desc = identity.getDescription();
|
||||
final String key = identity.getKey();
|
||||
final Intent intent = new Intent(
|
||||
getApplicationContext(), EditIdentityActivity.class);
|
||||
final Bundle args = new Bundle();
|
||||
final String hash = identity.getHash().toBase64();
|
||||
args.putString("hash", hash);
|
||||
args.putString(EditIdentityFragment.IDENTITY_KEY, key);
|
||||
intent.putExtras(args);
|
||||
final Header newHeader = new Header();
|
||||
newHeader.id = id;
|
||||
newHeader.title = name;
|
||||
newHeader.summary = desc;
|
||||
newHeader.fragment = SettingsFragment.class.getName();
|
||||
newHeader.fragmentArguments = args;
|
||||
newHeader.intent = intent;
|
||||
newHeader.extras = args;
|
||||
result[index++] = newHeader;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user