introduce SetupActiviy
This commit is contained in:
parent
35360fde91
commit
eeac779e25
27
build.gradle
27
build.gradle
|
@ -1,6 +1,12 @@
|
||||||
// Top-level build file where you can add configuration options common to all
|
|
||||||
// sub-projects/modules.
|
|
||||||
buildscript {
|
buildscript {
|
||||||
|
|
||||||
|
ext {
|
||||||
|
room_version = "2.5.0"
|
||||||
|
navVersion = '2.5.3'
|
||||||
|
appcompatVersion = "1.6.1"
|
||||||
|
lifecycleVersion = "2.2.0"
|
||||||
|
}
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
|
@ -8,11 +14,13 @@ buildscript {
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:7.4.1'
|
classpath 'com.android.tools.build:gradle:7.4.1'
|
||||||
classpath "com.diffplug.spotless:spotless-plugin-gradle:6.13.0"
|
classpath "com.diffplug.spotless:spotless-plugin-gradle:6.13.0"
|
||||||
|
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$navVersion"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
apply plugin: 'com.android.application'
|
apply plugin: 'com.android.application'
|
||||||
apply plugin: "com.diffplug.spotless"
|
apply plugin: "com.diffplug.spotless"
|
||||||
|
apply plugin: "androidx.navigation.safeargs"
|
||||||
|
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
|
@ -45,17 +53,25 @@ dependencies {
|
||||||
|
|
||||||
// Conversations 3.0 dependencies
|
// Conversations 3.0 dependencies
|
||||||
|
|
||||||
def room_version = "2.5.0"
|
|
||||||
|
|
||||||
implementation project(':libs:annotation')
|
implementation project(':libs:annotation')
|
||||||
annotationProcessor project(':libs:annotation-processor')
|
annotationProcessor project(':libs:annotation-processor')
|
||||||
|
|
||||||
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.8'
|
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.8'
|
||||||
|
|
||||||
|
implementation "androidx.appcompat:appcompat:$rootProject.ext.appcompatVersion"
|
||||||
|
|
||||||
|
implementation "androidx.lifecycle:lifecycle-extensions:$rootProject.ext.lifecycleVersion"
|
||||||
|
|
||||||
implementation "androidx.room:room-runtime:$room_version"
|
implementation "androidx.room:room-runtime:$room_version"
|
||||||
annotationProcessor "androidx.room:room-compiler:$room_version"
|
annotationProcessor "androidx.room:room-compiler:$room_version"
|
||||||
implementation "androidx.room:room-guava:$room_version"
|
implementation "androidx.room:room-guava:$room_version"
|
||||||
|
|
||||||
|
implementation "androidx.navigation:navigation-fragment:$rootProject.ext.navVersion"
|
||||||
|
implementation "androidx.navigation:navigation-ui:$rootProject.ext.navVersion"
|
||||||
|
|
||||||
|
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
|
||||||
|
|
||||||
|
|
||||||
implementation "androidx.security:security-crypto:1.0.0"
|
implementation "androidx.security:security-crypto:1.0.0"
|
||||||
|
|
||||||
|
|
||||||
|
@ -82,8 +98,7 @@ dependencies {
|
||||||
quicksyPlaystoreImplementation 'com.google.android.gms:play-services-auth-api-phone:18.0.1'
|
quicksyPlaystoreImplementation 'com.google.android.gms:play-services-auth-api-phone:18.0.1'
|
||||||
implementation 'org.sufficientlysecure:openpgp-api:10.0'
|
implementation 'org.sufficientlysecure:openpgp-api:10.0'
|
||||||
implementation 'com.theartofdev.edmodo:android-image-cropper:2.8.0'
|
implementation 'com.theartofdev.edmodo:android-image-cropper:2.8.0'
|
||||||
implementation 'androidx.appcompat:appcompat:1.6.0'
|
implementation 'androidx.exifinterface:exifinterface:1.3.6'
|
||||||
implementation 'androidx.exifinterface:exifinterface:1.3.5'
|
|
||||||
implementation 'androidx.cardview:cardview:1.0.0'
|
implementation 'androidx.cardview:cardview:1.0.0'
|
||||||
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
|
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
|
||||||
implementation 'com.google.android.material:material:1.8.0'
|
implementation 'com.google.android.material:material:1.8.0'
|
||||||
|
|
|
@ -85,7 +85,7 @@
|
||||||
android:networkSecurityConfig="@xml/network_security_configuration"
|
android:networkSecurityConfig="@xml/network_security_configuration"
|
||||||
android:preserveLegacyExternalStorage="true"
|
android:preserveLegacyExternalStorage="true"
|
||||||
android:requestLegacyExternalStorage="true"
|
android:requestLegacyExternalStorage="true"
|
||||||
android:theme="@style/ConversationsTheme"
|
android:theme="@style/Conversations3Theme"
|
||||||
tools:replace="android:label"
|
tools:replace="android:label"
|
||||||
tools:targetApi="q">
|
tools:targetApi="q">
|
||||||
|
|
||||||
|
@ -121,6 +121,14 @@
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</receiver>
|
</receiver>
|
||||||
|
|
||||||
|
<activity android:exported="true" android:name="im.conversations.android.ui.activity.SetupActivity"
|
||||||
|
android:windowSoftInputMode="adjustResize">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.ShareLocationActivity"
|
android:name=".ui.ShareLocationActivity"
|
||||||
android:label="@string/title_activity_share_location" />
|
android:label="@string/title_activity_share_location" />
|
||||||
|
@ -138,10 +146,7 @@
|
||||||
android:name=".ui.ConversationActivity"
|
android:name=".ui.ConversationActivity"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
android:theme="@style/SplashTheme">
|
android:theme="@style/SplashTheme">
|
||||||
<intent-filter>
|
|
||||||
<action android:name="android.intent.action.MAIN" />
|
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
|
||||||
</intent-filter>
|
|
||||||
</activity>
|
</activity>
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.ConversationsActivity"
|
android:name=".ui.ConversationsActivity"
|
||||||
|
|
|
@ -1,16 +1,22 @@
|
||||||
package im.conversations.android;
|
package im.conversations.android;
|
||||||
|
|
||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
|
import com.google.android.material.color.DynamicColors;
|
||||||
import im.conversations.android.xmpp.ConnectionPool;
|
import im.conversations.android.xmpp.ConnectionPool;
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class Conversations extends Application {
|
public class Conversations extends Application {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(Conversations.class);
|
||||||
|
|
||||||
public static final SecureRandom SECURE_RANDOM = new SecureRandom();
|
public static final SecureRandom SECURE_RANDOM = new SecureRandom();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
ConnectionPool.getInstance(this).reconfigure();
|
ConnectionPool.getInstance(this).reconfigure();
|
||||||
|
DynamicColors.applyToActivitiesIfAvailable(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
39
src/main/java/im/conversations/android/ui/Activities.java
Normal file
39
src/main/java/im/conversations/android/ui/Activities.java
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
package im.conversations.android.ui;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.res.Configuration;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.view.View;
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
import com.google.android.material.elevation.SurfaceColors;
|
||||||
|
|
||||||
|
public final class Activities {
|
||||||
|
|
||||||
|
private Activities() {}
|
||||||
|
|
||||||
|
public static void setStatusAndNavigationBarColors(
|
||||||
|
final AppCompatActivity activity, final View view) {
|
||||||
|
final var isLightMode = isLightMode(activity);
|
||||||
|
final var window = activity.getWindow();
|
||||||
|
final var flags = view.getSystemUiVisibility();
|
||||||
|
// an elevation of 4 matches the MaterialToolbar elevation
|
||||||
|
window.setStatusBarColor(SurfaceColors.SURFACE_0.getColor(activity));
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
window.setNavigationBarColor(SurfaceColors.SURFACE_1.getColor(activity));
|
||||||
|
if (isLightMode) {
|
||||||
|
view.setSystemUiVisibility(
|
||||||
|
flags
|
||||||
|
| View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
|
||||||
|
| View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR);
|
||||||
|
}
|
||||||
|
} else if (isLightMode) {
|
||||||
|
view.setSystemUiVisibility(flags | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isLightMode(final Context context) {
|
||||||
|
final int nightModeFlags =
|
||||||
|
context.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
|
||||||
|
return nightModeFlags != Configuration.UI_MODE_NIGHT_YES;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
package im.conversations.android.ui;
|
||||||
|
|
||||||
|
import android.view.KeyEvent;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.databinding.BindingAdapter;
|
||||||
|
import androidx.lifecycle.LiveData;
|
||||||
|
import com.google.android.material.textfield.TextInputEditText;
|
||||||
|
import com.google.android.material.textfield.TextInputLayout;
|
||||||
|
import com.google.common.base.Supplier;
|
||||||
|
|
||||||
|
public class BindingAdapters {
|
||||||
|
|
||||||
|
@BindingAdapter("errorText")
|
||||||
|
public static void setErrorText(
|
||||||
|
final TextInputLayout textInputLayout, final LiveData<String> error) {
|
||||||
|
textInputLayout.setError(error.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@BindingAdapter("editorAction")
|
||||||
|
public static void setEditorAction(
|
||||||
|
final TextInputEditText editText, final @NonNull Supplier<Boolean> callback) {
|
||||||
|
editText.setOnEditorActionListener(
|
||||||
|
(v, actionId, event) -> {
|
||||||
|
// event is null when using software keyboard
|
||||||
|
if (event == null || event.getAction() == KeyEvent.ACTION_UP) {
|
||||||
|
return Boolean.TRUE.equals(callback.get());
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
39
src/main/java/im/conversations/android/ui/Event.java
Normal file
39
src/main/java/im/conversations/android/ui/Event.java
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2019 Daniel Gultsch
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package im.conversations.android.ui;
|
||||||
|
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
|
public class Event<T> {
|
||||||
|
|
||||||
|
private final T event;
|
||||||
|
private final AtomicBoolean isConsumable = new AtomicBoolean(true);
|
||||||
|
|
||||||
|
public Event(T event) {
|
||||||
|
this.event = event;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T consume() {
|
||||||
|
if (isConsumable.compareAndSet(true, false)) {
|
||||||
|
return event;
|
||||||
|
}
|
||||||
|
throw new IllegalStateException("Event has already been consumed");
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isConsumable() {
|
||||||
|
return isConsumable.get();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package im.conversations.android.ui;
|
||||||
|
|
||||||
|
import androidx.annotation.IdRes;
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.fragment.app.FragmentManager;
|
||||||
|
import androidx.navigation.NavController;
|
||||||
|
import androidx.navigation.fragment.NavHostFragment;
|
||||||
|
|
||||||
|
public final class NavControllers {
|
||||||
|
|
||||||
|
private NavControllers() {}
|
||||||
|
|
||||||
|
public static NavController findNavController(
|
||||||
|
final AppCompatActivity activity, @IdRes int fragmentId) {
|
||||||
|
final FragmentManager fragmentManager = activity.getSupportFragmentManager();
|
||||||
|
final Fragment fragment = fragmentManager.findFragmentById(fragmentId);
|
||||||
|
if (fragment instanceof NavHostFragment) {
|
||||||
|
return ((NavHostFragment) fragment).getNavController();
|
||||||
|
}
|
||||||
|
throw new IllegalStateException("Fragment was not of type NavHostFragment");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
package im.conversations.android.ui.activity;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
import androidx.databinding.DataBindingUtil;
|
||||||
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
|
import androidx.navigation.NavController;
|
||||||
|
import eu.siacs.conversations.R;
|
||||||
|
import eu.siacs.conversations.SetupNavigationDirections;
|
||||||
|
import eu.siacs.conversations.databinding.ActivitySetupBinding;
|
||||||
|
import im.conversations.android.ui.Activities;
|
||||||
|
import im.conversations.android.ui.Event;
|
||||||
|
import im.conversations.android.ui.NavControllers;
|
||||||
|
import im.conversations.android.ui.model.SetupViewModel;
|
||||||
|
|
||||||
|
public class SetupActivity extends AppCompatActivity {
|
||||||
|
|
||||||
|
private SetupViewModel setupViewModel;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(final Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
final ActivitySetupBinding binding =
|
||||||
|
DataBindingUtil.setContentView(this, R.layout.activity_setup);
|
||||||
|
final ViewModelProvider viewModelProvider =
|
||||||
|
new ViewModelProvider(this, getDefaultViewModelProviderFactory());
|
||||||
|
this.setupViewModel = viewModelProvider.get(SetupViewModel.class);
|
||||||
|
this.setupViewModel.getRedirection().observe(this, this::onRedirectionEvent);
|
||||||
|
Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onRedirectionEvent(final Event<SetupViewModel.Target> targetEvent) {
|
||||||
|
if (targetEvent.isConsumable()) {
|
||||||
|
final NavController navController = getNavController();
|
||||||
|
final SetupViewModel.Target target = targetEvent.consume();
|
||||||
|
switch (target) {
|
||||||
|
case ENTER_PASSWORD:
|
||||||
|
navController.navigate(SetupNavigationDirections.enterPassword());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IllegalStateException(
|
||||||
|
String.format("Unable to navigate to target %s", target));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private NavController getNavController() {
|
||||||
|
return NavControllers.findNavController(this, R.id.nav_host_fragment);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
package im.conversations.android.ui.fragment.setup;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
|
import im.conversations.android.ui.model.SetupViewModel;
|
||||||
|
|
||||||
|
public abstract class AbstractSetupFragment extends Fragment {
|
||||||
|
|
||||||
|
SetupViewModel setupViewModel;
|
||||||
|
|
||||||
|
public void onCreate(final Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
final ViewModelProvider viewModelProvider =
|
||||||
|
new ViewModelProvider(requireActivity(), getDefaultViewModelProviderFactory());
|
||||||
|
this.setupViewModel = viewModelProvider.get(SetupViewModel.class);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
package im.conversations.android.ui.fragment.setup;
|
||||||
|
|
||||||
|
public class HostnameFragment extends AbstractSetupFragment {}
|
|
@ -0,0 +1,24 @@
|
||||||
|
package im.conversations.android.ui.fragment.setup;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.databinding.DataBindingUtil;
|
||||||
|
import eu.siacs.conversations.R;
|
||||||
|
import eu.siacs.conversations.databinding.FragmentPasswordBinding;
|
||||||
|
|
||||||
|
public class PasswordFragment extends AbstractSetupFragment {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View onCreateView(
|
||||||
|
@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||||
|
super.onCreateView(inflater, container, savedInstanceState);
|
||||||
|
FragmentPasswordBinding binding =
|
||||||
|
DataBindingUtil.inflate(inflater, R.layout.fragment_password, container, false);
|
||||||
|
binding.setSetupViewModel(setupViewModel);
|
||||||
|
binding.setLifecycleOwner(getViewLifecycleOwner());
|
||||||
|
return binding.getRoot();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
package im.conversations.android.ui.fragment.setup;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.databinding.DataBindingUtil;
|
||||||
|
import eu.siacs.conversations.R;
|
||||||
|
import eu.siacs.conversations.databinding.FragmentSignInBinding;
|
||||||
|
|
||||||
|
public class SignInFragment extends AbstractSetupFragment {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View onCreateView(
|
||||||
|
@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||||
|
super.onCreateView(inflater, container, savedInstanceState);
|
||||||
|
FragmentSignInBinding binding =
|
||||||
|
DataBindingUtil.inflate(inflater, R.layout.fragment_sign_in, container, false);
|
||||||
|
binding.setSetupViewModel(setupViewModel);
|
||||||
|
binding.setLifecycleOwner(getViewLifecycleOwner());
|
||||||
|
return binding.getRoot();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
package im.conversations.android.ui.model;
|
||||||
|
|
||||||
|
import android.app.Application;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.lifecycle.AndroidViewModel;
|
||||||
|
import androidx.lifecycle.LiveData;
|
||||||
|
import androidx.lifecycle.MutableLiveData;
|
||||||
|
import androidx.lifecycle.Transformations;
|
||||||
|
import im.conversations.android.ui.Event;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public class SetupViewModel extends AndroidViewModel {
|
||||||
|
|
||||||
|
private final MutableLiveData<String> xmppAddress = new MutableLiveData<>();
|
||||||
|
private final MutableLiveData<String> xmppAddressError = new MutableLiveData<>();
|
||||||
|
private final MutableLiveData<String> password = new MutableLiveData<>();
|
||||||
|
private final MutableLiveData<String> passwordError = new MutableLiveData<>();
|
||||||
|
private final MutableLiveData<Boolean> loading = new MutableLiveData<>(false);
|
||||||
|
|
||||||
|
private final MutableLiveData<Event<Target>> redirection = new MutableLiveData<>();
|
||||||
|
|
||||||
|
public SetupViewModel(@NonNull @NotNull Application application) {
|
||||||
|
super(application);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<Boolean> isLoading() {
|
||||||
|
return this.loading;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<String> getXmppAddressError() {
|
||||||
|
return Transformations.distinctUntilChanged(xmppAddressError);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MutableLiveData<String> getXmppAddress() {
|
||||||
|
return this.xmppAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MutableLiveData<String> getPassword() {
|
||||||
|
return password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<String> getPasswordError() {
|
||||||
|
return Transformations.distinctUntilChanged(this.passwordError);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean submitXmppAddress() {
|
||||||
|
redirection.postValue(new Event<>(Target.ENTER_PASSWORD));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean submitPassword() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<Event<Target>> getRedirection() {
|
||||||
|
return this.redirection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum Target {
|
||||||
|
ENTER_PASSWORD,
|
||||||
|
ENTER_HOSTNAME
|
||||||
|
}
|
||||||
|
}
|
22
src/main/res/anim/slide_from_left.xml
Normal file
22
src/main/res/anim/slide_from_left.xml
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?><!--
|
||||||
|
~ Copyright 2019 Daniel Gultsch
|
||||||
|
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
~ you may not use this file except in compliance with the License.
|
||||||
|
~ You may obtain a copy of the License at
|
||||||
|
~
|
||||||
|
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
~
|
||||||
|
~ Unless required by applicable law or agreed to in writing, software
|
||||||
|
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
~ See the License for the specific language governing permissions and
|
||||||
|
~ limitations under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<translate
|
||||||
|
android:duration="@integer/slide_animation_duration"
|
||||||
|
android:fromXDelta="-100%p"
|
||||||
|
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
|
||||||
|
android:toXDelta="0" />
|
||||||
|
</set>
|
22
src/main/res/anim/slide_from_right.xml
Normal file
22
src/main/res/anim/slide_from_right.xml
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?><!--
|
||||||
|
~ Copyright 2019 Daniel Gultsch
|
||||||
|
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
~ you may not use this file except in compliance with the License.
|
||||||
|
~ You may obtain a copy of the License at
|
||||||
|
~
|
||||||
|
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
~
|
||||||
|
~ Unless required by applicable law or agreed to in writing, software
|
||||||
|
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
~ See the License for the specific language governing permissions and
|
||||||
|
~ limitations under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<translate
|
||||||
|
android:duration="@integer/slide_animation_duration"
|
||||||
|
android:fromXDelta="100%p"
|
||||||
|
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
|
||||||
|
android:toXDelta="0" />
|
||||||
|
</set>
|
22
src/main/res/anim/slide_to_left.xml
Normal file
22
src/main/res/anim/slide_to_left.xml
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?><!--
|
||||||
|
~ Copyright 2019 Daniel Gultsch
|
||||||
|
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
~ you may not use this file except in compliance with the License.
|
||||||
|
~ You may obtain a copy of the License at
|
||||||
|
~
|
||||||
|
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
~
|
||||||
|
~ Unless required by applicable law or agreed to in writing, software
|
||||||
|
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
~ See the License for the specific language governing permissions and
|
||||||
|
~ limitations under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<translate
|
||||||
|
android:duration="@integer/slide_animation_duration"
|
||||||
|
android:fromXDelta="0"
|
||||||
|
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
|
||||||
|
android:toXDelta="-100%p" />
|
||||||
|
</set>
|
22
src/main/res/anim/slide_to_right.xml
Normal file
22
src/main/res/anim/slide_to_right.xml
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?><!--
|
||||||
|
~ Copyright 2019 Daniel Gultsch
|
||||||
|
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
~ you may not use this file except in compliance with the License.
|
||||||
|
~ You may obtain a copy of the License at
|
||||||
|
~
|
||||||
|
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
~
|
||||||
|
~ Unless required by applicable law or agreed to in writing, software
|
||||||
|
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
~ See the License for the specific language governing permissions and
|
||||||
|
~ limitations under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<translate
|
||||||
|
android:duration="@integer/slide_animation_duration"
|
||||||
|
android:fromXDelta="0"
|
||||||
|
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
|
||||||
|
android:toXDelta="100%p" />
|
||||||
|
</set>
|
10
src/main/res/drawable/ic_account_circle_24dp.xml
Normal file
10
src/main/res/drawable/ic_account_circle_24dp.xml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:tint="?attr/colorControlNormal"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10s10,-4.48 10,-10S17.52,2 12,2zM12,6c1.93,0 3.5,1.57 3.5,3.5S13.93,13 12,13s-3.5,-1.57 -3.5,-3.5S10.07,6 12,6zM12,20c-2.03,0 -4.43,-0.82 -6.14,-2.88C7.55,15.8 9.68,15 12,15s4.45,0.8 6.14,2.12C16.43,19.18 14.03,20 12,20z" />
|
||||||
|
</vector>
|
10
src/main/res/drawable/ic_settings_24dp.xml
Normal file
10
src/main/res/drawable/ic_settings_24dp.xml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:tint="?attr/colorControlNormal"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M19.14,12.94c0.04,-0.3 0.06,-0.61 0.06,-0.94c0,-0.32 -0.02,-0.64 -0.07,-0.94l2.03,-1.58c0.18,-0.14 0.23,-0.41 0.12,-0.61l-1.92,-3.32c-0.12,-0.22 -0.37,-0.29 -0.59,-0.22l-2.39,0.96c-0.5,-0.38 -1.03,-0.7 -1.62,-0.94L14.4,2.81c-0.04,-0.24 -0.24,-0.41 -0.48,-0.41h-3.84c-0.24,0 -0.43,0.17 -0.47,0.41L9.25,5.35C8.66,5.59 8.12,5.92 7.63,6.29L5.24,5.33c-0.22,-0.08 -0.47,0 -0.59,0.22L2.74,8.87C2.62,9.08 2.66,9.34 2.86,9.48l2.03,1.58C4.84,11.36 4.8,11.69 4.8,12s0.02,0.64 0.07,0.94l-2.03,1.58c-0.18,0.14 -0.23,0.41 -0.12,0.61l1.92,3.32c0.12,0.22 0.37,0.29 0.59,0.22l2.39,-0.96c0.5,0.38 1.03,0.7 1.62,0.94l0.36,2.54c0.05,0.24 0.24,0.41 0.48,0.41h3.84c0.24,0 0.44,-0.17 0.47,-0.41l0.36,-2.54c0.59,-0.24 1.13,-0.56 1.62,-0.94l2.39,0.96c0.22,0.08 0.47,0 0.59,-0.22l1.92,-3.32c0.12,-0.22 0.07,-0.47 -0.12,-0.61L19.14,12.94zM12,15.6c-1.98,0 -3.6,-1.62 -3.6,-3.6s1.62,-3.6 3.6,-3.6s3.6,1.62 3.6,3.6S13.98,15.6 12,15.6z" />
|
||||||
|
</vector>
|
32
src/main/res/layout/activity_setup.xml
Normal file
32
src/main/res/layout/activity_setup.xml
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?><!--
|
||||||
|
~ Copyright 2019 Daniel Gultsch
|
||||||
|
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
~ you may not use this file except in compliance with the License.
|
||||||
|
~ You may obtain a copy of the License at
|
||||||
|
~
|
||||||
|
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
~
|
||||||
|
~ Unless required by applicable law or agreed to in writing, software
|
||||||
|
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
~ See the License for the specific language governing permissions and
|
||||||
|
~ limitations under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<androidx.fragment.app.FragmentContainerView
|
||||||
|
android:id="@+id/nav_host_fragment"
|
||||||
|
android:name="androidx.navigation.fragment.NavHostFragment"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
app:defaultNavHost="true"
|
||||||
|
app:navGraph="@navigation/setup_navigation" />
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
</layout>
|
136
src/main/res/layout/fragment_password.xml
Normal file
136
src/main/res/layout/fragment_password.xml
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?><!--
|
||||||
|
~ Copyright 2019-2023 Daniel Gultsch
|
||||||
|
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
~ you may not use this file except in compliance with the License.
|
||||||
|
~ You may obtain a copy of the License at
|
||||||
|
~
|
||||||
|
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
~
|
||||||
|
~ Unless required by applicable law or agreed to in writing, software
|
||||||
|
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
~ See the License for the specific language governing permissions and
|
||||||
|
~ limitations under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<layout 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">
|
||||||
|
|
||||||
|
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
|
android:id="@+id/app_bar_layout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:liftOnScroll="false"
|
||||||
|
app:elevation="0dp">
|
||||||
|
|
||||||
|
<com.google.android.material.appbar.MaterialToolbar
|
||||||
|
android:id="@+id/material_toolbar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="?attr/actionBarSize"
|
||||||
|
app:title="@string/app_name"
|
||||||
|
app:menu="@menu/setup"
|
||||||
|
app:titleTextColor="?colorPrimary"
|
||||||
|
app:titleCentered="true" />
|
||||||
|
|
||||||
|
<com.google.android.material.progressindicator.LinearProgressIndicator
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:indeterminate="true"
|
||||||
|
android:visibility="@{setupViewModel.isLoading() ? View.VISIBLE : View.INVISIBLE}" />
|
||||||
|
|
||||||
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
|
<androidx.core.widget.NestedScrollView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:fillViewport="true"
|
||||||
|
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||||
|
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
android:minHeight="@dimen/setup_main_min_height"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="@dimen/setup_screen_padding">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/header"
|
||||||
|
android:textAppearance="?textAppearanceTitleMedium"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:layout_marginTop="@dimen/setup_screen_top_margin"
|
||||||
|
android:text="@string/welcome" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/xmpp_address"
|
||||||
|
android:textAppearance="?textAppearanceBodyMedium"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_below="@+id/header"
|
||||||
|
android:layout_marginTop="12sp"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:text="@{setupViewModel.xmppAddress}"
|
||||||
|
tools:text="username@exmample.com"
|
||||||
|
app:drawableStartCompat="@drawable/ic_account_circle_24dp"
|
||||||
|
android:drawablePadding="8sp" />
|
||||||
|
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:layout_marginTop="24sp"
|
||||||
|
android:id="@+id/password_input_layout"
|
||||||
|
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
|
||||||
|
android:layout_width="488dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:layout_below="@+id/xmpp_address"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:enabled="@{!setupViewModel.isLoading()}"
|
||||||
|
android:hint="@string/password"
|
||||||
|
app:errorText="@{setupViewModel.passwordError}">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/password"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:imeOptions="flagNoExtractUi|actionNext"
|
||||||
|
android:inputType="textPassword"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:text="@={setupViewModel.password}"
|
||||||
|
app:editorAction="@{()->setupViewModel.submitPassword()}" />
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/next"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:layout_alignParentBottom="true"
|
||||||
|
android:enabled="@{!setupViewModel.isLoading()}"
|
||||||
|
android:onClick="@{(v) -> setupViewModel.submitPassword()}"
|
||||||
|
android:text="@string/next" />
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
</androidx.core.widget.NestedScrollView>
|
||||||
|
|
||||||
|
|
||||||
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||||
|
|
||||||
|
|
||||||
|
<data>
|
||||||
|
|
||||||
|
<import type="android.view.View" />
|
||||||
|
|
||||||
|
<variable
|
||||||
|
name="setupViewModel"
|
||||||
|
type="im.conversations.android.ui.model.SetupViewModel" />
|
||||||
|
</data>
|
||||||
|
</layout>
|
145
src/main/res/layout/fragment_sign_in.xml
Normal file
145
src/main/res/layout/fragment_sign_in.xml
Normal file
|
@ -0,0 +1,145 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?><!--
|
||||||
|
~ Copyright 2019-2023 Daniel Gultsch
|
||||||
|
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
~ you may not use this file except in compliance with the License.
|
||||||
|
~ You may obtain a copy of the License at
|
||||||
|
~
|
||||||
|
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
~
|
||||||
|
~ Unless required by applicable law or agreed to in writing, software
|
||||||
|
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
~ See the License for the specific language governing permissions and
|
||||||
|
~ limitations under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
|
|
||||||
|
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
|
android:id="@+id/app_bar_layout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:liftOnScroll="false"
|
||||||
|
app:elevation="0dp">
|
||||||
|
|
||||||
|
<com.google.android.material.appbar.MaterialToolbar
|
||||||
|
android:id="@+id/material_toolbar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="?attr/actionBarSize"
|
||||||
|
app:title="@string/app_name"
|
||||||
|
app:menu="@menu/setup"
|
||||||
|
app:titleTextColor="?colorPrimary"
|
||||||
|
app:titleCentered="true" />
|
||||||
|
|
||||||
|
<com.google.android.material.progressindicator.LinearProgressIndicator
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:indeterminate="true"
|
||||||
|
android:visibility="@{setupViewModel.isLoading() ? View.VISIBLE : View.INVISIBLE}" />
|
||||||
|
|
||||||
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
|
<androidx.core.widget.NestedScrollView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:fillViewport="true"
|
||||||
|
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||||
|
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
android:minHeight="@dimen/setup_main_min_height"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="@dimen/setup_screen_padding">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/header"
|
||||||
|
android:textAppearance="?textAppearanceTitleMedium"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:layout_marginTop="@dimen/setup_screen_top_margin"
|
||||||
|
android:text="@string/sign_in" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/instructions"
|
||||||
|
android:textAppearance="?textAppearanceBodyMedium"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_below="@+id/header"
|
||||||
|
android:layout_marginTop="12sp"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:text="@string/sign_in_instruction" />
|
||||||
|
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:layout_marginTop="24sp"
|
||||||
|
android:id="@+id/xmpp_address_input_layout"
|
||||||
|
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
|
||||||
|
android:layout_width="488dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:layout_below="@+id/instructions"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:enabled="@{!setupViewModel.isLoading()}"
|
||||||
|
android:hint="@string/xmpp_address"
|
||||||
|
app:errorText="@{setupViewModel.xmppAddressError}">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/xmpp_address"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:imeOptions="flagNoExtractUi|actionNext"
|
||||||
|
android:inputType="textEmailAddress|textNoSuggestions"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:text="@={setupViewModel.xmppAddress}"
|
||||||
|
app:editorAction="@{()->setupViewModel.submitXmppAddress()}" />
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
style="@style/Widget.Material3.Button.TextButton"
|
||||||
|
android:id="@+id/register"
|
||||||
|
android:layout_marginTop="12sp"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/no_account_register"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:textColor="?colorSecondary"
|
||||||
|
android:enabled="@{!setupViewModel.isLoading()}"
|
||||||
|
android:layout_below="@+id/xmpp_address_input_layout"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/next"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:layout_alignParentBottom="true"
|
||||||
|
android:enabled="@{!setupViewModel.isLoading()}"
|
||||||
|
android:onClick="@{(v) -> setupViewModel.submitXmppAddress()}"
|
||||||
|
android:text="@string/next" />
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
</androidx.core.widget.NestedScrollView>
|
||||||
|
|
||||||
|
|
||||||
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||||
|
|
||||||
|
|
||||||
|
<data>
|
||||||
|
|
||||||
|
<import type="android.view.View" />
|
||||||
|
|
||||||
|
<variable
|
||||||
|
name="setupViewModel"
|
||||||
|
type="im.conversations.android.ui.model.SetupViewModel" />
|
||||||
|
</data>
|
||||||
|
</layout>
|
10
src/main/res/menu/setup.xml
Normal file
10
src/main/res/menu/setup.xml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
|
<item
|
||||||
|
android:id="@+id/account_settings"
|
||||||
|
android:icon="@drawable/ic_settings_24dp"
|
||||||
|
android:title="@string/account_settings"
|
||||||
|
app:showAsAction="ifRoom" />
|
||||||
|
|
||||||
|
</menu>
|
41
src/main/res/navigation/setup_navigation.xml
Normal file
41
src/main/res/navigation/setup_navigation.xml
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?><!--
|
||||||
|
~ Copyright 2019 Daniel Gultsch
|
||||||
|
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
~ you may not use this file except in compliance with the License.
|
||||||
|
~ You may obtain a copy of the License at
|
||||||
|
~
|
||||||
|
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
~
|
||||||
|
~ Unless required by applicable law or agreed to in writing, software
|
||||||
|
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
~ See the License for the specific language governing permissions and
|
||||||
|
~ limitations under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<navigation 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:id="@+id/setup_navigation"
|
||||||
|
app:startDestination="@+id/signIn">
|
||||||
|
|
||||||
|
<action
|
||||||
|
android:id="@+id/enterPassword"
|
||||||
|
app:destination="@+id/password"
|
||||||
|
app:enterAnim="@anim/slide_from_right"
|
||||||
|
app:exitAnim="@anim/slide_to_left"
|
||||||
|
app:popEnterAnim="@anim/slide_from_left"
|
||||||
|
app:popExitAnim="@anim/slide_to_right" />
|
||||||
|
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/signIn"
|
||||||
|
android:name="im.conversations.android.ui.fragment.setup.SignInFragment"
|
||||||
|
tools:layout="@layout/fragment_sign_in" />
|
||||||
|
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/password"
|
||||||
|
android:name="im.conversations.android.ui.fragment.setup.PasswordFragment"
|
||||||
|
tools:layout="@layout/fragment_password" />
|
||||||
|
|
||||||
|
|
||||||
|
</navigation>
|
|
@ -2,4 +2,7 @@
|
||||||
<dimen name="local_video_preview_height">96dp</dimen>
|
<dimen name="local_video_preview_height">96dp</dimen>
|
||||||
<dimen name="local_video_preview_width">128dp</dimen>
|
<dimen name="local_video_preview_width">128dp</dimen>
|
||||||
<dimen name="rtp_session_duration_top_margin">16dp</dimen>
|
<dimen name="rtp_session_duration_top_margin">16dp</dimen>
|
||||||
|
<dimen name="setup_screen_top_margin">8dp</dimen>
|
||||||
|
<dimen name="setup_screen_padding">16dp</dimen>
|
||||||
|
<dimen name="setup_main_min_height">288dp</dimen>
|
||||||
</resources>
|
</resources>
|
|
@ -44,4 +44,7 @@
|
||||||
<dimen name="local_video_preview_height">128dp</dimen>
|
<dimen name="local_video_preview_height">128dp</dimen>
|
||||||
<dimen name="local_video_preview_width">96dp</dimen>
|
<dimen name="local_video_preview_width">96dp</dimen>
|
||||||
<dimen name="rtp_session_duration_top_margin">24dp</dimen>
|
<dimen name="rtp_session_duration_top_margin">24dp</dimen>
|
||||||
|
<dimen name="setup_screen_top_margin">48dp</dimen>
|
||||||
|
<dimen name="setup_main_min_height">336dp</dimen>
|
||||||
|
<dimen name="setup_screen_padding">24dp</dimen>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
19
src/main/res/values/integers.xml
Normal file
19
src/main/res/values/integers.xml
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
~ Copyright 2019 Daniel Gultsch
|
||||||
|
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
~ you may not use this file except in compliance with the License.
|
||||||
|
~ You may obtain a copy of the License at
|
||||||
|
~
|
||||||
|
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
~
|
||||||
|
~ Unless required by applicable law or agreed to in writing, software
|
||||||
|
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
~ See the License for the specific language governing permissions and
|
||||||
|
~ limitations under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<resources>
|
||||||
|
<integer name="slide_animation_duration">300</integer>
|
||||||
|
</resources>
|
|
@ -1005,5 +1005,11 @@
|
||||||
<string name="pref_up_push_server_title">Push Server</string>
|
<string name="pref_up_push_server_title">Push Server</string>
|
||||||
<string name="pref_up_push_server_summary">A user-chosen push server to relay push messages via XMPP to your device.</string>
|
<string name="pref_up_push_server_summary">A user-chosen push server to relay push messages via XMPP to your device.</string>
|
||||||
<string name="no_account_deactivated">None (deactivated)</string>
|
<string name="no_account_deactivated">None (deactivated)</string>
|
||||||
|
<string name="sign_in">Sign in</string>
|
||||||
|
<string name="sign_in_instruction">with your XMPP account.</string>
|
||||||
|
<string name="enter_your_password">Type in your password</string>
|
||||||
|
<string name="welcome">Welcome</string>
|
||||||
|
<string name="no_account_register">No account? Register</string>
|
||||||
|
<string name="account_settings">Account settings</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
|
||||||
|
<style name="Conversations3Theme" parent="Theme.Material3.DayNight.NoActionBar">
|
||||||
|
<item name="android:statusBarColor">@android:color/transparent</item>
|
||||||
|
<item name="android:windowLightStatusBar">?attr/isLightTheme</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
|
||||||
<style name="ConversationsTheme" parent="Theme.AppCompat.Light.NoActionBar">
|
<style name="ConversationsTheme" parent="Theme.AppCompat.Light.NoActionBar">
|
||||||
<item name="colorPrimary">@color/green600</item>
|
<item name="colorPrimary">@color/green600</item>
|
||||||
<item name="colorPrimaryDark">@color/green800</item>
|
<item name="colorPrimaryDark">@color/green800</item>
|
||||||
|
|
Loading…
Reference in a new issue