You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

230 lines
7.5 KiB

package com.community.pocket.ui.login;
import android.app.Activity;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.Looper;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import androidx.annotation.RequiresApi;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModelProvider;
import com.community.pocket.R;
import com.community.pocket.data.model.LocalToken;
import com.community.pocket.data.model.Token;
import com.community.pocket.ui.BaseActivity;
import com.community.pocket.ui.listener.MyTextChange;
import com.community.pocket.ui.main.MainMenu;
import com.community.pocket.ui.main.ui.share.Response;
import com.community.pocket.ui.register.RegisterActivity;
import com.community.pocket.ui.resetpwd.ResetPwdActivity;
import com.community.pocket.util.AppDatabase;
import com.community.pocket.util.HttpJSONResponse;
import com.community.pocket.util.HttpRequest;
import com.community.pocket.util.HttpUtil;
import com.community.pocket.util.PropertiesUtil;
import org.jetbrains.annotations.NotNull;
import org.xutils.view.annotation.ContentView;
import org.xutils.view.annotation.Event;
import org.xutils.view.annotation.ViewInject;
import java.util.List;
import okhttp3.FormBody;
/**
* 登陆
*/
@ContentView(R.layout.activity_login)
public class LoginActivity extends BaseActivity {
private LoginViewModel loginViewModel;
private static AppDatabase sInstance;
//用户名
@ViewInject(R.id.username)
private EditText usernameEditText;
//密码
@ViewInject(R.id.password)
private EditText passwordEditText;
//登录按钮
@ViewInject(R.id.login)
private Button loginButton;
//进度条
@ViewInject(R.id.loading)
private ProgressBar loadingProgressBar;
@ViewInject(R.id.login_layout)
private ConstraintLayout layout;
private MutableLiveData<Boolean> bool = new MutableLiveData<>();
/**
* 保存令牌到数据库并跳转到主界面
*/
private void saveTokenToDB(@NotNull final LoginResponse response) {
new Thread(() -> {
Token token = response.getToken();
sInstance.tokenDao().save(token);
saveToken(response);
}).start();
}
/**
* 保存令牌到缓存
*/
private void saveToken(LoginResponse response) {
Token token = response.getToken();
LocalToken.getInstance(token);
startActivity(new Intent(getBaseContext(), MainMenu.class));
if (Looper.myLooper() == null) {
Looper.prepare();
response.toast(getBaseContext());
Looper.loop();
}
//Complete and destroy login activity once successful
finish();
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
HttpUtil.checkServer(this, bool);
bool.observe(this, aBoolean -> {
if (aBoolean) {
init();
}
});
}
private void init() {
loginViewModel = new ViewModelProvider(this, new ViewModelProvider.NewInstanceFactory()).get(LoginViewModel.class);
//后台检查token
hasOnlyUserToken();
//监听token校验状态
loginViewModel.getCheckToken().observe(this, loginResponse -> {
if (loginResponse.getResult() == Response.Result.OK) {
saveToken(loginResponse);
} else {
layout.setVisibility(View.VISIBLE);
}
});
//监听数据校验状态
loginViewModel.getLoginFormState().observe(this, loginFormState -> {
if (loginFormState == null) {
return;
}
loginButton.setEnabled(loginFormState.isDataValid());
if (loginFormState.getUsernameError() != null) {
usernameEditText.setError(getString(loginFormState.getUsernameError(), PropertiesUtil.getIntValue("username.length")));
}
if (loginFormState.getPasswordError() != null) {
passwordEditText.setError(getString(loginFormState.getPasswordError(), PropertiesUtil.getIntValue("password.length")));
}
});
//监听登陆请求结果
loginViewModel.getLoginResult().observe(this, loginResponse -> {
if (loginResponse == null) {
return;
}
loadingProgressBar.setVisibility(View.GONE);
setResult(Activity.RESULT_OK);
if (loginResponse.getResult() == Response.Result.OK) {
saveTokenToDB(loginResponse);
} else {
loginResponse.toast(getApplicationContext());
}
});
// 监听用户密码文本输入框内容改变
TextWatcher afterTextChangedListener = new MyTextChange() {
@Override
public void afterTextChanged(Editable s) {
loginViewModel.loginDataChanged(usernameEditText.getText().toString(),
passwordEditText.getText().toString());
}
};
//添加监听器到组件
usernameEditText.addTextChangedListener(afterTextChangedListener);
passwordEditText.addTextChangedListener(afterTextChangedListener);
}
/**
* 查询本地是否有且只有一个用户token,如果有则自动登录
*/
public void hasOnlyUserToken() {
new Thread(new Runnable() {
@Override
@HttpRequest("/login/token")
public void run() {
sInstance = AppDatabase.getInstance(getApplicationContext());
List<Token> tokenList = sInstance.tokenDao().queryAll();
if (tokenList != null && tokenList.size() == 1) {
Token currentToken = tokenList.get(0);
HttpUtil.getRequest(HttpUtil.Method.POST, new HttpJSONResponse<>(LoginResponse.class, (call, response, loginResponse) -> loginViewModel.getCheckToken().postValue(loginResponse)),
new FormBody.Builder()
.add("token", currentToken.getToken())
.add("username", currentToken.getUsername())
.build()
);
} else if (tokenList != null && tokenList.size() > 1) {
for (Token token : tokenList) {
sInstance.tokenDao().delete(token);
}
loginViewModel.getCheckToken().postValue(new LoginResponse());
} else {
loginViewModel.getCheckToken().postValue(new LoginResponse());
}
}
}).start();
}
//登录按钮触发登录请求操作
@RequiresApi(api = Build.VERSION_CODES.N)
@Event(value = R.id.login)
private void login(View v) {
//显示登录请求处理进度
loadingProgressBar.setVisibility(View.VISIBLE);
loginViewModel.login(usernameEditText.getText().toString(),
passwordEditText.getText().toString());
}
@Event(value = R.id.register)
private void register(View v) {
startActivity(new Intent(this, RegisterActivity.class));
}
@Event(value = R.id.login_to_resetPwd)
private void resetRwd(View v) {
startActivity(new Intent(this, ResetPwdActivity.class));
}
}