From 8ae896e9d40ba21f66f769dda3e0d3123ad8f348 Mon Sep 17 00:00:00 2001 From: nuclearfog Date: Sun, 22 Jan 2023 15:40:59 +0100 Subject: [PATCH] layout fix, added connectiondialog to login --- .../twidda/ui/activities/LoginActivity.java | 45 +++++--- .../twidda/ui/dialogs/ConnectionDialog.java | 105 +++++++++++++++++- app/src/main/res/layout/dialog_connection.xml | 33 +++++- app/src/main/res/values/dimens.xml | 2 + app/src/main/res/values/strings.xml | 1 + app/src/main/res/values/styles.xml | 2 +- 6 files changed, 168 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/org/nuclearfog/twidda/ui/activities/LoginActivity.java b/app/src/main/java/org/nuclearfog/twidda/ui/activities/LoginActivity.java index 2c07dddd..93176095 100644 --- a/app/src/main/java/org/nuclearfog/twidda/ui/activities/LoginActivity.java +++ b/app/src/main/java/org/nuclearfog/twidda/ui/activities/LoginActivity.java @@ -38,6 +38,8 @@ import org.nuclearfog.twidda.backend.async.LoginAction; import org.nuclearfog.twidda.backend.utils.AppStyles; import org.nuclearfog.twidda.backend.utils.ErrorHandler; import org.nuclearfog.twidda.database.GlobalSettings; +import org.nuclearfog.twidda.ui.dialogs.ConnectionDialog; +import org.nuclearfog.twidda.ui.dialogs.ConnectionDialog.OnConnectionSetCallback; /** * Account Activity of the App @@ -45,7 +47,7 @@ import org.nuclearfog.twidda.database.GlobalSettings; * * @author nuclearfog */ -public class LoginActivity extends AppCompatActivity implements OnClickListener, OnItemSelectedListener { +public class LoginActivity extends AppCompatActivity implements OnClickListener, OnItemSelectedListener, OnConnectionSetCallback { /** * request code to open {@link AccountActivity} @@ -70,6 +72,7 @@ public class LoginActivity extends AppCompatActivity implements OnClickListener, @Nullable private LoginAction loginAsync; private GlobalSettings settings; + private ConnectionDialog connectionDialog; private EditText pinInput; private Spinner hostSelector; @@ -77,9 +80,8 @@ public class LoginActivity extends AppCompatActivity implements OnClickListener, @Nullable private String loginLink; - - private String mastodonHost; - private String apiKey1, apiKey2; + @Nullable + private String hostname, key1, key2; @Override @@ -104,6 +106,7 @@ public class LoginActivity extends AppCompatActivity implements OnClickListener, toolbar.setTitle(R.string.login_info); setSupportActionBar(toolbar); NetworkAdapter adapter = new NetworkAdapter(this); + connectionDialog = new ConnectionDialog(this, this); hostSelector.setAdapter(adapter); hostSelector.setSelection(0); @@ -183,13 +186,13 @@ public class LoginActivity extends AppCompatActivity implements OnClickListener, // generate Twitter login link else if (hostSelector.getSelectedItemId() == NetworkAdapter.ID_TWITTER) { // use user defined token keys - if (apiKey1 != null && apiKey2 != null) { - if (apiKey1.trim().isEmpty() || apiKey2.trim().isEmpty()) { + if (key1 != null && key2 != null) { + if (key1.trim().isEmpty() || key2.trim().isEmpty()) { Toast.makeText(getApplicationContext(), R.string.error_empty_token, LENGTH_SHORT).show(); } else { Toast.makeText(getApplicationContext(), R.string.info_open_twitter_login, LENGTH_LONG).show(); loginAsync = new LoginAction(this, LoginAction.LOGIN_TWITTER, LoginAction.MODE_REQUEST); - loginAsync.execute(apiKey1, apiKey2); + loginAsync.execute(key1, key2); } } // use system tokens @@ -201,12 +204,12 @@ public class LoginActivity extends AppCompatActivity implements OnClickListener, } // generate Mastodon login else if (hostSelector.getSelectedItemId() == NetworkAdapter.ID_MASTODON) { - if (mastodonHost == null || Patterns.WEB_URL.matcher(mastodonHost).matches()){ + if (hostname == null || Patterns.WEB_URL.matcher(hostname).matches()){ Toast.makeText(getApplicationContext(), R.string.info_open_mastodon_login, LENGTH_LONG).show(); loginAsync = new LoginAction(this, LoginAction.LOGIN_MASTODON, LoginAction.MODE_REQUEST); - if (mastodonHost != null) { + if (hostname != null) { // open userdefined url - String link = mastodonHost; + String link = hostname; if (!link.startsWith("https://")) link = "https://" + link; if (link.endsWith("/")) @@ -232,13 +235,13 @@ public class LoginActivity extends AppCompatActivity implements OnClickListener, } // login to Twitter else if (hostSelector.getSelectedItemId() == NetworkAdapter.ID_TWITTER) { - if (apiKey1 != null && apiKey2 != null) { - if (apiKey1.trim().isEmpty() || apiKey2.trim().isEmpty()) { + if (key1 != null && key2 != null) { + if (key1.trim().isEmpty() || key2.trim().isEmpty()) { Toast.makeText(getApplicationContext(), R.string.error_empty_token, LENGTH_SHORT).show(); } else { Toast.makeText(getApplicationContext(), R.string.info_login_to_twitter, LENGTH_LONG).show(); loginAsync = new LoginAction(this, LoginAction.LOGIN_TWITTER, LoginAction.MODE_LOGIN); - loginAsync.execute(loginLink, code, apiKey1, apiKey2); + loginAsync.execute(loginLink, code, key1, key2); } } // use system tokens @@ -255,6 +258,14 @@ public class LoginActivity extends AppCompatActivity implements OnClickListener, loginAsync.execute(loginLink, code); } } + // open API settings dialog + else if (v.getId() == R.id.login_network_settings) { + if (hostSelector.getSelectedItemId() == NetworkAdapter.ID_TWITTER) { + connectionDialog.show(ConnectionDialog.TYPE_TWITTER); + } else if (hostSelector.getSelectedItemId() == NetworkAdapter.ID_MASTODON) { + connectionDialog.show(ConnectionDialog.TYPE_MASTODON); + } + } } @@ -269,6 +280,14 @@ public class LoginActivity extends AppCompatActivity implements OnClickListener, public void onNothingSelected(AdapterView parent) { } + + @Override + public void onConnectionSet(@Nullable String key1, @Nullable String key2, @Nullable String hostname) { + this.hostname = hostname; + this.key1 = key1; + this.key2 = key2; + } + /** * Called when the app is registered successfully */ diff --git a/app/src/main/java/org/nuclearfog/twidda/ui/dialogs/ConnectionDialog.java b/app/src/main/java/org/nuclearfog/twidda/ui/dialogs/ConnectionDialog.java index a323ea76..e1d9620e 100644 --- a/app/src/main/java/org/nuclearfog/twidda/ui/dialogs/ConnectionDialog.java +++ b/app/src/main/java/org/nuclearfog/twidda/ui/dialogs/ConnectionDialog.java @@ -1,19 +1,33 @@ package org.nuclearfog.twidda.ui.dialogs; +import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; +import static android.view.Window.FEATURE_NO_TITLE; + import android.app.Dialog; import android.content.Context; +import android.util.Patterns; import android.view.View; import android.view.View.OnClickListener; +import android.view.ViewGroup; import android.widget.Button; import android.widget.CompoundButton; import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.EditText; import android.widget.TextView; +import androidx.annotation.Nullable; + import com.kyleduo.switchbutton.SwitchButton; import org.nuclearfog.twidda.R; +import org.nuclearfog.twidda.backend.api.twitter.Tokens; +import org.nuclearfog.twidda.backend.utils.AppStyles; +/** + * API connection setup dialog + * + * @author nuclearfog + */ public class ConnectionDialog extends Dialog implements OnCheckedChangeListener, OnClickListener { public static final int TYPE_TWITTER = 1; @@ -23,15 +37,21 @@ public class ConnectionDialog extends Dialog implements OnCheckedChangeListener, private SwitchButton enableApi, enableV2, enableHost; private TextView apiLabel, v2Label, hostLabel; private EditText host, api1, api2; - private Button confirm; private OnConnectionSetCallback callback; private int type; + public ConnectionDialog(Context context, OnConnectionSetCallback callback) { super(context, R.style.ConfirmDialog); this.callback = callback; + requestWindowFeature(FEATURE_NO_TITLE); + setCanceledOnTouchOutside(false); + setCancelable(false); setContentView(R.layout.dialog_connection); + ViewGroup root = findViewById(R.id.dialog_connection_root); + Button confirm = findViewById(R.id.dialog_connection_confirm); + Button discard = findViewById(R.id.dialog_connection_discard); enableApi = findViewById(R.id.dialog_connection_custom_api); enableV2 = findViewById(R.id.dialog_connection_use_v2); enableHost = findViewById(R.id.dialog_connection_custom_host); @@ -41,18 +61,58 @@ public class ConnectionDialog extends Dialog implements OnCheckedChangeListener, host = findViewById(R.id.dialog_connection_hostname); api1 = findViewById(R.id.dialog_connection_api1); api2 = findViewById(R.id.dialog_connection_api2); - confirm = findViewById(R.id.dialog_connection_confirm); + int width = (int)(context.getResources().getDisplayMetrics().widthPixels*0.9); + getWindow().setLayout(width, WRAP_CONTENT); + AppStyles.setTheme(root); enableApi.setOnCheckedChangeListener(this); enableHost.setOnCheckedChangeListener(this); confirm.setOnClickListener(this); + discard.setOnClickListener(this); } @Override public void onClick(View v) { if (v.getId() == R.id.dialog_connection_confirm) { + String api1Text = api1.getText().toString(); + String api2Text = api2.getText().toString(); + String hostText = host.getText().toString(); + switch (type) { + case TYPE_TWITTER: + if (enableApi.isChecked() && !api1Text.trim().isEmpty() && !api2Text.trim().isEmpty()) { + if (enableV2.isChecked()) { + callback.onConnectionSet(api1Text, api2Text, OnConnectionSetCallback.TWITTER_V2); + } else { + callback.onConnectionSet(api1Text, api2Text, OnConnectionSetCallback.TWITTER_V1); + } + dismiss(); + } else if (!enableApi.isChecked()) { + if (!Tokens.DISABLE_API_V2) { + callback.onConnectionSet(null, null, OnConnectionSetCallback.TWITTER_V2); + } else { + callback.onConnectionSet(null, null, OnConnectionSetCallback.TWITTER_V1); + } + dismiss(); + } else { + // todo error message + } + break; + case TYPE_MASTODON: + if (enableHost.isChecked() && Patterns.WEB_URL.matcher(hostText).matches()) { + callback.onConnectionSet(null, null, hostText); + dismiss(); + } else if (!enableHost.isChecked()) { + callback.onConnectionSet(null, null, null); + dismiss(); + } else { + // todo error message + } + break; + } + } else if (v.getId() == R.id.dialog_connection_discard) { + dismiss(); } } @@ -63,9 +123,14 @@ public class ConnectionDialog extends Dialog implements OnCheckedChangeListener, if (isChecked) { enableV2.setVisibility(View.VISIBLE); v2Label.setVisibility(View.VISIBLE); + api1.setVisibility(View.VISIBLE); + api2.setVisibility(View.VISIBLE); } else { + enableV2.setCheckedImmediately(false); enableV2.setVisibility(View.INVISIBLE); v2Label.setVisibility(View.INVISIBLE); + api1.setVisibility(View.INVISIBLE); + api2.setVisibility(View.INVISIBLE); } } else if (buttonView.getId() == R.id.dialog_connection_custom_host) { @@ -80,25 +145,55 @@ public class ConnectionDialog extends Dialog implements OnCheckedChangeListener, @Override public void show() { + // ignore method call, call instead show(int) } public void show(int type) { switch(type) { case TYPE_TWITTER: + enableHost.setCheckedImmediately(false); + enableApi.setVisibility(View.VISIBLE); + apiLabel.setVisibility(View.VISIBLE); + api1.setVisibility(View.INVISIBLE); + api2.setVisibility(View.INVISIBLE); + hostLabel.setVisibility(View.GONE); + enableHost.setVisibility(View.GONE); host.setVisibility(View.GONE); - break; case TYPE_MASTODON: + enableApi.setCheckedImmediately(false); + enableV2.setCheckedImmediately(false); + hostLabel.setVisibility(View.VISIBLE); + enableHost.setVisibility(View.VISIBLE); + host.setVisibility(View.INVISIBLE); + enableApi.setVisibility(View.GONE); + apiLabel.setVisibility(View.GONE); + enableV2.setVisibility(View.GONE); + v2Label.setVisibility(View.GONE); + api1.setVisibility(View.GONE); + api2.setVisibility(View.GONE); break; } + this.type = type; super.show(); } - + /** + * Callback used to set API settings back to activity + */ public interface OnConnectionSetCallback { - void onConnectionSet(String key1, String key2, String hostname); + String TWITTER_V1 = "api-v1"; + + String TWITTER_V2 = "api-v2"; + + /** + * @param key1 first API key + * @param key2 second API key + * @param hostname hostname or type of API {@link #TWITTER_V1,#TWITTER_V2} + */ + void onConnectionSet(@Nullable String key1, @Nullable String key2, @Nullable String hostname); } } \ No newline at end of file diff --git a/app/src/main/res/layout/dialog_connection.xml b/app/src/main/res/layout/dialog_connection.xml index b59806a3..273611a8 100644 --- a/app/src/main/res/layout/dialog_connection.xml +++ b/app/src/main/res/layout/dialog_connection.xml @@ -2,15 +2,16 @@ @@ -22,6 +23,7 @@ android:text="@string/login_key_enable" android:lines="1" android:layout_weight="1" + android:layout_margin="@dimen/dialog_connection_layout_margin" app:layout_constraintStart_toEndOf="@id/dialog_connection_custom_api" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="@id/dialog_connection_custom_api" @@ -31,6 +33,8 @@ android:id="@+id/dialog_connection_use_v2" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:layout_margin="@dimen/dialog_connection_layout_margin" + android:visibility="invisible" app:layout_constraintStart_toEndOf="@id/dialog_connection_custom_api_label" app:layout_constraintTop_toTopOf="parent" app:layout_constraintEnd_toStartOf="@id/dialog_connection_use_v2_label"/> @@ -42,6 +46,8 @@ android:text="@string/login_key_enable_v2" android:lines="1" android:layout_weight="1" + android:layout_margin="@dimen/dialog_connection_layout_margin" + android:visibility="invisible" app:layout_constraintStart_toEndOf="@id/dialog_connection_use_v2" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="@id/dialog_connection_use_v2" @@ -55,6 +61,8 @@ android:hint="@string/settings_key1_hint" android:lines="1" android:layout_weight="1" + android:layout_margin="@dimen/dialog_connection_layout_margin" + android:visibility="invisible" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/dialog_connection_custom_api" app:layout_constraintEnd_toStartOf="@id/dialog_connection_api2"/> @@ -67,6 +75,8 @@ android:hint="@string/settings_key2_hint" android:lines="1" android:layout_weight="1" + android:layout_margin="@dimen/dialog_connection_layout_margin" + android:visibility="invisible" app:layout_constraintStart_toEndOf="@id/dialog_connection_api1" app:layout_constraintTop_toBottomOf="@id/dialog_connection_custom_api" app:layout_constraintEnd_toEndOf="parent"/> @@ -75,6 +85,7 @@ android:id="@+id/dialog_connection_custom_host" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:layout_margin="@dimen/dialog_connection_layout_margin" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/dialog_connection_api1" app:layout_constraintEnd_toStartOf="@id/dialog_connection_custom_host_label"/> @@ -86,6 +97,7 @@ android:text="@string/dialog_connection_custom_host" android:lines="1" android:layout_weight="1" + android:layout_margin="@dimen/dialog_connection_layout_margin" app:layout_constraintStart_toEndOf="@id/dialog_connection_custom_host" app:layout_constraintTop_toTopOf="@id/dialog_connection_custom_host" app:layout_constraintBottom_toBottomOf="@id/dialog_connection_custom_host" @@ -99,6 +111,8 @@ android:hint="@string/settings_mastodon_hint" android:lines="1" android:layout_weight="1" + android:layout_margin="@dimen/dialog_connection_layout_margin" + android:visibility="invisible" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/dialog_connection_custom_host" app:layout_constraintEnd_toEndOf="parent" /> @@ -110,8 +124,25 @@ android:text="@string/dialog_connection_apply" android:lines="1" android:padding="@dimen/dialog_connection_button_padding" + android:layout_margin="@dimen/dialog_connection_layout_margin" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/dialog_connection_hostname" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toStartOf="@id/dialog_connection_discard" + style="@style/FeedbackButton"/> + +