mirror of
https://github.com/overte-org/overte.git
synced 2025-06-17 14:40:46 +02:00
Android sign up
This commit is contained in:
parent
32da2cbef6
commit
f4be767d22
10 changed files with 536 additions and 1 deletions
|
@ -26,6 +26,7 @@
|
||||||
|
|
||||||
QAndroidJniObject __interfaceActivity;
|
QAndroidJniObject __interfaceActivity;
|
||||||
QAndroidJniObject __loginCompletedListener;
|
QAndroidJniObject __loginCompletedListener;
|
||||||
|
QAndroidJniObject __signupCompletedListener;
|
||||||
QAndroidJniObject __loadCompleteListener;
|
QAndroidJniObject __loadCompleteListener;
|
||||||
QAndroidJniObject __usernameChangedListener;
|
QAndroidJniObject __usernameChangedListener;
|
||||||
void tempMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString& message) {
|
void tempMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString& message) {
|
||||||
|
@ -306,6 +307,58 @@ Java_io_highfidelity_hifiinterface_fragment_LoginFragment_nativeLogin(JNIEnv *en
|
||||||
Q_ARG(const QString&, username), Q_ARG(const QString&, password));
|
Q_ARG(const QString&, username), Q_ARG(const QString&, password));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JNIEXPORT void Java_io_highfidelity_hifiinterface_InterfaceActivity_nativeInitAfterAppLoaded(JNIEnv* env, jobject obj) {
|
||||||
|
AndroidHelper::instance().moveToThread(qApp->thread());
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT void JNICALL
|
||||||
|
Java_io_highfidelity_hifiinterface_fragment_SignupFragment_nativeSignup(JNIEnv *env, jobject instance,
|
||||||
|
jstring email_, jstring username_,
|
||||||
|
jstring password_) {
|
||||||
|
|
||||||
|
const char *c_email = env->GetStringUTFChars(email_, 0);
|
||||||
|
const char *c_username = env->GetStringUTFChars(username_, 0);
|
||||||
|
const char *c_password = env->GetStringUTFChars(password_, 0);
|
||||||
|
QString email = QString(c_email);
|
||||||
|
QString username = QString(c_username);
|
||||||
|
QString password = QString(c_password);
|
||||||
|
env->ReleaseStringUTFChars(email_, c_email);
|
||||||
|
env->ReleaseStringUTFChars(username_, c_username);
|
||||||
|
env->ReleaseStringUTFChars(password_, c_password);
|
||||||
|
|
||||||
|
__signupCompletedListener = QAndroidJniObject(instance);
|
||||||
|
|
||||||
|
// disconnect any previous callback
|
||||||
|
QObject::disconnect(&AndroidHelper::instance(), &AndroidHelper::handleSignupCompleted, nullptr, nullptr);
|
||||||
|
QObject::disconnect(&AndroidHelper::instance(), &AndroidHelper::handleSignupFailed, nullptr, nullptr);
|
||||||
|
|
||||||
|
QObject::connect(&AndroidHelper::instance(), &AndroidHelper::handleSignupCompleted, []() {
|
||||||
|
jboolean jSuccess = (jboolean) true;
|
||||||
|
if (__signupCompletedListener.isValid()) {
|
||||||
|
__signupCompletedListener.callMethod<void>("handleSignupCompleted", "()V", jSuccess);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
QObject::connect(&AndroidHelper::instance(), &AndroidHelper::handleSignupFailed, [](QString errorString) {
|
||||||
|
jboolean jSuccess = (jboolean) false;
|
||||||
|
jstring jError = QAndroidJniObject::fromString(errorString).object<jstring>();
|
||||||
|
if (__signupCompletedListener.isValid()) {
|
||||||
|
QAndroidJniObject string = QAndroidJniObject::fromString(errorString);
|
||||||
|
__signupCompletedListener.callMethod<void>("handleSignupFailed", "(Ljava/lang/String;)V", string.object<jstring>());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
AndroidHelper::instance().signup(email, username, password);
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT void JNICALL
|
||||||
|
Java_io_highfidelity_hifiinterface_fragment_SignupFragment_nativeCancelSignup(JNIEnv *env, jobject instance) {
|
||||||
|
QObject::disconnect(&AndroidHelper::instance(), &AndroidHelper::handleSignupCompleted, nullptr, nullptr);
|
||||||
|
QObject::disconnect(&AndroidHelper::instance(), &AndroidHelper::handleSignupFailed, nullptr, nullptr);
|
||||||
|
|
||||||
|
__signupCompletedListener = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
JNIEXPORT jboolean JNICALL
|
JNIEXPORT jboolean JNICALL
|
||||||
Java_io_highfidelity_hifiinterface_fragment_FriendsFragment_nativeIsLoggedIn(JNIEnv *env, jobject instance) {
|
Java_io_highfidelity_hifiinterface_fragment_FriendsFragment_nativeIsLoggedIn(JNIEnv *env, jobject instance) {
|
||||||
auto accountManager = DependencyManager::get<AccountManager>();
|
auto accountManager = DependencyManager::get<AccountManager>();
|
||||||
|
|
|
@ -65,6 +65,7 @@ public class InterfaceActivity extends QtActivity implements WebViewFragment.OnW
|
||||||
private native void nativeEnterBackground();
|
private native void nativeEnterBackground();
|
||||||
private native void nativeEnterForeground();
|
private native void nativeEnterForeground();
|
||||||
private native long nativeOnExitVr();
|
private native long nativeOnExitVr();
|
||||||
|
private native void nativeInitAfterAppLoaded();
|
||||||
|
|
||||||
private AssetManager assetManager;
|
private AssetManager assetManager;
|
||||||
|
|
||||||
|
@ -335,6 +336,9 @@ public class InterfaceActivity extends QtActivity implements WebViewFragment.OnW
|
||||||
if (nativeEnterBackgroundCallEnqueued) {
|
if (nativeEnterBackgroundCallEnqueued) {
|
||||||
nativeEnterBackground();
|
nativeEnterBackground();
|
||||||
}
|
}
|
||||||
|
runOnUiThread(() -> {
|
||||||
|
nativeInitAfterAppLoaded();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void performHapticFeedback(int duration) {
|
public void performHapticFeedback(int duration) {
|
||||||
|
|
|
@ -25,6 +25,7 @@ import android.view.Window;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.squareup.picasso.Callback;
|
import com.squareup.picasso.Callback;
|
||||||
import com.squareup.picasso.Picasso;
|
import com.squareup.picasso.Picasso;
|
||||||
|
@ -33,12 +34,14 @@ import io.highfidelity.hifiinterface.fragment.FriendsFragment;
|
||||||
import io.highfidelity.hifiinterface.fragment.HomeFragment;
|
import io.highfidelity.hifiinterface.fragment.HomeFragment;
|
||||||
import io.highfidelity.hifiinterface.fragment.LoginFragment;
|
import io.highfidelity.hifiinterface.fragment.LoginFragment;
|
||||||
import io.highfidelity.hifiinterface.fragment.PolicyFragment;
|
import io.highfidelity.hifiinterface.fragment.PolicyFragment;
|
||||||
|
import io.highfidelity.hifiinterface.fragment.SignupFragment;
|
||||||
import io.highfidelity.hifiinterface.task.DownloadProfileImageTask;
|
import io.highfidelity.hifiinterface.task.DownloadProfileImageTask;
|
||||||
|
|
||||||
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener,
|
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener,
|
||||||
LoginFragment.OnLoginInteractionListener,
|
LoginFragment.OnLoginInteractionListener,
|
||||||
HomeFragment.OnHomeInteractionListener,
|
HomeFragment.OnHomeInteractionListener,
|
||||||
FriendsFragment.OnHomeInteractionListener {
|
FriendsFragment.OnHomeInteractionListener,
|
||||||
|
SignupFragment.OnSignupInteractionListener {
|
||||||
|
|
||||||
private static final int PROFILE_PICTURE_PLACEHOLDER = R.drawable.default_profile_avatar;
|
private static final int PROFILE_PICTURE_PLACEHOLDER = R.drawable.default_profile_avatar;
|
||||||
public static final String DEFAULT_FRAGMENT = "Home";
|
public static final String DEFAULT_FRAGMENT = "Home";
|
||||||
|
@ -139,6 +142,12 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
|
||||||
loadFragment(fragment, getString(R.string.login), getString(R.string.tagFragmentLogin), true);
|
loadFragment(fragment, getString(R.string.login), getString(R.string.tagFragmentLogin), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void loadSignupFragment() {
|
||||||
|
Fragment fragment = SignupFragment.newInstance();
|
||||||
|
|
||||||
|
loadFragment(fragment, getString(R.string.signup), getString(R.string.tagFragmentSignup), true);
|
||||||
|
}
|
||||||
|
|
||||||
private void loadPrivacyPolicyFragment() {
|
private void loadPrivacyPolicyFragment() {
|
||||||
Fragment fragment = PolicyFragment.newInstance();
|
Fragment fragment = PolicyFragment.newInstance();
|
||||||
|
|
||||||
|
@ -307,6 +316,22 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoginRequested() {
|
||||||
|
loadLoginFragment();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSignupRequested() {
|
||||||
|
loadSignupFragment();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSignupCompleted() {
|
||||||
|
Toast.makeText(this, "Sign up succeeded", Toast.LENGTH_SHORT).show();
|
||||||
|
loadLoginFragment();
|
||||||
|
}
|
||||||
|
|
||||||
public void handleUsernameChanged(String username) {
|
public void handleUsernameChanged(String username) {
|
||||||
runOnUiThread(() -> updateProfileHeader(username));
|
runOnUiThread(() -> updateProfileHeader(username));
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ public class LoginFragment extends Fragment {
|
||||||
private EditText mPassword;
|
private EditText mPassword;
|
||||||
private TextView mError;
|
private TextView mError;
|
||||||
private TextView mForgotPassword;
|
private TextView mForgotPassword;
|
||||||
|
private TextView mSignup;
|
||||||
private Button mLoginButton;
|
private Button mLoginButton;
|
||||||
|
|
||||||
private ProgressDialog mDialog;
|
private ProgressDialog mDialog;
|
||||||
|
@ -58,10 +59,12 @@ public class LoginFragment extends Fragment {
|
||||||
mError = rootView.findViewById(R.id.error);
|
mError = rootView.findViewById(R.id.error);
|
||||||
mLoginButton = rootView.findViewById(R.id.loginButton);
|
mLoginButton = rootView.findViewById(R.id.loginButton);
|
||||||
mForgotPassword = rootView.findViewById(R.id.forgotPassword);
|
mForgotPassword = rootView.findViewById(R.id.forgotPassword);
|
||||||
|
mSignup = rootView.findViewById(R.id.signup);
|
||||||
|
|
||||||
mLoginButton.setOnClickListener(view -> login());
|
mLoginButton.setOnClickListener(view -> login());
|
||||||
|
|
||||||
mForgotPassword.setOnClickListener(view -> forgotPassword());
|
mForgotPassword.setOnClickListener(view -> forgotPassword());
|
||||||
|
mSignup.setOnClickListener(view -> signup());
|
||||||
|
|
||||||
mPassword.setOnEditorActionListener(
|
mPassword.setOnEditorActionListener(
|
||||||
(textView, actionId, keyEvent) -> {
|
(textView, actionId, keyEvent) -> {
|
||||||
|
@ -121,6 +124,12 @@ public class LoginFragment extends Fragment {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void signup() {
|
||||||
|
if (mListener != null) {
|
||||||
|
mListener.onSignupRequested();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void hideKeyboard() {
|
private void hideKeyboard() {
|
||||||
View view = getActivity().getCurrentFocus();
|
View view = getActivity().getCurrentFocus();
|
||||||
if (view != null) {
|
if (view != null) {
|
||||||
|
@ -182,6 +191,7 @@ public class LoginFragment extends Fragment {
|
||||||
|
|
||||||
public interface OnLoginInteractionListener {
|
public interface OnLoginInteractionListener {
|
||||||
void onLoginCompleted();
|
void onLoginCompleted();
|
||||||
|
void onSignupRequested();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,190 @@
|
||||||
|
package io.highfidelity.hifiinterface.fragment;
|
||||||
|
|
||||||
|
import android.app.Fragment;
|
||||||
|
import android.app.ProgressDialog;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.view.inputmethod.EditorInfo;
|
||||||
|
import android.view.inputmethod.InputMethodManager;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.EditText;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import org.qtproject.qt5.android.QtNative;
|
||||||
|
|
||||||
|
import io.highfidelity.hifiinterface.R;
|
||||||
|
|
||||||
|
import static org.qtproject.qt5.android.QtActivityDelegate.ApplicationActive;
|
||||||
|
import static org.qtproject.qt5.android.QtActivityDelegate.ApplicationInactive;
|
||||||
|
|
||||||
|
public class SignupFragment extends Fragment {
|
||||||
|
|
||||||
|
private EditText mEmail;
|
||||||
|
private EditText mUsername;
|
||||||
|
private EditText mPassword;
|
||||||
|
private TextView mError;
|
||||||
|
private TextView mLogin;
|
||||||
|
|
||||||
|
private Button mSignupButton;
|
||||||
|
|
||||||
|
private ProgressDialog mDialog;
|
||||||
|
|
||||||
|
public native void nativeSignup(String email, String username, String password); // move to SignupFragment
|
||||||
|
public native void nativeCancelSignup();
|
||||||
|
|
||||||
|
private SignupFragment.OnSignupInteractionListener mListener;
|
||||||
|
|
||||||
|
public SignupFragment() {
|
||||||
|
// Required empty public constructor
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SignupFragment newInstance() {
|
||||||
|
SignupFragment fragment = new SignupFragment();
|
||||||
|
return fragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||||
|
Bundle savedInstanceState) {
|
||||||
|
View rootView = inflater.inflate(R.layout.fragment_signup, container, false);
|
||||||
|
|
||||||
|
mEmail = rootView.findViewById(R.id.email);
|
||||||
|
mUsername = rootView.findViewById(R.id.username);
|
||||||
|
mPassword = rootView.findViewById(R.id.password);
|
||||||
|
mError = rootView.findViewById(R.id.error);
|
||||||
|
mSignupButton = rootView.findViewById(R.id.signupButton);
|
||||||
|
mLogin = rootView.findViewById(R.id.login);
|
||||||
|
|
||||||
|
mSignupButton.setOnClickListener(view -> signup());
|
||||||
|
mLogin.setOnClickListener(view -> login());
|
||||||
|
mPassword.setOnEditorActionListener(
|
||||||
|
(textView, actionId, keyEvent) -> {
|
||||||
|
if (actionId == EditorInfo.IME_ACTION_DONE) {
|
||||||
|
mSignupButton.performClick();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
return rootView;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAttach(Context context) {
|
||||||
|
super.onAttach(context);
|
||||||
|
if (context instanceof OnSignupInteractionListener) {
|
||||||
|
mListener = (OnSignupInteractionListener) context;
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException(context.toString()
|
||||||
|
+ " must implement OnSignupInteractionListener");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDetach() {
|
||||||
|
super.onDetach();
|
||||||
|
mListener = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
// This hack intends to keep Qt threads running even after the app comes from background
|
||||||
|
QtNative.setApplicationState(ApplicationActive);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStop() {
|
||||||
|
super.onStop();
|
||||||
|
cancelActivityIndicator();
|
||||||
|
// Leave the Qt app paused
|
||||||
|
QtNative.setApplicationState(ApplicationInactive);
|
||||||
|
hideKeyboard();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void login() {
|
||||||
|
if (mListener != null) {
|
||||||
|
mListener.onLoginRequested();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void signup() {
|
||||||
|
String email = mEmail.getText().toString().trim();
|
||||||
|
String username = mUsername.getText().toString().trim();
|
||||||
|
String password = mPassword.getText().toString();
|
||||||
|
hideKeyboard();
|
||||||
|
if (email.isEmpty() || username.isEmpty() || password.isEmpty()) {
|
||||||
|
showError(getString(R.string.signup_email_username_or_password_incorrect));
|
||||||
|
} else {
|
||||||
|
mSignupButton.setEnabled(false);
|
||||||
|
hideError();
|
||||||
|
showActivityIndicator();
|
||||||
|
nativeSignup(email, username, password);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void hideKeyboard() {
|
||||||
|
View view = getActivity().getCurrentFocus();
|
||||||
|
if (view != null) {
|
||||||
|
InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||||
|
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showActivityIndicator() {
|
||||||
|
if (mDialog == null) {
|
||||||
|
mDialog = new ProgressDialog(getContext());
|
||||||
|
}
|
||||||
|
mDialog.setMessage(getString(R.string.creating_account));
|
||||||
|
mDialog.setCancelable(true);
|
||||||
|
mDialog.setOnCancelListener(dialogInterface -> {
|
||||||
|
nativeCancelSignup();
|
||||||
|
cancelActivityIndicator();
|
||||||
|
mSignupButton.setEnabled(true);
|
||||||
|
});
|
||||||
|
mDialog.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void cancelActivityIndicator() {
|
||||||
|
if (mDialog != null) {
|
||||||
|
mDialog.cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void showError(String error) {
|
||||||
|
mError.setText(error);
|
||||||
|
mError.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void hideError() {
|
||||||
|
mError.setText("");
|
||||||
|
mError.setVisibility(View.INVISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface OnSignupInteractionListener {
|
||||||
|
void onSignupCompleted();
|
||||||
|
void onLoginRequested();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handleSignupCompleted() {
|
||||||
|
getActivity().runOnUiThread(() -> {
|
||||||
|
mSignupButton.setEnabled(true);
|
||||||
|
cancelActivityIndicator();
|
||||||
|
if (mListener != null) {
|
||||||
|
mListener.onSignupCompleted();
|
||||||
|
}
|
||||||
|
mError.setText("handleSignupCompleted");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handleSignupFailed(String error) {
|
||||||
|
getActivity().runOnUiThread(() -> {
|
||||||
|
mSignupButton.setEnabled(true);
|
||||||
|
cancelActivityIndicator();
|
||||||
|
mError.setText(error);
|
||||||
|
mError.setVisibility(View.VISIBLE);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -120,6 +120,20 @@
|
||||||
app:layout_constraintRight_toLeftOf="@id/loginButton"
|
app:layout_constraintRight_toLeftOf="@id/loginButton"
|
||||||
android:textColor="@color/colorButton1"/>
|
android:textColor="@color/colorButton1"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/signup"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:fontFamily="@font/raleway_semibold"
|
||||||
|
android:textSize="14dp"
|
||||||
|
android:text="@string/signup"
|
||||||
|
android:textStyle="italic"
|
||||||
|
android:paddingRight="10dp"
|
||||||
|
android:layout_marginTop="20dp"
|
||||||
|
app:layout_constraintLeft_toLeftOf="@id/passwordLayout"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/forgotPassword"
|
||||||
|
app:layout_constraintRight_toLeftOf="@id/loginButton"
|
||||||
|
android:textColor="@color/colorButton1"/>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
146
android/app/src/main/res/layout/fragment_signup.xml
Normal file
146
android/app/src/main/res/layout/fragment_signup.xml
Normal file
|
@ -0,0 +1,146 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@color/backgroundLight">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/header"
|
||||||
|
android:layout_width="@dimen/header_hifi_width"
|
||||||
|
android:layout_height="@dimen/header_hifi_height"
|
||||||
|
android:layout_marginTop="@dimen/header_hifi_margin_top"
|
||||||
|
android:contentDescription="HighFidelity"
|
||||||
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:srcCompat="@drawable/hifi_header" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/error"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="16dp"
|
||||||
|
android:fontFamily="@font/raleway"
|
||||||
|
android:textColor="@color/colorLoginError"
|
||||||
|
android:textSize="12sp"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/email"
|
||||||
|
app:layout_constraintLeft_toLeftOf="@id/email"
|
||||||
|
app:layout_constraintRight_toRightOf="@id/email"
|
||||||
|
android:visibility="invisible"/>
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/email"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="35dp"
|
||||||
|
android:layout_marginLeft="46dp"
|
||||||
|
android:layout_marginRight="46dp"
|
||||||
|
android:background="@drawable/rounded_edit"
|
||||||
|
android:padding="7dp"
|
||||||
|
android:paddingRight="12dp"
|
||||||
|
android:paddingTop="14dp"
|
||||||
|
android:ems="10"
|
||||||
|
android:fontFamily="@font/raleway"
|
||||||
|
android:textSize="17sp"
|
||||||
|
android:inputType="textEmailAddress"
|
||||||
|
android:textStyle="italic"
|
||||||
|
android:textColor="@color/editTextColor"
|
||||||
|
android:textColorHint="@color/editTextColor"
|
||||||
|
android:gravity="left|center_vertical"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/header"
|
||||||
|
android:layout_marginTop="70dp"
|
||||||
|
android:hint="@string/email" />
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/username"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="35dp"
|
||||||
|
android:layout_marginLeft="46dp"
|
||||||
|
android:layout_marginRight="46dp"
|
||||||
|
android:background="@drawable/rounded_edit"
|
||||||
|
android:padding="7dp"
|
||||||
|
android:paddingRight="12dp"
|
||||||
|
android:paddingTop="14dp"
|
||||||
|
android:ems="10"
|
||||||
|
android:fontFamily="@font/raleway"
|
||||||
|
android:textSize="17sp"
|
||||||
|
android:inputType="text"
|
||||||
|
android:textStyle="italic"
|
||||||
|
android:textColor="@color/editTextColor"
|
||||||
|
android:textColorHint="@color/editTextColor"
|
||||||
|
android:gravity="left|center_vertical"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/email"
|
||||||
|
android:layout_marginTop="13dp"
|
||||||
|
android:hint="@string/username" />
|
||||||
|
|
||||||
|
|
||||||
|
<android.support.design.widget.TextInputLayout
|
||||||
|
android:id="@+id/passwordLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="46dp"
|
||||||
|
android:layout_marginRight="46dp"
|
||||||
|
app:passwordToggleTint="@color/showPasswordColor"
|
||||||
|
app:passwordToggleEnabled="true"
|
||||||
|
app:hintAnimationEnabled="false"
|
||||||
|
app:passwordToggleDrawable="@drawable/selector_show_password"
|
||||||
|
app:hintEnabled="false"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/username"
|
||||||
|
android:layout_marginTop="13dp"
|
||||||
|
>
|
||||||
|
<android.support.design.widget.TextInputEditText
|
||||||
|
android:id="@+id/password"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="35dp"
|
||||||
|
android:background="@drawable/rounded_edit"
|
||||||
|
android:padding="7dp"
|
||||||
|
android:drawablePadding="55dp"
|
||||||
|
android:paddingTop="14dp"
|
||||||
|
android:drawableEnd="@drawable/ic_eye_noshow"
|
||||||
|
android:ems="10"
|
||||||
|
android:fontFamily="@font/raleway"
|
||||||
|
android:textSize="17sp"
|
||||||
|
android:textStyle="italic"
|
||||||
|
android:textColor="@color/editTextColor"
|
||||||
|
android:textColorHint="@color/editTextColor"
|
||||||
|
android:gravity="left|center_vertical"
|
||||||
|
android:imeOptions="actionDone"
|
||||||
|
android:hint="@string/password"
|
||||||
|
android:inputType="textPassword" />
|
||||||
|
</android.support.design.widget.TextInputLayout>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/signupButton"
|
||||||
|
android:layout_width="154dp"
|
||||||
|
android:layout_height="38dp"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:background="@drawable/rounded_button"
|
||||||
|
android:fontFamily="@font/raleway_semibold"
|
||||||
|
android:paddingBottom="0dp"
|
||||||
|
android:paddingLeft="20dp"
|
||||||
|
android:paddingRight="20dp"
|
||||||
|
android:paddingTop="0dp"
|
||||||
|
android:text="@string/signup"
|
||||||
|
android:textColor="@color/white_opaque"
|
||||||
|
android:textAllCaps="false"
|
||||||
|
android:textSize="15sp"
|
||||||
|
app:layout_constraintRight_toRightOf="@id/username"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/passwordLayout"
|
||||||
|
app:layout_goneMarginTop="4dp"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/login"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:fontFamily="@font/raleway_semibold"
|
||||||
|
android:textSize="14dp"
|
||||||
|
android:text="@string/login"
|
||||||
|
android:textStyle="italic"
|
||||||
|
android:paddingRight="10dp"
|
||||||
|
app:layout_constraintLeft_toLeftOf="@id/passwordLayout"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/signupButton"
|
||||||
|
app:layout_constraintRight_toLeftOf="@id/loginButton"
|
||||||
|
android:textColor="@color/colorButton1"/>
|
||||||
|
|
||||||
|
</android.support.constraint.ConstraintLayout>
|
|
@ -10,6 +10,8 @@
|
||||||
<string name="popular">POPULAR</string>
|
<string name="popular">POPULAR</string>
|
||||||
<string name="bookmarks">BOOKMARKS</string>
|
<string name="bookmarks">BOOKMARKS</string>
|
||||||
<string name="goto_url_hint">Type a domain url</string>
|
<string name="goto_url_hint">Type a domain url</string>
|
||||||
|
<string name="email">Email</string>
|
||||||
|
<string name="username">Username</string>
|
||||||
<string name="username_or_email">Username or email</string>
|
<string name="username_or_email">Username or email</string>
|
||||||
<string name="password">Password</string>
|
<string name="password">Password</string>
|
||||||
<string name="login">Login</string>
|
<string name="login">Login</string>
|
||||||
|
@ -23,10 +25,14 @@
|
||||||
<string name="privacyPolicy">Privacy Policy</string>
|
<string name="privacyPolicy">Privacy Policy</string>
|
||||||
<string name="your_last_location">Your Last Location</string>
|
<string name="your_last_location">Your Last Location</string>
|
||||||
<string name="online">Online</string>
|
<string name="online">Online</string>
|
||||||
|
<string name="signup">Sign up</string>
|
||||||
|
<string name="creating_account">Creating your High Fidelity account</string>
|
||||||
|
<string name="signup_email_username_or_password_incorrect">Email, username or password incorrect.</string>
|
||||||
|
|
||||||
<!-- tags -->
|
<!-- tags -->
|
||||||
<string name="tagFragmentHome">tagFragmentHome</string>
|
<string name="tagFragmentHome">tagFragmentHome</string>
|
||||||
<string name="tagFragmentLogin">tagFragmentLogin</string>
|
<string name="tagFragmentLogin">tagFragmentLogin</string>
|
||||||
|
<string name="tagFragmentSignup">tagFragmentSignup</string>
|
||||||
<string name="tagFragmentPolicy">tagFragmentPolicy</string>
|
<string name="tagFragmentPolicy">tagFragmentPolicy</string>
|
||||||
<string name="tagFragmentPeople">tagFragmentPeople</string>
|
<string name="tagFragmentPeople">tagFragmentPeople</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
//
|
//
|
||||||
#include "AndroidHelper.h"
|
#include "AndroidHelper.h"
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include <AccountManager.h>
|
||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
|
|
||||||
#if defined(qApp)
|
#if defined(qApp)
|
||||||
|
@ -56,3 +57,78 @@ void AndroidHelper::processURL(const QString &url) {
|
||||||
qApp->acceptURL(url);
|
qApp->acceptURL(url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AndroidHelper::signup(QString email, QString username, QString password) {
|
||||||
|
JSONCallbackParameters callbackParams;
|
||||||
|
callbackParams.callbackReceiver = this;
|
||||||
|
callbackParams.jsonCallbackMethod = "signupCompleted";
|
||||||
|
callbackParams.errorCallbackMethod = "signupFailed";
|
||||||
|
|
||||||
|
QJsonObject payload;
|
||||||
|
|
||||||
|
QJsonObject userObject;
|
||||||
|
userObject.insert("email", email);
|
||||||
|
userObject.insert("username", username);
|
||||||
|
userObject.insert("password", password);
|
||||||
|
|
||||||
|
payload.insert("user", userObject);
|
||||||
|
|
||||||
|
static const QString API_SIGNUP_PATH = "api/v1/users";
|
||||||
|
|
||||||
|
auto accountManager = DependencyManager::get<AccountManager>();
|
||||||
|
|
||||||
|
accountManager->sendRequest(API_SIGNUP_PATH, AccountManagerAuth::None,
|
||||||
|
QNetworkAccessManager::PostOperation, callbackParams,
|
||||||
|
QJsonDocument(payload).toJson());
|
||||||
|
}
|
||||||
|
|
||||||
|
void AndroidHelper::signupCompleted(QNetworkReply* reply) {
|
||||||
|
emit handleSignupCompleted();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString AndroidHelper::errorStringFromAPIObject(const QJsonValue& apiObject) {
|
||||||
|
if (apiObject.isArray()) {
|
||||||
|
return apiObject.toArray()[0].toString();
|
||||||
|
} else if (apiObject.isString()) {
|
||||||
|
return apiObject.toString();
|
||||||
|
} else {
|
||||||
|
return "is invalid";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AndroidHelper::signupFailed(QNetworkReply* reply) {
|
||||||
|
// parse the returned JSON to see what the problem was
|
||||||
|
auto jsonResponse = QJsonDocument::fromJson(reply->readAll());
|
||||||
|
|
||||||
|
static const QString RESPONSE_DATA_KEY = "data";
|
||||||
|
|
||||||
|
auto dataJsonValue = jsonResponse.object()[RESPONSE_DATA_KEY];
|
||||||
|
|
||||||
|
if (dataJsonValue.isObject()) {
|
||||||
|
auto dataObject = dataJsonValue.toObject();
|
||||||
|
|
||||||
|
static const QString EMAIL_DATA_KEY = "email";
|
||||||
|
static const QString USERNAME_DATA_KEY = "username";
|
||||||
|
static const QString PASSWORD_DATA_KEY = "password";
|
||||||
|
|
||||||
|
QStringList errorStringList;
|
||||||
|
|
||||||
|
if (dataObject.contains(EMAIL_DATA_KEY)) {
|
||||||
|
errorStringList.append(QString("Email %1.").arg(errorStringFromAPIObject(dataObject[EMAIL_DATA_KEY])));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dataObject.contains(USERNAME_DATA_KEY)) {
|
||||||
|
errorStringList.append(QString("Username %1.").arg(errorStringFromAPIObject(dataObject[USERNAME_DATA_KEY])));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dataObject.contains(PASSWORD_DATA_KEY)) {
|
||||||
|
errorStringList.append(QString("Password %1.").arg(errorStringFromAPIObject(dataObject[PASSWORD_DATA_KEY])));
|
||||||
|
}
|
||||||
|
|
||||||
|
emit handleSignupFailed(errorStringList.join('\n'));
|
||||||
|
} else {
|
||||||
|
static const QString DEFAULT_SIGN_UP_FAILURE_MESSAGE = "There was an unknown error while creating your account. Please try again later.";
|
||||||
|
emit handleSignupFailed(DEFAULT_SIGN_UP_FAILURE_MESSAGE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
#define hifi_Android_Helper_h
|
#define hifi_Android_Helper_h
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
#include <QNetworkReply>
|
||||||
|
#include <QtCore/QEventLoop>
|
||||||
|
|
||||||
class AndroidHelper : public QObject {
|
class AndroidHelper : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -33,8 +35,12 @@ public:
|
||||||
AndroidHelper(AndroidHelper const&) = delete;
|
AndroidHelper(AndroidHelper const&) = delete;
|
||||||
void operator=(AndroidHelper const&) = delete;
|
void operator=(AndroidHelper const&) = delete;
|
||||||
|
|
||||||
|
void signup(QString email, QString username, QString password);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void showLoginDialog();
|
void showLoginDialog();
|
||||||
|
void signupCompleted(QNetworkReply* reply);
|
||||||
|
void signupFailed(QNetworkReply* reply);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void androidActivityRequested(const QString &activityName, const bool backToScene, QList<QString> args = QList<QString>());
|
void androidActivityRequested(const QString &activityName, const bool backToScene, QList<QString> args = QList<QString>());
|
||||||
|
@ -45,9 +51,14 @@ signals:
|
||||||
|
|
||||||
void hapticFeedbackRequested(int duration);
|
void hapticFeedbackRequested(int duration);
|
||||||
|
|
||||||
|
void handleSignupCompleted();
|
||||||
|
void handleSignupFailed(QString errorString);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AndroidHelper();
|
AndroidHelper();
|
||||||
~AndroidHelper();
|
~AndroidHelper();
|
||||||
|
|
||||||
|
QString errorStringFromAPIObject(const QJsonValue& apiObject);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue