Merge branch 'master' of https://github.com/highfidelity/hifi into loginInitiative2

This commit is contained in:
Wayne Chen 2018-11-14 14:47:56 -08:00
commit c85b840db0
360 changed files with 6543 additions and 3927 deletions

View file

@ -1,6 +1,6 @@
set(TARGET_NAME native-lib)
setup_hifi_library()
link_hifi_libraries(shared task networking gl gpu qml image fbx render-utils physics entities octree ${PLATFORM_GL_BACKEND})
link_hifi_libraries(shared task networking gl gpu qml image fbx hfm render-utils physics entities octree ${PLATFORM_GL_BACKEND})
target_opengl()
target_bullet()

View file

@ -51,6 +51,9 @@ android {
debug {
buildConfigField "String", "BACKTRACE_URL", "\"" + (System.getenv("CMAKE_BACKTRACE_URL") ? System.getenv("CMAKE_BACKTRACE_URL") : '') + "\""
buildConfigField "String", "BACKTRACE_TOKEN", "\"" + (System.getenv("CMAKE_BACKTRACE_TOKEN") ? System.getenv("CMAKE_BACKTRACE_TOKEN") : '') + "\""
buildConfigField "String", "OAUTH_CLIENT_ID", "\"" + (System.getenv("OAUTH_CLIENT_ID") ? System.getenv("OAUTH_CLIENT_ID") : '') + "\""
buildConfigField "String", "OAUTH_CLIENT_SECRET", "\"" + (System.getenv("OAUTH_CLIENT_SECRET") ? System.getenv("OAUTH_CLIENT_SECRET") : '') + "\""
buildConfigField "String", "OAUTH_REDIRECT_URI", "\"" + (System.getenv("OAUTH_REDIRECT_URI") ? System.getenv("OAUTH_REDIRECT_URI") : '') + "\""
}
release {
minifyEnabled false
@ -61,6 +64,9 @@ android {
project.hasProperty("HIFI_ANDROID_KEY_PASSWORD")? signingConfigs.release : null
buildConfigField "String", "BACKTRACE_URL", "\"" + (System.getenv("CMAKE_BACKTRACE_URL") ? System.getenv("CMAKE_BACKTRACE_URL") : '') + "\""
buildConfigField "String", "BACKTRACE_TOKEN", "\"" + (System.getenv("CMAKE_BACKTRACE_TOKEN") ? System.getenv("CMAKE_BACKTRACE_TOKEN") : '') + "\""
buildConfigField "String", "OAUTH_CLIENT_ID", "\"" + (System.getenv("OAUTH_CLIENT_ID") ? System.getenv("OAUTH_CLIENT_ID") : '') + "\""
buildConfigField "String", "OAUTH_CLIENT_SECRET", "\"" + (System.getenv("OAUTH_CLIENT_SECRET") ? System.getenv("OAUTH_CLIENT_SECRET") : '') + "\""
buildConfigField "String", "OAUTH_REDIRECT_URI", "\"" + (System.getenv("OAUTH_REDIRECT_URI") ? System.getenv("OAUTH_REDIRECT_URI") : '') + "\""
}
}

View file

@ -71,6 +71,10 @@
android:screenOrientation="portrait"
android:theme="@style/Theme.AppCompat.Translucent.NoActionBar" />
<activity android:name=".LoginMenuActivity"
android:screenOrientation="portrait"
android:theme="@style/Theme.AppCompat.Translucent.NoActionBar" />
<service
android:name=".BreakpadUploaderService"
android:enabled="true"

View file

@ -24,6 +24,9 @@
#include <udt/PacketHeaders.h>
#include <SettingHandle.h>
#define AUTO_LOGOUT_SETTING_NAME "wallet/autoLogout"
#define WALLET_USERNAME_SETTING_NAME "wallet/savedUsername"
QAndroidJniObject __interfaceActivity;
QAndroidJniObject __loginCompletedListener;
QAndroidJniObject __signupCompletedListener;
@ -210,11 +213,13 @@ JNIEXPORT void Java_io_highfidelity_hifiinterface_InterfaceActivity_nativeOnDest
JNIEXPORT void Java_io_highfidelity_hifiinterface_InterfaceActivity_nativeGotoUrl(JNIEnv* env, jobject obj, jstring url) {
QAndroidJniObject jniUrl("java/lang/String", "(Ljava/lang/String;)V", url);
DependencyManager::get<AddressManager>()->loadSettings(jniUrl.toString());
AndroidHelper::instance().muteMic();
}
JNIEXPORT void Java_io_highfidelity_hifiinterface_InterfaceActivity_nativeGoToUser(JNIEnv* env, jobject obj, jstring username) {
QAndroidJniObject jniUsername("java/lang/String", "(Ljava/lang/String;)V", username);
DependencyManager::get<AddressManager>()->goToUser(jniUsername.toString(), false);
AndroidHelper::instance().muteMic();
}
JNIEXPORT void Java_io_highfidelity_hifiinterface_InterfaceActivity_nativeOnPause(JNIEnv* env, jobject obj) {
@ -259,7 +264,56 @@ JNIEXPORT jstring JNICALL Java_io_highfidelity_hifiinterface_fragment_HomeFragme
}
JNIEXPORT void JNICALL
Java_io_highfidelity_hifiinterface_fragment_LoginFragment_nativeCancelLogin(JNIEnv *env, jobject instance) {
Java_io_highfidelity_hifiinterface_HifiUtils_updateHifiSetting(JNIEnv *env, jobject instance,
jstring group_, jstring key_,
jboolean value_) {
const char *c_group = env->GetStringUTFChars(group_, 0);
const char *c_key = env->GetStringUTFChars(key_, 0);
const QString group = QString::fromUtf8(c_group);
const QString key = QString::fromUtf8(c_key);
env->ReleaseStringUTFChars(group_, c_group);
env->ReleaseStringUTFChars(key_, c_key);
bool value = value_;
Setting::Handle<bool> setting { QStringList() << group << key , !value };
setting.set(value);
}
JNIEXPORT jboolean JNICALL
Java_io_highfidelity_hifiinterface_HifiUtils_getHifiSettingBoolean(JNIEnv *env,
jobject instance,
jstring group_,
jstring key_,
jboolean defaultValue) {
const char *c_group = env->GetStringUTFChars(group_, 0);
const char *c_key = env->GetStringUTFChars(key_, 0);
const QString group = QString::fromUtf8(c_group);
const QString key = QString::fromUtf8(c_key);
env->ReleaseStringUTFChars(group_, c_group);
env->ReleaseStringUTFChars(key_, c_key);
Setting::Handle<bool> setting { QStringList() << group << key , defaultValue};
return setting.get();
}
JNIEXPORT jboolean JNICALL
Java_io_highfidelity_hifiinterface_HifiUtils_isUserLoggedIn(JNIEnv *env, jobject instance) {
return DependencyManager::get<AccountManager>()->isLoggedIn();
}
JNIEXPORT jboolean JNICALL
Java_io_highfidelity_hifiinterface_HifiUtils_isKeepingLoggedIn(JNIEnv *env, jobject instance) {
Setting::Handle<bool> setting(AUTO_LOGOUT_SETTING_NAME, true);
return !setting.get();
}
JNIEXPORT void JNICALL
Java_io_highfidelity_hifiinterface_fragment_LoginFragment_cancelLogin(JNIEnv *env, jobject instance) {
auto accountManager = DependencyManager::get<AccountManager>();
@ -269,17 +323,16 @@ 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,
Java_io_highfidelity_hifiinterface_fragment_LoginFragment_login(JNIEnv *env, jobject instance,
jstring username_, jstring password_,
jobject usernameChangedListener) {
jboolean keepLoggedIn) {
const char *c_username = env->GetStringUTFChars(username_, 0);
const char *c_password = env->GetStringUTFChars(password_, 0);
QString username = QString(c_username);
@ -290,7 +343,53 @@ Java_io_highfidelity_hifiinterface_fragment_LoginFragment_nativeLogin(JNIEnv *en
auto accountManager = DependencyManager::get<AccountManager>();
__loginCompletedListener = QAndroidJniObject(instance);
__usernameChangedListener = QAndroidJniObject(usernameChangedListener);
QObject::connect(accountManager.data(), &AccountManager::loginComplete, [username, keepLoggedIn](const QUrl& authURL) {
jboolean jSuccess = (jboolean) true;
if (__loginCompletedListener.isValid()) {
__loginCompletedListener.callMethod<void>("handleLoginCompleted", "(Z)V", jSuccess);
}
Setting::Handle<QVariant>(AUTO_LOGOUT_SETTING_NAME).set(!keepLoggedIn);
QString usernameToSave = keepLoggedIn ? username : "";
Setting::Handle<QVariant>(WALLET_USERNAME_SETTING_NAME).set(usernameToSave);
});
QObject::connect(accountManager.data(), &AccountManager::loginFailed, []() {
jboolean jSuccess = (jboolean) false;
if (__loginCompletedListener.isValid()) {
__loginCompletedListener.callMethod<void>("handleLoginCompleted", "(Z)V", jSuccess);
}
});
QMetaObject::invokeMethod(accountManager.data(), "requestAccessToken",
Q_ARG(const QString&, username), Q_ARG(const QString&, password));
}
JNIEXPORT void JNICALL
Java_io_highfidelity_hifiinterface_fragment_LoginFragment_retrieveAccessToken(JNIEnv *env,
jobject instance,
jstring authCode_,
jstring clientId_,
jstring clientSecret_,
jstring redirectUri_) {
const char *c_authCode = env->GetStringUTFChars(authCode_, 0);
const char *c_clientId = env->GetStringUTFChars(clientId_, 0);
const char *c_clientSecret = env->GetStringUTFChars(clientSecret_, 0);
const char *c_redirectUri = env->GetStringUTFChars(redirectUri_, 0);
QString authCode = QString(c_authCode);
QString clientId = QString(c_clientId);
QString clientSecret = QString(c_clientSecret);
QString redirectUri = QString(c_redirectUri);
env->ReleaseStringUTFChars(authCode_, c_authCode);
env->ReleaseStringUTFChars(clientId_, c_clientId);
env->ReleaseStringUTFChars(clientSecret_, c_clientSecret);
env->ReleaseStringUTFChars(redirectUri_, c_redirectUri);
auto accountManager = DependencyManager::get<AccountManager>();
__loginCompletedListener = QAndroidJniObject(instance); // TODO: use a different listener?
QObject::connect(accountManager.data(), &AccountManager::loginComplete, [](const QUrl& authURL) {
jboolean jSuccess = (jboolean) true;
@ -306,24 +405,19 @@ 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<void>("handleUsernameChanged", "(Ljava/lang/String;)V", string.object<jstring>());
}
});
QMetaObject::invokeMethod(accountManager.data(), "requestAccessTokenWithAuthCode",
Q_ARG(const QString&, authCode), Q_ARG(const QString&, clientId),
Q_ARG(const QString&, clientSecret), Q_ARG(const QString&, redirectUri));
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);
jboolean keepLoggedIn) {
Java_io_highfidelity_hifiinterface_fragment_LoginFragment_login(env, instance, username_, password_, keepLoggedIn);
}
JNIEXPORT void Java_io_highfidelity_hifiinterface_InterfaceActivity_nativeInitAfterAppLoaded(JNIEnv* env, jobject obj) {
@ -331,7 +425,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 +453,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<jstring>();
if (__signupCompletedListener.isValid()) {
QAndroidJniObject string = QAndroidJniObject::fromString(errorString);
__signupCompletedListener.callMethod<void>("handleSignupFailed", "(Ljava/lang/String;)V", string.object<jstring>());
@ -371,19 +463,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<AccountManager>();
return accountManager->isLoggedIn();
}
JNIEXPORT jstring JNICALL
Java_io_highfidelity_hifiinterface_fragment_FriendsFragment_nativeGetAccessToken(JNIEnv *env, jobject instance) {
auto accountManager = DependencyManager::get<AccountManager>();
@ -406,23 +492,40 @@ Java_io_highfidelity_hifiinterface_SplashActivity_registerLoadCompleteListener(J
});
}
JNIEXPORT jboolean JNICALL
Java_io_highfidelity_hifiinterface_MainActivity_nativeIsLoggedIn(JNIEnv *env, jobject instance) {
return DependencyManager::get<AccountManager>()->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<AccountManager>()->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<AccountManager>()->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<AccountManager>();
QObject::connect(accountManager.data(), &AccountManager::usernameChanged, [](const QString& username) {
QAndroidJniObject string = QAndroidJniObject::fromString(username);
if (__usernameChangedListener.isValid()) {
__usernameChangedListener.callMethod<void>("handleUsernameChanged", "(Ljava/lang/String;)V", string.object<jstring>());
}
});
}
JNIEXPORT void JNICALL
Java_io_highfidelity_hifiinterface_InterfaceActivity_nativeBeforeEnterBackground(JNIEnv *env, jobject obj) {
AndroidHelper::instance().notifyBeforeEnterBackground();
@ -443,46 +546,6 @@ JNIEXPORT void Java_io_highfidelity_hifiinterface_WebViewActivity_nativeProcessU
AndroidHelper::instance().processURL(QString::fromUtf8(nativeString));
}
JNIEXPORT void JNICALL
Java_io_highfidelity_hifiinterface_fragment_SettingsFragment_updateHifiSetting(JNIEnv *env,
jobject instance,
jstring group_,
jstring key_,
jboolean value_) {
const char *c_group = env->GetStringUTFChars(group_, 0);
const char *c_key = env->GetStringUTFChars(key_, 0);
const QString group = QString::fromUtf8(c_group);
const QString key = QString::fromUtf8(c_key);
env->ReleaseStringUTFChars(group_, c_group);
env->ReleaseStringUTFChars(key_, c_key);
bool value = value_;
Setting::Handle<bool> setting { QStringList() << group << key , !value };
setting.set(value);
}
JNIEXPORT jboolean JNICALL
Java_io_highfidelity_hifiinterface_fragment_SettingsFragment_getHifiSettingBoolean(JNIEnv *env,
jobject instance,
jstring group_,
jstring key_,
jboolean defaultValue) {
const char *c_group = env->GetStringUTFChars(group_, 0);
const char *c_key = env->GetStringUTFChars(key_, 0);
const QString group = QString::fromUtf8(c_group);
const QString key = QString::fromUtf8(c_key);
env->ReleaseStringUTFChars(group_, c_group);
env->ReleaseStringUTFChars(key_, c_key);
Setting::Handle<bool> setting { QStringList() << group << key , defaultValue};
return setting.get();
}
JNIEXPORT void JNICALL
Java_io_highfidelity_hifiinterface_receiver_HeadsetStateReceiver_notifyHeadsetOn(JNIEnv *env,
jobject instance,

View file

@ -64,4 +64,10 @@ public class HifiUtils {
public native String protocolVersionSignature();
public native boolean isUserLoggedIn();
public native void updateHifiSetting(String group, String key, boolean value);
public native boolean getHifiSettingBoolean(String group, String key, boolean defaultValue);
public native boolean isKeepingLoggedIn();
}

View file

@ -76,7 +76,7 @@ public class InterfaceActivity extends QtActivity implements WebViewFragment.OnW
private static boolean inVrMode;
private boolean nativeEnterBackgroundCallEnqueued = false;
private SlidingDrawer webSlidingDrawer;
private SlidingDrawer mWebSlidingDrawer;
// private GvrApi gvrApi;
// Opaque native pointer to the Application C++ object.
// This object is owned by the InterfaceActivity instance and passed to the native methods.
@ -116,17 +116,6 @@ public class InterfaceActivity extends QtActivity implements WebViewFragment.OnW
//nativeGvrApi =
nativeOnCreate(this, assetManager /*, gvrApi.getNativeGvrContext()*/);
Point size = new Point();
getWindowManager().getDefaultDisplay().getRealSize(size);
try {
PackageInfo pInfo = this.getPackageManager().getPackageInfo(getPackageName(), 0);
String version = pInfo.versionName;
// setAppVersion(version);
} catch (PackageManager.NameNotFoundException e) {
Log.e("GVR", "Error getting application version", e);
}
final View rootView = getWindow().getDecorView().findViewById(android.R.id.content);
// This is a workaround to hide the menu bar when the virtual keyboard is shown from Qt
@ -137,26 +126,6 @@ public class InterfaceActivity extends QtActivity implements WebViewFragment.OnW
});
startActivity(new Intent(this, SplashActivity.class));
mVibrator = (Vibrator) this.getSystemService(VIBRATOR_SERVICE);
FrameLayout mainLayout = findViewById(android.R.id.content);
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
webSlidingDrawer = (SlidingDrawer) inflater.inflate(R.layout.web_drawer, mainLayout, false);
QtLayout qtLayout = (QtLayout) mainLayout.getChildAt(0);
QtLayout.LayoutParams layoutParams = new QtLayout.LayoutParams(webSlidingDrawer.getLayoutParams());
webSlidingDrawer.setOnDrawerCloseListener(() -> {
WebViewFragment webViewFragment = (WebViewFragment) getFragmentManager().findFragmentByTag("webViewFragment");
webViewFragment.close();
});
int widthPx = Math.max(size.x, size.y);
int heightPx = Math.min(size.x, size.y);
layoutParams.x = (int) (widthPx - WEB_DRAWER_RIGHT_MARGIN * getResources().getDisplayMetrics().xdpi / NORMAL_DPI);
layoutParams.y = (int) (heightPx - WEB_DRAWER_BOTTOM_MARGIN * getResources().getDisplayMetrics().ydpi / NORMAL_DPI);
layoutParams.resolveLayoutDirection(View.LAYOUT_DIRECTION_RTL);
qtLayout.addView(webSlidingDrawer, layoutParams);
webSlidingDrawer.setVisibility(View.GONE);
headsetStateReceiver = new HeadsetStateReceiver();
}
@ -289,14 +258,47 @@ public class InterfaceActivity extends QtActivity implements WebViewFragment.OnW
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
if (intent.hasExtra(DOMAIN_URL)) {
webSlidingDrawer.setVisibility(View.GONE);
hideWebDrawer();
nativeGotoUrl(intent.getStringExtra(DOMAIN_URL));
} else if (intent.hasExtra(EXTRA_GOTO_USERNAME)) {
webSlidingDrawer.setVisibility(View.GONE);
hideWebDrawer();
nativeGoToUser(intent.getStringExtra(EXTRA_GOTO_USERNAME));
}
}
private void hideWebDrawer() {
if (mWebSlidingDrawer != null) {
mWebSlidingDrawer.setVisibility(View.GONE);
}
}
public void showWebDrawer() {
if (mWebSlidingDrawer == null) {
FrameLayout mainLayout = findViewById(android.R.id.content);
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
QtLayout qtLayout = (QtLayout) mainLayout.getChildAt(0);
mWebSlidingDrawer = (SlidingDrawer) inflater.inflate(R.layout.web_drawer, mainLayout, false);
QtLayout.LayoutParams layoutParams = new QtLayout.LayoutParams(mWebSlidingDrawer.getLayoutParams());
mWebSlidingDrawer.setOnDrawerCloseListener(() -> {
WebViewFragment webViewFragment = (WebViewFragment) getFragmentManager().findFragmentByTag("webViewFragment");
webViewFragment.close();
});
Point size = new Point();
getWindowManager().getDefaultDisplay().getRealSize(size);
int widthPx = Math.max(size.x, size.y);
int heightPx = Math.min(size.x, size.y);
layoutParams.x = (int) (widthPx - WEB_DRAWER_RIGHT_MARGIN * getResources().getDisplayMetrics().xdpi / NORMAL_DPI);
layoutParams.y = (int) (heightPx - WEB_DRAWER_BOTTOM_MARGIN * getResources().getDisplayMetrics().ydpi / NORMAL_DPI);
layoutParams.resolveLayoutDirection(View.LAYOUT_DIRECTION_RTL);
qtLayout.addView(mWebSlidingDrawer, layoutParams);
}
mWebSlidingDrawer.setVisibility(View.VISIBLE);
}
public void openAndroidActivity(String activityName, boolean backToScene) {
openAndroidActivity(activityName, backToScene, null);
}
@ -313,29 +315,29 @@ 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);
loginIntent.putExtra(LoginMenuActivity.EXTRA_BACK_ON_SKIP, true);
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;
case "WebView":
runOnUiThread(() -> {
webSlidingDrawer.setVisibility(View.VISIBLE);
if (!webSlidingDrawer.isOpened()) {
webSlidingDrawer.animateOpen();
showWebDrawer();
if (!mWebSlidingDrawer.isOpened()) {
mWebSlidingDrawer.animateOpen();
}
if (args != null && args.containsKey(WebViewActivity.WEB_VIEW_ACTIVITY_EXTRA_URL)) {
WebViewFragment webViewFragment = (WebViewFragment) getFragmentManager().findFragmentByTag("webViewFragment");
webViewFragment.loadUrl((String) args.get(WebViewActivity.WEB_VIEW_ACTIVITY_EXTRA_URL), true);
webViewFragment.setToolbarVisible(true);
webViewFragment.setCloseAction(() -> {
if (webSlidingDrawer.isOpened()) {
webSlidingDrawer.animateClose();
if (mWebSlidingDrawer.isOpened()) {
mWebSlidingDrawer.animateClose();
}
webSlidingDrawer.setVisibility(View.GONE);
hideWebDrawer();
});
}
});
@ -381,4 +383,7 @@ public class InterfaceActivity extends QtActivity implements WebViewFragment.OnW
public void onExpand() {
keepInterfaceRunning = true;
}
@Override
public void onOAuthAuthorizeCallback(Uri uri) { }
}

View file

@ -0,0 +1,210 @@
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.OnBackPressedListener;
import io.highfidelity.hifiinterface.fragment.SignupFragment;
import io.highfidelity.hifiinterface.fragment.StartMenuFragment;
public class LoginMenuActivity extends AppCompatActivity
implements StartMenuFragment.StartMenuInteractionListener,
LoginFragment.OnLoginInteractionListener,
SignupFragment.OnSignupInteractionListener {
/**
* Set EXTRA_FINISH_ON_BACK to finish the app when back button is pressed
*/
public static final String EXTRA_FINISH_ON_BACK = "finishOnBack";
/**
* Set EXTRA_BACK_TO_SCENE to back to the scene
*/
public static final String EXTRA_BACK_TO_SCENE = "backToScene";
/**
* Set EXTRA_BACK_ON_SKIP to finish this activity when skip button is pressed
*/
public static final String EXTRA_BACK_ON_SKIP = "backOnSkip";
public static final String EXTRA_DOMAIN_URL = "url";
private boolean finishOnBack;
private boolean backToScene;
private boolean backOnSkip;
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);
backOnSkip = getIntent().getBooleanExtra(EXTRA_BACK_ON_SKIP, false);
if (savedInstanceState != null) {
finishOnBack = savedInstanceState.getBoolean(EXTRA_FINISH_ON_BACK, false);
backToScene = savedInstanceState.getBoolean(EXTRA_BACK_TO_SCENE, false);
backOnSkip = savedInstanceState.getBoolean(EXTRA_BACK_ON_SKIP, 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);
backOnSkip = savedInstanceState.getBoolean(EXTRA_BACK_ON_SKIP, 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(false);
}
@Override
public void onSkipLoginClicked() {
if (backOnSkip) {
onBackPressed();
} else {
loadMainActivity();
}
}
@Override
public void onSteamLoginButtonClicked() {
loadLoginFragment(true);
}
private void loadSignupFragment() {
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
Fragment fragment = SignupFragment.newInstance();
String tag = getString(R.string.tagFragmentSignup);
fragmentTransaction.replace(R.id.content_frame, fragment, tag);
fragmentTransaction.addToBackStack(tag);
fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
fragmentTransaction.commit();
hideStatusBar();
}
private void loadLoginFragment(boolean useOauth) {
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
Fragment fragment = LoginFragment.newInstance(useOauth);
String tag = getString(R.string.tagFragmentLogin);
fragmentTransaction.replace(R.id.content_frame, fragment, tag);
fragmentTransaction.addToBackStack(tag);
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) {
FragmentManager.BackStackEntry backEntry = fm.getBackStackEntryAt(index);
String tag = backEntry.getName();
Fragment topFragment = getFragmentManager().findFragmentByTag(tag);
if (!(topFragment instanceof OnBackPressedListener) ||
!((OnBackPressedListener) topFragment).doBack()) {
super.onBackPressed();
}
} else if (finishOnBack){
finishAffinity();
} else {
finish();
}
}
}

