This commit is contained in:
Yaroslav Dmytrotsa 2015-08-06 18:34:14 +03:00
commit 81d71704de
9 changed files with 292 additions and 62 deletions

View File

@ -2,6 +2,7 @@ package io.syng.activity;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Color;
@ -20,6 +21,7 @@ import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
@ -31,6 +33,7 @@ import android.widget.ListView;
import android.widget.Spinner;
import android.widget.TextView;
import com.afollestad.materialdialogs.MaterialDialog;
import com.bumptech.glide.Glide;
import java.util.ArrayList;
@ -72,6 +75,10 @@ public abstract class BaseActivity extends AppCompatActivity implements OnItemCl
protected abstract void onDAppClick(String item);
private SpinnerAdapter spinnerAdapter;
private Profile requestProfile;
private int currentPosition;
@SuppressLint("InflateParams")
@Override
public void setContentView(final int layoutResID) {
@ -130,20 +137,71 @@ public abstract class BaseActivity extends AppCompatActivity implements OnItemCl
mHandler.postDelayed(mRunnable, delayMills);
}
protected void changeProfile(Profile profile) {
SyngApplication application = (SyngApplication)getApplication();
List<String> privateKeys = profile.getPrivateKeys();
application.sEthereumConnector.init(privateKeys);
currentPosition = spinnerAdapter.getPosition(profile);
}
protected void requestChangeProfile(Profile profile) {
requestProfile = profile;
new MaterialDialog.Builder(BaseActivity.this)
.title(R.string.request_profile_password)
.customView(R.layout.profile_password, true)
.positiveText(R.string.ok)
.negativeText(R.string.cancel)
.contentColor(getResources().getColor(R.color.accent))
.dividerColorRes(R.color.accent)
.backgroundColorRes(R.color.primary_dark)
.positiveColorRes(R.color.accent)
.negativeColorRes(R.color.accent)
.widgetColorRes(R.color.accent)
.callback(new MaterialDialog.ButtonCallback() {
@Override
public void onPositive(MaterialDialog dialog) {
View view = dialog.getCustomView();
EditText passwordInput = (EditText) view.findViewById(R.id.passwordInput);
if (requestProfile.decrypt(passwordInput.getText().toString())) {
changeProfile(requestProfile);
} else {
dialog.hide();
mAccountSpinner.setSelection(currentPosition, false);
}
}
@Override
public void onNegative(MaterialDialog dialog) {
dialog.hide();
mAccountSpinner.setSelection(currentPosition, false);
}
})
.build()
.show();
}
public void initSpinner() {
List<Profile> profilesList = ((SyngApplication) getApplication()).mPreferenceManager.getProfiles();
ArrayList<String> spinnerItems = new ArrayList<>();
for (Profile profile : profilesList) {
spinnerItems.add(profile.getName());
}
mAccountSpinner.setAdapter(new ArrayAdapter<>(this, android.R.layout.simple_dropdown_item_1line, spinnerItems.toArray(new String[spinnerItems.size()])));
spinnerAdapter = new SpinnerAdapter(this, android.R.layout.simple_dropdown_item_1line, profilesList);
mAccountSpinner.setAdapter(spinnerAdapter);
mAccountSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
//String item = (String) adapterView.getItemAtPosition(i);
if (adapterView != null && adapterView.getChildAt(0) != null) {
((TextView) adapterView.getChildAt(0)).setTextColor(Color.parseColor("#ffffff"));
}
Profile profile = spinnerAdapter.getItem(i);
if (profile.getPasswordProtectedProfile()) {
requestChangeProfile(profile);
} else {
changeProfile(profile);
}
}
@ -268,4 +326,54 @@ public abstract class BaseActivity extends AppCompatActivity implements OnItemCl
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
public class SpinnerAdapter extends ArrayAdapter<Profile> {
private Context context;
private List<Profile> values;
public SpinnerAdapter(Context context, int textViewResourceId, List<Profile> values) {
super(context, textViewResourceId, values);
this.context = context;
this.values = values;
}
public int getCount() {
return values.size();
}
public Profile getItem(int position){
return values.get(position);
}
public long getItemId(int position){
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
return getCustomView(position, convertView, parent);
}
@Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
return getCustomView(position, convertView, parent);
}
public View getCustomView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = getLayoutInflater();
View row=inflater.inflate(android.R.layout.simple_dropdown_item_1line, parent, false);
TextView label=(TextView)row.findViewById(android.R.id.text1);
label.setText(spinnerAdapter.getItem(position).getName());
return row;
}
}
}

