- The user can add contacts (Only the name. Still in progress...)
This commit is contained in:
parent
cb309f1db2
commit
5eae79d011
11 changed files with 413 additions and 30 deletions
|
@ -1,11 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="cy.agorise.crystalwallet">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
|
||||
<application
|
||||
android:name="cy.agorise.crystalwallet.application.CrystalApplication"
|
||||
android:name=".application.CrystalApplication"
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="Crystal"
|
||||
|
@ -19,38 +20,35 @@
|
|||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name=".activities.BoardActivity"
|
||||
android:theme="@style/AppTheme.NoActionBar" > <!-- Dirty trick to avoid toolbar error on balance -->
|
||||
<activity
|
||||
android:name=".activities.BoardActivity"
|
||||
android:theme="@style/AppTheme.NoActionBar"> <!-- Dirty trick to avoid toolbar error on balance -->
|
||||
</activity>
|
||||
<activity android:name=".activities.AccountSeedsManagementActivity" >
|
||||
</activity>
|
||||
<activity android:name=".activities.ImportSeedActivity" >
|
||||
</activity>
|
||||
<activity android:name=".activities.CreateSeedActivity" >
|
||||
</activity>
|
||||
<activity android:name=".activities.SendTransactionActivity" >
|
||||
</activity>
|
||||
<activity android:name=".activities.GeneralSettingsActivity" >
|
||||
</activity>
|
||||
<activity android:name=".activities.CryptoCoinTransactionReceiptActivity" >
|
||||
</activity>
|
||||
<activity android:name=".activities.BackupSeedActivity" >
|
||||
</activity>
|
||||
<activity android:name=".activities.PinRequestActivity" >
|
||||
</activity>
|
||||
<activity android:name=".activities.SettingsActivity"
|
||||
android:theme="@style/AppTheme.NoActionBar" >
|
||||
</activity>
|
||||
<activity android:name=".activities.AccountsActivity"
|
||||
android:theme="@style/ActivityDialog"
|
||||
android:parentActivityName=".activities.BoardActivity" >
|
||||
<activity android:name=".activities.AccountSeedsManagementActivity"></activity>
|
||||
<activity android:name=".activities.ImportSeedActivity"></activity>
|
||||
<activity android:name=".activities.CreateSeedActivity"></activity>
|
||||
<activity android:name=".activities.SendTransactionActivity"></activity>
|
||||
<activity android:name=".activities.GeneralSettingsActivity"></activity>
|
||||
<activity android:name=".activities.CryptoCoinTransactionReceiptActivity"></activity>
|
||||
<activity android:name=".activities.BackupSeedActivity"></activity>
|
||||
<activity android:name=".activities.PinRequestActivity"></activity>
|
||||
<activity
|
||||
android:name=".activities.SettingsActivity"
|
||||
android:theme="@style/AppTheme.NoActionBar"></activity>
|
||||
<activity
|
||||
android:name=".activities.AccountsActivity"
|
||||
android:parentActivityName=".activities.BoardActivity"
|
||||
android:theme="@style/ActivityDialog">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value=".activities.BoardActivity" />
|
||||
</activity>
|
||||
|
||||
<service android:name=".service.CrystalWalletService"
|
||||
android:exported="false"/>
|
||||
<service
|
||||
android:name=".service.CrystalWalletService"
|
||||
android:exported="false" />
|
||||
|
||||
<activity android:name=".activities.CreateContactActivity"></activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
|
@ -204,6 +204,12 @@ public class BoardActivity extends AppCompatActivity {
|
|||
}
|
||||
}
|
||||
|
||||
@OnClick(R.id.fabAddContact)
|
||||
public void beginCreateContact(){
|
||||
Intent intent = new Intent(this, CreateContactActivity.class);
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
/*
|
||||
* dispatch the user to the receive fragment using this account
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,113 @@
|
|||
package cy.agorise.crystalwallet.activities;
|
||||
|
||||
import android.arch.lifecycle.ViewModelProviders;
|
||||
import android.content.Intent;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.os.Bundle;
|
||||
import android.text.Editable;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
import butterknife.OnTextChanged;
|
||||
import cy.agorise.crystalwallet.R;
|
||||
import cy.agorise.crystalwallet.cryptonetinforequests.CryptoNetInfoRequestListener;
|
||||
import cy.agorise.crystalwallet.cryptonetinforequests.CryptoNetInfoRequests;
|
||||
import cy.agorise.crystalwallet.cryptonetinforequests.ValidateCreateBitsharesAccountRequest;
|
||||
import cy.agorise.crystalwallet.models.Contact;
|
||||
import cy.agorise.crystalwallet.models.GrapheneAccount;
|
||||
import cy.agorise.crystalwallet.viewmodels.ContactListViewModel;
|
||||
import cy.agorise.crystalwallet.viewmodels.ContactViewModel;
|
||||
import cy.agorise.crystalwallet.viewmodels.validators.CreateContactValidator;
|
||||
import cy.agorise.crystalwallet.viewmodels.validators.CreateSeedValidator;
|
||||
import cy.agorise.crystalwallet.viewmodels.validators.UIValidatorListener;
|
||||
import cy.agorise.crystalwallet.viewmodels.validators.validationfields.ValidationField;
|
||||
|
||||
public class CreateContactActivity extends AppCompatActivity implements UIValidatorListener {
|
||||
|
||||
@BindView(R.id.etName)
|
||||
EditText etName;
|
||||
@BindView(R.id.tvNameError)
|
||||
TextView tvNameError;
|
||||
@BindView(R.id.btnCancel)
|
||||
Button btnCancel;
|
||||
@BindView(R.id.btnCreate)
|
||||
Button btnCreate;
|
||||
|
||||
CreateContactValidator createContactValidator;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_create_contact);
|
||||
ButterKnife.bind(this);
|
||||
|
||||
btnCreate.setEnabled(false);
|
||||
createContactValidator = new CreateContactValidator(this.getApplicationContext(),etName);
|
||||
createContactValidator.setListener(this);
|
||||
}
|
||||
|
||||
@OnTextChanged(value = R.id.etName,
|
||||
callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
|
||||
void afterContactNameChanged(Editable editable) {
|
||||
this.createContactValidator.validate();
|
||||
}
|
||||
|
||||
|
||||
@OnClick(R.id.btnCancel)
|
||||
public void cancel(){
|
||||
this.finish();
|
||||
}
|
||||
|
||||
@OnClick(R.id.btnCreate)
|
||||
public void createContact(){
|
||||
if (this.createContactValidator.isValid()) {
|
||||
Contact newContact = new Contact();
|
||||
newContact.setName(etName.getText().toString());
|
||||
ContactViewModel contactViewModel = ViewModelProviders.of(this).get(ContactViewModel.class);
|
||||
if (contactViewModel.addContact(newContact)){
|
||||
this.finish();
|
||||
} else {
|
||||
createContactValidator.validate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onValidationSucceeded(final ValidationField field) {
|
||||
final CreateContactActivity activity = this;
|
||||
|
||||
activity.runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
|
||||
if (field.getView() == etName) {
|
||||
tvNameError.setText("");
|
||||
}
|
||||
|
||||
if (activity.createContactValidator.isValid()){
|
||||
btnCreate.setEnabled(true);
|
||||
} else {
|
||||
btnCreate.setEnabled(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onValidationFailed(final ValidationField field) {
|
||||
runOnUiThread(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (field.getView() == etName) {
|
||||
tvNameError.setText(field.getMessage());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -26,4 +26,10 @@ public interface ContactDao {
|
|||
|
||||
@Query("SELECT * FROM contact WHERE id = :id")
|
||||
LiveData<Contact> getById(long id);
|
||||
|
||||
@Query("SELECT count(*) FROM contact WHERE name = :name")
|
||||
boolean existsByName(String name);
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.ABORT)
|
||||
public long[] add(Contact... contacts);
|
||||
}
|
||||
|
|
|
@ -1,14 +1,28 @@
|
|||
package cy.agorise.crystalwallet.fragments;
|
||||
|
||||
import android.arch.lifecycle.LiveData;
|
||||
import android.arch.lifecycle.Observer;
|
||||
import android.arch.lifecycle.ViewModelProviders;
|
||||
import android.arch.paging.PagedList;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import cy.agorise.crystalwallet.R;
|
||||
import cy.agorise.crystalwallet.models.Contact;
|
||||
import cy.agorise.crystalwallet.viewmodels.ContactListViewModel;
|
||||
import cy.agorise.crystalwallet.views.ContactListView;
|
||||
|
||||
public class ContactsFragment extends Fragment {
|
||||
|
||||
@BindView(R.id.vContactListView)
|
||||
ContactListView contactListView;
|
||||
|
||||
public ContactsFragment() {
|
||||
// Required empty public constructor
|
||||
}
|
||||
|
@ -29,6 +43,19 @@ public class ContactsFragment extends Fragment {
|
|||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
// Inflate the layout for this fragment
|
||||
return inflater.inflate(R.layout.fragment_contacts, container, false);
|
||||
View v = inflater.inflate(R.layout.fragment_contacts, container, false);
|
||||
ButterKnife.bind(this, v);
|
||||
|
||||
ContactListViewModel contactListViewModel = ViewModelProviders.of(this).get(ContactListViewModel.class);
|
||||
LiveData<PagedList<Contact>> contactsLiveData = contactListViewModel.getContactList();
|
||||
|
||||
contactsLiveData.observe(this, new Observer<PagedList<Contact>>() {
|
||||
@Override
|
||||
public void onChanged(@Nullable PagedList<Contact> contacts) {
|
||||
contactListView.setData(contacts);
|
||||
}
|
||||
});
|
||||
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,4 +33,8 @@ public class ContactListViewModel extends AndroidViewModel {
|
|||
public LiveData<PagedList<Contact>> getContactList(){
|
||||
return this.contactList;
|
||||
}
|
||||
|
||||
public boolean contactExists(String name){
|
||||
return this.db.contactDao().existsByName(name);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
package cy.agorise.crystalwallet.viewmodels;
|
||||
|
||||
import android.app.Application;
|
||||
import android.arch.lifecycle.AndroidViewModel;
|
||||
import android.arch.lifecycle.LiveData;
|
||||
import android.arch.paging.PagedList;
|
||||
|
||||
import cy.agorise.crystalwallet.dao.CrystalDatabase;
|
||||
import cy.agorise.crystalwallet.models.Contact;
|
||||
|
||||
/**
|
||||
* Created by Henry Varona on 2/4/2018.
|
||||
*/
|
||||
|
||||
public class ContactViewModel extends AndroidViewModel {
|
||||
|
||||
private CrystalDatabase db;
|
||||
|
||||
public ContactViewModel(Application application) {
|
||||
super(application);
|
||||
this.db = CrystalDatabase.getAppDatabase(application.getApplicationContext());
|
||||
}
|
||||
|
||||
public boolean addContact(Contact contact){
|
||||
return this.db.contactDao().add(contact)[0] >= 0;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package cy.agorise.crystalwallet.viewmodels.validators;
|
||||
|
||||
import android.content.Context;
|
||||
import android.widget.EditText;
|
||||
|
||||
import cy.agorise.crystalwallet.viewmodels.validators.validationfields.BitsharesAccountNameDoesntExistsValidationField;
|
||||
import cy.agorise.crystalwallet.viewmodels.validators.validationfields.ContactNameValidationField;
|
||||
import cy.agorise.crystalwallet.viewmodels.validators.validationfields.PinConfirmationValidationField;
|
||||
import cy.agorise.crystalwallet.viewmodels.validators.validationfields.PinValidationField;
|
||||
|
||||
/**
|
||||
* Created by Henry Varona on 2/2/2018.
|
||||
*/
|
||||
|
||||
public class CreateContactValidator extends UIValidator {
|
||||
|
||||
public CreateContactValidator(Context context, EditText nameEdit){
|
||||
super(context);
|
||||
this.addField(new ContactNameValidationField(nameEdit));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
package cy.agorise.crystalwallet.viewmodels.validators.validationfields;
|
||||
|
||||
import android.arch.lifecycle.LifecycleOwner;
|
||||
import android.arch.lifecycle.LiveData;
|
||||
import android.arch.lifecycle.Observer;
|
||||
import android.arch.lifecycle.ViewModelProviders;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Spinner;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import cy.agorise.crystalwallet.R;
|
||||
import cy.agorise.crystalwallet.cryptonetinforequests.CryptoNetInfoRequestListener;
|
||||
import cy.agorise.crystalwallet.cryptonetinforequests.CryptoNetInfoRequests;
|
||||
import cy.agorise.crystalwallet.cryptonetinforequests.ValidateExistBitsharesAccountRequest;
|
||||
import cy.agorise.crystalwallet.models.GeneralSetting;
|
||||
import cy.agorise.crystalwallet.viewmodels.ContactListViewModel;
|
||||
import cy.agorise.crystalwallet.viewmodels.GeneralSettingListViewModel;
|
||||
|
||||
/**
|
||||
* Created by Henry Varona on 2/03/2017.
|
||||
*/
|
||||
|
||||
public class ContactNameValidationField extends ValidationField {
|
||||
|
||||
private EditText nameField;
|
||||
|
||||
public ContactNameValidationField(EditText nameField){
|
||||
super(nameField);
|
||||
this.nameField = nameField;
|
||||
}
|
||||
|
||||
public void validate(){
|
||||
final String newValue = this.nameField.getText().toString();
|
||||
|
||||
|
||||
if (!newValue.equals("")) {
|
||||
if (!newValue.equals(this.getLastValue())) {
|
||||
this.setLastValue(newValue);
|
||||
this.startValidating();
|
||||
|
||||
ContactListViewModel contactListViewModel = ViewModelProviders.of((FragmentActivity) view.getContext()).get(ContactListViewModel.class);
|
||||
if (contactListViewModel.contactExists(newValue)) {
|
||||
this.setMessageForValue(newValue, "This name is already used by another contact.");
|
||||
this.setValidForValue(newValue, false);
|
||||
} else {
|
||||
this.setValidForValue(newValue, true);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.setLastValue("");
|
||||
this.startValidating();
|
||||
this.setMessageForValue("", "");
|
||||
this.setValidForValue("", false);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -12,9 +12,7 @@ import android.widget.RelativeLayout;
|
|||
|
||||
import cy.agorise.crystalwallet.R;
|
||||
import cy.agorise.crystalwallet.models.Contact;
|
||||
import cy.agorise.crystalwallet.models.CryptoCoinTransaction;
|
||||
import cy.agorise.crystalwallet.viewmodels.ContactListViewModel;
|
||||
import cy.agorise.crystalwallet.viewmodels.TransactionListViewModel;
|
||||
|
||||
/**
|
||||
* Created by Henry Varona on 1/15/2018.
|
||||
|
|
124
app/src/main/res/layout/activity_create_contact.xml
Normal file
124
app/src/main/res/layout/activity_create_contact.xml
Normal file
|
@ -0,0 +1,124 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout 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"
|
||||
android:orientation="vertical"
|
||||
android:paddingBottom="0dp"
|
||||
android:paddingLeft="0dp"
|
||||
android:paddingRight="0dp"
|
||||
android:paddingTop="@dimen/activity_vertical_margin">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvName"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/activity_horizontal_margin"
|
||||
android:layout_marginRight="@dimen/activity_horizontal_margin"
|
||||
android:layout_marginTop="10dp"
|
||||
android:text="Contact Name"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etName"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/activity_horizontal_margin"
|
||||
android:layout_marginRight="@dimen/activity_horizontal_margin"
|
||||
android:background="@drawable/edittext_bg"
|
||||
android:maxLines="1"
|
||||
android:textColor="@color/black" />
|
||||
<TextView
|
||||
android:id="@+id/tvNameError"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/activity_horizontal_margin"
|
||||
android:layout_marginRight="@dimen/activity_horizontal_margin"
|
||||
android:maxLines="1"
|
||||
android:textColor="@color/red" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/activity_horizontal_margin"
|
||||
android:layout_marginRight="@dimen/activity_horizontal_margin"
|
||||
android:layout_marginTop="10dp"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnCancel"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_margin="10dp"
|
||||
android:background="@color/pink"
|
||||
android:text="@string/cancel"
|
||||
android:textColor="@color/white" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnCreate"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_margin="10dp"
|
||||
android:background="@color/green"
|
||||
android:padding="10dp"
|
||||
android:text="Create Contact"
|
||||
android:textColor="@color/white" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/white"
|
||||
android:gravity="bottom"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/black"></LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="35dp"
|
||||
android:background="@color/bottomBarColor"
|
||||
android:gravity="bottom"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvAppVersion_brain_key_activity"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center"
|
||||
android:text="@string/v_1_0_beta" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvBlockNumberHead_brain_key_activity"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="2"
|
||||
android:gravity="center"
|
||||
android:text="@string/block_number" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivSocketConnected_brain_key_activity"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_weight="0.5" />
|
||||
|
||||
<ImageView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_weight="0.5"
|
||||
android:src="@drawable/icon_setting"
|
||||
android:visibility="invisible" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
Loading…
Reference in a new issue