View file

@ -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,19 +144,10 @@ 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 loadSignupFragment() {
Fragment fragment = SignupFragment.newInstance();
loadFragment(fragment, getString(R.string.signup), getString(R.string.tagFragmentSignup), true, false);
private void startLoginMenuActivity() {
Intent intent = new Intent(this, LoginMenuActivity.class);
intent.putExtra(LoginMenuActivity.EXTRA_BACK_ON_SKIP, true);
startActivity(intent);
}
private void loadPrivacyPolicyFragment() {
@ -223,7 +205,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 +221,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 +271,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 +327,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 +371,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()) {

View file

@ -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();
}
}

View file

@ -28,11 +28,18 @@ import java.net.MalformedURLException;
import java.net.URL;
import io.highfidelity.hifiinterface.fragment.WebViewFragment;
import io.highfidelity.hifiinterface.fragment.WebViewFragment.OnWebViewInteractionListener;
public class WebViewActivity extends Activity implements WebViewFragment.OnWebViewInteractionListener {
public class WebViewActivity extends Activity implements OnWebViewInteractionListener {
public static final String WEB_VIEW_ACTIVITY_EXTRA_URL = "url";
public static final String WEB_VIEW_ACTIVITY_EXTRA_CLEAR_COOKIES = "clear_cookies";
public static final String RESULT_OAUTH_CODE = "code";
public static final String RESULT_OAUTH_STATE = "state";
private static final String FRAGMENT_TAG = "WebViewActivity_WebFragment";
private static final String OAUTH_CODE = "code";
private static final String OAUTH_STATE = "state";
private native void nativeProcessURL(String url);
@ -47,14 +54,15 @@ public class WebViewActivity extends Activity implements WebViewFragment.OnWebVi
mActionBar = getActionBar();
mActionBar.setDisplayHomeAsUpEnabled(true);
loadWebViewFragment(getIntent().getStringExtra(WEB_VIEW_ACTIVITY_EXTRA_URL));
loadWebViewFragment(getIntent().getStringExtra(WEB_VIEW_ACTIVITY_EXTRA_URL), getIntent().getBooleanExtra(WEB_VIEW_ACTIVITY_EXTRA_CLEAR_COOKIES, false));
}
private void loadWebViewFragment(String url) {
private void loadWebViewFragment(String url, boolean clearCookies) {
WebViewFragment fragment = WebViewFragment.newInstance();
Bundle bundle = new Bundle();
bundle.putString(WebViewFragment.URL, url);
bundle.putBoolean(WebViewFragment.TOOLBAR_VISIBLE, false);
bundle.putBoolean(WebViewFragment.CLEAR_COOKIES, clearCookies);
fragment.setArguments(bundle);
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction ft = fragmentManager.beginTransaction();
@ -131,4 +139,13 @@ public class WebViewActivity extends Activity implements WebViewFragment.OnWebVi
@Override
public void onExpand() { }
@Override
public void onOAuthAuthorizeCallback(Uri uri) {
Intent result = new Intent();
result.putExtra(RESULT_OAUTH_CODE, uri.getQueryParameter(OAUTH_CODE));
result.putExtra(RESULT_OAUTH_STATE, uri.getQueryParameter(OAUTH_STATE));
setResult(Activity.RESULT_OK, result);
finish();
}
}

View file

@ -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;

View file

@ -2,41 +2,65 @@ 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.support.annotation.Nullable;
import android.util.Log;
import android.view.KeyEvent;
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.CheckBox;
import android.widget.EditText;
import android.widget.TextView;
import org.qtproject.qt5.android.QtNative;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Random;
import io.highfidelity.hifiinterface.BuildConfig;
import io.highfidelity.hifiinterface.HifiUtils;
import io.highfidelity.hifiinterface.R;
import io.highfidelity.hifiinterface.WebViewActivity;
import static org.qtproject.qt5.android.QtActivityDelegate.ApplicationActive;
import static org.qtproject.qt5.android.QtActivityDelegate.ApplicationInactive;
public class LoginFragment extends Fragment {
public class LoginFragment extends Fragment
implements OnBackPressedListener {
private static final String ARG_USE_OAUTH = "use_oauth";
private static final String TAG = "Interface";
private final String OAUTH_CLIENT_ID = BuildConfig.OAUTH_CLIENT_ID;
private final String OAUTH_REDIRECT_URI = BuildConfig.OAUTH_REDIRECT_URI;
private final String OAUTH_AUTHORIZE_BASE_URL = "https://highfidelity.com/oauth/authorize";
private static final int OAUTH_AUTHORIZE_REQUEST = 1;
private EditText mUsername;
private EditText mPassword;
private TextView mError;
private TextView mForgotPassword;
private TextView mSignup;
private Button mLoginButton;
private CheckBox mKeepMeLoggedInCheckbox;
private ViewGroup mLoginForm;
private ViewGroup mLoggingInFrame;
private ViewGroup mLoggedInFrame;
private boolean mLoginInProgress;
private boolean mLoginSuccess;
private boolean mUseOauth;
private String mOauthState;
private ProgressDialog mDialog;
public native void login(String username, String password, boolean keepLoggedIn);
private native void retrieveAccessToken(String authCode, String clientId, String clientSecret, String redirectUri);
public native void nativeLogin(String username, String password, Activity usernameChangedListener);
public native void nativeCancelLogin();
public native void cancelLogin();
private LoginFragment.OnLoginInteractionListener mListener;
@ -44,11 +68,22 @@ public class LoginFragment extends Fragment {
// Required empty public constructor
}
public static LoginFragment newInstance() {
public static LoginFragment newInstance(boolean useOauth) {
LoginFragment fragment = new LoginFragment();
Bundle args = new Bundle();
args.putBoolean(ARG_USE_OAUTH, useOauth);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mUseOauth = getArguments().getBoolean(ARG_USE_OAUTH, false);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
@ -58,22 +93,29 @@ 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);
mKeepMeLoggedInCheckbox = rootView.findViewById(R.id.keepMeLoggedIn);
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());
mPassword.setOnEditorActionListener(
(textView, actionId, keyEvent) -> {
if (actionId == EditorInfo.IME_ACTION_DONE) {
mLoginButton.performClick();
return true;
}
return false;
});
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));
mKeepMeLoggedInCheckbox.setChecked(HifiUtils.getInstance().isKeepingLoggedIn());
if (mUseOauth) {
openWebForAuthorization();
} else {
showLoginForm();
}
return rootView;
}
@ -104,13 +146,57 @@ public class LoginFragment extends Fragment {
@Override
public void onStop() {
super.onStop();
cancelActivityIndicator();
// Leave the Qt app paused
QtNative.setApplicationState(ApplicationInactive);
hideKeyboard();
}
public void login() {
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == OAUTH_AUTHORIZE_REQUEST) {
if (resultCode == Activity.RESULT_OK) {
String authCode = data.getStringExtra(WebViewActivity.RESULT_OAUTH_CODE);
String state = data.getStringExtra(WebViewActivity.RESULT_OAUTH_STATE);
if (state != null && state.equals(mOauthState) && mListener != null) {
mOauthState = null;
showActivityIndicator();
mLoginInProgress = true;
retrieveAccessToken(authCode, BuildConfig.OAUTH_CLIENT_ID, BuildConfig.OAUTH_CLIENT_SECRET, BuildConfig.OAUTH_REDIRECT_URI);
}
} else {
onCancelLogin();
}
}
}
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 +206,10 @@ public class LoginFragment extends Fragment {
mLoginButton.setEnabled(false);
hideError();
showActivityIndicator();
nativeLogin(username, password, getActivity());
}
}
public void signup() {
if (mListener != null) {
mListener.onSignupRequested();
mLoginInProgress = true;
mLoginSuccess = false;
boolean keepUserLoggedIn = mKeepMeLoggedInCheckbox.isChecked();
login(username, password, keepUserLoggedIn);
}
}
@ -138,33 +221,32 @@ 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);
mLoggingInFrame.bringToFront();
}
private void cancelActivityIndicator() {
if (mDialog != null) {
mDialog.cancel();
}
private void showLoginForm() {
mLoggingInFrame.setVisibility(View.GONE);
mLoggedInFrame.setVisibility(View.GONE);
mLoginForm.setVisibility(View.VISIBLE);
mLoginForm.bringToFront();
}
private void showLoggedInMessage() {
mLoginForm.setVisibility(View.GONE);
mLoggingInFrame.setVisibility(View.GONE);
mLoggedInFrame.setVisibility(View.VISIBLE);
mLoggedInFrame.bringToFront();
}
private void showError(String error) {
mError.setText(error);
mError.setVisibility(View.VISIBLE);
@ -176,22 +258,71 @@ public class LoginFragment extends Fragment {
}
public void handleLoginCompleted(boolean success) {
mLoginInProgress = false;
getActivity().runOnUiThread(() -> {
mLoginButton.setEnabled(true);
cancelActivityIndicator();
if (success) {
if (mListener != null) {
mListener.onLoginCompleted();
}
mLoginSuccess = true;
showLoggedInMessage();
} else {
showError(getString(R.string.login_username_or_password_incorrect));
if (!mUseOauth) {
showLoginForm();
showError(getString(R.string.login_username_or_password_incorrect));
} else {
openWebForAuthorization();
}
}
});
}
@Override
public boolean doBack() {
if (mLoginInProgress) {
cancelLogin();
showLoginForm();
mLoginInProgress = false;
mLoginButton.setEnabled(true);
return true;
} else if (mLoginSuccess) {
onGetStartedClicked();
return true;
} else {
return false;
}
}
private void updateOauthState() {
// as we only use oauth for steam that's ok for now
mOauthState = "steam-" + Long.toString(new Random().nextLong());
}
private String buildAuthorizeUrl() {
StringBuilder sb = new StringBuilder(OAUTH_AUTHORIZE_BASE_URL);
sb.append("?client_id=").append(OAUTH_CLIENT_ID);
try {
String redirectUri = URLEncoder.encode(OAUTH_REDIRECT_URI, "utf-8");
sb.append("&redirect_uri=").append(redirectUri);
} catch (UnsupportedEncodingException e) {
Log.e(TAG, "Cannot build oauth autorization url", e);
}
sb.append("&response_type=code&scope=owner");
sb.append("&state=").append(mOauthState);
return sb.toString();
}
private void openWebForAuthorization() {
Intent openUrlIntent = new Intent(getActivity(), WebViewActivity.class);
updateOauthState();
openUrlIntent.putExtra(WebViewActivity.WEB_VIEW_ACTIVITY_EXTRA_URL, buildAuthorizeUrl());
openUrlIntent.putExtra(WebViewActivity.WEB_VIEW_ACTIVITY_EXTRA_CLEAR_COOKIES, true);
startActivityForResult(openUrlIntent, OAUTH_AUTHORIZE_REQUEST);
}
public interface OnLoginInteractionListener {
void onLoginCompleted();
void onSignupRequested();
void onCancelLogin();
void onSkipLoginClicked();
}
}

View file

@ -0,0 +1,11 @@
package io.highfidelity.hifiinterface.fragment;
public interface OnBackPressedListener {
/**
* Processes the back pressed event and returns true if it was managed by this Fragment
* @return
*/
boolean doBack();
}

View file

@ -3,32 +3,35 @@ package io.highfidelity.hifiinterface.fragment;
import android.content.SharedPreferences;
import android.media.audiofx.AcousticEchoCanceler;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.PreferenceFragment;
import android.preference.PreferenceManager;
import android.support.annotation.Nullable;
import io.highfidelity.hifiinterface.HifiUtils;
import io.highfidelity.hifiinterface.R;
public class SettingsFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener {
public native void updateHifiSetting(String group, String key, boolean value);
public native boolean getHifiSettingBoolean(String group, String key, boolean defaultValue);
private final String HIFI_SETTINGS_ANDROID_GROUP = "Android";
private final String HIFI_SETTINGS_AEC_KEY = "aec";
private final String PREFERENCE_KEY_AEC = "aec";
private final boolean DEFAULT_AEC_ENABLED = true;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.settings);
boolean aecAvailable = AcousticEchoCanceler.isAvailable();
PreferenceManager.setDefaultValues(getContext(), R.xml.settings, false);
if (!AcousticEchoCanceler.isAvailable()) {
getPreferenceScreen().getPreferenceManager().findPreference("aec").setEnabled(false);
if (!aecAvailable) {
findPreference(PREFERENCE_KEY_AEC).setEnabled(false);
HifiUtils.getInstance().updateHifiSetting(HIFI_SETTINGS_ANDROID_GROUP, HIFI_SETTINGS_AEC_KEY, false);
}
getPreferenceScreen().getSharedPreferences().edit().putBoolean(PREFERENCE_KEY_AEC,
getHifiSettingBoolean(HIFI_SETTINGS_ANDROID_GROUP, HIFI_SETTINGS_AEC_KEY, false));
aecAvailable && HifiUtils.getInstance().getHifiSettingBoolean(HIFI_SETTINGS_ANDROID_GROUP, HIFI_SETTINGS_AEC_KEY, DEFAULT_AEC_ENABLED)).commit();
}
public static SettingsFragment newInstance() {
@ -46,15 +49,13 @@ public class SettingsFragment extends PreferenceFragment implements SharedPrefer
public void onPause() {
super.onPause();
getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
Preference pref = findPreference(key);
switch (key) {
case "aec":
updateHifiSetting(HIFI_SETTINGS_ANDROID_GROUP, HIFI_SETTINGS_AEC_KEY, sharedPreferences.getBoolean(key, false));
HifiUtils.getInstance().updateHifiSetting(HIFI_SETTINGS_ANDROID_GROUP, HIFI_SETTINGS_AEC_KEY, sharedPreferences.getBoolean(key, false));
break;
default:
break;

View file

@ -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();
}
}

View file

@ -1,42 +1,50 @@
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;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.TextView;
import org.qtproject.qt5.android.QtNative;
import io.highfidelity.hifiinterface.HifiUtils;
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 {
public class SignupFragment extends Fragment
implements OnBackPressedListener {
private EditText mEmail;
private EditText mUsername;
private EditText mPassword;
private TextView mError;
private TextView mCancelButton;
private TextView mActivityText;
private Button mSignupButton;
private CheckBox mKeepMeLoggedInCheckbox;
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();
private boolean mLoginInProgress;
private boolean mSignupInProgress;
private boolean mSignupSuccess;
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, boolean keepLoggedIn);
public native void cancelLogin();
private SignupFragment.OnSignupInteractionListener mListener;
@ -59,18 +67,23 @@ 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);
mKeepMeLoggedInCheckbox = rootView.findViewById(R.id.keepMeLoggedIn);
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 -> onGetStartedClicked());
mPassword.setOnEditorActionListener((textView, actionId, keyEvent) -> onPasswordEditorAction(textView, actionId, keyEvent));
mKeepMeLoggedInCheckbox.setChecked(HifiUtils.getInstance().isKeepingLoggedIn());
return rootView;
}
@ -101,15 +114,22 @@ public class SignupFragment extends Fragment {
@Override
public void onStop() {
super.onStop();
cancelActivityIndicator();
// 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 +143,11 @@ public class SignupFragment extends Fragment {
} else {
mSignupButton.setEnabled(false);
hideError();
mActivityText.setText(R.string.creating_account);
showActivityIndicator();
nativeSignup(email, username, password);
mSignupInProgress = true;
mSignupSuccess = false;
signup(email, username, password);
}
}
@ -137,23 +160,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,51 +188,73 @@ public class SignupFragment extends Fragment {
public interface OnSignupInteractionListener {
void onSignupCompleted();
void onLoginRequested();
void onCancelSignup();
}
private void onGetStartedClicked() {
if (mListener != null) {
mListener.onSignupCompleted();
}
}
public void handleSignupCompleted() {
mSignupInProgress = false;
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());
mLoginInProgress = true;
boolean keepUserLoggedIn = mKeepMeLoggedInCheckbox.isChecked();
login(username, password, keepUserLoggedIn);
}
public void handleSignupFailed(String error) {
mSignupInProgress = false;
getActivity().runOnUiThread(() -> {
mSignupButton.setEnabled(true);
cancelActivityIndicator();
showSignupForm();
mError.setText(error);
mError.setVisibility(View.VISIBLE);
});
}
public void handleLoginCompleted(boolean success) {
mLoginInProgress = false;
getActivity().runOnUiThread(() -> {
mSignupButton.setEnabled(true);
cancelActivityIndicator();
if (success) {
if (mListener != null) {
mListener.onSignupCompleted();
}
mSignupSuccess = true;
showLoggedInMessage();
} else {
// Registration was successful but login failed.
// Let the user to login manually
mListener.onLoginRequested();
mListener.onCancelSignup();
showSignupForm();
}
});
}
@Override
public boolean doBack() {
if (mSignupInProgress) {
cancelSignup();
} else if (mLoginInProgress) {
cancelLogin();
}
if (mSignupInProgress || mLoginInProgress) {
showSignupForm();
mLoginInProgress = false;
mSignupInProgress = false;
mSignupButton.setEnabled(true);
return true;
} else if (mSignupSuccess) {
onGetStartedClicked();
return true;
} else {
return false;
}
}
}

