add stub hostname fragment

This commit is contained in:
Daniel Gultsch 2023-02-25 15:13:47 +01:00
parent cf5910e96e
commit 99c11fba17
No known key found for this signature in database
GPG key ID: F43D18AD2A0982C2
7 changed files with 252 additions and 3 deletions

View file

@ -41,6 +41,9 @@ public class SetupActivity extends BaseActivity {
case ENTER_PASSWORD: case ENTER_PASSWORD:
navController.navigate(SetupNavigationDirections.enterPassword()); navController.navigate(SetupNavigationDirections.enterPassword());
break; break;
case ENTER_HOSTNAME:
navController.navigate(SetupNavigationDirections.enterHostname());
break;
case DONE: case DONE:
startActivity(new Intent(this, MainActivity.class)); startActivity(new Intent(this, MainActivity.class));
finish(); finish();

View file

@ -1,3 +1,24 @@
package im.conversations.android.ui.fragment.setup; package im.conversations.android.ui.fragment.setup;
public class HostnameFragment extends AbstractSetupFragment {} 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 im.conversations.android.R;
import im.conversations.android.databinding.FragmentHostnameBinding;
public class HostnameFragment extends AbstractSetupFragment {
@Override
public View onCreateView(
@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
FragmentHostnameBinding binding =
DataBindingUtil.inflate(inflater, R.layout.fragment_hostname, container, false);
binding.setSetupViewModel(setupViewModel);
binding.setLifecycleOwner(getViewLifecycleOwner());
return binding.getRoot();
}
}

View file

@ -34,6 +34,9 @@ public class SetupViewModel extends AndroidViewModel {
private final MutableLiveData<String> xmppAddressError = new MutableLiveData<>(); private final MutableLiveData<String> xmppAddressError = new MutableLiveData<>();
private final MutableLiveData<String> password = new MutableLiveData<>(); private final MutableLiveData<String> password = new MutableLiveData<>();
private final MutableLiveData<String> passwordError = new MutableLiveData<>(); private final MutableLiveData<String> passwordError = new MutableLiveData<>();
private final MutableLiveData<String> hostname = new MutableLiveData<>();
private final MutableLiveData<String> port = new MutableLiveData<>();
private final MutableLiveData<Boolean> opportunisticTls = new MutableLiveData<>();
private final MutableLiveData<Boolean> loading = new MutableLiveData<>(false); private final MutableLiveData<Boolean> loading = new MutableLiveData<>(false);
private final MutableLiveData<Event<Target>> redirection = new MutableLiveData<>(); private final MutableLiveData<Event<Target>> redirection = new MutableLiveData<>();
@ -69,6 +72,18 @@ public class SetupViewModel extends AndroidViewModel {
return password; return password;
} }
public MutableLiveData<String> getHostname() {
return hostname;
}
public MutableLiveData<String> getPort() {
return port;
}
public MutableLiveData<Boolean> getOpportunisticTls() {
return this.opportunisticTls;
}
public LiveData<String> getPasswordError() { public LiveData<String> getPasswordError() {
return Transformations.distinctUntilChanged(this.passwordError); return Transformations.distinctUntilChanged(this.passwordError);
} }
@ -210,6 +225,16 @@ public class SetupViewModel extends AndroidViewModel {
return true; return true;
} }
public boolean submitHostname() {
final var account = this.account;
if (account == null) {
this.redirectIfNecessary(Target.ENTER_HOSTNAME, Target.ENTER_ADDRESS);
return true;
}
return true;
}
public boolean submitPassword() { public boolean submitPassword() {
final var account = this.account; final var account = this.account;
if (account == null) { if (account == null) {

View file

@ -0,0 +1,182 @@
<?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:elevation="0dp"
app:liftOnScroll="false">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/material_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:menu="@menu/activity_setup"
app:title="@string/app_name"
app:titleCentered="true"
app:titleTextColor="?colorPrimary" />
<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:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="@dimen/setup_screen_top_margin"
android:text="@string/info_required"
android:textAppearance="?textAppearanceTitleMedium" />
<TextView
android:id="@+id/xmpp_address"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/header"
android:layout_centerHorizontal="true"
android:layout_marginTop="12sp"
android:drawablePadding="8sp"
android:text="@{setupViewModel.xmppAddress}"
android:textAppearance="?textAppearanceBodyMedium"
app:drawableStartCompat="@drawable/ic_account_circle_24dp"
tools:text="username@exmample.com" />
<LinearLayout
android:layout_width="496dp"
android:layout_height="wrap_content"
android:layout_below="@+id/xmpp_address"
android:layout_centerHorizontal="true"
android:layout_gravity="center_horizontal"
android:layout_marginTop="24sp"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/hostname_input_layout"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="4dp"
android:layout_weight="3"
android:enabled="@{!setupViewModel.isLoading()}"
android:hint="@string/account_settings_hostname"
app:errorText="@{setupViewModel.xmppAddressError}">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/hostname"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:imeOptions="flagNoExtractUi|actionNext"
android:inputType="text|textNoSuggestions"
android:maxLines="1"
android:text="@={setupViewModel.hostname}"
app:editorAction="@{()->setupViewModel.submitHostname()}" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/port_input_layout"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="4dp"
android:layout_weight="1"
android:enabled="@{!setupViewModel.isLoading()}"
android:hint="@string/account_settings_port"
app:errorText="@{setupViewModel.xmppAddressError}">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/port"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:imeOptions="flagNoExtractUi|actionNext"
android:inputType="number"
android:maxLines="1"
android:text="@={setupViewModel.port}"
app:editorAction="@{()->setupViewModel.submitHostname()}" />
</com.google.android.material.textfield.TextInputLayout>
</LinearLayout>
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="4dp"
android:layout_marginVertical="8sp"
android:checked="@={setupViewModel.opportunisticTls}"
android:enabled="@{!setupViewModel.isLoading()}"
android:text="@string/use_opportunistic_tls"
tools:checked="true" />
</LinearLayout>
<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.submitHostname()}"
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>

View file

@ -25,13 +25,29 @@
app:enterAnim="@anim/slide_from_right" app:enterAnim="@anim/slide_from_right"
app:exitAnim="@anim/slide_to_left" app:exitAnim="@anim/slide_to_left"
app:popEnterAnim="@anim/slide_from_left" app:popEnterAnim="@anim/slide_from_left"
app:popExitAnim="@anim/slide_to_right" /> app:popExitAnim="@anim/slide_to_right"
app:popUpTo="@+id/hostname" />
<action
android:id="@+id/enterHostname"
app:destination="@+id/hostname"
app:enterAnim="@anim/slide_from_right"
app:exitAnim="@anim/slide_to_left"
app:popEnterAnim="@anim/slide_from_left"
app:popExitAnim="@anim/slide_to_right"
app:popUpTo="@+id/signIn" />
<fragment <fragment
android:id="@+id/signIn" android:id="@+id/signIn"
android:name="im.conversations.android.ui.fragment.setup.SignInFragment" android:name="im.conversations.android.ui.fragment.setup.SignInFragment"
tools:layout="@layout/fragment_sign_in" /> tools:layout="@layout/fragment_sign_in" />
<fragment
android:id="@+id/hostname"
android:name="im.conversations.android.ui.fragment.setup.HostnameFragment"
tools:layout="@layout/fragment_hostname" />
<fragment <fragment
android:id="@+id/password" android:id="@+id/password"
android:name="im.conversations.android.ui.fragment.setup.PasswordFragment" android:name="im.conversations.android.ui.fragment.setup.PasswordFragment"

View file

@ -1038,5 +1038,7 @@
<string name="pref_automatic_download">Automatic download</string> <string name="pref_automatic_download">Automatic download</string>
<string name="pref_category_sending">Sending</string> <string name="pref_category_sending">Sending</string>
<string name="pref_category_receiving">Receiving</string> <string name="pref_category_receiving">Receiving</string>
<string name="use_opportunistic_tls">Opportunistic TLS (STARTTLS)</string>
<string name="info_required">Info required</string>
</resources> </resources>