diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index b216819ed0..57e708068f 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -71,6 +71,10 @@ android:screenOrientation="portrait" android:theme="@style/Theme.AppCompat.Translucent.NoActionBar" /> + + (); @@ -269,17 +269,15 @@ Java_io_highfidelity_hifiinterface_fragment_LoginFragment_nativeCancelLogin(JNIE } JNIEXPORT void JNICALL -Java_io_highfidelity_hifiinterface_fragment_SignupFragment_nativeCancelLogin(JNIEnv *env, +Java_io_highfidelity_hifiinterface_fragment_SignupFragment_cancelLogin(JNIEnv *env, jobject instance) { - Java_io_highfidelity_hifiinterface_fragment_LoginFragment_nativeCancelLogin(env, instance); + Java_io_highfidelity_hifiinterface_fragment_LoginFragment_cancelLogin(env, instance); } - JNIEXPORT void JNICALL -Java_io_highfidelity_hifiinterface_fragment_LoginFragment_nativeLogin(JNIEnv *env, jobject instance, - jstring username_, jstring password_, - jobject usernameChangedListener) { +Java_io_highfidelity_hifiinterface_fragment_LoginFragment_login(JNIEnv *env, jobject instance, + jstring username_, jstring password_) { const char *c_username = env->GetStringUTFChars(username_, 0); const char *c_password = env->GetStringUTFChars(password_, 0); QString username = QString(c_username); @@ -290,7 +288,6 @@ Java_io_highfidelity_hifiinterface_fragment_LoginFragment_nativeLogin(JNIEnv *en auto accountManager = DependencyManager::get(); __loginCompletedListener = QAndroidJniObject(instance); - __usernameChangedListener = QAndroidJniObject(usernameChangedListener); QObject::connect(accountManager.data(), &AccountManager::loginComplete, [](const QUrl& authURL) { jboolean jSuccess = (jboolean) true; @@ -306,24 +303,16 @@ Java_io_highfidelity_hifiinterface_fragment_LoginFragment_nativeLogin(JNIEnv *en } }); - QObject::connect(accountManager.data(), &AccountManager::usernameChanged, [](const QString& username) { - QAndroidJniObject string = QAndroidJniObject::fromString(username); - if (__usernameChangedListener.isValid()) { - __usernameChangedListener.callMethod("handleUsernameChanged", "(Ljava/lang/String;)V", string.object()); - } - }); - QMetaObject::invokeMethod(accountManager.data(), "requestAccessToken", Q_ARG(const QString&, username), Q_ARG(const QString&, password)); } JNIEXPORT void JNICALL -Java_io_highfidelity_hifiinterface_fragment_SignupFragment_nativeLogin(JNIEnv *env, +Java_io_highfidelity_hifiinterface_fragment_SignupFragment_login(JNIEnv *env, jobject instance, jstring username_, - jstring password_, - jobject usernameChangedListener) { - Java_io_highfidelity_hifiinterface_fragment_LoginFragment_nativeLogin(env, instance, username_, password_, usernameChangedListener); + jstring password_) { + Java_io_highfidelity_hifiinterface_fragment_LoginFragment_login(env, instance, username_, password_); } JNIEXPORT void Java_io_highfidelity_hifiinterface_InterfaceActivity_nativeInitAfterAppLoaded(JNIEnv* env, jobject obj) { @@ -331,7 +320,7 @@ JNIEXPORT void Java_io_highfidelity_hifiinterface_InterfaceActivity_nativeInitAf } JNIEXPORT void JNICALL -Java_io_highfidelity_hifiinterface_fragment_SignupFragment_nativeSignup(JNIEnv *env, jobject instance, +Java_io_highfidelity_hifiinterface_fragment_SignupFragment_signup(JNIEnv *env, jobject instance, jstring email_, jstring username_, jstring password_) { @@ -359,8 +348,6 @@ Java_io_highfidelity_hifiinterface_fragment_SignupFragment_nativeSignup(JNIEnv * }); QObject::connect(&AndroidHelper::instance(), &AndroidHelper::handleSignupFailed, [](QString errorString) { - jboolean jSuccess = (jboolean) false; - jstring jError = QAndroidJniObject::fromString(errorString).object(); if (__signupCompletedListener.isValid()) { QAndroidJniObject string = QAndroidJniObject::fromString(errorString); __signupCompletedListener.callMethod("handleSignupFailed", "(Ljava/lang/String;)V", string.object()); @@ -371,19 +358,13 @@ Java_io_highfidelity_hifiinterface_fragment_SignupFragment_nativeSignup(JNIEnv * } JNIEXPORT void JNICALL -Java_io_highfidelity_hifiinterface_fragment_SignupFragment_nativeCancelSignup(JNIEnv *env, jobject instance) { +Java_io_highfidelity_hifiinterface_fragment_SignupFragment_cancelSignup(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 -Java_io_highfidelity_hifiinterface_fragment_FriendsFragment_nativeIsLoggedIn(JNIEnv *env, jobject instance) { - auto accountManager = DependencyManager::get(); - return accountManager->isLoggedIn(); -} - JNIEXPORT jstring JNICALL Java_io_highfidelity_hifiinterface_fragment_FriendsFragment_nativeGetAccessToken(JNIEnv *env, jobject instance) { auto accountManager = DependencyManager::get(); @@ -407,22 +388,43 @@ Java_io_highfidelity_hifiinterface_SplashActivity_registerLoadCompleteListener(J } JNIEXPORT jboolean JNICALL -Java_io_highfidelity_hifiinterface_MainActivity_nativeIsLoggedIn(JNIEnv *env, jobject instance) { +Java_io_highfidelity_hifiinterface_HifiUtils_isUserLoggedIn(JNIEnv *env, jobject instance) { return DependencyManager::get()->isLoggedIn(); } JNIEXPORT void JNICALL -Java_io_highfidelity_hifiinterface_MainActivity_nativeLogout(JNIEnv *env, jobject instance) { +Java_io_highfidelity_hifiinterface_MainActivity_logout(JNIEnv *env, jobject instance) { DependencyManager::get()->logout(); } JNIEXPORT jstring JNICALL -Java_io_highfidelity_hifiinterface_MainActivity_nativeGetDisplayName(JNIEnv *env, +Java_io_highfidelity_hifiinterface_MainActivity_getUsername(JNIEnv *env, jobject instance) { QString username = DependencyManager::get()->getAccountInfo().getUsername(); return env->NewStringUTF(username.toLatin1().data()); } +JNIEXPORT void JNICALL +Java_io_highfidelity_hifiinterface_MainActivity_setUsernameChangedListener(JNIEnv *env, + jobject instance, + jobject usernameChangedListener) { + __usernameChangedListener = QAndroidJniObject(usernameChangedListener); + + if (!__usernameChangedListener.isValid()) { + return; + } + + auto accountManager = DependencyManager::get(); + + QObject::connect(accountManager.data(), &AccountManager::usernameChanged, [](const QString& username) { + QAndroidJniObject string = QAndroidJniObject::fromString(username); + if (__usernameChangedListener.isValid()) { + __usernameChangedListener.callMethod("handleUsernameChanged", "(Ljava/lang/String;)V", string.object()); + } + }); + +} + JNIEXPORT void JNICALL Java_io_highfidelity_hifiinterface_InterfaceActivity_nativeBeforeEnterBackground(JNIEnv *env, jobject obj) { AndroidHelper::instance().notifyBeforeEnterBackground(); diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/HifiUtils.java b/android/app/src/main/java/io/highfidelity/hifiinterface/HifiUtils.java index f92cd0a385..a35734b9d7 100644 --- a/android/app/src/main/java/io/highfidelity/hifiinterface/HifiUtils.java +++ b/android/app/src/main/java/io/highfidelity/hifiinterface/HifiUtils.java @@ -64,4 +64,7 @@ public class HifiUtils { public native String protocolVersionSignature(); + public native boolean isUserLoggedIn(); + + } diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/InterfaceActivity.java b/android/app/src/main/java/io/highfidelity/hifiinterface/InterfaceActivity.java index 90e411173b..5250d2582b 100644 --- a/android/app/src/main/java/io/highfidelity/hifiinterface/InterfaceActivity.java +++ b/android/app/src/main/java/io/highfidelity/hifiinterface/InterfaceActivity.java @@ -313,11 +313,10 @@ public class InterfaceActivity extends QtActivity implements WebViewFragment.OnW break; case "Login": nativeBeforeEnterBackground(); - Intent loginIntent = new Intent(this, MainActivity.class); - loginIntent.putExtra(MainActivity.EXTRA_FRAGMENT, activityName); - loginIntent.putExtra(MainActivity.EXTRA_BACK_TO_SCENE, backToScene); + Intent loginIntent = new Intent(this, LoginMenuActivity.class); + loginIntent.putExtra(LoginMenuActivity.EXTRA_BACK_TO_SCENE, backToScene); if (args != null && args.containsKey(DOMAIN_URL)) { - loginIntent.putExtra(DOMAIN_URL, (String) args.get(DOMAIN_URL)); + loginIntent.putExtra(LoginMenuActivity.EXTRA_DOMAIN_URL, (String) args.get(DOMAIN_URL)); } startActivity(loginIntent); break; diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/LoginMenuActivity.java b/android/app/src/main/java/io/highfidelity/hifiinterface/LoginMenuActivity.java new file mode 100644 index 0000000000..ac9fd2eed1 --- /dev/null +++ b/android/app/src/main/java/io/highfidelity/hifiinterface/LoginMenuActivity.java @@ -0,0 +1,177 @@ +package io.highfidelity.hifiinterface; + + +import android.app.Fragment; +import android.app.FragmentManager; +import android.app.FragmentTransaction; +import android.content.Intent; +import android.os.Bundle; +import android.support.v7.app.AppCompatActivity; +import android.view.View; + +import io.highfidelity.hifiinterface.fragment.LoginFragment; +import io.highfidelity.hifiinterface.fragment.SignupFragment; +import io.highfidelity.hifiinterface.fragment.StartMenuFragment; + +public class LoginMenuActivity extends AppCompatActivity + implements StartMenuFragment.StartMenuInteractionListener, + LoginFragment.OnLoginInteractionListener, + SignupFragment.OnSignupInteractionListener { + + public static final String EXTRA_FINISH_ON_BACK = "finishOnBack"; + public static final String EXTRA_BACK_TO_SCENE = "backToScene"; + public static final String EXTRA_DOMAIN_URL = "url"; + + private boolean finishOnBack; + private boolean backToScene; + private String domainUrlToBack; + + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_encourage_login); + + finishOnBack = getIntent().getBooleanExtra(EXTRA_FINISH_ON_BACK, false); + backToScene = getIntent().getBooleanExtra(EXTRA_BACK_TO_SCENE, false); + domainUrlToBack = getIntent().getStringExtra(EXTRA_DOMAIN_URL); + + if (savedInstanceState != null) { + finishOnBack = savedInstanceState.getBoolean(EXTRA_FINISH_ON_BACK, false); + backToScene = savedInstanceState.getBoolean(EXTRA_BACK_TO_SCENE, false); + domainUrlToBack = savedInstanceState.getString(EXTRA_DOMAIN_URL); + } + + loadMenuFragment(); + } + + @Override + protected void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + outState.putBoolean(EXTRA_FINISH_ON_BACK, finishOnBack); + outState.putBoolean(EXTRA_BACK_TO_SCENE, backToScene); + outState.putString(EXTRA_DOMAIN_URL, domainUrlToBack); + } + + @Override + protected void onRestoreInstanceState(Bundle savedInstanceState) { + super.onRestoreInstanceState(savedInstanceState); + finishOnBack = savedInstanceState.getBoolean(EXTRA_FINISH_ON_BACK, false); + backToScene = savedInstanceState.getBoolean(EXTRA_BACK_TO_SCENE, false); + domainUrlToBack = savedInstanceState.getString(EXTRA_DOMAIN_URL); + } + + private void loadMenuFragment() { + FragmentManager fragmentManager = getFragmentManager(); + FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); + Fragment fragment = StartMenuFragment.newInstance(); + fragmentTransaction.replace(R.id.content_frame, fragment); + fragmentTransaction.addToBackStack(fragment.toString()); + fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); + fragmentTransaction.commit(); + hideStatusBar(); + } + + @Override + protected void onResume() { + super.onResume(); + hideStatusBar(); + } + + private void hideStatusBar() { + View decorView = getWindow().getDecorView(); + // Hide the status bar. + int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; + decorView.setSystemUiVisibility(uiOptions); + } + + @Override + public void onSignupButtonClicked() { + loadSignupFragment(); + } + + @Override + public void onLoginButtonClicked() { + loadLoginFragment(); + } + + @Override + public void onSkipLoginClicked() { + loadMainActivity(); + } + + + private void loadSignupFragment() { + FragmentManager fragmentManager = getFragmentManager(); + FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); + Fragment fragment = SignupFragment.newInstance(); + fragmentTransaction.replace(R.id.content_frame, fragment); + fragmentTransaction.addToBackStack(fragment.toString()); + fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); + fragmentTransaction.commit(); + hideStatusBar(); + } + + private void loadLoginFragment() { + FragmentManager fragmentManager = getFragmentManager(); + FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); + Fragment fragment = LoginFragment.newInstance(); + fragmentTransaction.replace(R.id.content_frame, fragment); + fragmentTransaction.addToBackStack(fragment.toString()); + fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); + fragmentTransaction.commit(); + hideStatusBar(); + } + + @Override + public void onLoginCompleted() { + loadMainActivity(); + } + + @Override + public void onCancelLogin() { + getFragmentManager().popBackStack(); + } + + @Override + public void onCancelSignup() { + getFragmentManager().popBackStack(); + } + + private void loadMainActivity() { + finish(); + if (backToScene) { + backToScene = false; + goToDomain(domainUrlToBack != null? domainUrlToBack : ""); + } else { + startActivity(new Intent(this, MainActivity.class)); + } + } + + private void goToDomain(String domainUrl) { + Intent intent = new Intent(this, InterfaceActivity.class); + intent.putExtra(InterfaceActivity.DOMAIN_URL, domainUrl); + finish(); + intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); + startActivity(intent); + } + + + @Override + public void onSignupCompleted() { + loadMainActivity(); + } + + @Override + public void onBackPressed() { + FragmentManager fm = getFragmentManager(); + int index = fm.getBackStackEntryCount() - 1; + if (index > 0) { + super.onBackPressed(); + } else if (finishOnBack){ + finishAffinity(); + } else { + finish(); + } + } +} diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/MainActivity.java b/android/app/src/main/java/io/highfidelity/hifiinterface/MainActivity.java index 7df04100b0..76cda847cb 100644 --- a/android/app/src/main/java/io/highfidelity/hifiinterface/MainActivity.java +++ b/android/app/src/main/java/io/highfidelity/hifiinterface/MainActivity.java @@ -1,5 +1,6 @@ package io.highfidelity.hifiinterface; +import android.app.Activity; import android.app.Fragment; import android.app.FragmentManager; import android.app.FragmentTransaction; @@ -29,23 +30,16 @@ import android.widget.TextView; import com.squareup.picasso.Callback; import com.squareup.picasso.Picasso; -import java.util.HashMap; -import java.util.Map; - import io.highfidelity.hifiinterface.fragment.FriendsFragment; import io.highfidelity.hifiinterface.fragment.HomeFragment; -import io.highfidelity.hifiinterface.fragment.LoginFragment; import io.highfidelity.hifiinterface.fragment.PolicyFragment; import io.highfidelity.hifiinterface.fragment.SettingsFragment; -import io.highfidelity.hifiinterface.fragment.SignedInFragment; -import io.highfidelity.hifiinterface.fragment.SignupFragment;import io.highfidelity.hifiinterface.task.DownloadProfileImageTask; +import io.highfidelity.hifiinterface.fragment.SignupFragment; +import io.highfidelity.hifiinterface.task.DownloadProfileImageTask; public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener, - LoginFragment.OnLoginInteractionListener, HomeFragment.OnHomeInteractionListener, - FriendsFragment.OnHomeInteractionListener, - SignupFragment.OnSignupInteractionListener, - SignedInFragment.OnSignedInInteractionListener { + FriendsFragment.OnHomeInteractionListener { private static final int PROFILE_PICTURE_PLACEHOLDER = R.drawable.default_profile_avatar; public static final String DEFAULT_FRAGMENT = "Home"; @@ -55,9 +49,9 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On private String TAG = "HighFidelity"; - public native boolean nativeIsLoggedIn(); - public native void nativeLogout(); - public native String nativeGetDisplayName(); + public native void logout(); + public native void setUsernameChangedListener(Activity usernameChangedListener); + public native String getUsername(); private DrawerLayout mDrawerLayout; private NavigationView mNavigationView; @@ -130,9 +124,6 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On private void loadFragment(String fragment) { switch (fragment) { - case "Login": - loadLoginFragment(); - break; case "Home": loadHomeFragment(true); break; @@ -153,14 +144,8 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On loadFragment(fragment, getString(R.string.home), getString(R.string.tagFragmentHome), addToBackStack, true); } - private void loadLoginFragment() { - Fragment fragment = LoginFragment.newInstance(); - loadFragment(fragment, getString(R.string.login), getString(R.string.tagFragmentLogin), true, true); - } - - private void loadSignedInFragment() { - Fragment fragment = SignedInFragment.newInstance(); - loadFragment(fragment, getString(R.string.welcome), getString(R.string.tagFragmentSignedIn), true, true); + private void startLoginMenuActivity() { + startActivity(new Intent(this, LoginMenuActivity.class)); } private void loadSignupFragment() { @@ -223,7 +208,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On private void updateLoginMenu() { - if (nativeIsLoggedIn()) { + if (HifiUtils.getInstance().isUserLoggedIn()) { mLoginPanel.setVisibility(View.GONE); mProfilePanel.setVisibility(View.VISIBLE); mLogoutOption.setVisibility(View.VISIBLE); @@ -239,7 +224,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On } private void updateProfileHeader() { - updateProfileHeader(nativeGetDisplayName()); + updateProfileHeader(getUsername()); } private void updateProfileHeader(String username) { if (!username.isEmpty()) { @@ -289,15 +274,22 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On @Override protected void onStart() { super.onStart(); + setUsernameChangedListener(this); updateLoginMenu(); } + @Override + protected void onStop() { + super.onStop(); + setUsernameChangedListener(null); + } + public void onLoginClicked(View view) { - loadLoginFragment(); + startLoginMenuActivity(); } public void onLogoutClicked(View view) { - nativeLogout(); + logout(); updateLoginMenu(); exitLoggedInFragment(); @@ -338,42 +330,6 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On startActivity(intent); } - @Override - public void onLoginCompleted() { - loadHomeFragment(false); - updateLoginMenu(); - if (backToScene) { - backToScene = false; - goToLastLocation(); - } - } - - @Override - public void onGettingStarted() { - loadHomeFragment(false); - if (backToScene) { - backToScene = false; - goToLastLocation(); - } - } - - @Override - public void onLoginRequested() { - // go back from signup to login - onBackPressed(); - } - - @Override - public void onSignupRequested() { - loadSignupFragment(); - } - - @Override - public void onSignupCompleted() { - loadSignedInFragment(); - updateLoginMenu(); - } - public void handleUsernameChanged(String username) { runOnUiThread(() -> updateProfileHeader(username)); } @@ -418,7 +374,6 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On public void onBackPressed() { // if a fragment needs to internally manage back presses.. FragmentManager fm = getFragmentManager(); - Log.d("[BACK]", "getBackStackEntryCount " + fm.getBackStackEntryCount()); Fragment friendsFragment = fm.findFragmentByTag(getString(R.string.tagFragmentPeople)); if (friendsFragment != null && friendsFragment instanceof FriendsFragment) { if (((FriendsFragment) friendsFragment).onBackPressed()) { diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/SplashActivity.java b/android/app/src/main/java/io/highfidelity/hifiinterface/SplashActivity.java index e0aa967aaa..bb42467ace 100644 --- a/android/app/src/main/java/io/highfidelity/hifiinterface/SplashActivity.java +++ b/android/app/src/main/java/io/highfidelity/hifiinterface/SplashActivity.java @@ -3,7 +3,6 @@ package io.highfidelity.hifiinterface; import android.app.Activity; import android.content.Intent; import android.os.Bundle; -import android.os.Handler; import android.view.View; public class SplashActivity extends Activity { @@ -37,7 +36,13 @@ public class SplashActivity extends Activity { } public void onAppLoadedComplete() { - startActivity(new Intent(this, MainActivity.class)); + if (HifiUtils.getInstance().isUserLoggedIn()) { + startActivity(new Intent(this, MainActivity.class)); + } else { + Intent menuIntent = new Intent(this, LoginMenuActivity.class); + menuIntent.putExtra(LoginMenuActivity.EXTRA_FINISH_ON_BACK, true); + startActivity(menuIntent); + } SplashActivity.this.finish(); } } diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/fragment/FriendsFragment.java b/android/app/src/main/java/io/highfidelity/hifiinterface/fragment/FriendsFragment.java index 2475c4d887..e19a9c5a7a 100644 --- a/android/app/src/main/java/io/highfidelity/hifiinterface/fragment/FriendsFragment.java +++ b/android/app/src/main/java/io/highfidelity/hifiinterface/fragment/FriendsFragment.java @@ -23,8 +23,6 @@ import io.highfidelity.hifiinterface.view.UserListAdapter; public class FriendsFragment extends Fragment { - public native boolean nativeIsLoggedIn(); - public native String nativeGetAccessToken(); private RecyclerView mUsersView; diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/fragment/LoginFragment.java b/android/app/src/main/java/io/highfidelity/hifiinterface/fragment/LoginFragment.java index f22e5cd6bb..81493b1f65 100644 --- a/android/app/src/main/java/io/highfidelity/hifiinterface/fragment/LoginFragment.java +++ b/android/app/src/main/java/io/highfidelity/hifiinterface/fragment/LoginFragment.java @@ -1,13 +1,11 @@ package io.highfidelity.hifiinterface.fragment; -import android.app.Activity; import android.app.Fragment; -import android.app.ProgressDialog; import android.content.Context; -import android.content.DialogInterface; import android.content.Intent; import android.net.Uri; import android.os.Bundle; +import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -29,14 +27,13 @@ public class LoginFragment extends Fragment { private EditText mUsername; private EditText mPassword; private TextView mError; - private TextView mForgotPassword; - private TextView mSignup; private Button mLoginButton; + private ViewGroup mLoginForm; + private ViewGroup mLoggingInFrame; + private ViewGroup mLoggedInFrame; - private ProgressDialog mDialog; - - public native void nativeLogin(String username, String password, Activity usernameChangedListener); - public native void nativeCancelLogin(); + public native void login(String username, String password, Fragment usernameChangedListener); + public native void cancelLogin(); private LoginFragment.OnLoginInteractionListener mListener; @@ -58,22 +55,21 @@ public class LoginFragment extends Fragment { mPassword = rootView.findViewById(R.id.password); mError = rootView.findViewById(R.id.error); mLoginButton = rootView.findViewById(R.id.loginButton); - mForgotPassword = rootView.findViewById(R.id.forgotPassword); - mSignup = rootView.findViewById(R.id.signupButton); + mLoginForm = rootView.findViewById(R.id.loginForm); + mLoggingInFrame = rootView.findViewById(R.id.loggingInFrame); + mLoggedInFrame = rootView.findViewById(R.id.loggedInFrame); - mLoginButton.setOnClickListener(view -> login()); + rootView.findViewById(R.id.forgotPassword).setOnClickListener(view -> onForgotPasswordClicked()); - mForgotPassword.setOnClickListener(view -> forgotPassword()); - mSignup.setOnClickListener(view -> signup()); + rootView.findViewById(R.id.cancel).setOnClickListener(view -> onCancelLogin()); + + rootView.findViewById(R.id.getStarted).setOnClickListener(view -> onGetStartedClicked()); + + mLoginButton.setOnClickListener(view -> onLoginButtonClicked()); + + rootView.findViewById(R.id.takeMeInWorld).setOnClickListener(view -> skipLogin()); + mPassword.setOnEditorActionListener((textView, actionId, keyEvent) -> onPasswordEditorAction(textView, actionId, keyEvent)); - mPassword.setOnEditorActionListener( - (textView, actionId, keyEvent) -> { - if (actionId == EditorInfo.IME_ACTION_DONE) { - mLoginButton.performClick(); - return true; - } - return false; - }); return rootView; } @@ -104,13 +100,39 @@ public class LoginFragment extends Fragment { @Override public void onStop() { super.onStop(); - cancelActivityIndicator(); + showLoginForm(); // Leave the Qt app paused QtNative.setApplicationState(ApplicationInactive); hideKeyboard(); } - public void login() { + private void onCancelLogin() { + if (mListener != null) { + mListener.onCancelLogin(); + } + } + + private boolean onPasswordEditorAction(TextView textView, int actionId, KeyEvent keyEvent) { + if (actionId == EditorInfo.IME_ACTION_DONE) { + mLoginButton.performClick(); + return true; + } + return false; + } + + private void skipLogin() { + if (mListener != null) { + mListener.onSkipLoginClicked(); + } + } + + private void onGetStartedClicked() { + if (mListener != null) { + mListener.onLoginCompleted(); + } + } + + public void onLoginButtonClicked() { String username = mUsername.getText().toString().trim(); String password = mPassword.getText().toString(); hideKeyboard(); @@ -120,13 +142,7 @@ public class LoginFragment extends Fragment { mLoginButton.setEnabled(false); hideError(); showActivityIndicator(); - nativeLogin(username, password, getActivity()); - } - } - - public void signup() { - if (mListener != null) { - mListener.onSignupRequested(); + login(username, password, this); } } @@ -138,33 +154,29 @@ public class LoginFragment extends Fragment { } } - private void forgotPassword() { + private void onForgotPasswordClicked() { Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://highfidelity.com/users/password/new")); startActivity(intent); } private void showActivityIndicator() { - if (mDialog == null) { - mDialog = new ProgressDialog(getContext()); - } - mDialog.setMessage(getString(R.string.logging_in)); - mDialog.setCancelable(true); - mDialog.setOnCancelListener(new DialogInterface.OnCancelListener() { - @Override - public void onCancel(DialogInterface dialogInterface) { - nativeCancelLogin(); - cancelActivityIndicator(); - mLoginButton.setEnabled(true); - } - }); - mDialog.show(); + mLoginForm.setVisibility(View.GONE); + mLoggedInFrame.setVisibility(View.GONE); + mLoggingInFrame.setVisibility(View.VISIBLE); } - private void cancelActivityIndicator() { - if (mDialog != null) { - mDialog.cancel(); - } + private void showLoginForm() { + mLoggingInFrame.setVisibility(View.GONE); + mLoggedInFrame.setVisibility(View.GONE); + mLoginForm.setVisibility(View.VISIBLE); } + + private void showLoggedInMessage() { + mLoginForm.setVisibility(View.GONE); + mLoggingInFrame.setVisibility(View.GONE); + mLoggedInFrame.setVisibility(View.VISIBLE); + } + private void showError(String error) { mError.setText(error); mError.setVisibility(View.VISIBLE); @@ -178,12 +190,10 @@ public class LoginFragment extends Fragment { public void handleLoginCompleted(boolean success) { getActivity().runOnUiThread(() -> { mLoginButton.setEnabled(true); - cancelActivityIndicator(); if (success) { - if (mListener != null) { - mListener.onLoginCompleted(); - } + showLoggedInMessage(); } else { + showLoginForm(); showError(getString(R.string.login_username_or_password_incorrect)); } }); @@ -191,7 +201,8 @@ public class LoginFragment extends Fragment { public interface OnLoginInteractionListener { void onLoginCompleted(); - void onSignupRequested(); + void onCancelLogin(); + void onSkipLoginClicked(); } } diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/fragment/SignedInFragment.java b/android/app/src/main/java/io/highfidelity/hifiinterface/fragment/SignedInFragment.java deleted file mode 100644 index 9ed2f1c7f5..0000000000 --- a/android/app/src/main/java/io/highfidelity/hifiinterface/fragment/SignedInFragment.java +++ /dev/null @@ -1,73 +0,0 @@ -package io.highfidelity.hifiinterface.fragment; - -import android.app.Fragment; -import android.content.Context; -import android.os.Bundle; -import android.text.Html; -import android.text.Spanned; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.Button; -import android.widget.TextView; - -import java.io.IOException; -import java.io.InputStream; - -import io.highfidelity.hifiinterface.R; - -public class SignedInFragment extends Fragment { - - private Button mGetStartedButton; - private OnSignedInInteractionListener mListener; - - public SignedInFragment() { - // Required empty public constructor - } - - public static SignedInFragment newInstance() { - SignedInFragment fragment = new SignedInFragment(); - return fragment; - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - View rootView = inflater.inflate(R.layout.fragment_signedin, container, false); - mGetStartedButton = rootView.findViewById(R.id.getStarted); - - mGetStartedButton.setOnClickListener(view -> { - getStarted(); - }); - - return rootView; - } - - @Override - public void onAttach(Context context) { - super.onAttach(context); - if (context instanceof SignedInFragment.OnSignedInInteractionListener) { - mListener = (SignedInFragment.OnSignedInInteractionListener) context; - } else { - throw new RuntimeException(context.toString() - + " must implement OnSignedInInteractionListener"); - } - } - - @Override - public void onDetach() { - super.onDetach(); - mListener = null; - } - - public void getStarted() { - if (mListener != null) { - mListener.onGettingStarted(); - } - } - - public interface OnSignedInInteractionListener { - void onGettingStarted(); - } - -} diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/fragment/SignupFragment.java b/android/app/src/main/java/io/highfidelity/hifiinterface/fragment/SignupFragment.java index 33644e5bda..e0297bb9ab 100644 --- a/android/app/src/main/java/io/highfidelity/hifiinterface/fragment/SignupFragment.java +++ b/android/app/src/main/java/io/highfidelity/hifiinterface/fragment/SignupFragment.java @@ -1,10 +1,9 @@ package io.highfidelity.hifiinterface.fragment; -import android.app.Activity; import android.app.Fragment; -import android.app.ProgressDialog; import android.content.Context; import android.os.Bundle; +import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -27,16 +26,17 @@ public class SignupFragment extends Fragment { private EditText mUsername; private EditText mPassword; private TextView mError; - private TextView mCancelButton; - + private TextView mActivityText; private Button mSignupButton; - private ProgressDialog mDialog; + private ViewGroup mSignupForm; + private ViewGroup mLoggingInFrame; + private ViewGroup mLoggedInFrame; - public native void nativeSignup(String email, String username, String password); // move to SignupFragment - public native void nativeCancelSignup(); - public native void nativeLogin(String username, String password, Activity usernameChangedListener); - public native void nativeCancelLogin(); + public native void signup(String email, String username, String password); // move to SignupFragment + public native void cancelSignup(); + public native void login(String username, String password); + public native void cancelLogin(); private SignupFragment.OnSignupInteractionListener mListener; @@ -59,18 +59,20 @@ public class SignupFragment extends Fragment { mPassword = rootView.findViewById(R.id.password); mError = rootView.findViewById(R.id.error); mSignupButton = rootView.findViewById(R.id.signupButton); - mCancelButton = rootView.findViewById(R.id.cancelButton); + mActivityText = rootView.findViewById(R.id.activityText); + + mSignupForm = rootView.findViewById(R.id.signupForm); + mLoggedInFrame = rootView.findViewById(R.id.loggedInFrame); + mLoggingInFrame = rootView.findViewById(R.id.loggingInFrame); + + rootView.findViewById(R.id.cancel).setOnClickListener(view -> onCancelSignup()); mSignupButton.setOnClickListener(view -> signup()); - mCancelButton.setOnClickListener(view -> login()); - mPassword.setOnEditorActionListener( - (textView, actionId, keyEvent) -> { - if (actionId == EditorInfo.IME_ACTION_DONE) { - mSignupButton.performClick(); - return true; - } - return false; - }); + + rootView.findViewById(R.id.getStarted).setOnClickListener(view -> onGetStartedPressed()); + + mPassword.setOnEditorActionListener((textView, actionId, keyEvent) -> onPasswordEditorAction(textView, actionId, keyEvent)); + return rootView; } @@ -101,15 +103,23 @@ public class SignupFragment extends Fragment { @Override public void onStop() { super.onStop(); - cancelActivityIndicator(); + showSignupForm(); // Leave the Qt app paused QtNative.setApplicationState(ApplicationInactive); hideKeyboard(); } - private void login() { + private boolean onPasswordEditorAction(TextView textView, int actionId, KeyEvent keyEvent) { + if (actionId == EditorInfo.IME_ACTION_DONE) { + mSignupButton.performClick(); + return true; + } + return false; + } + + private void onCancelSignup() { if (mListener != null) { - mListener.onLoginRequested(); + mListener.onCancelSignup(); } } @@ -123,8 +133,9 @@ public class SignupFragment extends Fragment { } else { mSignupButton.setEnabled(false); hideError(); + mActivityText.setText(R.string.creating_account); showActivityIndicator(); - nativeSignup(email, username, password); + signup(email, username, password); } } @@ -137,23 +148,21 @@ public class SignupFragment extends Fragment { } 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(); + mSignupForm.setVisibility(View.GONE); + mLoggedInFrame.setVisibility(View.GONE); + mLoggingInFrame.setVisibility(View.VISIBLE); } - private void cancelActivityIndicator() { - if (mDialog != null) { - mDialog.cancel(); - } + private void showLoggedInMessage() { + mSignupForm.setVisibility(View.GONE); + mLoggingInFrame.setVisibility(View.GONE); + mLoggedInFrame.setVisibility(View.VISIBLE); + } + + private void showSignupForm() { + mLoggingInFrame.setVisibility(View.GONE); + mLoggedInFrame.setVisibility(View.GONE); + mSignupForm.setVisibility(View.VISIBLE); } private void showError(String error) { mError.setText(error); @@ -167,29 +176,30 @@ public class SignupFragment extends Fragment { public interface OnSignupInteractionListener { void onSignupCompleted(); - void onLoginRequested(); + void onCancelSignup(); } + private void onGetStartedPressed() { + if (mListener != null) { + mListener.onSignupCompleted(); + } + } + + public void handleSignupCompleted() { String username = mUsername.getText().toString().trim(); String password = mPassword.getText().toString(); - mDialog.setMessage(getString(R.string.logging_in)); - mDialog.setCancelable(true); - mDialog.setOnCancelListener(dialogInterface -> { - nativeCancelLogin(); - cancelActivityIndicator(); - if (mListener != null) { - mListener.onLoginRequested(); - } + getActivity().runOnUiThread(() -> { + mActivityText.setText(R.string.logging_in); }); - mDialog.show(); - nativeLogin(username, password, getActivity()); + + login(username, password); } public void handleSignupFailed(String error) { getActivity().runOnUiThread(() -> { mSignupButton.setEnabled(true); - cancelActivityIndicator(); + showSignupForm(); mError.setText(error); mError.setVisibility(View.VISIBLE); }); @@ -198,20 +208,15 @@ public class SignupFragment extends Fragment { public void handleLoginCompleted(boolean success) { getActivity().runOnUiThread(() -> { mSignupButton.setEnabled(true); - cancelActivityIndicator(); - if (success) { - if (mListener != null) { - mListener.onSignupCompleted(); - } + showLoggedInMessage(); } else { // Registration was successful but login failed. // Let the user to login manually - mListener.onLoginRequested(); + mListener.onCancelSignup(); + showSignupForm(); } }); } - - } diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/fragment/StartMenuFragment.java b/android/app/src/main/java/io/highfidelity/hifiinterface/fragment/StartMenuFragment.java new file mode 100644 index 0000000000..22614fa300 --- /dev/null +++ b/android/app/src/main/java/io/highfidelity/hifiinterface/fragment/StartMenuFragment.java @@ -0,0 +1,85 @@ +package io.highfidelity.hifiinterface.fragment; + +import android.content.Context; +import android.os.Bundle; +import android.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import io.highfidelity.hifiinterface.R; + +public class StartMenuFragment extends Fragment { + + private StartMenuInteractionListener mListener; + + public StartMenuFragment() { + // Required empty public constructor + } + + public static StartMenuFragment newInstance() { + StartMenuFragment fragment = new StartMenuFragment(); + return fragment; + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + View rootView = inflater.inflate(R.layout.fragment_login_menu, container, false); + rootView.findViewById(R.id.signupButton).setOnClickListener(view -> { + if (mListener != null) { + mListener.onSignupButtonClicked(); + } + }); + + rootView.findViewById(R.id.loginButton).setOnClickListener(view -> { + if (mListener != null) { + mListener.onLoginButtonClicked(); + } + }); + + rootView.findViewById(R.id.takeMeInWorld).setOnClickListener(view -> { + if (mListener != null) { + mListener.onSkipLoginClicked(); + } + }); + + + + return rootView; + } + + @Override + public void onAttach(Context context) { + super.onAttach(context); + if (context instanceof StartMenuInteractionListener) { + mListener = (StartMenuInteractionListener) context; + } else { + throw new RuntimeException(context.toString() + + " must implement StartMenuInteractionListener"); + } + } + + @Override + public void onDetach() { + super.onDetach(); + mListener = null; + } + + /** + * This interface must be implemented by activities that contain this + * fragment to allow an interaction in this fragment to be communicated + * to the activity and potentially other fragments contained in that + * activity. + *

+ * See the Android Training lesson Communicating with Other Fragments for more information. + */ + public interface StartMenuInteractionListener { + void onSignupButtonClicked(); + void onLoginButtonClicked(); + void onSkipLoginClicked(); + } +} diff --git a/android/app/src/main/res/drawable/encourage_login_background.jpg b/android/app/src/main/res/drawable/encourage_login_background.jpg new file mode 100644 index 0000000000..5382880c3e Binary files /dev/null and b/android/app/src/main/res/drawable/encourage_login_background.jpg differ diff --git a/android/app/src/main/res/drawable/hifi_header.xml b/android/app/src/main/res/drawable/hifi_header.xml index 9f7c85297a..7762fea81e 100644 --- a/android/app/src/main/res/drawable/hifi_header.xml +++ b/android/app/src/main/res/drawable/hifi_header.xml @@ -1,6 +1,6 @@ diff --git a/android/app/src/main/res/drawable/ic_right_arrow.xml b/android/app/src/main/res/drawable/ic_right_arrow.xml new file mode 100644 index 0000000000..e35d1a2733 --- /dev/null +++ b/android/app/src/main/res/drawable/ic_right_arrow.xml @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/android/app/src/main/res/drawable/rounded_button.xml b/android/app/src/main/res/drawable/rounded_button_color1.xml similarity index 100% rename from android/app/src/main/res/drawable/rounded_button.xml rename to android/app/src/main/res/drawable/rounded_button_color1.xml diff --git a/android/app/src/main/res/drawable/rounded_button_color3.xml b/android/app/src/main/res/drawable/rounded_button_color3.xml new file mode 100644 index 0000000000..6230885b30 --- /dev/null +++ b/android/app/src/main/res/drawable/rounded_button_color3.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/android/app/src/main/res/drawable/rounded_edit.xml b/android/app/src/main/res/drawable/rounded_edit.xml deleted file mode 100644 index 3c1cac4d1d..0000000000 --- a/android/app/src/main/res/drawable/rounded_edit.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/android/app/src/main/res/layout/activity_encourage_login.xml b/android/app/src/main/res/layout/activity_encourage_login.xml new file mode 100644 index 0000000000..d7c9ff6b4d --- /dev/null +++ b/android/app/src/main/res/layout/activity_encourage_login.xml @@ -0,0 +1,14 @@ + + + + + + \ No newline at end of file diff --git a/android/app/src/main/res/layout/fragment_login.xml b/android/app/src/main/res/layout/fragment_login.xml index 6933ad1eb5..2f48424ae8 100644 --- a/android/app/src/main/res/layout/fragment_login.xml +++ b/android/app/src/main/res/layout/fragment_login.xml @@ -6,6 +6,17 @@ android:layout_height="match_parent" android:background="@color/backgroundLight"> + + + + - - - - - - - - - -