View File

@ -34,7 +34,7 @@ public class ProfileManagerActivity extends BaseActivity implements OnFragmentIn
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_profile_manager);
saveProfileLink = (TextView)findViewById(R.id.save_profile_link);
saveProfileLink = (TextView) findViewById(R.id.save_profile_link);
saveProfileLink.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
@ -74,9 +74,9 @@ public class ProfileManagerActivity extends BaseActivity implements OnFragmentIn
.build()
.show();
} else {
profileManagerFragment.addProfile(profile);
hideAddProfile();
}
profileManagerFragment.addProfile(profile);
hideAddProfile();
}
}
});
addProfileLink = (TextView) findViewById(R.id.add_profile_link);
@ -91,9 +91,9 @@ public class ProfileManagerActivity extends BaseActivity implements OnFragmentIn
if (savedInstanceState == null) {
addProfileFragment = new AddProfileFragment();
profileManagerFragment = new ProfileManagerFragment();
getFragmentManager().beginTransaction()
// .add(R.id.profileManagerFragmentContainer, profileManagerFragment)
// .add(R.id.addProfileFragmentContainer, addProfileFragment)
getSupportFragmentManager().beginTransaction()
.add(R.id.profileManagerFragmentContainer, profileManagerFragment)
.add(R.id.addProfileFragmentContainer, addProfileFragment)
.commit();
}
@ -134,27 +134,6 @@ public class ProfileManagerActivity extends BaseActivity implements OnFragmentIn
public void onFragmentInteraction(Uri uri) {
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
// getMenuInflater().inflate(R.menu.menu_profile_manager, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
// if (id == R.id.action_settings) {
// return true;
// }
return super.onOptionsItemSelected(item);
}
@Override
protected void onDAppClick(String item) {

View File

@ -1,24 +1,36 @@
package io.syng.app;
import android.content.Context;
import android.os.Message;
import android.support.multidex.MultiDexApplication;
import org.ethereum.android.service.ConnectorHandler;
import org.ethereum.android.service.EthereumConnector;
import com.squareup.leakcanary.LeakCanary;
import com.squareup.leakcanary.RefWatcher;
import io.syng.service.EthereumService;
import io.syng.util.PreferenceManager;
public class SyngApplication extends MultiDexApplication {
public class SyngApplication extends MultiDexApplication implements ConnectorHandler {
public PreferenceManager mPreferenceManager;
public static EthereumConnector sEthereumConnector = null;
private RefWatcher refWatcher;
@Override public void onCreate() {
super.onCreate();
mPreferenceManager = new PreferenceManager(this);
refWatcher = LeakCanary.install(this);
if (sEthereumConnector == null) {
sEthereumConnector = new EthereumConnector(this, EthereumService.class);
sEthereumConnector.registerHandler(this);
sEthereumConnector.bindService();
}
// refWatcher = RefWatcher.DISABLED;
}
@ -26,6 +38,9 @@ public class SyngApplication extends MultiDexApplication {
public void onTerminate() {
super.onTerminate();
mPreferenceManager.close();
sEthereumConnector.removeHandler(this);
sEthereumConnector.unbindService();
sEthereumConnector = null;
}
@ -34,6 +49,23 @@ public class SyngApplication extends MultiDexApplication {
return application.refWatcher;
}
@Override
public void onConnectorConnected() {
sEthereumConnector.startJsonRpc();
}
@Override
public void onConnectorDisconnected() {
}
@Override
public String getID() {
return "1";
}
@Override
public boolean handleMessage(Message message) {
return false;
}
}

View File

@ -6,14 +6,22 @@ import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.InputType;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;
import com.afollestad.materialdialogs.MaterialDialog;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@ -52,6 +60,32 @@ public class AddProfileFragment extends Fragment {
private int dapEditPosition = -1;
private TextView walletModeButton;
private MaterialDialog walletModeDialog;
private RadioButton walletCreate;
private RadioButton walletImportFile;
private RadioButton accountModeImportString;
private EditText walletImportSource;
private int accountMode;
private String accountPrivateKey = null;
protected View.OnClickListener accountModeListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
accountMode = view.getId();
switch(accountMode) {
case R.id.radio_new_account:
walletImportSource.setInputType(InputType.TYPE_NULL);
break;
case R.id.radio_import_file:
case R.id.radio_import_string:
walletImportSource.setInputType(InputType.TYPE_CLASS_TEXT);
break;
}
}
};
public void setProfile(Profile profile) {
profileName.setText(profile != null ? profile.getName() : "");
@ -71,7 +105,7 @@ public class AddProfileFragment extends Fragment {
}
public Profile getProfile() {
Profile profile = new Profile();
Profile profile = accountPrivateKey != null ? new Profile(accountPrivateKey) : new Profile();
profile.setName(profileName.getText().toString());
profile.setPasswordProtectedProfile(profilePasswordProtected.isChecked());
List<Dapp> dapps = mAdapter.getItems();
@ -105,6 +139,84 @@ public class AddProfileFragment extends Fragment {
profileName = (EditText) view.findViewById(R.id.profile_name);
profilePasswordProtected = (Switch) view.findViewById(R.id.profile_password_protected);
walletModeButton = (TextView)view.findViewById(R.id.wallet_mode);
walletModeDialog = new MaterialDialog.Builder(getActivity())
.title(R.string.wallet_title)
.customView(R.layout.wallet_creation_mode, true)
.positiveText(R.string.ok)
.negativeText(R.string.cancel)
.contentColor(getResources().getColor(R.color.accent))
.dividerColorRes(R.color.accent)
.backgroundColorRes(R.color.primary_dark)
.positiveColorRes(R.color.accent)
.negativeColorRes(R.color.accent)
.widgetColorRes(R.color.accent)
.autoDismiss(false)
.callback(new MaterialDialog.ButtonCallback() {
@Override
public void onPositive(MaterialDialog dialog) {
boolean hideDialog = true;
accountPrivateKey = null;
switch (accountMode) {
case R.id.radio_new_account:
break;
case R.id.radio_import_file:
File file = new File(walletImportSource.getText().toString());
if (file.exists()) {
StringBuilder text = new StringBuilder();
try {
BufferedReader buffer = new BufferedReader(new FileReader(file));
String line;
while ((line = buffer.readLine()) != null) {
text.append(line);
}
buffer.close();
accountPrivateKey = text.toString();
} catch (IOException e) {
}
} else {
Toast.makeText(getActivity(), "File not found", Toast.LENGTH_LONG).show();
hideDialog = false;
}
break;
case R.id.radio_import_string:
accountPrivateKey = walletImportSource.getText().toString();
break;
}
if (hideDialog) {
dialog.hide();
}
}
@Override
public void onNegative(MaterialDialog dialog) {
dialog.hide();
}
})
.build();
walletModeButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
walletModeDialog.show();
}
});
View accountModeView = walletModeDialog.getCustomView();
walletCreate = (RadioButton)accountModeView.findViewById(R.id.radio_new_account);
walletImportFile = (RadioButton)accountModeView.findViewById(R.id.radio_import_file);
accountModeImportString = (RadioButton)accountModeView.findViewById(R.id.radio_import_string);
walletImportSource = (EditText)accountModeView.findViewById(R.id.accout_import_source);
walletCreate.setOnClickListener(accountModeListener);
walletImportFile.setOnClickListener(accountModeListener);
accountModeImportString.setOnClickListener(accountModeListener);
mDappsRecyclerView = (RecyclerView) view.findViewById(R.id.profile_dapps_list);
// use this setting to improve performance if you know that changes

View File

@ -50,8 +50,6 @@ public class ConsoleFragment extends Fragment implements ConnectorHandler {
private String mConsoleLog = "";
private static EthereumConnector sEthereumConnector;
private TextView mConsoleText;
private Handler mHandler = new Handler();
@ -100,10 +98,6 @@ public class ConsoleFragment extends Fragment implements ConnectorHandler {
ImageView ethereumText = (ImageView) view.findViewById(R.id.iv_ethereum_text);
Glide.with(this).load(R.drawable.ethereum_text).into(ethereumText);
Glide.with(this).load(R.drawable.ethereum_icon).into(ethereumIcon);
if (sEthereumConnector == null) {
sEthereumConnector = new EthereumConnector(getActivity(), EthereumService.class);
}
return view;
}
@ -111,17 +105,19 @@ public class ConsoleFragment extends Fragment implements ConnectorHandler {
public void onPause() {
super.onPause();
mHandler.removeCallbacksAndMessages(null);
// sEthereumConnector.removeHandler(this);
sEthereumConnector.removeListener(mHandlerIdentifier);
sEthereumConnector.unbindService();
SyngApplication application = (SyngApplication)getActivity().getApplication();
application.sEthereumConnector.removeHandler(this);
application.sEthereumConnector.removeListener(mHandlerIdentifier);
application.sEthereumConnector.unbindService();
}
@Override
public void onResume() {
super.onResume();
mHandler.post(mRunnable);
sEthereumConnector.registerHandler(this);
sEthereumConnector.bindService();
SyngApplication application = (SyngApplication)getActivity().getApplication();
application.sEthereumConnector.registerHandler(this);
application.sEthereumConnector.bindService();
}
@ -150,7 +146,8 @@ public class ConsoleFragment extends Fragment implements ConnectorHandler {
@Override
public void onConnectorConnected() {
sEthereumConnector.addListener(mHandlerIdentifier, EnumSet.allOf(EventFlag.class));
SyngApplication application = (SyngApplication)getActivity().getApplication();
application.sEthereumConnector.addListener(mHandlerIdentifier, EnumSet.allOf(EventFlag.class));
}
@Override
@ -162,9 +159,6 @@ public class ConsoleFragment extends Fragment implements ConnectorHandler {
super.onDestroy();
RefWatcher refWatcher = SyngApplication.getRefWatcher(getActivity());
refWatcher.watch(this);
if (getActivity().isFinishing()) {
sEthereumConnector = null;
}
}
private LogEntry myHandleMessage(Message message) {

View File

@ -19,9 +19,16 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Name"
android:textColor="@color/accent"
/>
android:textColor="@color/accent"/>
</android.support.design.widget.TextInputLayout>
<TextView
android:id="@+id/wallet_mode"
android:text="@string/wallet_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/accent"/>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
@ -32,8 +39,7 @@
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/profile_password_protected"
android:textColor="@color/accent"
/>
android:textColor="@color/accent"/>
</LinearLayout>
</LinearLayout>
@ -42,7 +48,6 @@
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_below="@id/profile_settings"
android:scrollbars="vertical"
/>
android:scrollbars="vertical"/>
</RelativeLayout>

View File

@ -11,12 +11,12 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/accent"
android:text="@string/create_new_account"/>
android:text="@string/create_new_wallet"/>
<RadioButton android:id="@+id/radio_import_file"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/accent"
android:text="@string/import_account_from_file"/>
android:text="@string/import_wallet_from_file"/>
<RadioButton android:id="@+id/radio_import_string"
android:layout_width="wrap_content"
android:layout_height="wrap_content"

View File

@ -19,10 +19,10 @@
<string name="title_activity_spash_screen">Syng</string>
<string name="account_mode_title">Account</string>
<string name="wallet_title">Wallet</string>
<string name="ok">OK</string>
<string name="create_new_account">Create new Account</string>
<string name="import_account_from_file">Import account from file</string>
<string name="create_new_wallet">Create new Wallet</string>
<string name="import_wallet_from_file">Import wallet from file</string>
<string name="import_account_from_string">Import account from string</string>
<string name="request_profile_password">Profile Password</string>

@ -1 +1 @@
Subproject commit 6340cc47a4e496c5a25840097d66bfbbb0a557ab
Subproject commit a64d216537a4163c5ba422edcf513435a9423b96