View file

@ -0,0 +1,93 @@
package io.highfidelity.hifiinterface.fragment;
import android.app.Fragment;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import io.highfidelity.hifiinterface.R;
public class StartMenuFragment extends Fragment {
private String TAG = "HighFidelity";
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.steamLoginButton).setOnClickListener(view -> {
if (mListener != null) {
mListener.onSteamLoginButtonClicked();
}
});
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.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface StartMenuInteractionListener {
void onSignupButtonClicked();
void onLoginButtonClicked();
void onSkipLoginClicked();
void onSteamLoginButtonClicked();
}
}

View file

@ -4,9 +4,11 @@ import android.app.Fragment;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.net.http.SslError;
import android.os.Bundle;
import android.os.Handler;
import android.text.TextUtils;
import android.view.GestureDetector;
import android.view.KeyEvent;
import android.view.LayoutInflater;
@ -14,6 +16,7 @@ import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AlphaAnimation;
import android.webkit.CookieManager;
import android.webkit.SslErrorHandler;
import android.webkit.WebChromeClient;
import android.webkit.WebResourceError;
@ -25,6 +28,7 @@ import android.webkit.WebViewClient;
import android.widget.ProgressBar;
import android.widget.Toast;
import io.highfidelity.hifiinterface.BuildConfig;
import io.highfidelity.hifiinterface.R;
import io.highfidelity.hifiinterface.WebViewActivity;
@ -32,6 +36,7 @@ public class WebViewFragment extends Fragment implements GestureDetector.OnGestu
public static final String URL = "url";
public static final String TOOLBAR_VISIBLE = "toolbar_visible";
public static final String CLEAR_COOKIES = "clear_cookies";
private static final long DELAY_HIDE_TOOLBAR_MILLIS = 3000;
private static final long FADE_OUT_DURATION = 2000;
@ -41,6 +46,7 @@ public class WebViewFragment extends Fragment implements GestureDetector.OnGestu
private ProgressBar mProgressBar;
private String mUrl;
private boolean mToolbarVisible;
private boolean mClearCookies;
private OnWebViewInteractionListener mListener;
private Runnable mCloseAction;
@ -170,6 +176,7 @@ public class WebViewFragment extends Fragment implements GestureDetector.OnGestu
if (getArguments() != null) {
mUrl = getArguments().getString(URL);
mToolbarVisible = getArguments().getBoolean(TOOLBAR_VISIBLE);
mClearCookies = getArguments().getBoolean(CLEAR_COOKIES);
}
}
@ -179,6 +186,10 @@ public class WebViewFragment extends Fragment implements GestureDetector.OnGestu
View rootView = inflater.inflate(R.layout.fragment_web_view, container, false);
mProgressBar = rootView.findViewById(R.id.toolbarProgressBar);
myWebView = rootView.findViewById(R.id.web_view);
if (mClearCookies) {
CookieManager.getInstance().removeAllCookies(null);
}
mHandler = new Handler();
gestureDetector = new GestureDetector(this);
gestureDetector.setOnDoubleTapListener(new GestureDetector.OnDoubleTapListener() {
@ -251,6 +262,7 @@ public class WebViewFragment extends Fragment implements GestureDetector.OnGestu
void onWebLoaded(String url, SafenessLevel safenessLevel);
void onTitleReceived(String title);
void onExpand();
void onOAuthAuthorizeCallback(Uri uri);
}
@ -320,6 +332,18 @@ public class WebViewFragment extends Fragment implements GestureDetector.OnGestu
super.onLoadResource(view, url);
}
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
if (!TextUtils.isEmpty(BuildConfig.OAUTH_REDIRECT_URI) &&
request.getUrl().toString().startsWith(BuildConfig.OAUTH_REDIRECT_URI)) {
if (mListener != null) {
mListener.onOAuthAuthorizeCallback(request.getUrl());
}
return true;
}
return super.shouldOverrideUrlLoading(view, request);
}
}
class HiFiWebChromeClient extends WebChromeClient {

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="350dp"
android:width="340dp"
android:height="100dp"
android:viewportWidth="350"
android:viewportHeight="100">

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="11dp"
android:height="14dp"
android:viewportWidth="11"
android:viewportHeight="14">
<path
android:fillColor="#ffffff"
android:pathData="M2.98427,0.868092 C2.35913,0.324495,1.41169,0.390596,0.868092,1.01573 C0.324495,1.64087,0.390596,2.58831,1.01573,3.13191 L2.98427,0.868092 Z M8,7.21739 L8.93497,8.39035 L10.3436,7.26752 L8.98427,6.08548 L8,7.21739 Z M1.06503,10.827 C0.417224,11.3434,0.310672,12.2872,0.82704,12.935 C1.34341,13.5828,2.28716,13.6893,2.93497,13.173 L1.06503,10.827 Z M1.01573,3.13191 L7.01573,8.3493 L8.98427,6.08548 L2.98427,0.868092 L1.01573,3.13191 Z M7.06503,6.04443 L1.06503,10.827 L2.93497,13.173 L8.93497,8.39035 L7.06503,6.04443 Z" />
</vector>

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="21dp"
android:height="21dp"
android:viewportWidth="21"
android:viewportHeight="21">
<path
android:fillColor="#ffffff"
android:pathData="M10.4866,0 C4.92045,0,0.367395,4.32104,0,9.78734 L5.45262,11.9841 C5.93184,11.651,6.51333,11.4545,7.14145,11.4545 C7.27641,11.4545,7.4083,11.4666,7.53829,11.4841 L10.1047,7.72495 C10.1083,5.56672,11.861,3.81818,14.0229,3.81818 C16.1872,3.81818,17.9416,5.57035,17.9416,7.73182 C17.9416,9.89329,16.1872,11.6455,14.0229,11.6455 C14.021,11.6455,14.0189,11.6453,14.017,11.6453 L10.0936,14.2008 C10.0986,14.2712,10.1043,14.3419,10.1043,14.4136 C10.1043,16.048,8.77791,17.3727,7.14145,17.3727 C5.69539,17.3727,4.49304,16.3376,4.2325,14.969 L0.378099,13.3841 C1.6334,17.7801,5.6822,21,10.4866,21 C16.2931,21,21,16.2991,21,10.5 C21,4.70114,16.2931,0,10.4866,0 Z M7.14145,16.0364 C6.96655,16.0364,6.79833,16.0081,6.64044,15.9569 L6.63968,15.9589 L6.59151,15.939 C6.54506,15.9224,6.49975,15.9037,6.45541,15.8831 L5.15462,15.3483 C5.50614,16.0927,6.26253,16.6091,7.14145,16.6091 C8.35546,16.6091,9.33971,15.6263,9.33971,14.4136 C9.33971,13.201,8.35546,12.2182,7.14145,12.2182 C6.87269,12.2182,6.61636,12.2688,6.37818,12.357 L7.75448,12.9114 C7.76404,12.9154,7.77359,12.9188,7.78296,12.923 L7.89001,12.9662 L7.88714,12.9732 C8.40898,13.243,8.76625,13.7861,8.76625,14.4136 C8.76625,15.3098,8.03872,16.0364,7.14145,16.0364 Z M16.7946,7.73182 C16.7946,6.20302,15.5537,4.96364,14.0229,4.96364 C12.4922,4.96364,11.2512,6.20302,11.2512,7.73182 C11.2512,9.26062,12.4922,10.5,14.0229,10.5 C15.5537,10.5,16.7946,9.26062,16.7946,7.73182 Z M12.0158,7.73182 C12.0158,6.62474,12.9144,5.72727,14.0229,5.72727 C15.1314,5.72727,16.03,6.62474,16.03,7.73182 C16.03,8.8389,15.1314,9.73636,14.0229,9.73636 C12.9144,9.73636,12.0158,8.8389,12.0158,7.73182 Z" />
</vector>

View file

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_pressed="true" >
<shape android:shape="rectangle" >
<corners android:radius="4dip" />
<stroke android:width="1dip" android:color="@color/colorButton2" />
<solid android:color="@color/colorButton2"/>
</shape>
</item>
<item android:state_focused="true">
<shape android:shape="rectangle" >
<corners android:radius="4dip" />
<stroke android:width="1dip" android:color="@color/colorButton2" />
<solid android:color="@color/colorButton2"/>
</shape>
</item>
<item>
<shape android:shape="rectangle" >
<corners android:radius="4dip" />
<stroke android:width="1dip" android:color="@color/colorButton2" />
<solid android:color="@color/colorButton2"/>
</shape>
</item>
</selector>

View file

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_pressed="true" >
<shape android:shape="rectangle" >
<corners android:radius="4dip" />
<stroke android:width="1dip" android:color="@color/colorButton4" />
<solid android:color="@color/colorButton4"/>
</shape>
</item>
<item android:state_focused="true">
<shape android:shape="rectangle" >
<corners android:radius="4dip" />
<stroke android:width="1dip" android:color="@color/colorButton4" />
<solid android:color="@color/colorButton4"/>
</shape>
</item>
<item>
<shape android:shape="rectangle" >
<corners android:radius="4dip" />
<stroke android:width="1dip" android:color="@color/colorButton4" />
<solid android:color="@color/colorButton4"/>
</shape>
</item>
</selector>

View file

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" android:padding="9dp">
<corners android:radius="4dip" />
<stroke android:width="1dip" android:color="@android:color/black" />
<solid android:color="@color/backgroundEditText"/>
</shape>

View file

@ -0,0 +1,14 @@
<?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"
tools:context=".LoginMenuActivity">
<FrameLayout
android:id="@+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.constraint.ConstraintLayout>

View file

@ -6,6 +6,17 @@
android:layout_height="match_parent"
android:background="@color/backgroundLight">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/encourage_login_background"
android:scaleType="fitXY" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#B2000000" />
<ImageView
android:id="@+id/header"
android:layout_width="@dimen/header_hifi_width"
@ -17,126 +28,246 @@
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/hifi_header" />
<TextView
android:id="@+id/error"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="25dp"
android:layout_marginLeft="9dp"
android:layout_marginRight="9dp"
android:fontFamily="@font/raleway"
android:textColor="@color/colorLoginError"
android:textSize="14sp"
app:layout_constraintBottom_toTopOf="@id/username"
app:layout_constraintLeft_toLeftOf="@id/username"
android:visibility="invisible"/>
<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="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/username_or_email" />
<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/loginButton"
android:layout_width="154dp"
android:layout_height="38dp"
android:background="@drawable/rounded_button"
android:fontFamily="@font/raleway_semibold"
android:paddingBottom="0dp"
android:paddingTop="0dp"
android:text="@string/login"
android:textColor="@color/white_opaque"
android:textAllCaps="false"
android:textSize="18sp"
app:layout_constraintRight_toRightOf="@id/username"
app:layout_constraintTop_toBottomOf="@id/forgotPassword"
app:layout_goneMarginTop="4dp"/>
<TextView
android:id="@+id/forgotPassword"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="9dp"
android:paddingBottom="16dp"
android:fontFamily="@font/raleway_semibold"
android:textSize="14dp"
android:text="@string/forgot_password"
android:textStyle="italic"
app:layout_constraintRight_toRightOf="@id/passwordLayout"
app:layout_constraintTop_toBottomOf="@id/passwordLayout"
android:textColor="@color/colorButton1"/>
<Button
android:id="@+id/signupButton"
<android.support.constraint.ConstraintLayout
android:id="@+id/loggingInFrame"
android:layout_width="0dp"
app:layout_constraintWidth_default="spread"
android:layout_height="38dp"
android:background="@drawable/rounded_secondary_button"
android:fontFamily="@font/raleway_semibold"
android:paddingBottom="0dp"
android:paddingTop="0dp"
android:layout_marginRight="15dp"
android:text="@string/signup"
android:textColor="@color/white_opaque"
android:textAllCaps="false"
android:textSize="18sp"
app:layout_constraintLeft_toLeftOf="@id/passwordLayout"
app:layout_constraintTop_toTopOf="@id/loginButton"
app:layout_constraintRight_toLeftOf="@id/loginButton"
app:layout_goneMarginTop="4dp"/>
android:layout_height="0dp"
android:layout_marginTop="@dimen/login_form_margin_top"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/header"
app:layout_constraintBottom_toBottomOf="parent"
android:visibility="gone">
<TextView
android:id="@+id/loggingInText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/logging_in"
android:fontFamily="@font/raleway_bold"
android:textSize="24sp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:layout_marginTop="83dp"
/>
<ProgressBar
android:layout_width="101dp"
android:layout_height="101dp"
android:layout_marginTop="20dp"
app:layout_constraintTop_toBottomOf="@id/loggingInText"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:indeterminateTint="#00B4EF"
/>
</android.support.constraint.ConstraintLayout>
<android.support.constraint.ConstraintLayout
android:id="@+id/loggedInFrame"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="@dimen/login_form_margin_top"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/header"
app:layout_constraintBottom_toBottomOf="parent"
android:visibility="gone">
<TextView
android:id="@+id/loggedInText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/logged_in_welcome"
android:fontFamily="@font/raleway_bold"
android:textSize="24sp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:layout_marginTop="115dp"
/>
<Button
android:id="@+id/getStarted"
android:layout_width="@dimen/button_medium_width"
android:layout_height="@dimen/button_medium_height"
android:layout_marginTop="22dp"
android:background="@drawable/rounded_button_color1"
android:fontFamily="@font/raleway_bold"
android:text="@string/get_started"
android:textColor="@color/white_opaque"
android:textAllCaps="false"
android:textSize="@dimen/button_medium_text_size"
app:layout_constraintTop_toBottomOf="@id/loggedInText"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_goneMarginTop="4dp"/>
</android.support.constraint.ConstraintLayout>
<android.support.constraint.ConstraintLayout
android:id="@+id/loginForm"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="@dimen/login_form_margin_top"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/header"
app:layout_constraintBottom_toBottomOf="parent"
android:visibility="gone">
<TextView
android:id="@+id/error"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="25dp"
android:layout_marginLeft="9dp"
android:layout_marginRight="9dp"
android:fontFamily="sans-serif"
android:textColor="@color/colorLoginError"
android:textSize="14sp"
app:layout_constraintBottom_toTopOf="@id/username"
app:layout_constraintLeft_toLeftOf="@id/username"
android:visibility="invisible"/>
<EditText
android:id="@+id/username"
android:layout_width="match_parent"
android:layout_height="27dp"
android:layout_marginLeft="@dimen/login_margin"
android:layout_marginRight="@dimen/login_margin"
android:background="@color/white_opaque"
android:paddingLeft="@dimen/edit_text_padding"
android:ems="10"
android:fontFamily="sans-serif"
android:textSize="@dimen/login_edit_text_size"
android:inputType="textEmailAddress"
android:textColor="@color/editTextColor"
android:textColorHint="@color/editTextColor"
android:gravity="left|center_vertical"
android:hint="@string/username_or_email"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="83dp"/>
<android.support.design.widget.TextInputLayout
android:id="@+id/passwordLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/login_margin"
android:layout_marginRight="@dimen/login_margin"
android:background="@color/white_opaque"
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="15dp"
>
<android.support.design.widget.TextInputEditText
android:id="@+id/password"
android:layout_width="match_parent"
android:layout_height="@dimen/login_edit_text_height"
android:background="@color/white_opaque"
android:paddingLeft="@dimen/edit_text_padding"
android:drawablePadding="45dp"
android:drawableEnd="@drawable/ic_eye_noshow"
android:ems="10"
android:fontFamily="sans-serif"
android:textSize="@dimen/login_edit_text_size"
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>
<CheckBox
android:id="@+id/keepMeLoggedIn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="13dp"
android:layout_marginRight="66dp"
app:layout_constraintTop_toBottomOf="@id/passwordLayout"
app:layout_constraintRight_toRightOf="parent"
android:padding="0dp" />
<TextView
android:id="@+id/keepMeLoggedInLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/raleway_bold"
android:textSize="12sp"
android:text="@string/keep_me_logged_in"
app:layout_constraintRight_toLeftOf="@id/keepMeLoggedIn"
app:layout_constraintTop_toTopOf="@id/keepMeLoggedIn"
app:layout_constraintBottom_toBottomOf="@id/keepMeLoggedIn"
android:textColor="@color/white_opaque"/>
<Button
android:id="@+id/loginButton"
android:layout_width="@dimen/button_medium_width"
android:layout_height="@dimen/button_medium_height"
android:background="@drawable/rounded_button_color3"
android:fontFamily="@font/raleway_bold"
android:layout_marginTop="@dimen/button_medium_margin"
android:text="@string/log_in"
android:textColor="@color/white_opaque"
android:textAllCaps="false"
android:textSize="@dimen/button_medium_text_size"
app:layout_constraintRight_toRightOf="@id/username"
app:layout_constraintTop_toBottomOf="@id/keepMeLoggedIn" />
<TextView
android:id="@+id/cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="8dp"
app:layout_constraintLeft_toLeftOf="@id/passwordLayout"
app:layout_constraintTop_toTopOf="@id/loginButton"
app:layout_constraintBottom_toBottomOf="@id/loginButton"
app:layout_constraintRight_toLeftOf="@id/loginButton"
android:textColor="@color/white_opaque"
android:fontFamily="@font/raleway_bold"
android:textSize="@dimen/button_medium_text_size"
android:text="@string/cancel_uppercase" />
<TextView
android:id="@+id/forgotPassword"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="sans-serif"
android:textSize="14sp"
android:layout_marginTop="18dp"
android:text="@string/cant_access_your_account"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/loginButton"
android:textColor="@color/colorButton1"/>
<TextView
android:id="@+id/takeMeInWorld"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/raleway_bold"
android:textSize="14sp"
android:layout_marginBottom="11dp"
android:padding="5dp"
android:text="@string/take_me_in_world"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:textColor="@color/white_opaque"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_right_arrow"
android:layout_marginLeft="4dp"
app:layout_constraintLeft_toRightOf="@id/takeMeInWorld"
app:layout_constraintTop_toTopOf="@id/takeMeInWorld"
app:layout_constraintBottom_toBottomOf="@id/takeMeInWorld"
/>
</android.support.constraint.ConstraintLayout>

View file

@ -0,0 +1,122 @@
<?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"
tools:context=".fragment.StartMenuFragment">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/encourage_login_background"
android:scaleType="fitXY"
/>
<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/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="@font/raleway_bold"
android:textSize="@dimen/login_menu_text_size"
android:layout_marginTop="37dp"
android:text="@string/be_anywere"
android:gravity="center"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/header"
/>
<Button
android:id="@+id/signupButton"
android:layout_width="@dimen/button_large_width"
android:layout_height="@dimen/button_large_height"
android:layout_marginTop="48dp"
android:background="@drawable/rounded_button_color1"
android:fontFamily="@font/raleway_bold"
android:text="@string/signup_uppercase"
android:textColor="@color/white_opaque"
android:textAllCaps="false"
android:textSize="@dimen/button_large_text_size"
app:layout_constraintTop_toBottomOf="@id/text"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="@dimen/login_menu_translucent_rectangle_height"
app:layout_constraintBottom_toBottomOf="parent" android:background="#B2000000">
<Button
android:id="@+id/loginButton"
android:layout_width="@dimen/button_large_width"
android:layout_height="@dimen/button_large_height"
android:background="@drawable/rounded_button_color3"
android:fontFamily="@font/raleway_bold"
android:layout_marginTop="@dimen/login_menu_button_margin_top"
android:text="@string/log_in"
android:textColor="@color/white_opaque"
android:textAllCaps="false"
android:textSize="@dimen/button_large_text_size"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"/>
<Button
android:id="@+id/steamLoginButton"
android:layout_width="@dimen/button_large_width"
android:layout_height="@dimen/button_large_height"
android:background="@drawable/rounded_button_color4"
android:fontFamily="@font/raleway_bold"
android:layout_marginTop="10dp"
android:text="@string/steam_log_in"
android:textAlignment="center"
android:textColor="@color/white_opaque"
android:textAllCaps="false"
android:textSize="@dimen/button_large_text_size"
android:drawableLeft="@drawable/ic_steam"
android:paddingLeft="38dp"
android:paddingRight="38dp"
app:layout_constraintTop_toBottomOf="@id/loginButton"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"/>
<TextView
android:id="@+id/takeMeInWorld"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/raleway_bold"
android:textSize="14sp"
android:layout_marginBottom="11dp"
android:padding="5dp"
android:text="@string/take_me_in_world"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:textColor="@color/white_opaque"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_right_arrow"
android:layout_marginLeft="4dp"
app:layout_constraintLeft_toRightOf="@id/takeMeInWorld"
app:layout_constraintTop_toTopOf="@id/takeMeInWorld"
app:layout_constraintBottom_toBottomOf="@id/takeMeInWorld"
/>
</android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout>

View file

@ -1,63 +0,0 @@
<?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/welcome"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:paddingLeft="86dp"
android:paddingRight="86dp"
android:fontFamily="@font/raleway"
android:textColor="@color/clearText"
android:textSize="24sp"
android:text="@string/signedin_welcome"
app:layout_constraintTop_toBottomOf="@id/header"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:gravity="center"
/>
<Button
android:id="@+id/getStarted"
android:layout_width="217dp"
android:layout_height="38dp"
android:layout_marginTop="30dp"
android:background="@drawable/rounded_button"
android:fontFamily="@font/raleway_semibold"
android:paddingBottom="0dp"
android:paddingLeft="25dp"
android:paddingRight="25dp"
android:paddingTop="0dp"
android:text="@string/get_started"
android:textColor="@color/white_opaque"
android:textAllCaps="false"
android:textSize="18sp"
app:layout_constraintTop_toBottomOf="@id/welcome"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_goneMarginTop="4dp"/>
</android.support.constraint.ConstraintLayout>

View file

@ -6,6 +6,18 @@
android:layout_height="match_parent"
android:background="@color/backgroundLight">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/encourage_login_background"
android:scaleType="fitXY" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#B2000000" />
<ImageView
android:id="@+id/header"
android:layout_width="@dimen/header_hifi_width"
@ -17,93 +29,168 @@
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/hifi_header" />
<android.support.constraint.ConstraintLayout
android:id="@+id/loggingInFrame"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="100dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/header"
app:layout_constraintBottom_toBottomOf="parent"
android:visibility="gone">
<TextView
android:id="@+id/activityText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/logging_in"
android:fontFamily="@font/raleway_bold"
android:textSize="24sp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:layout_marginTop="83dp"
/>
<ProgressBar
android:layout_width="101dp"
android:layout_height="101dp"
android:layout_marginTop="20dp"
app:layout_constraintTop_toBottomOf="@id/activityText"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:indeterminateTint="#00B4EF"
/>
</android.support.constraint.ConstraintLayout>
<android.support.constraint.ConstraintLayout
android:id="@+id/loggedInFrame"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="100dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/header"
app:layout_constraintBottom_toBottomOf="parent"
android:visibility="gone">
<TextView
android:id="@+id/loggedInText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/logged_in_welcome"
android:fontFamily="@font/raleway_bold"
android:textSize="24sp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:layout_marginTop="115dp"
/>
<Button
android:id="@+id/getStarted"
android:layout_width="@dimen/button_medium_width"
android:layout_height="@dimen/button_medium_height"
android:layout_marginTop="22dp"
android:background="@drawable/rounded_button_color1"
android:fontFamily="@font/raleway_bold"
android:text="@string/get_started"
android:textColor="@color/white_opaque"
android:textAllCaps="false"
android:textSize="@dimen/button_medium_text_size"
app:layout_constraintTop_toBottomOf="@id/loggedInText"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />
</android.support.constraint.ConstraintLayout>
<android.support.constraint.ConstraintLayout
android:id="@+id/signupForm"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="100dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/header"
app:layout_constraintBottom_toBottomOf="parent"
android:visibility="visible">
<TextView
android:id="@+id/error"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:layout_marginLeft="9dp"
android:layout_marginRight="9dp"
android:fontFamily="@font/raleway"
android:fontFamily="sans-serif"
android:textColor="@color/colorLoginError"
android:textSize="14sp"
app:layout_constraintBottom_toTopOf="@id/email"
app:layout_constraintLeft_toLeftOf="@id/email"
app:layout_constraintRight_toRightOf="@id/email"
app:layout_constraintBottom_toTopOf="@id/username"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="@id/username"
app:layout_constraintRight_toRightOf="@id/username"
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:layout_height="@dimen/login_edit_text_height"
android:layout_marginLeft="@dimen/signup_margin"
android:layout_marginRight="@dimen/signup_margin"
android:background="@color/white_opaque"
android:paddingLeft="@dimen/edit_text_padding"
android:ems="10"
android:fontFamily="@font/raleway"
android:textSize="17sp"
android:fontFamily="sans-serif"
android:textSize="@dimen/login_edit_text_size"
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="7dp"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="70dp"
android:hint="@string/username" />
<EditText
android:id="@+id/email"
android:layout_width="match_parent"
android:layout_height="@dimen/login_edit_text_height"
android:layout_marginLeft="@dimen/signup_margin"
android:layout_marginRight="@dimen/signup_margin"
android:background="@color/white_opaque"
android:paddingLeft="@dimen/edit_text_padding"
android:ems="10"
android:fontFamily="sans-serif"
android:textSize="@dimen/login_edit_text_size"
android:inputType="textEmailAddress"
android:textColor="@color/editTextColor"
android:textColorHint="@color/editTextColor"
android:gravity="left|center_vertical"
app:layout_constraintTop_toBottomOf="@id/username"
android:layout_marginTop="14dp"
android:hint="@string/email" />
<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"
android:layout_marginLeft="@dimen/signup_margin"
android:layout_marginRight="@dimen/signup_margin"
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="7dp"
app:layout_constraintTop_toBottomOf="@id/email"
android:layout_marginTop="15dp"
>
<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:layout_height="27dp"
android:background="@color/white_opaque"
android:paddingLeft="@dimen/edit_text_padding"
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:fontFamily="sans-serif"
android:textSize="@dimen/login_edit_text_size"
android:textColor="@color/editTextColor"
android:textColorHint="@color/editTextColor"
android:gravity="left|center_vertical"
@ -112,40 +199,54 @@
android:inputType="textPassword" />
</android.support.design.widget.TextInputLayout>
<CheckBox
android:id="@+id/keepMeLoggedIn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="13dp"
android:layout_marginRight="66dp"
app:layout_constraintTop_toBottomOf="@id/passwordLayout"
app:layout_constraintRight_toRightOf="parent"
android:padding="0dp" />
<TextView
android:id="@+id/keepMeLoggedInLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/raleway_bold"
android:textSize="12sp"
android:text="@string/keep_me_logged_in"
app:layout_constraintRight_toLeftOf="@id/keepMeLoggedIn"
app:layout_constraintTop_toTopOf="@id/keepMeLoggedIn"
app:layout_constraintBottom_toBottomOf="@id/keepMeLoggedIn"
android:textColor="@color/white_opaque"/>
<Button
android:id="@+id/signupButton"
android:layout_width="154dp"
android:layout_height="38dp"
android:layout_marginTop="44dp"
android:background="@drawable/rounded_button"
android:fontFamily="@font/raleway_semibold"
android:paddingBottom="0dp"
android:paddingTop="0dp"
android:text="@string/signup"
android:layout_width="@dimen/button_medium_width"
android:layout_height="@dimen/button_medium_height"
android:layout_marginTop="10dp"
android:background="@drawable/rounded_button_color1"
android:fontFamily="@font/raleway_bold"
android:text="@string/signup_uppercase"
android:textColor="@color/white_opaque"
android:textAllCaps="false"
android:textSize="18sp"
android:textSize="@dimen/button_medium_text_size"
app:layout_constraintRight_toRightOf="@id/username"
app:layout_constraintTop_toBottomOf="@id/passwordLayout"
app:layout_goneMarginTop="4dp"/>
app:layout_constraintTop_toBottomOf="@id/keepMeLoggedIn" />
<Button
android:id="@+id/cancelButton"
android:layout_width="0dp"
app:layout_constraintWidth_default="spread"
android:layout_height="38dp"
android:background="@drawable/rounded_secondary_button"
android:fontFamily="@font/raleway_semibold"
android:paddingBottom="0dp"
android:paddingTop="0dp"
android:layout_marginRight="15dp"
android:text="@string/cancel"
android:textColor="@color/white_opaque"
android:textAllCaps="false"
android:textSize="18sp"
<TextView
android:id="@+id/cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="@id/passwordLayout"
app:layout_constraintTop_toTopOf="@id/signupButton"
app:layout_constraintBottom_toBottomOf="@id/signupButton"
app:layout_constraintRight_toLeftOf="@id/signupButton"
app:layout_goneMarginTop="4dp"/>
android:textColor="@color/white_opaque"
android:fontFamily="@font/raleway_bold"
android:textSize="@dimen/button_medium_text_size"
android:text="@string/cancel_uppercase" />
</android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout>

View file

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="header_hifi_margin_top">35dp</dimen>
<dimen name="header_hifi_height">84dp</dimen>
<dimen name="header_hifi_width">340dp</dimen>
<dimen name="button_medium_width">171dp</dimen>
<dimen name="button_medium_height">42dp</dimen>
<dimen name="button_medium_margin">10dp</dimen>
<dimen name="login_edit_text_size">14sp</dimen>
<dimen name="button_large_text_size">18sp</dimen>
<dimen name="button_medium_text_size">18sp</dimen>
<dimen name="login_margin">72dp</dimen>
<dimen name="signup_margin">76dp</dimen>
<dimen name="login_form_margin_top">100dp</dimen>
<dimen name="login_edit_text_height">27dp</dimen>
<dimen name="button_large_width">238dp</dimen>
<dimen name="button_large_height">42dp</dimen>
<dimen name="login_menu_translucent_rectangle_height">270dp</dimen>
<dimen name="login_menu_button_margin_top">86dp</dimen>
<dimen name="login_menu_text_size">22sp</dimen>
<dimen name="login_edit_text_padding">16dp</dimen>
</resources>

View file

@ -10,6 +10,8 @@
<color name="tabs">#1EB5EC</color>
<color name="colorButton1">#00B4EF</color>
<color name="colorButton2">#828282</color>
<color name="colorButton3">#8F8F8F</color>
<color name="colorButton4">#434343</color>
<color name="backgroundDark">#333333</color>
<color name="backgroundLight">#4F4F4F</color>
<color name="backgroundSearch">#33999999</color>

View file

@ -33,10 +33,26 @@
<dimen name="domainMarginBottom">6dp</dimen>
<dimen name="domainNameHeight">64dp</dimen>
<dimen name="header_hifi_margin_top">56dp</dimen>
<dimen name="header_hifi_height">101dp</dimen>
<dimen name="header_hifi_width">425dp</dimen>
<dimen name="header_hifi_margin_top">32dp</dimen>
<dimen name="header_hifi_height">76dp</dimen>
<dimen name="header_hifi_width">306dp</dimen>
<dimen name="list_vertical_padding">8dp</dimen>
<dimen name="button_medium_width">150dp</dimen>
<dimen name="button_medium_height">38dp</dimen>
<dimen name="login_margin">65dp</dimen>
<dimen name="signup_margin">68dp</dimen>
<dimen name="login_form_margin_top">90dp</dimen>
<dimen name="button_medium_margin">9dp</dimen>
<dimen name="button_medium_text_size">16sp</dimen>
<dimen name="button_large_text_size">16sp</dimen>
<dimen name="login_edit_text_size">13sp</dimen>
<dimen name="login_edit_text_height">24dp</dimen>
<dimen name="button_large_width">214dp</dimen>
<dimen name="button_large_height">38dp</dimen>
<dimen name="login_menu_translucent_rectangle_height">300dp</dimen>
<dimen name="login_menu_button_margin_top">77dp</dimen>
<dimen name="login_menu_text_size">20sp</dimen>
<dimen name="login_edit_text_padding">14dp</dimen>
</resources>

View file

@ -16,9 +16,9 @@
<string name="password">Password</string>
<string name="login">Login</string>
<string name="logout">Logout</string>
<string name="forgot_password"><u>Forgot password?</u>\u00A0</string>
<string name="cant_access_your_account"><u>Can\u0027t access your account?</u></string>
<string name="login_username_or_password_incorrect">Username or password incorrect.</string>
<string name="logging_in">Logging into High Fidelity</string>
<string name="logging_in">Logging in</string>
<string name="search_hint"><i>Search for a place by name</i>\u00A0</string>
<string name="search_loading">Loading places…</string>
<string name="search_no_results">No places exist with that name</string>
@ -26,16 +26,20 @@
<string name="your_last_location">Your Last Location</string>
<string name="online">Online</string>
<string name="signup">Sign Up</string>
<string name="signup_uppercase">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>
<string name="signedin_welcome">You are now signed into High Fidelity</string>
<string name="logged_in_welcome">You are now logged in!</string>
<string name="welcome">Welcome</string>
<string name="cancel">Cancel</string>
<string name="get_started">Get Started</string>
<string name="cancel_uppercase">CANCEL</string>
<string name="get_started">GET STARTED</string>
<!-- tags -->
<string name="tagFragmentHome">tagFragmentHome</string>
<string name="tagFragmentLogin">tagFragmentLogin</string>
<string name="tagFragmentLoggingIn">tagFragmentLogginIn</string>
<string name="tagFragmentSignup">tagFragmentSignup</string>
<string name="tagFragmentPolicy">tagFragmentPolicy</string>
<string name="tagFragmentPeople">tagFragmentPeople</string>
@ -45,4 +49,9 @@
<string name="AEC">AEC</string>
<string name="acoustic_echo_cancellation">Acoustic Echo Cancellation</string>
<string name="settings_developer">Developer</string>
<string name="log_in">LOG IN</string>
<string name="keep_me_logged_in">Keep Me Logged In</string>
<string name="take_me_in_world">No thanks, take me in-world!</string>
<string name="be_anywere">BE ANYWHERE, WITH ANYONE \nRIGHT NOW</string>
<string name="steam_log_in">STEAM LOG IN</string>
</resources>

View file

@ -6,6 +6,7 @@
<SwitchPreference
android:key="aec"
android:title="@string/AEC"
android:summary="@string/acoustic_echo_cancellation" />
android:summary="@string/acoustic_echo_cancellation"
android:defaultValue="true" />
</PreferenceCategory>
</PreferenceScreen>

View file

@ -11,7 +11,7 @@ setup_memory_debugger()
# link in the shared libraries
link_hifi_libraries(
audio avatars octree gpu graphics fbx entities
audio avatars octree gpu graphics fbx hfm entities
networking animation recording shared script-engine embedded-webserver
controllers physics plugins midi image
)

View file

@ -89,7 +89,8 @@ AudioMixer::AudioMixer(ReceivedMessage& message) :
PacketType::NodeIgnoreRequest,
PacketType::RadiusIgnoreRequest,
PacketType::RequestsDomainListData,
PacketType::PerAvatarGainSet },
PacketType::PerAvatarGainSet,
PacketType::AudioSoloRequest },
this, "queueAudioPacket");
// packets whose consequences are global should be processed on the main thread

