redesign login dialog (use sso by default) / use activity instead of dialog

This commit is contained in:
David Luhmer 2019-04-08 23:05:35 -03:00
parent 1836876cbe
commit ec29ea7aee
12 changed files with 333 additions and 396 deletions

View file

@ -52,6 +52,9 @@
<activity
android:name=".SyncIntervalSelectorActivity"
android:label="@string/title_activity_sync_interval_selector" />
<activity
android:name=".LoginDialogActivity"
android:label="@string/action_sign_in_short" />
<activity
android:name=".NewFeedActivity"
android:label="@string/title_activity_new_feed"
@ -148,12 +151,6 @@
android:resource="@xml/file_provider_paths" />
</provider>
<!--
<activity
android:name=".authentication.AuthenticatorActivity"
android:label="@string/title_activity_settings"
android:launchMode="singleTask" >
-->
<!-- android:theme="@style/Theme.Transparent" > -->
<!-- </activity> -->

View file

@ -21,16 +21,13 @@
package de.luhmer.owncloudnewsreader;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.preference.PreferenceManager;
import androidx.appcompat.app.AlertDialog;
import android.text.Editable;
import android.text.InputType;
import android.text.SpannableString;
@ -39,18 +36,15 @@ import android.text.TextWatcher;
import android.text.method.LinkMovementMethod;
import android.text.util.Linkify;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Switch;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.material.textfield.TextInputLayout;
import com.nextcloud.android.sso.AccountImporter;
@ -67,13 +61,15 @@ import java.net.URL;
import javax.inject.Inject;
import androidx.fragment.app.DialogFragment;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import butterknife.BindView;
import butterknife.ButterKnife;
import de.luhmer.owncloudnewsreader.authentication.AuthenticatorActivity;
import butterknife.OnClick;
import de.luhmer.owncloudnewsreader.database.DatabaseConnectionOrm;
import de.luhmer.owncloudnewsreader.di.ApiProvider;
import de.luhmer.owncloudnewsreader.model.NextcloudNewsVersion;
import de.luhmer.owncloudnewsreader.ssl.MemorizingTrustManager;
import de.luhmer.owncloudnewsreader.ssl.OkHttpSSLClient;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
@ -87,24 +83,24 @@ import static de.luhmer.owncloudnewsreader.Constants.MIN_NEXTCLOUD_FILES_APP_VER
* Activity which displays a login screen to the user, offering registration as
* well.
*/
public class LoginDialogFragment extends DialogFragment {
public class LoginDialogActivity extends AppCompatActivity {
private final String TAG = LoginDialogFragment.class.getCanonicalName();
private final String TAG = LoginDialogActivity.class.getCanonicalName();
public static final int RESULT_LOGIN = 16000;
/**
* Keep track of the login task to ensure we can cancel it if requested.
*/
protected @Inject ApiProvider mApi;
protected @Inject SharedPreferences mPrefs;
protected @Inject MemorizingTrustManager mMemorizingTrustManager;
//private UserLoginTask mAuthTask = null;
private Activity mActivity;
// Values for email and password at the time of the login attempt.
private String mUsername;
private String mPassword;
private String mOc_root_path;
private boolean mCbDisableHostnameVerification;
// UI references.
protected @BindView(R.id.username) EditText mUsernameView;
@ -113,168 +109,90 @@ public class LoginDialogFragment extends DialogFragment {
protected @BindView(R.id.edt_owncloudRootPath) EditText mOc_root_path_View;
protected @BindView(R.id.cb_AllowAllSSLCertificates) CheckBox mCbDisableHostnameVerificationView;
protected @BindView(R.id.imgView_ShowPassword) ImageView mImageViewShowPwd;
protected @BindView(R.id.swSingleSignOn) Switch mSwSingleSignOn;
protected @BindView(R.id.btnSingleSignOn) Button mBtnSingleSignOn;
protected @BindView(R.id.tv_manual_login) TextView mTvManualLogin;
protected @BindView(R.id.old_login_wrapper) RelativeLayout mOldLoginWrapper;
private SingleSignOnAccount importedAccount = null;
private boolean mPasswordVisible = false;
private LoginSuccessfulListener listener;
public interface LoginSuccessfulListener {
void loginSucceeded();
}
public void setActivity(Activity mActivity) {
this.mActivity = mActivity;
}
/**
* @param listener the listener to set
*/
public void setListener(LoginSuccessfulListener listener) {
this.listener = listener;
}
@Override
public void onCreate(Bundle savedInstance) {
super.onCreate(savedInstance);
((NewsReaderApplication) getActivity().getApplication()).getAppComponent().injectFragment(this);
}
((NewsReaderApplication) getApplication()).getAppComponent().injectActivity(this);
setContentView(R.layout.activity_login_dialog);
ButterKnife.bind(this);
public static LoginDialogFragment newInstance() {
LoginDialogFragment loginDialogFragment = new LoginDialogFragment();
Bundle args = new Bundle();
loginDialogFragment.setArguments(args);
return loginDialogFragment;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
//setRetainInstance(true);
// Build the dialog and set up the button click handlers
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
LayoutInflater inflater = getActivity().getLayoutInflater();
View view = inflater.inflate(R.layout.dialog_signin, null);
ButterKnife.bind(this, view);
builder.setView(view);
builder.setTitle(getString(R.string.action_sign_in_short));
builder.setPositiveButton(getString(R.string.action_sign_in_short), null);
// Manual Login
mImageViewShowPwd.setOnClickListener(ImgViewShowPasswordListener);
mPasswordView.addTextChangedListener(PasswordTextChangedListener);
mPasswordView.addTextChangedListener(PasswordTextChangedListener);
mUsername = mPrefs.getString(SettingsActivity.EDT_USERNAME_STRING, "");
mPassword = mPrefs.getString(SettingsActivity.EDT_PASSWORD_STRING, "");
mOc_root_path = mPrefs.getString(SettingsActivity.EDT_OWNCLOUDROOTPATH_STRING, "");
boolean useSSO = mPrefs.getBoolean(SettingsActivity.SW_USE_SINGLE_SIGN_ON, false);
mCbDisableHostnameVerification = mPrefs.getBoolean(SettingsActivity.CB_DISABLE_HOSTNAME_VERIFICATION_STRING, false);
boolean mCbDisableHostnameVerification = mPrefs.getBoolean(SettingsActivity.CB_DISABLE_HOSTNAME_VERIFICATION_STRING, false);
if(!mPassword.isEmpty()) {
if(!mPassword.isEmpty()) {
mImageViewShowPwd.setVisibility(View.GONE);
}
// Set up the login form.
mUsernameView.setText(mUsername);
mPasswordView.setText(mPassword);
mOc_root_path_View.setText(mOc_root_path);
// Set up the login form.
mUsernameView.setText(mUsername);
mPasswordView.setText(mPassword);
mOc_root_path_View.setText(mOc_root_path);
mCbDisableHostnameVerificationView.setChecked(mCbDisableHostnameVerification);
mCbDisableHostnameVerificationView.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mPrefs.edit()
.putBoolean(SettingsActivity.CB_DISABLE_HOSTNAME_VERIFICATION_STRING, isChecked)
.commit();
}
});
if(useSSO) {
mSwSingleSignOn.setChecked(true);
syncUiElementState();
}
mSwSingleSignOn.setOnCheckedChangeListener(new OnCheckedChangeListener() {
mCbDisableHostnameVerificationView.setChecked(mCbDisableHostnameVerification);
mCbDisableHostnameVerificationView.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@SuppressLint("ApplySharedPref")
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(isChecked) {
if (!VersionCheckHelper.verifyMinVersion(getActivity(), MIN_NEXTCLOUD_FILES_APP_VERSION_CODE)) {
mSwSingleSignOn.setChecked(false);
return;
}
}
syncUiElementState();
mUsernameView.setText("");
mPasswordView.setText("");
mOc_root_path_View.setText("");
mCbDisableHostnameVerificationView.setChecked(false);
mPasswordContainerView.setVisibility(View.VISIBLE);
mImageViewShowPwd.setVisibility(View.VISIBLE);
mCbDisableHostnameVerificationView.setVisibility(View.VISIBLE);
if(isChecked) {
try {
AccountImporter.pickNewAccount(LoginDialogFragment.this);
} catch (NextcloudFilesAppNotInstalledException e) {
UiExceptionManager.showDialogForException(getActivity(), e);
}
} else {
importedAccount = null;
}
mPrefs.edit()
.putBoolean(SettingsActivity.CB_DISABLE_HOSTNAME_VERIFICATION_STRING, isChecked)
.commit();
}
});
AlertDialog dialog = builder.create();
// Set dialog to resize when soft keyboard pops up
dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
return dialog;
}
private void syncUiElementState() {
boolean useSSO = mSwSingleSignOn.isChecked();
mUsernameView.setEnabled(!useSSO);
mPasswordView.setEnabled(!useSSO);
mOc_root_path_View.setEnabled(!useSSO);
mCbDisableHostnameVerificationView.setEnabled(!useSSO);
}
@Override
public void onStart() {
super.onStart();
final AlertDialog dialog = (AlertDialog) getDialog();
// Override the onClickListeners, as the default implementation would dismiss the dialog
if (dialog != null) {
Button positiveButton = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
positiveButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(mSwSingleSignOn.isChecked() && importedAccount == null) {
Toast.makeText(getContext(), "Please select account first by disabling and re-enabling sso", Toast.LENGTH_LONG).show();
} else {
attemptLogin();
}
}
});
}
}
@Override
protected void onStart() {
super.onStart();
mMemorizingTrustManager.bindDisplayActivity(this);
}
@Override
public void onCancel(DialogInterface dialog) {
super.onCancel(dialog);
if(mActivity instanceof AuthenticatorActivity)
mActivity.finish();
}
@Override
protected void onStop() {
mMemorizingTrustManager.unbindDisplayActivity(this);
super.onStop();
}
@OnClick(R.id.btnSingleSignOn)
public void startSingleSignOn() {
if (!VersionCheckHelper.verifyMinVersion(LoginDialogActivity.this, MIN_NEXTCLOUD_FILES_APP_VERSION_CODE)) {
// Dialog will be shown automatically
return;
}
mOldLoginWrapper.setVisibility(View.GONE);
try {
AccountImporter.pickNewAccount(LoginDialogActivity.this);
} catch (NextcloudFilesAppNotInstalledException e) {
UiExceptionManager.showDialogForException(LoginDialogActivity.this, e);
}
}
@OnClick(R.id.btnLogin)
public void startManualLogin() {
attemptLogin();
}
@OnClick(R.id.tv_manual_login)
public void manualLogin() {
mOldLoginWrapper.setVisibility(View.VISIBLE);
}
private TextWatcher PasswordTextChangedListener = new TextWatcher() {
@Override
@ -308,12 +226,40 @@ public class LoginDialogFragment extends DialogFragment {
}
};
private ProgressDialog BuildPendingDialogWhileLoggingIn()
{
ProgressDialog pDialog = new ProgressDialog(getActivity());
private ProgressDialog BuildPendingDialogWhileLoggingIn() {
ProgressDialog pDialog = new ProgressDialog(this);
pDialog.setTitle(getString(R.string.login_progress_signing_in));
return pDialog;
}
}
private void loginSingleSignOn() {
final ProgressDialog dialogLogin = BuildPendingDialogWhileLoggingIn();
dialogLogin.show();
Editor editor = mPrefs.edit();
editor.putString(SettingsActivity.EDT_OWNCLOUDROOTPATH_STRING, importedAccount.url);
editor.putString(SettingsActivity.EDT_PASSWORD_STRING, importedAccount.token);
editor.putString(SettingsActivity.EDT_USERNAME_STRING, importedAccount.username);
editor.putBoolean(SettingsActivity.SW_USE_SINGLE_SIGN_ON, true);
editor.commit();
SingleAccountHelper.setCurrentAccount(this, importedAccount.name);
mApi.initApi(new NextcloudAPI.ApiConnectedListener() {
@Override
public void onConnected() {
Log.d(TAG, "onConnected() called");
finishLogin(dialogLogin);
}
@Override
public void onError(Exception ex) {
dialogLogin.dismiss();
Log.d(TAG, "onError() called with: ex = [" + ex + "]");
ShowAlertDialog(getString(R.string.login_dialog_title_error), ex.getMessage(), LoginDialogActivity.this);
}
});
}
/**
* Attempts to sign in or register the account specified by the login form.
@ -321,15 +267,17 @@ public class LoginDialogFragment extends DialogFragment {
* errors are presented and no actual login attempt is made.
*/
public void attemptLogin() {
//if (mAuthTask != null) {
// return;
//}
// Reset errors.
mUsernameView.setError(null);
mPasswordView.setError(null);
mOc_root_path_View.setError(null);
// Append "https://" is url doesn't contain it already
mOc_root_path = mOc_root_path_View.getText().toString().trim();
if(!mOc_root_path.startsWith("http")) {
mOc_root_path_View.setText("https://" + mOc_root_path);
}
// Store values at the time of the login attempt.
mUsername = mUsernameView.getText().toString().trim();
mPassword = mPasswordView.getText().toString();
@ -338,36 +286,33 @@ public class LoginDialogFragment extends DialogFragment {
boolean cancel = false;
View focusView = null;
// Only run checks if we don't use sso
if(!mSwSingleSignOn.isChecked()) {
// Check for a valid password.
if (TextUtils.isEmpty(mPassword)) {
mPasswordView.setError(getString(R.string.error_field_required));
focusView = mPasswordView;
cancel = true;
}
// Check for a valid email address.
if (TextUtils.isEmpty(mUsername)) {
mUsernameView.setError(getString(R.string.error_field_required));
focusView = mUsernameView;
cancel = true;
}
// Check for a valid password.
if (TextUtils.isEmpty(mPassword)) {
mPasswordView.setError(getString(R.string.error_field_required));
focusView = mPasswordView;
cancel = true;
}
// Check for a valid email address.
if (TextUtils.isEmpty(mUsername)) {
mUsernameView.setError(getString(R.string.error_field_required));
focusView = mUsernameView;
cancel = true;
}
if (TextUtils.isEmpty(mOc_root_path)) {
mOc_root_path_View.setError(getString(R.string.error_field_required));
if (TextUtils.isEmpty(mOc_root_path)) {
mOc_root_path_View.setError(getString(R.string.error_field_required));
focusView = mOc_root_path_View;
cancel = true;
} else {
try {
URL url = new URL(mOc_root_path);
if (!url.getProtocol().equals("https"))
ShowAlertDialog(getString(R.string.login_dialog_title_security_warning),
getString(R.string.login_dialog_text_security_warning), this);
} catch (MalformedURLException e) {
mOc_root_path_View.setError(getString(R.string.error_invalid_url));
focusView = mOc_root_path_View;
cancel = true;
} else {
try {
URL url = new URL(mOc_root_path);
if (!url.getProtocol().equals("https"))
ShowAlertDialog(getString(R.string.login_dialog_title_security_warning),
getString(R.string.login_dialog_text_security_warning), getActivity());
} catch (MalformedURLException e) {
mOc_root_path_View.setError(getString(R.string.error_invalid_url));
focusView = mOc_root_path_View;
cancel = true;
}
}
}
@ -380,18 +325,13 @@ public class LoginDialogFragment extends DialogFragment {
editor.putString(SettingsActivity.EDT_OWNCLOUDROOTPATH_STRING, mOc_root_path);
editor.putString(SettingsActivity.EDT_PASSWORD_STRING, mPassword);
editor.putString(SettingsActivity.EDT_USERNAME_STRING, mUsername);
editor.putBoolean(SettingsActivity.SW_USE_SINGLE_SIGN_ON, importedAccount != null);
editor.putBoolean(SettingsActivity.SW_USE_SINGLE_SIGN_ON, false);
editor.commit();
final ProgressDialog dialogLogin = BuildPendingDialogWhileLoggingIn();
dialogLogin.show();
if(mSwSingleSignOn.isChecked()) {
SingleAccountHelper.setCurrentAccount(getActivity(), importedAccount.name);
}
mApi.initApi(new NextcloudAPI.ApiConnectedListener() {
mApi.initApi(new NextcloudAPI.ApiConnectedListener() {
@Override
public void onConnected() {
Log.d(TAG, "onConnected() called");
@ -402,7 +342,7 @@ public class LoginDialogFragment extends DialogFragment {
public void onError(Exception ex) {
dialogLogin.dismiss();
Log.d(TAG, "onError() called with: ex = [" + ex + "]");
ShowAlertDialog(getString(R.string.login_dialog_title_error), ex.getMessage(), getActivity());
ShowAlertDialog(getString(R.string.login_dialog_title_error), ex.getMessage(), LoginDialogActivity.this);
}
});
}
@ -428,7 +368,7 @@ public class LoginDialogFragment extends DialogFragment {
mPrefs.edit().putString(Constants.NEWS_WEB_VERSION_NUMBER_STRING, version.version).apply();
if(version.version.equals("0")) {
ShowAlertDialog(getString(R.string.login_dialog_title_error), getString(R.string.login_dialog_text_zero_version_code), getActivity());
ShowAlertDialog(getString(R.string.login_dialog_title_error), getString(R.string.login_dialog_text_zero_version_code), LoginDialogActivity.this);
loginSuccessful = false;
}
@ -447,9 +387,9 @@ public class LoginDialogFragment extends DialogFragment {
getString(R.string.login_dialog_title_error),
getString(R.string.login_dialog_text_news_app_not_installed_on_server,
"https://github.com/nextcloud/news/blob/master/docs/install.md#installing-from-the-app-store"),
getActivity());
LoginDialogActivity.this);
} else {
ShowAlertDialog(getString(R.string.login_dialog_title_error), t.getMessage(), getActivity());
ShowAlertDialog(getString(R.string.login_dialog_title_error), t.getMessage(), LoginDialogActivity.this);
}
}
@ -461,13 +401,13 @@ public class LoginDialogFragment extends DialogFragment {
if(loginSuccessful) {
//Reset Database
DatabaseConnectionOrm dbConn = new DatabaseConnectionOrm(getActivity());
DatabaseConnectionOrm dbConn = new DatabaseConnectionOrm(LoginDialogActivity.this);
dbConn.resetDatabase();
listener.loginSucceeded();
LoginDialogFragment.this.getDialog().cancel();
if(mActivity instanceof AuthenticatorActivity)
mActivity.finish();
Intent returnIntent = new Intent();
setResult(RESULT_OK, returnIntent);
finish();
}
}
});
@ -494,20 +434,11 @@ public class LoginDialogFragment extends DialogFragment {
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
AccountImporter.onActivityResult(requestCode, resultCode, data, LoginDialogFragment.this, new AccountImporter.IAccountAccessGranted() {
AccountImporter.onActivityResult(requestCode, resultCode, data, LoginDialogActivity.this, new AccountImporter.IAccountAccessGranted() {
@Override
public void accountAccessGranted(SingleSignOnAccount account) {
mUsernameView.setText(account.username);
mPasswordView.setText("");
mOc_root_path_View.setText(account.url);
mPasswordContainerView.setVisibility(View.GONE);
mImageViewShowPwd.setVisibility(View.GONE);
mCbDisableHostnameVerificationView.setVisibility(View.GONE);
LoginDialogFragment.this.importedAccount = account;
attemptLogin();
LoginDialogActivity.this.importedAccount = account;
loginSingleSignOn();
}
});
}

View file

@ -80,7 +80,6 @@ import androidx.customview.widget.ViewDragHelper;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import androidx.preference.PreferenceManager;
@ -88,7 +87,6 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import butterknife.BindView;
import butterknife.ButterKnife;
import de.luhmer.owncloudnewsreader.ListView.SubscriptionExpandableListAdapter;
import de.luhmer.owncloudnewsreader.LoginDialogFragment.LoginSuccessfulListener;
import de.luhmer.owncloudnewsreader.adapter.NewsListRecyclerAdapter;
import de.luhmer.owncloudnewsreader.adapter.RecyclerItemClickListener;
import de.luhmer.owncloudnewsreader.adapter.ViewHolder;
@ -117,7 +115,8 @@ import io.reactivex.subjects.PublishSubject;
import uk.co.deanwild.materialshowcaseview.MaterialShowcaseSequence;
import uk.co.deanwild.materialshowcaseview.ShowcaseConfig;
import static de.luhmer.owncloudnewsreader.LoginDialogFragment.ShowAlertDialog;
import static de.luhmer.owncloudnewsreader.LoginDialogActivity.RESULT_LOGIN;
import static de.luhmer.owncloudnewsreader.LoginDialogActivity.ShowAlertDialog;
/**
* An activity representing a list of NewsReader. This activity has different
@ -189,7 +188,7 @@ public class NewsReaderListActivity extends PodcastFragmentActivity implements
//Init config --> if nothing is configured start the login dialog.
if (mPrefs.getString(SettingsActivity.EDT_OWNCLOUDROOTPATH_STRING, null) == null) {
StartLoginFragment(NewsReaderListActivity.this);
StartLoginActivity();
}
@ -446,7 +445,7 @@ public class NewsReaderListActivity extends PodcastFragmentActivity implements
UiExceptionManager.showDialogForException(this, e);
} catch (NextcloudFilesAppAccountPermissionNotGrantedException e) {
// Unable to reauthenticate account just like that..
StartLoginFragment(this);
StartLoginActivity();
}
//StartLoginFragment(this);
@ -651,7 +650,7 @@ public class NewsReaderListActivity extends PodcastFragmentActivity implements
public void startSync()
{
if(mPrefs.getString(SettingsActivity.EDT_OWNCLOUDROOTPATH_STRING, null) == null) {
StartLoginFragment(this);
StartLoginActivity();
} else {
if (!OwnCloudSyncService.isSyncRunning()) {
mPostDelayHandler.stopRunningPostDelayHandler(); //Stop pending sync handler
@ -775,7 +774,7 @@ public class NewsReaderListActivity extends PodcastFragmentActivity implements
break;
case R.id.action_login:
StartLoginFragment(NewsReaderListActivity.this);
StartLoginActivity();
break;
case R.id.action_add_new_feed:
@ -783,7 +782,7 @@ public class NewsReaderListActivity extends PodcastFragmentActivity implements
Intent newFeedIntent = new Intent(this, NewFeedActivity.class);
startActivityForResult(newFeedIntent, RESULT_ADD_NEW_FEED);
} else {
StartLoginFragment(NewsReaderListActivity.this);
StartLoginActivity();
}
break;
@ -949,8 +948,11 @@ public class NewsReaderListActivity extends PodcastFragmentActivity implements
startSync();
}
}
} else if(requestCode == RESULT_LOGIN) {
resetUiAndStartSync();
}
AccountImporter.onActivityResult(requestCode, resultCode, data, this, new AccountImporter.IAccountAccessGranted() {
@Override
public void accountAccessGranted(SingleSignOnAccount account) {
@ -1005,16 +1007,9 @@ public class NewsReaderListActivity extends PodcastFragmentActivity implements
return (NewsReaderDetailFragment) getSupportFragmentManager().findFragmentById(R.id.content_frame);
}
public static void StartLoginFragment(final FragmentActivity activity) {
LoginDialogFragment dialog = LoginDialogFragment.newInstance();
dialog.setActivity(activity);
dialog.setListener(new LoginSuccessfulListener() {
@Override
public void loginSucceeded() {
((NewsReaderListActivity) activity).resetUiAndStartSync();
}
});
dialog.show(activity.getSupportFragmentManager(), "NoticeDialogFragment");
public void StartLoginActivity() {
Intent loginIntent = new Intent(this, LoginDialogActivity.class);
startActivityForResult(loginIntent, RESULT_LOGIN);
}
private void resetUiAndStartSync() {

View file

@ -1,30 +0,0 @@
package de.luhmer.owncloudnewsreader.authentication;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import de.luhmer.owncloudnewsreader.NewsReaderListActivity;
import de.luhmer.owncloudnewsreader.R;
public class AuthenticatorActivity extends AppCompatActivity {
public final static String ARG_ACCOUNT_TYPE = "ACCOUNT_TYPE";
public final static String ARG_AUTH_TYPE = "AUTH_TYPE";
public final static String ARG_ACCOUNT_NAME = "ACCOUNT_NAME";
public final static String ARG_IS_ADDING_NEW_ACCOUNT = "IS_ADDING_ACCOUNT";
public static final String KEY_ERROR_MESSAGE = "ERR_MSG";
public final static String PARAM_USER_PASS = "USER_PASS";
/**
* Called when the activity is first created.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_authenticator);
NewsReaderListActivity.StartLoginFragment(this);
}
}

View file

@ -11,6 +11,8 @@ import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import de.luhmer.owncloudnewsreader.LoginDialogActivity;
import static android.accounts.AccountManager.KEY_BOOLEAN_RESULT;
public class OwnCloudAccountAuthenticator extends AbstractAccountAuthenticator {
@ -29,10 +31,10 @@ public class OwnCloudAccountAuthenticator extends AbstractAccountAuthenticator {
public Bundle addAccount(AccountAuthenticatorResponse response, String accountType, String authTokenType, String[] requiredFeatures, Bundle options) throws NetworkErrorException {
Log.d("udinic", TAG + "> addAccount");
final Intent intent = new Intent(mContext, AuthenticatorActivity.class);
intent.putExtra(AuthenticatorActivity.ARG_ACCOUNT_TYPE, accountType);
intent.putExtra(AuthenticatorActivity.ARG_AUTH_TYPE, authTokenType);
intent.putExtra(AuthenticatorActivity.ARG_IS_ADDING_NEW_ACCOUNT, true);
final Intent intent = new Intent(mContext, LoginDialogActivity.class);
//intent.putExtra(AuthenticatorActivity.ARG_ACCOUNT_TYPE, accountType);
//intent.putExtra(AuthenticatorActivity.ARG_AUTH_TYPE, authTokenType);
//intent.putExtra(AuthenticatorActivity.ARG_IS_ADDING_NEW_ACCOUNT, true);
intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response);
final Bundle bundle = new Bundle();
@ -94,10 +96,10 @@ public class OwnCloudAccountAuthenticator extends AbstractAccountAuthenticator {
// If we get here, then we couldn't access the user's password - so we
// need to re-prompt them for their credentials. We do that by creating
// an intent to display our AuthenticatorActivity.
final Intent intent = new Intent(mContext, AuthenticatorActivity.class);
final Intent intent = new Intent(mContext, LoginDialogActivity.class);
intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response);
intent.putExtra(AuthenticatorActivity.ARG_ACCOUNT_TYPE, account.type);
intent.putExtra(AuthenticatorActivity.ARG_AUTH_TYPE, authTokenType);
//intent.putExtra(AuthenticatorActivity.ARG_ACCOUNT_TYPE, account.type);
//intent.putExtra(AuthenticatorActivity.ARG_AUTH_TYPE, authTokenType);
final Bundle bundle = new Bundle();
bundle.putParcelable(AccountManager.KEY_INTENT, intent);
return bundle;

View file

@ -3,7 +3,7 @@ package de.luhmer.owncloudnewsreader.di;
import javax.inject.Singleton;
import dagger.Component;
import de.luhmer.owncloudnewsreader.LoginDialogFragment;
import de.luhmer.owncloudnewsreader.LoginDialogActivity;
import de.luhmer.owncloudnewsreader.NewFeedActivity;
import de.luhmer.owncloudnewsreader.NewsDetailFragment;
import de.luhmer.owncloudnewsreader.NewsReaderDetailFragment;
@ -31,10 +31,10 @@ public interface AppComponent {
void injectActivity(NewFeedActivity activity);
void injectActivity(SettingsActivity activity);
void injectActivity(SyncIntervalSelectorActivity activity);
void injectActivity(LoginDialogActivity activity);
void injectFragment(NewsReaderListDialogFragment fragment);
void injectFragment(NewsReaderListFragment fragment);
void injectFragment(LoginDialogFragment fragment);
void injectFragment(SettingsFragment fragment);
void injectFragment(NewsDetailFragment fragment);
void injectFragment(NewsReaderDetailFragment fragment);

View file

@ -41,7 +41,6 @@ import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import androidx.core.app.NotificationCompat;
import android.util.Log;
import android.util.SparseArray;
@ -62,6 +61,7 @@ import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import androidx.core.app.NotificationCompat;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.FragmentActivity;
import de.luhmer.owncloudnewsreader.R;

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
<solid android:color="@color/material_grey_100"/>
<corners android:radius="32dp"/>
</shape>

View file

@ -1,14 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<FrameLayout
android:id="@+id/authenticator_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
</FrameLayout>
</LinearLayout>

View file

@ -0,0 +1,156 @@
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/login_form"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/nextcloudBlue">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/abc_dialog_padding_material"
android:layout_marginRight="@dimen/abc_dialog_padding_material"
android:layout_marginTop="@dimen/abc_dialog_padding_material"
android:layout_marginBottom="@dimen/abc_dialog_padding_material"
android:orientation="vertical"
android:layout_gravity="center">
<ImageView
android:id="@+id/img_nextcloud_logo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@drawable/nextcloud_logo"/>
<Button
android:id="@+id/btnSingleSignOn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:layout_marginStart="4dp"
android:background="@drawable/rounded_button"
android:textColor="@android:color/black"
android:text="Login using Nextcloud Files App" />
<TextView
android:id="@+id/tv_manual_login"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginBottom="16dp"
android:gravity="center"
android:textColor="@color/material_grey_100"
android:text="Manual login"/>
<RelativeLayout
android:id="@+id/old_login_wrapper"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone">
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/username_container"
android:layout_marginTop="8dp"
app:counterOverflowTextColor="@android:color/white">
<EditText
android:id="@+id/username"
android:gravity="start"
android:textAlignment="viewStart"
android:inputType="textEmailAddress"
android:hint="@string/pref_title_username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/material_grey_100"
android:textColorHint="@android:color/white" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/username_container"
android:layout_alignParentStart="true"
android:id="@+id/password_container"
app:counterOverflowTextColor="@android:color/white">
<EditText
android:id="@+id/password"
android:gravity="start"
android:textAlignment="viewStart"
android:hint="@string/pref_title_password"
android:inputType="textPassword"
android:maxLines="1"
android:singleLine="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/material_grey_100"
android:textColorHint="@android:color/white"/>
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/url_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/password_container"
android:layout_alignParentStart="true"
app:counterOverflowTextColor="@android:color/white">
<EditText
android:id="@+id/edt_owncloudRootPath"
android:gravity="start"
android:textAlignment="viewStart"
android:hint="@string/pref_title_owncloudRootPath"
android:inputType="textUri"
android:maxLines="1"
android:selectAllOnFocus="true"
android:singleLine="true"
android:title="@string/pref_default_owncloudRootPath"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/material_grey_100"
android:textColorHint="@android:color/white"/>
</com.google.android.material.textfield.TextInputLayout>
<ImageView
android:id="@+id/imgView_ShowPassword"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:src="@drawable/ic_action_visibility"
android:layout_alignTop="@+id/password_container"
android:layout_alignBottom="@+id/password_container"
android:layout_alignEnd="@+id/password_container"
android:contentDescription="@string/content_desc_show_password"/>
<androidx.appcompat.widget.AppCompatCheckBox
android:id="@+id/cb_AllowAllSSLCertificates"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/pref_title_DisableHostnameVerification"
android:layout_below="@+id/url_container"
android:textColor="@color/material_grey_100"
app:buttonTint="@color/material_grey_300"/>
<Button
android:id="@+id/btnLogin"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginStart="4dp"
android:background="@drawable/rounded_button"
android:textColor="@android:color/black"
android:layout_below="@id/cb_AllowAllSSLCertificates"
android:text="@string/action_sign_in_short" />
</RelativeLayout>
</LinearLayout>
</ScrollView>

View file

@ -1,105 +0,0 @@
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/login_form"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="@dimen/abc_dialog_padding_material"
android:paddingRight="@dimen/abc_dialog_padding_material"
android:paddingTop="@dimen/abc_dialog_padding_material">
<Switch
android:id="@+id/swSingleSignOn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:text="Use single sign on" />
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/username_container"
android:layout_marginTop="8dp"
android:layout_below="@id/swSingleSignOn">
<EditText
android:id="@+id/username"
android:gravity="start"
android:textAlignment="viewStart"
android:inputType="textEmailAddress"
android:hint="@string/pref_title_username"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/username_container"
android:layout_alignParentStart="true"
android:id="@+id/password_container">
<EditText
android:id="@+id/password"
android:gravity="start"
android:textAlignment="viewStart"
android:hint="@string/pref_title_password"
android:inputType="textPassword"
android:maxLines="1"
android:singleLine="true"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/url_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/password_container"
android:layout_alignParentStart="true">
<EditText
android:id="@+id/edt_owncloudRootPath"
android:gravity="start"
android:textAlignment="viewStart"
android:hint="@string/pref_title_owncloudRootPath"
android:inputType="textUri"
android:maxLines="1"
android:selectAllOnFocus="true"
android:singleLine="true"
android:title="@string/pref_default_owncloudRootPath"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</com.google.android.material.textfield.TextInputLayout>
<ImageView
android:id="@+id/imgView_ShowPassword"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:src="@drawable/ic_action_visibility"
android:layout_alignTop="@+id/password_container"
android:layout_alignBottom="@+id/password_container"
android:layout_alignEnd="@+id/password_container"
android:contentDescription="@string/content_desc_show_password"/>
<CheckBox
android:id="@+id/cb_AllowAllSSLCertificates"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/pref_title_DisableHostnameVerification"
android:layout_below="@+id/url_container" />
</RelativeLayout>
</ScrollView>