diff --git a/app/build.gradle b/app/build.gradle index 570367950b18f699e4dec692eaa60f7f0025eabe..a3923fcaf9e1539e6cae85bf6ab5735f931fe31e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -122,12 +122,14 @@ dependencies { compile "io.reactivex.rxjava2:rxandroid:2.0.1" compile "io.reactivex.rxjava2:rxjava:$rxJavaVersion" -// MQTT + //MQTT compile 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.0.2' compile ('org.eclipse.paho:org.eclipse.paho.android.service:1.0.2') { exclude module: 'support-v4' } + //RXPermissions + compile 'com.tbruyelle.rxpermissions2:rxpermissions:0.9.4@aar' androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index d50fe7de70df8946d5b5d230a37558ef9fc7c412..3d49d7c04fb91c3bf16137dcae722274fca719f2 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,16 +1,21 @@ - + + + - - + + + + + - - + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/tecsynt/nynja/intetfaces/OnChooserPhotoDialogListener.java b/app/src/main/java/com/tecsynt/nynja/intetfaces/OnChooserPhotoDialogListener.java new file mode 100644 index 0000000000000000000000000000000000000000..4419d9389c38de3e36691888cd07f3e5f94ab43c --- /dev/null +++ b/app/src/main/java/com/tecsynt/nynja/intetfaces/OnChooserPhotoDialogListener.java @@ -0,0 +1,12 @@ +package com.tecsynt.nynja.intetfaces; + +/* + * Created by Bo on 29.06.2017. + */ + +public interface OnChooserPhotoDialogListener { + + void onCameraClick(); + + void onGalleryClick(); +} diff --git a/app/src/main/java/com/tecsynt/nynja/models/Phone.java b/app/src/main/java/com/tecsynt/nynja/models/Phone.java new file mode 100644 index 0000000000000000000000000000000000000000..63183c9ff297c5894fac6bbb7e44ba61df9de24d --- /dev/null +++ b/app/src/main/java/com/tecsynt/nynja/models/Phone.java @@ -0,0 +1,42 @@ +package com.tecsynt.nynja.models; + +/* + * Created by Bo on 29.06.2017. + */ + +import android.os.Parcel; +import android.os.Parcelable; + +public class Phone implements Parcelable { + + private String phone; + + public Phone() { + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeString(this.phone); + } + + protected Phone(Parcel in) { + this.phone = in.readString(); + } + + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + @Override + public Phone createFromParcel(Parcel source) { + return new Phone(source); + } + + @Override + public Phone[] newArray(int size) { + return new Phone[size]; + } + }; +} diff --git a/app/src/main/java/com/tecsynt/nynja/models/UserPerson.java b/app/src/main/java/com/tecsynt/nynja/models/UserPerson.java new file mode 100644 index 0000000000000000000000000000000000000000..ef88e8af5b678a6dd641c68d184f53e7ae8e105c --- /dev/null +++ b/app/src/main/java/com/tecsynt/nynja/models/UserPerson.java @@ -0,0 +1,79 @@ +package com.tecsynt.nynja.models; + +/* + * Created by Bo on 29.06.2017. + */ + +import android.os.Parcel; +import android.os.Parcelable; + +import java.util.ArrayList; +import java.util.List; + +public class UserPerson implements Parcelable { + + private String name; + private String surname; + private List phoneList = new ArrayList<>(); + + public UserPerson() { + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getSurname() { + return surname; + } + + public void setSurname(String surname) { + this.surname = surname; + } + + public List getPhoneList() { + return phoneList; + } + + public void setPhoneList(List phoneList) { + this.phoneList = phoneList; + } + + public String getFullName() { + return (name + " " + surname).trim(); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeString(this.name); + dest.writeString(this.surname); + dest.writeTypedList(this.phoneList); + } + + protected UserPerson(Parcel in) { + this.name = in.readString(); + this.surname = in.readString(); + this.phoneList = in.createTypedArrayList(Phone.CREATOR); + } + + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + @Override + public UserPerson createFromParcel(Parcel source) { + return new UserPerson(source); + } + + @Override + public UserPerson[] newArray(int size) { + return new UserPerson[size]; + } + }; +} diff --git a/app/src/main/java/com/tecsynt/nynja/mvp/presenters/EditProfilePresenter.java b/app/src/main/java/com/tecsynt/nynja/mvp/presenters/EditProfilePresenter.java new file mode 100644 index 0000000000000000000000000000000000000000..5bead7ce6565321ae0cbf8143e2985f60b76406e --- /dev/null +++ b/app/src/main/java/com/tecsynt/nynja/mvp/presenters/EditProfilePresenter.java @@ -0,0 +1,42 @@ +package com.tecsynt.nynja.mvp.presenters; + +import android.text.TextUtils; + +import com.arellomobile.mvp.InjectViewState; +import com.arellomobile.mvp.MvpPresenter; +import com.tecsynt.nynja.models.UserPerson; +import com.tecsynt.nynja.mvp.view.EditProfileView; +import com.tecsynt.nynja.utils.StringUtils; + +/** + * Date: 25.06.17 + * Time: 04:10 + * + * @author Max Chervatiuk + * Email: duo.blood@gmail.com + */ +@InjectViewState +public class EditProfilePresenter extends MvpPresenter { + + private void showErrorMessage(String errorMessage) { + getViewState().onErrorMessage(errorMessage); + } + + public void saveClick(String firstName, String lastName) { + if (StringUtils.isNotEmpty(firstName) && firstName.length() > 2) { + //// FIXME: 29.06.2017 update on server + UserPerson userPerson = new UserPerson(); + userPerson.setName(firstName); + userPerson.setSurname(lastName); + getViewState().onSaveClick(userPerson); + } else { + String errorMessage; + if (TextUtils.isEmpty(firstName)) { + errorMessage = "FirstName cannot be empty."; + } else { + errorMessage = "FirstName length should be at least 2 symbols."; + } + showErrorMessage(errorMessage); + } + } +} diff --git a/app/src/main/java/com/tecsynt/nynja/mvp/presenters/MyProfilePresenter.java b/app/src/main/java/com/tecsynt/nynja/mvp/presenters/MyProfilePresenter.java index 081a3334da18e40fa2ea19c060bae2b09330209b..f046f5d34c45e124166c6df3652c8e5d4a77f886 100644 --- a/app/src/main/java/com/tecsynt/nynja/mvp/presenters/MyProfilePresenter.java +++ b/app/src/main/java/com/tecsynt/nynja/mvp/presenters/MyProfilePresenter.java @@ -11,19 +11,23 @@ import com.tecsynt.nynja.mvp.view.MyProfileView; @InjectViewState public class MyProfilePresenter extends MvpPresenter { - public void navigateToEditProfileScreen() { + public void clickOnEditProfile() { getViewState().navigateToEditProfile(); } - public void navigateToQrCodeScreen() { + public void clickOnQrCode() { getViewState().navigateToQqCode(); } - public void navigateToCameraScreen() { + public void clickOnCamera() { + getViewState().navigateToCamera(); } - public void navigateToGalleryScreen() { + public void clickOnGallery() { + getViewState().navigateToGallery(); } - + public void showChooserImageDialog() { + getViewState().showChooserImageDialog(); + } } diff --git a/app/src/main/java/com/tecsynt/nynja/mvp/view/EditProfileView.java b/app/src/main/java/com/tecsynt/nynja/mvp/view/EditProfileView.java new file mode 100644 index 0000000000000000000000000000000000000000..dfc51e6678636d01da6a865e4c70b1c881ca0e11 --- /dev/null +++ b/app/src/main/java/com/tecsynt/nynja/mvp/view/EditProfileView.java @@ -0,0 +1,15 @@ +package com.tecsynt.nynja.mvp.view; + +/* + * Created by Bo on 29.06.2017. + */ + +import com.arellomobile.mvp.MvpView; +import com.tecsynt.nynja.models.UserPerson; + +public interface EditProfileView extends MvpView { + + void onErrorMessage(String errorMessage); + + void onSaveClick(UserPerson userPerson); +} diff --git a/app/src/main/java/com/tecsynt/nynja/mvp/view/MyProfileView.java b/app/src/main/java/com/tecsynt/nynja/mvp/view/MyProfileView.java index 482da5f0f689ac9d6d1a0cc8a5b7245c436dd477..d59739f4f1e90e05f292f48b2866b1fefd5894d9 100644 --- a/app/src/main/java/com/tecsynt/nynja/mvp/view/MyProfileView.java +++ b/app/src/main/java/com/tecsynt/nynja/mvp/view/MyProfileView.java @@ -16,4 +16,6 @@ public interface MyProfileView extends MvpView { void navigateToCamera(); void navigateToGallery(); + + void showChooserImageDialog(); } diff --git a/app/src/main/java/com/tecsynt/nynja/server/com/softwarejoint/bert/Bert.java b/app/src/main/java/com/tecsynt/nynja/server/com/softwarejoint/bert/Bert.java index 987023d8a61c4fc9048d445fed83b10f71be91a7..005adfb6ac93f304f3baa8cb9c247011277ad042 100644 --- a/app/src/main/java/com/tecsynt/nynja/server/com/softwarejoint/bert/Bert.java +++ b/app/src/main/java/com/tecsynt/nynja/server/com/softwarejoint/bert/Bert.java @@ -1,10 +1,7 @@ package com.tecsynt.nynja.server.com.softwarejoint.bert; -import android.annotation.SuppressLint; - import java.nio.charset.Charset; import java.util.ArrayList; -import java.util.HashMap; abstract class Bert { diff --git a/app/src/main/java/com/tecsynt/nynja/server/com/softwarejoint/bert/BertDecoder.java b/app/src/main/java/com/tecsynt/nynja/server/com/softwarejoint/bert/BertDecoder.java index e3f696afd0ada2062e616ada24a8cb23aa613cf7..600737a6ddf251bb6fc4a9da98acc3d9a4a38b71 100644 --- a/app/src/main/java/com/tecsynt/nynja/server/com/softwarejoint/bert/BertDecoder.java +++ b/app/src/main/java/com/tecsynt/nynja/server/com/softwarejoint/bert/BertDecoder.java @@ -8,7 +8,6 @@ import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.Map; -import java.util.Objects; @SuppressWarnings("WeakerAccess") public class BertDecoder extends Bert implements DistributionHeader { diff --git a/app/src/main/java/com/tecsynt/nynja/server/com/softwarejoint/bert/model/ServerResponse.java b/app/src/main/java/com/tecsynt/nynja/server/com/softwarejoint/bert/model/ServerResponse.java index f851127e2d2ac10db7d575c4464b71dd6066b767..db1d5c08746f012e72ebfc5b39e69fbb19f3c07b 100644 --- a/app/src/main/java/com/tecsynt/nynja/server/com/softwarejoint/bert/model/ServerResponse.java +++ b/app/src/main/java/com/tecsynt/nynja/server/com/softwarejoint/bert/model/ServerResponse.java @@ -2,8 +2,6 @@ package com.tecsynt.nynja.server.com.softwarejoint.bert.model; import android.support.annotation.NonNull; import android.support.annotation.Nullable; -import android.util.Log; - import com.tecsynt.nynja.server.com.softwarejoint.bert.BertAtom; import com.tecsynt.nynja.server.com.softwarejoint.bert.BertTuple; diff --git a/app/src/main/java/com/tecsynt/nynja/ui/activities/EditProfileActivity.java b/app/src/main/java/com/tecsynt/nynja/ui/activities/EditProfileActivity.java index 60655216bd7022361082109927950f19cd61c7e9..70ba86202b10ac0ee02c12c6af7e81cb2b3bdd9b 100644 --- a/app/src/main/java/com/tecsynt/nynja/ui/activities/EditProfileActivity.java +++ b/app/src/main/java/com/tecsynt/nynja/ui/activities/EditProfileActivity.java @@ -4,8 +4,10 @@ import android.content.Context; import android.content.Intent; import android.os.Bundle; +import com.tecsynt.nynja.models.UserPerson; import com.tecsynt.nynja.ui.base.BaseActivity; import com.tecsynt.nynja.ui.fragments.profile.EditProfileFragment; +import com.tecsynt.nynja.ui.fragments.profile.MyProfileFragment; /** * Created by dmitro.boiko on 27/06/2017. @@ -13,11 +15,14 @@ import com.tecsynt.nynja.ui.fragments.profile.EditProfileFragment; public class EditProfileActivity extends BaseActivity { - public static Intent getLaunchEditProfileActivity(Context context) { - return new Intent(context, EditProfileActivity.class); + public static Intent getLaunchEditProfileActivity(Context context, UserPerson userPerson) { + Intent intent = new Intent(context, EditProfileActivity.class); + intent.putExtra(MyProfileFragment.EDIT_PROFILE_TAG, userPerson); + return intent; } - @Override protected void onCreate(Bundle savedInstanceState) { + @Override + protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); EditProfileFragment fragment = new EditProfileFragment(); fragment.setArguments(getIntent().getExtras()); diff --git a/app/src/main/java/com/tecsynt/nynja/ui/activities/QRCodeGeneratorActivity.java b/app/src/main/java/com/tecsynt/nynja/ui/activities/QRCodeGeneratorActivity.java index 78631d301de42427cb3f449ddc48f38685651711..bbe1de471720d5b0bb64dc6513803dcc3ad6c14b 100644 --- a/app/src/main/java/com/tecsynt/nynja/ui/activities/QRCodeGeneratorActivity.java +++ b/app/src/main/java/com/tecsynt/nynja/ui/activities/QRCodeGeneratorActivity.java @@ -8,10 +8,13 @@ import android.widget.ImageView; import com.google.zxing.WriterException; import com.tecsynt.nynja.R; +import com.tecsynt.nynja.models.UserPerson; import com.tecsynt.nynja.ui.base.BaseActivity; +import com.tecsynt.nynja.ui.fragments.profile.MyProfileFragment; import com.tecsynt.nynja.utils.ZxingEncoder; import butterknife.BindView; +import butterknife.OnClick; /** @@ -23,21 +26,31 @@ public class QRCodeGeneratorActivity extends BaseActivity { @BindView(R.id.qr_code_qrcodegeneratoractivity) ImageView qrCode; - public static Intent getLaunchQRCodeGeneratorActivity(Context context) { - return new Intent(context, QRCodeGeneratorActivity.class); + public static Intent getLaunchQRCodeGeneratorActivity(Context context, UserPerson userPerson) { + Intent intent = new Intent(context, QRCodeGeneratorActivity.class); + intent.putExtra(MyProfileFragment.EDIT_PROFILE_TAG, userPerson); + return intent; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_qr_code_generator); - - try { - Bitmap qrCodeBitmap = ZxingEncoder.getInstance().generate_QR_CODE("TEST DATA"); - qrCode.setImageBitmap(qrCodeBitmap); - } catch (WriterException e) { - e.printStackTrace(); + if (getIntent() != null && getIntent().getExtras() != null) { + try { + //// FIXME: 29.06.2017 add real data + UserPerson userPerson = getIntent().getParcelableExtra(MyProfileFragment.EDIT_PROFILE_TAG); + String data = userPerson.getPhoneList().get(0) + ";" + userPerson.getFullName(); + Bitmap qrCodeBitmap = ZxingEncoder.getInstance().generate_QR_CODE(data); + qrCode.setImageBitmap(qrCodeBitmap); + } catch (WriterException e) { + e.printStackTrace(); + } } + } + @OnClick(android.R.id.content) + public void onContentClick() { + finish(); } } diff --git a/app/src/main/java/com/tecsynt/nynja/ui/base/BaseActivity.java b/app/src/main/java/com/tecsynt/nynja/ui/base/BaseActivity.java index f6dafecc5b7b54f9a7aa09aee1c7430585e451f4..368eef3ffcce357c6e0a49de1cdfee5395c4f252 100644 --- a/app/src/main/java/com/tecsynt/nynja/ui/base/BaseActivity.java +++ b/app/src/main/java/com/tecsynt/nynja/ui/base/BaseActivity.java @@ -1,8 +1,17 @@ package com.tecsynt.nynja.ui.base; +import android.app.ProgressDialog; +import android.content.Context; +import android.os.Bundle; import android.support.annotation.LayoutRes; +import android.support.annotation.Nullable; +import android.support.annotation.StringRes; +import android.view.View; +import android.view.ViewGroup; +import android.view.inputmethod.InputMethodManager; import com.arellomobile.mvp.MvpAppCompatActivity; +import com.tbruyelle.rxpermissions2.RxPermissions; import butterknife.ButterKnife; @@ -13,9 +22,67 @@ import butterknife.ButterKnife; public abstract class BaseActivity extends MvpAppCompatActivity { + private ProgressDialog mProgressDialog; + protected RxPermissions rxPermissions; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + rxPermissions = new RxPermissions(this); + } + @Override public void setContentView(@LayoutRes int layoutResID) { super.setContentView(layoutResID); ButterKnife.bind(this); } + + @Override + public void setContentView(View view) { + super.setContentView(view); + ButterKnife.bind(this); + } + + @Override + public void setContentView(View view, ViewGroup.LayoutParams params) { + super.setContentView(view, params); + ButterKnife.bind(this); + } + + private void showDialog(@Nullable String message) { + mProgressDialog = new ProgressDialog(this, ProgressDialog.STYLE_SPINNER); + mProgressDialog.setMessage(message); + mProgressDialog.setCancelable(false); + mProgressDialog.show(); + } + + public void showProgressDialog(@StringRes int messageResId) { + showDialog(getString(messageResId)); + } + + public void showProgressDialog(@Nullable String message) { + showDialog(message); + } + + public void hideProgressDialog() { + if (mProgressDialog != null) { + mProgressDialog.cancel(); + mProgressDialog = null; + } + } + + public void hideKeyboard() { + InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + View v = this.getCurrentFocus(); + if (v != null) { + imm.hideSoftInputFromWindow(v.getWindowToken(), 0); + v.clearFocus(); + } + } + + @Override + protected void onDestroy() { + super.onDestroy(); + hideProgressDialog(); + } } diff --git a/app/src/main/java/com/tecsynt/nynja/ui/base/BaseDialogFragment.java b/app/src/main/java/com/tecsynt/nynja/ui/base/BaseDialogFragment.java new file mode 100644 index 0000000000000000000000000000000000000000..d4924a1d27e8f63a3023aafc29e4a7ef1c90853e --- /dev/null +++ b/app/src/main/java/com/tecsynt/nynja/ui/base/BaseDialogFragment.java @@ -0,0 +1,33 @@ +package com.tecsynt.nynja.ui.base; + +/* + * Created by Bo on 29.06.2017. + */ + + +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v7.app.AppCompatDialogFragment; +import android.view.View; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public class BaseDialogFragment extends AppCompatDialogFragment { + + protected Unbinder unbinder; + + @Override + public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + unbinder = ButterKnife.bind(this, view); + } + + @Override + public void onDestroy() { + super.onDestroy(); + if (unbinder != null) { + unbinder.unbind(); + } + } +} diff --git a/app/src/main/java/com/tecsynt/nynja/ui/base/BaseFragment.java b/app/src/main/java/com/tecsynt/nynja/ui/base/BaseFragment.java index 0be48943ee94d4ee72fa19819bae5f5eca2d5c8b..dbb0c20ed08690abcf38aee1d6c631fe43244acd 100644 --- a/app/src/main/java/com/tecsynt/nynja/ui/base/BaseFragment.java +++ b/app/src/main/java/com/tecsynt/nynja/ui/base/BaseFragment.java @@ -5,6 +5,7 @@ import android.support.annotation.Nullable; import android.view.View; import com.arellomobile.mvp.MvpAppCompatFragment; +import com.tbruyelle.rxpermissions2.RxPermissions; import butterknife.ButterKnife; import butterknife.Unbinder; @@ -17,11 +18,13 @@ import butterknife.Unbinder; public abstract class BaseFragment extends MvpAppCompatFragment { private Unbinder mUnBinder; + protected RxPermissions rxPermissions; @Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); mUnBinder = ButterKnife.bind(this, view); + rxPermissions = new RxPermissions(getActivity()); } @Override diff --git a/app/src/main/java/com/tecsynt/nynja/ui/dialogs/ChooserPhotoDialog.java b/app/src/main/java/com/tecsynt/nynja/ui/dialogs/ChooserPhotoDialog.java new file mode 100644 index 0000000000000000000000000000000000000000..9187c5f658a8458fe4ec18893fe50dc210104661 --- /dev/null +++ b/app/src/main/java/com/tecsynt/nynja/ui/dialogs/ChooserPhotoDialog.java @@ -0,0 +1,81 @@ +package com.tecsynt.nynja.ui.dialogs; + +/* + * Created by Bo on 29.06.2017. + */ + +import android.app.Dialog; +import android.app.DialogFragment; +import android.graphics.Color; +import android.graphics.drawable.ColorDrawable; +import android.os.Bundle; +import android.support.v4.app.FragmentManager; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.Window; + +import com.tecsynt.nynja.R; +import com.tecsynt.nynja.intetfaces.OnChooserPhotoDialogListener; +import com.tecsynt.nynja.ui.base.BaseDialogFragment; + +import butterknife.OnClick; + +public class ChooserPhotoDialog extends BaseDialogFragment { + + private OnChooserPhotoDialogListener chooserPhotoDialogListener; + + private static ChooserPhotoDialog newInstance(OnChooserPhotoDialogListener chooserPhotoDialogListener) { + ChooserPhotoDialog chooserPhotoDialog = new ChooserPhotoDialog(); + chooserPhotoDialog.setChooserPhotoDialogListener(chooserPhotoDialogListener); + return chooserPhotoDialog; + } + + public static void show(OnChooserPhotoDialogListener onChooserPhotoDialogListener, FragmentManager fragmentManager) { + ChooserPhotoDialog chooserPhotoDialog = ChooserPhotoDialog.newInstance(onChooserPhotoDialogListener); + chooserPhotoDialog.setStyle(DialogFragment.STYLE_NO_TITLE, R.style.AppTheme_FullWidthDialog); + chooserPhotoDialog.show(fragmentManager, chooserPhotoDialog.getClass().getSimpleName()); + } + + public void setChooserPhotoDialogListener(OnChooserPhotoDialogListener chooserPhotoDialogListener) { + this.chooserPhotoDialogListener = chooserPhotoDialogListener; + } + + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + Dialog dialog = super.onCreateDialog(savedInstanceState); + Window window = dialog.getWindow(); + if (window != null) { + dialog.getWindow().setGravity(Gravity.BOTTOM); + dialog.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); + dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); + dialog.getWindow().getAttributes().windowAnimations = R.style.SlidingBottomDialogAnimation; + } + return dialog; + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + return inflater.inflate(R.layout.dialog_chooser_photo, container, false); + } + + + @OnClick(R.id.camera_dialog_chooser_photo) + public void onCameraClick() { + chooserPhotoDialogListener.onCameraClick(); + dismiss(); + } + + @OnClick(R.id.gallery_dialog_chooser_photo) + public void onGalleryClick() { + chooserPhotoDialogListener.onGalleryClick(); + dismiss(); + } + + @OnClick(R.id.cancel_dialog_chooser_photo) + public void onCancelClick() { + dismiss(); + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/tecsynt/nynja/ui/fragments/profile/EditProfileFragment.java b/app/src/main/java/com/tecsynt/nynja/ui/fragments/profile/EditProfileFragment.java index 50025a9df4fd861f5ab9ac46c5d883bd5232b64d..d41ba278c6564a1a5cdfcf994835041870dc9536 100644 --- a/app/src/main/java/com/tecsynt/nynja/ui/fragments/profile/EditProfileFragment.java +++ b/app/src/main/java/com/tecsynt/nynja/ui/fragments/profile/EditProfileFragment.java @@ -1,23 +1,75 @@ package com.tecsynt.nynja.ui.fragments.profile; +import android.app.Activity; +import android.content.Intent; import android.os.Bundle; import android.support.annotation.Nullable; +import android.support.design.widget.TextInputEditText; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import com.arellomobile.mvp.presenter.InjectPresenter; import com.tecsynt.nynja.R; +import com.tecsynt.nynja.models.UserPerson; +import com.tecsynt.nynja.mvp.presenters.EditProfilePresenter; +import com.tecsynt.nynja.mvp.view.EditProfileView; import com.tecsynt.nynja.ui.base.BaseFragment; +import com.tecsynt.nynja.utils.StringUtils; + +import butterknife.BindView; +import butterknife.OnClick; /** * Created by dmitro.boiko on 27/06/2017. */ -public class EditProfileFragment extends BaseFragment { +public class EditProfileFragment extends BaseFragment implements EditProfileView { + + @BindView(R.id.first_name_edt_first_name) + TextInputEditText firstName; + + @BindView(R.id.last_name_edt_first_name) + TextInputEditText lastName; + + @InjectPresenter + EditProfilePresenter editProfilePresenter; @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_edit_profile, container, false); } + + @Override + public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + if (getArguments() != null) { + UserPerson userPerson = getArguments().getParcelable(MyProfileFragment.EDIT_PROFILE_TAG); + setUserModel(userPerson); + } + } + + private void setUserModel(UserPerson userPerson) { + firstName.setText(userPerson.getName()); + lastName.setText(userPerson.getSurname()); + } + + @OnClick(R.id.next_button_fragmenteditprofile) + public void onSaveButtonClick() { + editProfilePresenter.saveClick(StringUtils.getText(firstName), StringUtils.getText(lastName)); + } + + @Override + public void onErrorMessage(String errorMessage) { + + } + + @Override + public void onSaveClick(UserPerson userPerson) { + Intent intent = new Intent(); + intent.putExtra(MyProfileFragment.EDIT_PROFILE_TAG, userPerson); + getActivity().setResult(Activity.RESULT_OK, intent); + getActivity().finish(); + } } diff --git a/app/src/main/java/com/tecsynt/nynja/ui/fragments/profile/MyProfileFragment.java b/app/src/main/java/com/tecsynt/nynja/ui/fragments/profile/MyProfileFragment.java index 76520cdf06774e5a4b1c12a071d1efa7476fb9b0..10602abd71356be5a728220597229f10cef82694 100644 --- a/app/src/main/java/com/tecsynt/nynja/ui/fragments/profile/MyProfileFragment.java +++ b/app/src/main/java/com/tecsynt/nynja/ui/fragments/profile/MyProfileFragment.java @@ -1,64 +1,221 @@ package com.tecsynt.nynja.ui.fragments.profile; +import android.Manifest; +import android.app.Activity; +import android.content.Intent; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.net.Uri; import android.os.Bundle; +import android.provider.MediaStore; import android.support.annotation.Nullable; +import android.support.v4.content.FileProvider; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; import com.arellomobile.mvp.presenter.InjectPresenter; +import com.tecsynt.nynja.BuildConfig; import com.tecsynt.nynja.R; +import com.tecsynt.nynja.intetfaces.OnChooserPhotoDialogListener; +import com.tecsynt.nynja.models.UserPerson; import com.tecsynt.nynja.mvp.presenters.MyProfilePresenter; import com.tecsynt.nynja.mvp.view.MyProfileView; import com.tecsynt.nynja.ui.activities.EditProfileActivity; import com.tecsynt.nynja.ui.activities.QRCodeGeneratorActivity; import com.tecsynt.nynja.ui.base.BaseFragment; +import com.tecsynt.nynja.ui.dialogs.ChooserPhotoDialog; +import com.tecsynt.nynja.utils.ImageUtils; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; + +import butterknife.BindView; import butterknife.OnClick; +import butterknife.Optional; /** * Created by dmitro.boiko on 27/06/2017. **/ -public class MyProfileFragment extends BaseFragment implements MyProfileView { +public class MyProfileFragment extends BaseFragment implements MyProfileView, + OnChooserPhotoDialogListener { + + private static final int IMAGE_REQUEST_CODE = 42; + private static final int GALLERY_REQUEST_CODE = 43; + private static final int EDIT_PROFILE_REQUEST_CODE = 44; + public static final String EDIT_PROFILE_TAG = "edit_profile"; + + @BindView(R.id.userphoto_myprofilefragment) + ImageView userPhoto; + @BindView(R.id.username_myprofilefragment) + TextView userName; @InjectPresenter MyProfilePresenter mPresenter; + private String photoPath; + private UserPerson userPerson; + @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_my_profile, container, false); } - @OnClick(R.id.edit_name_myprofilefragment) + + @Override + public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + //// FIXME: 29.06.2017 set real user info + userPerson = new UserPerson(); + userPerson.setName("Marshall"); + userPerson.setSurname("Taplits"); + setUserModel(userPerson); + } + + @OnClick(R.id.username_myprofilefragment) public void onEditNameClick() { - mPresenter.navigateToEditProfileScreen(); + mPresenter.clickOnEditProfile(); } @OnClick(R.id.qrcode_myprofilefragment) public void oncQrCodeClick() { - mPresenter.navigateToQrCodeScreen(); + mPresenter.clickOnQrCode(); + } + + @Optional + @OnClick({R.id.photo_myprofilefragment, R.id.userphoto_myprofilefragment}) + public void onPhotoClick() { + mPresenter.showChooserImageDialog(); } - @OnClick(R.id.photo_myprofilefragment) - public void oncPhotoClick() { - mPresenter.navigateToGalleryScreen(); + @Override + public void navigateToEditProfile() { + startActivityForResult(EditProfileActivity.getLaunchEditProfileActivity(getContext(), + userPerson), EDIT_PROFILE_REQUEST_CODE); } - @Override public void navigateToEditProfile() { - startActivity(EditProfileActivity.getLaunchEditProfileActivity(getContext())); + @Override + public void navigateToQqCode() { + startActivity(QRCodeGeneratorActivity.getLaunchQRCodeGeneratorActivity(getContext(), userPerson)); } - @Override public void navigateToQqCode() { - startActivity(QRCodeGeneratorActivity.getLaunchQRCodeGeneratorActivity(getContext())); + @Override + public void navigateToCamera() { + rxPermissions. + request(Manifest.permission.CAMERA) + .subscribe(granted -> { + if (granted) { + startPhotoActivity(); + } else { + //// FIXME: 29.06.2017 message? + } + }); } - @Override public void navigateToCamera() { + private void startPhotoActivity() { + Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); + if (takePictureIntent.resolveActivity(getContext().getPackageManager()) != null) { + File photoFile = null; + try { + photoFile = ImageUtils.createImageFile(getContext()); + photoPath = photoFile.getAbsolutePath(); + } catch (IOException e) { + e.printStackTrace(); + } + if (photoFile != null) { + Uri photoURI = FileProvider.getUriForFile(getContext(), + BuildConfig.APPLICATION_ID + ".fileprovider", + photoFile); + takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI); + startActivityForResult(takePictureIntent, IMAGE_REQUEST_CODE); + } + } + } + @Override + public void navigateToGallery() { + rxPermissions. + request(Manifest.permission.READ_EXTERNAL_STORAGE) + .subscribe(granted -> { + if (granted) { + startGalleryActivity(); + } else { + //// FIXME: 29.06.2017 message? + } + }); } - @Override public void navigateToGallery() { + @Override + public void showChooserImageDialog() { + ChooserPhotoDialog.show(this, getChildFragmentManager()); + } + @Override + + public void onActivityResult(int requestCode, int resultCode, Intent data) { + if (resultCode == Activity.RESULT_OK) { + if (requestCode == IMAGE_REQUEST_CODE) { + decodePhoto(); + } else if (requestCode == GALLERY_REQUEST_CODE && data != null) { + decodePhotoFromGallery(data); + } else if (requestCode == EDIT_PROFILE_REQUEST_CODE && data != null) { + UserPerson userPerson = data.getParcelableExtra(EDIT_PROFILE_TAG); + setUserModel(userPerson); + } + } + super.onActivityResult(requestCode, resultCode, data); + } + + private void setUserModel(UserPerson userPerson) { + this.userPerson = userPerson; + userName.setText(this.userPerson.getFullName()); + } + + private void decodePhotoFromGallery(Intent data) { + try { + Uri imageUri = data.getData(); + Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContext().getContentResolver(), imageUri); + setUserAvatar(bitmap); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private void startGalleryActivity() { + Intent galleryIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI); + startActivityForResult(galleryIntent, GALLERY_REQUEST_CODE); + } + + private void decodePhoto() { + Uri imageUri = Uri.parse(photoPath); + try { + File file = new File(imageUri.getPath()); + InputStream ims = new FileInputStream(file); + setUserAvatar(BitmapFactory.decodeStream(ims)); + //// FIXME: 29.06.2017 should we add photo to gallery?? + } catch (Exception e) { + e.printStackTrace(); + } + } + + private void setUserAvatar(Bitmap bitmap) { + userPhoto.setImageBitmap(ImageUtils.circleTransform(bitmap)); + userPhoto.setPadding(0, 0, 0, 0); + } + + @Override + public void onCameraClick() { + mPresenter.clickOnCamera(); + } + + @Override + public void onGalleryClick() { + mPresenter.clickOnGallery(); } } diff --git a/app/src/main/java/com/tecsynt/nynja/utils/ImageUtils.java b/app/src/main/java/com/tecsynt/nynja/utils/ImageUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..dd40acacabf58fc17233d23ae997700e8825585c --- /dev/null +++ b/app/src/main/java/com/tecsynt/nynja/utils/ImageUtils.java @@ -0,0 +1,54 @@ +package com.tecsynt.nynja.utils; + +/* + * Created by Bo on 29.06.2017. + */ + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.BitmapShader; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; + +public class ImageUtils { + + public static File createImageFile(Context context) throws IOException { + // Create an image file name + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); + String imageFileName = "JPEG_" + timeStamp + "_"; + File storageDir = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES); + return File.createTempFile( + imageFileName, /* prefix */ + ".jpg", /* suffix */ + storageDir /* directory */ + ); + } + + public static Bitmap circleTransform(Bitmap source) { + int size = Math.min(source.getWidth(), source.getHeight()); + + int x = (source.getWidth() - size) / 2; + int y = (source.getHeight() - size) / 2; + + Bitmap squaredBitmap = Bitmap.createBitmap(source, x, y, size, size); + if (squaredBitmap != source) { + source.recycle(); + } + Bitmap bitmap = Bitmap.createBitmap(size, size, source.getConfig()); + Canvas canvas = new Canvas(bitmap); + Paint paint = new Paint(); + BitmapShader shader = new BitmapShader(squaredBitmap, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP); + paint.setShader(shader); + paint.setAntiAlias(true); + float r = size / 2f; + canvas.drawCircle(r, r, r, paint); + squaredBitmap.recycle(); + return bitmap; + } +} diff --git a/app/src/main/java/com/tecsynt/nynja/utils/StringUtils.java b/app/src/main/java/com/tecsynt/nynja/utils/StringUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..27bd2fd5c042ca294770bca97fdf348587573813 --- /dev/null +++ b/app/src/main/java/com/tecsynt/nynja/utils/StringUtils.java @@ -0,0 +1,20 @@ +package com.tecsynt.nynja.utils; + +/* + * Created by Bo on 29.06.2017. + */ + +import android.support.annotation.Nullable; +import android.text.TextUtils; +import android.widget.TextView; + +public class StringUtils { + + public static boolean isNotEmpty(String data) { + return data != null && !TextUtils.isEmpty(data.trim()); + } + + public static String getText(@Nullable TextView view) { + return view != null ? view.getText().toString() : ""; + } +} diff --git a/app/src/main/java/com/tecsynt/nynja/utils/ValidationUtils.java b/app/src/main/java/com/tecsynt/nynja/utils/ValidationUtils.java index 4ba30bd2cf58dfce316066a2ae3f756e91528f36..129ef6ecea804678b998fbba040d5c002f0829c8 100644 --- a/app/src/main/java/com/tecsynt/nynja/utils/ValidationUtils.java +++ b/app/src/main/java/com/tecsynt/nynja/utils/ValidationUtils.java @@ -1,5 +1,7 @@ package com.tecsynt.nynja.utils; +import android.util.Patterns; + /** * Created by Max Chervatiuk on 22.06.17. * Email: duo.blood@gmail.com @@ -10,4 +12,9 @@ package com.tecsynt.nynja.utils; public class ValidationUtils { //// TODO: 22.06.17 Implement class + + public static boolean isEmailVaild(String email) { + return email != null && Patterns.EMAIL_ADDRESS.matcher(email).matches(); + } + } diff --git a/app/src/main/res/anim/slide_out_down.xml b/app/src/main/res/anim/slide_out_down.xml new file mode 100644 index 0000000000000000000000000000000000000000..0f339542171f83543ab99b34f7c689abae030dc1 --- /dev/null +++ b/app/src/main/res/anim/slide_out_down.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/app/src/main/res/anim/slide_up_dialog.xml b/app/src/main/res/anim/slide_up_dialog.xml new file mode 100644 index 0000000000000000000000000000000000000000..3c613f3bc140e9af65d571ad270837f40fac7d27 --- /dev/null +++ b/app/src/main/res/anim/slide_up_dialog.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/app/src/main/res/layout/dialog_chooser_photo.xml b/app/src/main/res/layout/dialog_chooser_photo.xml new file mode 100644 index 0000000000000000000000000000000000000000..a357fe15950b0e501c93a7701a6d6433f29ef78d --- /dev/null +++ b/app/src/main/res/layout/dialog_chooser_photo.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_my_profile.xml b/app/src/main/res/layout/fragment_my_profile.xml index 317294d816b3448853777e671c9ef7cefa7c3bc7..7e6556dd1507134f78d0d5a3b2149837ff4d6ff1 100644 --- a/app/src/main/res/layout/fragment_my_profile.xml +++ b/app/src/main/res/layout/fragment_my_profile.xml @@ -44,38 +44,24 @@ android:src="@drawable/qr_code" /> - + android:paddingStart="42dp" + tools:text="Marshall Taplits" + android:drawablePadding="8dp" + android:textColor="@color/colorAccent" + android:textSize="31sp" /> - - - - + android:textSize="20sp" /> \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a24595f7336996446c2e2ca807c16506e870936b..00ab602cd96dc8ecd870d9456dacd7e577baf86f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -12,4 +12,9 @@ Last Name --- --- + + Camera + Choose from gallery + Cancel + diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 1a06fc201e9e3b10be3a8989f8b718461352278f..40fec0ed2d9cae9b74f41c83a8c63f8a631f2f7a 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -25,4 +25,17 @@ + + + + diff --git a/app/src/main/res/xml/provider_paths.xml b/app/src/main/res/xml/provider_paths.xml new file mode 100644 index 0000000000000000000000000000000000000000..21c6b01f50f0f0d5eabcd0a668b0bf03d5f6e32e --- /dev/null +++ b/app/src/main/res/xml/provider_paths.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/build.gradle b/build.gradle index 53dc8ba6a966d40fc6db8c4e2007b719dea5e076..15429c62eb6604873f703213981ed61f18ffbdfc 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:2.3.1' + classpath 'com.android.tools.build:gradle:2.3.2' classpath 'me.tatarka:gradle-retrolambda:3.6.1' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files