View file

@ -98,6 +98,9 @@ int AudioMixerClientData::processPackets(ConcurrentAddedStreams& addedStreams) {
case PacketType::RadiusIgnoreRequest:
parseRadiusIgnoreRequest(packet, node);
break;
case PacketType::AudioSoloRequest:
parseSoloRequest(packet, node);
break;
default:
Q_UNREACHABLE();
}
@ -295,6 +298,25 @@ void AudioMixerClientData::parseRadiusIgnoreRequest(QSharedPointer<ReceivedMessa
}
}
void AudioMixerClientData::parseSoloRequest(QSharedPointer<ReceivedMessage> message, const SharedNodePointer& node) {
uint8_t addToSolo;
message->readPrimitive(&addToSolo);
while (message->getBytesLeftToRead()) {
// parse out the UUID being soloed from the packet
QUuid soloedUUID = QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID));
if (addToSolo) {
_soloedNodes.push_back(soloedUUID);
} else {
auto it = std::remove(std::begin(_soloedNodes), std::end(_soloedNodes), soloedUUID);
_soloedNodes.erase(it, std::end(_soloedNodes));
}
}
}
AvatarAudioStream* AudioMixerClientData::getAvatarAudioStream() {
auto it = std::find_if(_audioStreams.begin(), _audioStreams.end(), [](const SharedStreamPointer& stream){
return stream->getStreamIdentifier().isNull();

View file

@ -65,6 +65,7 @@ public:
void parsePerAvatarGainSet(ReceivedMessage& message, const SharedNodePointer& node);
void parseNodeIgnoreRequest(QSharedPointer<ReceivedMessage> message, const SharedNodePointer& node);
void parseRadiusIgnoreRequest(QSharedPointer<ReceivedMessage> message, const SharedNodePointer& node);
void parseSoloRequest(QSharedPointer<ReceivedMessage> message, const SharedNodePointer& node);
// attempt to pop a frame from each audio stream, and return the number of streams from this client
int checkBuffersBeforeFrameSend();
@ -150,6 +151,9 @@ public:
const Node::IgnoredNodeIDs& getIgnoringNodeIDs() const { return _ignoringNodeIDs; }
const std::vector<QUuid>& getSoloedNodes() const { return _soloedNodes; }
bool getHasReceivedFirstMix() const { return _hasReceivedFirstMix; }
void setHasReceivedFirstMix(bool hasReceivedFirstMix) { _hasReceivedFirstMix = hasReceivedFirstMix; }
@ -209,6 +213,8 @@ private:
std::atomic_bool _isIgnoreRadiusEnabled { false };
std::vector<QUuid> _soloedNodes;
bool _hasReceivedFirstMix { false };
};

View file

@ -272,6 +272,10 @@ bool shouldBeSkipped(MixableStream& stream, const Node& listener,
return true;
}
if (!listenerData.getSoloedNodes().empty()) {
return !contains(listenerData.getSoloedNodes(), stream.nodeStreamID.nodeID);
}
bool shouldCheckIgnoreBox = (listenerAudioStream.isIgnoreBoxEnabled() ||
stream.positionalStream->isIgnoreBoxEnabled());
if (shouldCheckIgnoreBox &&
@ -310,6 +314,7 @@ bool AudioMixerSlave::prepareMix(const SharedNodePointer& listener) {
memset(_mixSamples, 0, sizeof(_mixSamples));
bool isThrottling = _numToRetain != -1;
bool isSoloing = !listenerData->getSoloedNodes().empty();
auto& streams = listenerData->getStreams();
@ -376,13 +381,14 @@ bool AudioMixerSlave::prepareMix(const SharedNodePointer& listener) {
stream.approximateVolume = approximateVolume(stream, listenerAudioStream);
} else {
if (shouldBeSkipped(stream, *listener, *listenerAudioStream, *listenerData)) {
addStream(stream, *listenerAudioStream, 0.0f);
addStream(stream, *listenerAudioStream, 0.0f, isSoloing);
streams.skipped.push_back(move(stream));
++stats.activeToSkipped;
return true;
}
addStream(stream, *listenerAudioStream, listenerData->getMasterAvatarGain());
addStream(stream, *listenerAudioStream, listenerData->getMasterAvatarGain(),
isSoloing);
if (shouldBeInactive(stream)) {
// To reduce artifacts we still call render to flush the HRTF for every silent
@ -417,7 +423,8 @@ bool AudioMixerSlave::prepareMix(const SharedNodePointer& listener) {
return true;
}
addStream(stream, *listenerAudioStream, listenerData->getMasterAvatarGain());
addStream(stream, *listenerAudioStream, listenerData->getMasterAvatarGain(),
isSoloing);
if (shouldBeInactive(stream)) {
// To reduce artifacts we still call render to flush the HRTF for every silent
@ -484,7 +491,7 @@ bool AudioMixerSlave::prepareMix(const SharedNodePointer& listener) {
void AudioMixerSlave::addStream(AudioMixerClientData::MixableStream& mixableStream,
AvatarAudioStream& listeningNodeStream,
float masterListenerGain) {
float masterListenerGain, bool isSoloing) {
++stats.totalMixes;
auto streamToAdd = mixableStream.positionalStream;
@ -495,9 +502,13 @@ void AudioMixerSlave::addStream(AudioMixerClientData::MixableStream& mixableStre
glm::vec3 relativePosition = streamToAdd->getPosition() - listeningNodeStream.getPosition();
float distance = glm::max(glm::length(relativePosition), EPSILON);
float gain = computeGain(masterListenerGain, listeningNodeStream, *streamToAdd, relativePosition, distance, isEcho);
float azimuth = isEcho ? 0.0f : computeAzimuth(listeningNodeStream, listeningNodeStream, relativePosition);
float gain = 1.0f;
if (!isSoloing) {
gain = computeGain(masterListenerGain, listeningNodeStream, *streamToAdd, relativePosition, distance, isEcho);
}
const int HRTF_DATASET_INDEX = 1;
if (!streamToAdd->lastPopSucceeded()) {

View file

@ -57,7 +57,7 @@ private:
bool prepareMix(const SharedNodePointer& listener);
void addStream(AudioMixerClientData::MixableStream& mixableStream,
AvatarAudioStream& listeningNodeStream,
float masterListenerGain);
float masterListenerGain, bool isSoloing);
void updateHRTFParameters(AudioMixerClientData::MixableStream& mixableStream,
AvatarAudioStream& listeningNodeStream,
float masterListenerGain);

View file

@ -3411,20 +3411,11 @@ void DomainServer::maybeHandleReplacementEntityFile() {
}
void DomainServer::handleOctreeFileReplacement(QByteArray octreeFile) {
//Assume we have compressed data
auto compressedOctree = octreeFile;
QByteArray jsonOctree;
bool wasCompressed = gunzip(compressedOctree, jsonOctree);
if (!wasCompressed) {
// the source was not compressed, assume we were sent regular JSON data
jsonOctree = compressedOctree;
}
OctreeUtils::RawEntityData data;
if (data.readOctreeDataInfoFromData(jsonOctree)) {
if (data.readOctreeDataInfoFromData(octreeFile)) {
data.resetIdAndVersion();
QByteArray compressedOctree;
gzip(data.toByteArray(), compressedOctree);
// write the compressed octree data to a special file

View file

@ -206,7 +206,7 @@ endif()
link_hifi_libraries(
shared workload task octree ktx gpu gl procedural graphics graphics-scripting render
pointers
recording fbx networking model-networking entities avatars trackers
recording hfm fbx networking model-networking entities avatars trackers
audio audio-client animation script-engine physics
render-utils entities-renderer avatars-renderer ui qml auto-updater midi
controllers plugins image trackers

Binary file not shown.

View file

@ -1,70 +1,138 @@
{
"version": "1.1",
"root": {
"id": "userAnimStateMachine",
"id": "networkAnimStateMachine",
"type": "stateMachine",
"data": {
"currentState": "idleAnim",
"currentState": "transitAnimStateMachine",
"states": [
{
"id": "idleAnim",
"id": "transitAnimStateMachine",
"interpTarget": 6,
"interpDuration": 6,
"transitions": [
{ "var": "postTransitAnim", "state": "postTransitAnim" },
{ "var": "preTransitAnim", "state": "preTransitAnim" }
{ "var": "userNetworkAnimA", "state": "userNetworkAnimA" },
{ "var": "userNetworkAnimB", "state": "userNetworkAnimB" }
]
},
{
"id": "preTransitAnim",
"id": "userNetworkAnimA",
"interpTarget": 6,
"interpDuration": 6,
"transitions": [
{ "var": "idleAnim", "state": "idleAnim" },
{ "var": "transitAnim", "state": "transitAnim" }
{ "var": "transitAnimStateMachine", "state": "transitAnimStateMachine" },
{ "var": "userNetworkAnimB", "state": "userNetworkAnimB" }
]
},
{
"id": "transitAnim",
"id": "userNetworkAnimB",
"interpTarget": 6,
"interpDuration": 6,
"transitions": [
{ "var": "preTransitAnim", "state": "preTransitAnim" },
{ "var": "postTransitAnim", "state": "postTransitAnim" }
]
},
{
"id": "postTransitAnim",
"interpTarget": 6,
"interpDuration": 6,
"transitions": [
{ "var": "transitAnim", "state": "transitAnim" },
{ "var": "idleAnim", "state": "idleAnim" }
]
},
{
"id": "userAnimA",
"interpTarget": 6,
"interpDuration": 6,
"transitions": [
{ "var": "idleAnim", "state": "idleAnim" },
{ "var": "userAnimB", "state": "userAnimB" }
]
},
{
"id": "userAnimB",
"interpTarget": 6,
"interpDuration": 6,
"transitions": [
{ "var": "idleAnim", "state": "idleAnim" },
{ "var": "userAnimA", "state": "userAnimA" }
{ "var": "transitAnimStateMachine", "state": "transitAnimStateMachine" },
{ "var": "userNetworkAnimA", "state": "userNetworkAnimA" }
]
}
]
},
"children": [
{
"id": "idleAnim",
"id": "transitAnimStateMachine",
"type": "stateMachine",
"data": {
"currentState": "idleAnim",
"states": [
{
"id": "idleAnim",
"interpTarget": 6,
"interpDuration": 6,
"transitions": [
{ "var": "postTransitAnim", "state": "postTransitAnim" },
{ "var": "preTransitAnim", "state": "preTransitAnim" }
]
},
{
"id": "preTransitAnim",
"interpTarget": 4,
"interpDuration": 4,
"transitions": [
{ "var": "idleAnim", "state": "idleAnim" },
{ "var": "transitAnim", "state": "transitAnim" }
]
},
{
"id": "transitAnim",
"interpTarget": 2,
"interpDuration": 2,
"transitions": [
{ "var": "preTransitAnim", "state": "preTransitAnim" },
{ "var": "postTransitAnim", "state": "postTransitAnim" }
]
},
{
"id": "postTransitAnim",
"interpTarget": 4,
"interpDuration": 4,
"transitions": [
{ "var": "transitAnim", "state": "transitAnim" },
{ "var": "idleAnim", "state": "idleAnim" }
]
}
]
},
"children" : [
{
"id": "idleAnim",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/idle.fbx",
"startFrame": 0.0,
"endFrame": 90.0,
"timeScale": 1.0,
"loopFlag": true
},
"children": []
},
{
"id": "preTransitAnim",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/teleport.fbx",
"startFrame": 0.0,
"endFrame": 10.0,
"timeScale": 1.0,
"loopFlag": false
},
"children": []
},
{
"id": "transitAnim",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/teleport.fbx",
"startFrame": 11.0,
"endFrame": 18.0,
"timeScale": 1.0,
"loopFlag": false
},
"children": []
},
{
"id": "postTransitAnim",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/teleport.fbx",
"startFrame": 19.0,
"endFrame": 44.0,
"timeScale": 1.0,
"loopFlag": false
},
"children": []
}
]
},
{
"id": "userNetworkAnimA",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/idle.fbx",
@ -76,55 +144,7 @@
"children": []
},
{
"id": "preTransitAnim",
"type": "clip",
"data": {
"url": "https://hifi-content.s3.amazonaws.com/luis/test_scripts/transitApp/animations/teleport01_warp.fbx",
"startFrame": 0.0,
"endFrame": 10.0,
"timeScale": 1.0,
"loopFlag": false
},
"children": []
},
{
"id": "transitAnim",
"type": "clip",
"data": {
"url": "https://hifi-content.s3.amazonaws.com/luis/test_scripts/transitApp/animations/teleport01_warp.fbx",
"startFrame": 11.0,
"endFrame": 11.0,
"timeScale": 1.0,
"loopFlag": true
},
"children": []
},
{
"id": "postTransitAnim",
"type": "clip",
"data": {
"url": "https://hifi-content.s3.amazonaws.com/luis/test_scripts/transitApp/animations/teleport01_warp.fbx",
"startFrame": 22.0,
"endFrame": 49.0,
"timeScale": 1.0,
"loopFlag": false
},
"children": []
},
{
"id": "userAnimA",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/idle.fbx",
"startFrame": 0.0,
"endFrame": 90.0,
"timeScale": 1.0,
"loopFlag": true
},
"children": []
},
{
"id": "userAnimB",
"id": "userNetworkAnimB",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/idle.fbx",

View file

@ -18,6 +18,11 @@
window.isKeyboardRaised = false;
window.isNumericKeyboard = false;
window.isPasswordField = false;
window.lastActiveElement = null;
function getActiveElement() {
return document.activeElement;
}
function shouldSetPasswordField() {
var nodeType = document.activeElement.type;
@ -65,10 +70,11 @@
var keyboardRaised = shouldRaiseKeyboard();
var numericKeyboard = shouldSetNumeric();
var passwordField = shouldSetPasswordField();
var activeElement = getActiveElement();
if (isWindowFocused &&
(keyboardRaised !== window.isKeyboardRaised || numericKeyboard !== window.isNumericKeyboard
|| passwordField !== window.isPasswordField)) {
|| passwordField !== window.isPasswordField || activeElement !== window.lastActiveElement)) {
if (typeof EventBridge !== "undefined" && EventBridge !== null) {
EventBridge.emitWebEvent(
@ -90,6 +96,7 @@
window.isKeyboardRaised = keyboardRaised;
window.isNumericKeyboard = numericKeyboard;
window.isPasswordField = passwordField;
window.lastActiveElement = activeElement;
}
}, POLL_FREQUENCY);

View file

@ -1,4 +1,20 @@
<svg width="22" height="26" fill="none" version="1.1" viewBox="0 0 22 26" xmlns="http://www.w3.org/2000/svg">
<path d="M1 7L11 1L21 7M1 7L11 13M1 7V19L11 25M11 13L21 7M11 13V25M21 7V19L11 25" stroke="#000" stroke-linejoin="round" stroke-width="2"/>
<circle class="st1" cx="19.407" cy="2.5881" r="2.5846" fill="#ef3b4e" stroke-width=".24043"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 22.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 50 50" style="enable-background:new 0 0 50 50;" xml:space="preserve">
<style type="text/css">
.st0{fill:#EF3B4E;}
</style>
<g>
<circle cx="27.8" cy="13.3" r="2.4"/>
<circle cx="19.7" cy="7.2" r="2.3"/>
<circle cx="9.4" cy="6.9" r="2.2"/>
<path d="M41.8,17.5l-8.9-5.2c0.1,0.3,0.1,0.7,0.1,1c0,1-0.3,1.8-0.8,2.6l5.1,2.9L25,26l-12.3-7.1l3.1-1.8c-0.4-0.7-0.7-1.6-0.7-2.5
c0-0.4,0.1-0.8,0.2-1.2l-7.1,4.1c-0.5,0.3-0.9,0.9-0.9,1.5v16.5c0,0.6,0.3,1.2,0.9,1.5l16,9.2c0.3,0.2,0.6,0.2,0.9,0.2
s0.6-0.1,0.9-0.2l16-9.2c0.5-0.3,0.9-0.9,0.9-1.5V19C42.7,18.4,42.3,17.8,41.8,17.5z M10.7,21.7L23.3,29v12.8l-12.5-7.2V21.7z
M39.2,34.5l-12.5,7.2V28.9l12.5-7.2V34.5z"/>
<circle cx="25" cy="20.3" r="2.8"/>
<circle cx="20" cy="14.6" r="2.4"/>
</g>
<circle class="st0" cx="44.1" cy="6" r="5.6"/>
</svg>

Before

Width:  |  Height:  |  Size: 356 B

After

Width:  |  Height:  |  Size: 1 KiB

View file

@ -1,3 +1,16 @@
<svg width="22" height="26" viewBox="0 0 22 26" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1 7L11 1L21 7M1 7L11 13M1 7V19L11 25M11 13L21 7M11 13V25M21 7V19L11 25" stroke="black" stroke-width="2" stroke-linejoin="round"/>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 22.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 50 50" style="enable-background:new 0 0 50 50;" xml:space="preserve">
<g>
<circle cx="27.8" cy="13.3" r="2.4"/>
<circle cx="19.7" cy="7.2" r="2.3"/>
<circle cx="9.4" cy="6.9" r="2.2"/>
<path d="M41.8,17.5l-8.9-5.2c0.1,0.3,0.1,0.7,0.1,1c0,1-0.3,1.8-0.8,2.6l5.1,2.9L25,26l-12.3-7.1l3.1-1.8c-0.4-0.7-0.7-1.6-0.7-2.5
c0-0.4,0.1-0.8,0.2-1.2l-7.1,4.1c-0.5,0.3-0.9,0.9-0.9,1.5v16.5c0,0.6,0.3,1.2,0.9,1.5l16,9.2c0.3,0.2,0.6,0.2,0.9,0.2
s0.6-0.1,0.9-0.2l16-9.2c0.5-0.3,0.9-0.9,0.9-1.5V19C42.7,18.4,42.3,17.8,41.8,17.5z M10.7,21.7L23.3,29v12.8l-12.5-7.2V21.7z
M39.2,34.5l-12.5,7.2V28.9l12.5-7.2V34.5z"/>
<circle cx="25" cy="20.3" r="2.8"/>
<circle cx="20" cy="14.6" r="2.4"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 243 B

After

Width:  |  Height:  |  Size: 966 B

View file

@ -1,4 +1,21 @@
<svg width="22" height="26" fill="none" version="1.1" viewBox="0 0 22 26" xmlns="http://www.w3.org/2000/svg">
<path d="M1 7L11 1L21 7M1 7L11 13M1 7V19L11 25M11 13L21 7M11 13V25M21 7V19L11 25" stroke="#fff" stroke-linejoin="round" stroke-width="2"/>
<circle class="st1" cx="19.41" cy="2.5828" r="2.5846" fill="#ef3b4e" stroke-width=".24043"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 22.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 50 50" style="enable-background:new 0 0 50 50;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
.st1{fill:#EF3B4E;}
</style>
<g>
<circle class="st0" cx="27.8" cy="13.3" r="2.4"/>
<circle class="st0" cx="19.7" cy="7.2" r="2.3"/>
<circle class="st0" cx="9.4" cy="6.9" r="2.2"/>
<path class="st0" d="M41.8,17.5l-8.9-5.2c0.1,0.3,0.1,0.7,0.1,1c0,1-0.3,1.8-0.8,2.6l5.1,2.9L25,26l-12.3-7.1l3.1-1.8
c-0.4-0.7-0.7-1.6-0.7-2.5c0-0.4,0.1-0.8,0.2-1.2l-7.1,4.1c-0.5,0.3-0.9,0.9-0.9,1.5v16.5c0,0.6,0.3,1.2,0.9,1.5l16,9.2
c0.3,0.2,0.6,0.2,0.9,0.2s0.6-0.1,0.9-0.2l16-9.2c0.5-0.3,0.9-0.9,0.9-1.5V19C42.7,18.4,42.3,17.8,41.8,17.5z M10.7,21.7L23.3,29
v12.8l-12.5-7.2V21.7z M39.2,34.5l-12.5,7.2V28.9l12.5-7.2V34.5z"/>
<circle class="st0" cx="25" cy="20.3" r="2.8"/>
<circle class="st0" cx="20" cy="14.6" r="2.4"/>
</g>
<circle class="st1" cx="44.1" cy="6" r="5.6"/>
</svg>

Before

Width:  |  Height:  |  Size: 355 B

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -1,3 +1,19 @@
<svg width="22" height="26" viewBox="0 0 22 26" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1 7L11 1L21 7M1 7L11 13M1 7V19L11 25M11 13L21 7M11 13V25M21 7V19L11 25" stroke="white" stroke-width="2" stroke-linejoin="round"/>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 22.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 50 50" style="enable-background:new 0 0 50 50;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
</style>
<g>
<circle class="st0" cx="27.8" cy="13.3" r="2.4"/>
<circle class="st0" cx="19.7" cy="7.2" r="2.3"/>
<circle class="st0" cx="9.4" cy="6.9" r="2.2"/>
<path class="st0" d="M41.8,17.5l-8.9-5.2c0.1,0.3,0.1,0.7,0.1,1c0,1-0.3,1.8-0.8,2.6l5.1,2.9L25,26l-12.3-7.1l3.1-1.8
c-0.4-0.7-0.7-1.6-0.7-2.5c0-0.4,0.1-0.8,0.2-1.2l-7.1,4.1c-0.5,0.3-0.9,0.9-0.9,1.5v16.5c0,0.6,0.3,1.2,0.9,1.5l16,9.2
c0.3,0.2,0.6,0.2,0.9,0.2s0.6-0.1,0.9-0.2l16-9.2c0.5-0.3,0.9-0.9,0.9-1.5V19C42.7,18.4,42.3,17.8,41.8,17.5z M10.7,21.7L23.3,29
v12.8l-12.5-7.2V21.7z M39.2,34.5l-12.5,7.2V28.9l12.5-7.2V34.5z"/>
<circle class="st0" cx="25" cy="20.3" r="2.8"/>
<circle class="st0" cx="20" cy="14.6" r="2.4"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 243 B

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -0,0 +1,8 @@
{
"compressed": {
"COMPRESSED_SRGB8_ALPHA8_ETC2_EAC": "../Eyes_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC.ktx",
"COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT": "../Eyes_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT.ktx"
},
"original": "../Eyes.png",
"uncompressed": ""
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1,002 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

View file

@ -0,0 +1,8 @@
{
"compressed": {
"COMPRESSED_SRGB8_ALPHA8_ETC2_EAC": "../lambert1_Base_Color_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC.ktx",
"COMPRESSED_SRGB_S3TC_DXT1_EXT": "../lambert1_Base_Color_COMPRESSED_SRGB_S3TC_DXT1_EXT.ktx"
},
"original": "../lambert1_Base_Color.png",
"uncompressed": ""
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

View file

@ -0,0 +1,8 @@
{
"compressed": {
"COMPRESSED_RG11_EAC": "../lambert1_Normal_OpenGL_COMPRESSED_RG11_EAC.ktx",
"COMPRESSED_RG_RGTC2": "../lambert1_Normal_OpenGL_COMPRESSED_RG_RGTC2.ktx"
},
"original": "../lambert1_Normal_OpenGL.png",
"uncompressed": ""
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 525 KiB

After

Width:  |  Height:  |  Size: 511 KiB

View file

@ -0,0 +1,8 @@
{
"compressed": {
"COMPRESSED_R11_EAC": "../lambert1_Roughness_COMPRESSED_R11_EAC.ktx",
"COMPRESSED_RED_RGTC1": "../lambert1_Roughness_COMPRESSED_RED_RGTC1.ktx"
},
"original": "../lambert1_Roughness.png",
"uncompressed": ""
}

View file

@ -50,6 +50,9 @@ Item {
StatText {
text: root.positionText
}
StatText {
text: root.recenterText
}
StatText {
text: "Anim Vars:--------------------------------------------------------------------------------"
}
@ -92,6 +95,9 @@ Item {
StatText {
text: root.rotationText
}
StatText {
text: root.sittingText
}
StatText {
text: "State Machines:---------------------------------------------------------------------------"
}
@ -122,6 +128,9 @@ Item {
StatText {
text: root.velocityText
}
StatText {
text: root.walkingText
}
StatText {
text: "Alpha Values:--------------------------------------------------------------------------"
}

View file

@ -114,7 +114,6 @@ ScrollingWindow {
sourceSize: Qt.size(width, height);
verticalAlignment: Image.AlignVCenter;
horizontalAlignment: Image.AlignHCenter
onSourceChanged: console.log("Icon url: " + source)
}
}
@ -249,10 +248,6 @@ ScrollingWindow {
root.loadingChanged(loadRequest.status);
}
onIconChanged: {
console.log("New icon: " + icon)
}
onWindowCloseRequested: {
root.destroy();
}

View file

@ -26,6 +26,8 @@ Item {
property bool interactive: false
property bool blurOnCtrlShift: true
StylesUIt.HifiConstants {
id: hifi
}
@ -34,10 +36,34 @@ Item {
webViewCore.stop();
}
Timer {
id: delayedUnfocuser
repeat: false
interval: 200
onTriggered: {
// The idea behind this is to delay unfocusing, so that fast lower/raise will not result actual unfocusing.
// Fast lower/raise happens every time keyboard is being re-raised (see the code below in OffscreenQmlSurface::setKeyboardRaised)
//
// if (raised) {
// item->setProperty("keyboardRaised", QVariant(!raised));
// }
//
// item->setProperty("keyboardRaised", QVariant(raised));
//
webViewCore.runJavaScript("if (document.activeElement) document.activeElement.blur();", function(result) {
console.log('unfocus completed: ', result);
});
}
}
function unfocus() {
webViewCore.runJavaScript("if (document.activeElement) document.activeElement.blur();", function(result) {
console.log('unfocus completed: ', result);
});
delayedUnfocuser.start();
}
function stopUnfocus() {
delayedUnfocuser.stop();
}
function onLoadingChanged(loadRequest) {
@ -156,8 +182,8 @@ Item {
}
Keys.onPressed: {
if ((event.modifiers & Qt.ShiftModifier) && (event.modifiers & Qt.ControlModifier)) {
webViewCore.focus = false;
if (blurOnCtrlShift && (event.modifiers & Qt.ShiftModifier) && (event.modifiers & Qt.ControlModifier)) {
webViewCore.focus = false;
}
}
}

View file

@ -13,6 +13,8 @@ Item {
onKeyboardRaisedChanged: {
if(!keyboardRaised) {
webroot.unfocus();
} else {
webroot.stopUnfocus();
}
}
property bool punctuationMode: false

View file

@ -17,6 +17,8 @@ Item {
onKeyboardRaisedChanged: {
if(!keyboardRaised) {
webroot.unfocus();
} else {
webroot.stopUnfocus();
}
}
property bool punctuationMode: false

View file

@ -15,11 +15,14 @@ Item {
onKeyboardRaisedChanged: {
if(!keyboardRaised) {
webroot.unfocus();
} else {
webroot.stopUnfocus();
}
}
property bool punctuationMode: false
property bool passwordField: false
property alias flickable: webroot.interactive
property alias blurOnCtrlShift: webroot.blurOnCtrlShift
function stop() {
webroot.stop();

View file

@ -80,8 +80,6 @@ ModalWindow {
property int clickedButton: OriginalDialogs.StandardButton.NoButton;
Component.onCompleted: {
console.log("Helper " + helper + " drives " + drives);
fileDialogItem.keyboardEnabled = HMD.active;
// HACK: The following lines force the model to initialize properly such that the go-up button
@ -809,7 +807,6 @@ ModalWindow {
}
}
console.log("Selecting " + selection)
selectedFile(selection);
root.destroy();
}

View file

@ -765,8 +765,7 @@ TabletModalWindow {
return;
}
}
console.log("Selecting " + selection)
selectedFile(selection);
root.destroy();
}

View file

@ -22,8 +22,6 @@ Preference {
Component.onCompleted: {
dataTextField.text = preference.value;
console.log("MyAvatar modelName " + MyAvatar.getFullAvatarModelName())
console.log("Application : " + ApplicationInterface)
ApplicationInterface.fullAvatarURLChanged.connect(processNewAvatar);
}

View file

@ -70,7 +70,6 @@ Preference {
dir: fileDialogHelper.pathToUrl(preference.value)
});
browser.selectedFile.connect(function(fileUrl){
console.log(fileUrl);
dataTextField.text = fileDialogHelper.urlToPath(fileUrl);
});
}

View file

@ -62,7 +62,7 @@ Rectangle {
}
}
catch(err) {
console.error(err);
//console.error(err);
}
}
}

View file

@ -49,6 +49,7 @@ Item {
property string defaultThumbnail: Qt.resolvedUrl("../../images/default-domain.gif");
property int shadowHeight: 10;
property bool hovered: false
property bool scrolling: false
HifiConstants { id: hifi }
@ -133,7 +134,7 @@ Item {
}
onStatusChanged: {
if (status == Image.Error) {
console.log("source: " + source + ": failed to load " + hifiUrl);
console.log("source: " + source + ": failed to load");
source = defaultThumbnail;
}
}
@ -236,11 +237,12 @@ Item {
property var hoverThunk: function () { };
property var unhoverThunk: function () { };
Rectangle {
anchors.fill: parent;
visible: root.hovered
color: "transparent";
border.width: 4; border.color: hifiStyleConstants.colors.primaryHighlight;
z: 1;
anchors.fill: parent
visible: root.hovered && !root.scrolling
color: "transparent"
border.width: 4
border.color: hifiStyleConstants.colors.primaryHighlight
z: 1
}
MouseArea {
anchors.fill: parent;
@ -255,6 +257,12 @@ Item {
hoverThunk();
}
onExited: unhoverThunk();
onCanceled: unhoverThunk();
}
MouseArea {
// This second mouse area causes onEntered to fire on the first if you scroll just a little and the cursor stays on
// the original card. I.e., the original card is re-highlighted if the cursor is on it after scrolling finishes.
anchors.fill: parent
}
StateImage {
id: actionIcon;

View file

@ -103,19 +103,14 @@ OriginalDesktop.Desktop {
property bool autoAdd: false
function initWebviewProfileHandlers(profile) {
console.log("The webview url in desktop is: " + currentUrl);
downloadUrl = currentUrl;
if (webViewProfileSetup) return;
webViewProfileSetup = true;
profile.downloadRequested.connect(function(download){
console.log("Download start: " + download.state);
adaptedPath = File.convertUrlToPath(downloadUrl);
tempDir = File.getTempDir();
console.log("Temp dir created: " + tempDir);
download.path = tempDir + "/" + adaptedPath;
console.log("Path where object should download: " + download.path);
console.log("Auto add: " + autoAdd);
download.accept();
if (download.state === WebEngineDownloadItem.DownloadInterrupted) {
console.log("download failed to complete");

View file

@ -141,6 +141,8 @@ Column {
textSizeSmall: root.textSizeSmall;
stackShadowNarrowing: root.stackShadowNarrowing;
shadowHeight: root.stackedCardShadowHeight;
scrolling: scroll.moving
hoverThunk: function () {
hovered = true;
if(root.autoScrollTimerEnabled) {

View file

@ -1287,7 +1287,7 @@ Rectangle {
connectionsOnlineDot.visible = message.shouldShowDot;
break;
default:
console.log('Unrecognized message:', JSON.stringify(message));
console.log('Pal.qml: Unrecognized message');
}
}
function sortModel() {

View file

@ -20,7 +20,6 @@ Item {
// Public function for initiating an http request.
// REQUIRES parent to be root to have sendToScript!
function request(options, callback) {
console.debug('HttpRequest', JSON.stringify(options));
httpCalls[httpCounter] = callback;
var message = {method: 'http.request', params: options, id: httpCounter++, jsonrpc: "2.0"};
parent.sendToScript(message);
@ -33,7 +32,6 @@ Item {
return;
}
delete httpCalls[message.id];
console.debug('HttpRequest response', JSON.stringify(message));
callback(message.error, message.response);
}
}

View file

@ -362,7 +362,7 @@ Rectangle {
spectatorCameraPreview.visible = message.setting;
break;
default:
console.log('Unrecognized message from spectatorCamera.js:', JSON.stringify(message));
console.log('Unrecognized message from spectatorCamera.js');
}
}
signal sendToScript(var message);

View file

@ -261,7 +261,6 @@ Rectangle {
anchors.right: parent.right
onLinkActivated: {
popup.showSpecifyWearableUrl(function(url) {
console.debug('popup.showSpecifyWearableUrl: ', url);
addWearable(root.avatarName, url);
modified = true;
});

View file

@ -29,9 +29,6 @@ Item {
when: avatarUrl !== ''
value: avatarUrl
}
onSourceChanged: {
console.debug('avatarImage: source = ', source);
}
visible: avatarImage.status !== Image.Loading && avatarImage.status !== Image.Error
}

View file

@ -96,9 +96,6 @@ Rectangle {
AvatarThumbnail {
id: avatarThumbnail
avatarUrl: avatarImageUrl
onAvatarUrlChanged: {
console.debug('CreateFavoritesDialog: onAvatarUrlChanged: ', avatarUrl);
}
wearablesCount: avatarWearablesCount
}

View file

@ -17,9 +17,6 @@ Rectangle {
property alias dialogButtons: buttons
property string imageSource: null
onImageSourceChanged: {
console.debug('imageSource = ', imageSource)
}
property string button1color: hifi.buttons.noneBorderlessGray;
property string button1text: ''

View file

@ -1094,7 +1094,7 @@ Rectangle {
refreshBuyUI();
break;
default:
console.log('Unrecognized message from marketplaces.js:', JSON.stringify(message));
console.log('Checkout.qml: Unrecognized message from marketplaces.js');
}
}
signal sendToScript(var message);

View file

@ -1867,7 +1867,7 @@ Item {
sendAssetStep.selectedRecipientUserName = message.userName;
break;
default:
console.log('SendAsset: Unrecognized message from wallet.js:', JSON.stringify(message));
console.log('SendAsset: Unrecognized message from wallet.js');
}
}
signal sendSignalToParent(var msg);

View file

@ -597,7 +597,7 @@ Rectangle {
resetCert(true);
break;
default:
console.log('Unrecognized message from marketplaces.js:', JSON.stringify(message));
console.log('InspectionCertificate.qml: Unrecognized message from marketplaces.js');
}
}
signal sendToScript(var message);

Some files were not shown because too many files have changed in this diff Show more