Merge pull request '仮置きログイン, 登録画面実装' (#145) from feature/auth_activity into main

Reviewed-on: #145
This commit is contained in:
Fujimatsu 2024-07-07 15:23:10 +00:00
commit edfc33b653
9 changed files with 237 additions and 75 deletions

View File

@ -3,20 +3,7 @@
<component name="deploymentTargetDropDown"> <component name="deploymentTargetDropDown">
<value> <value>
<entry key="app"> <entry key="app">
<State> <State />
<runningDeviceTargetSelectedWithDropDown>
<Target>
<type value="RUNNING_DEVICE_TARGET" />
<deviceKey>
<Key>
<type value="SERIAL_NUMBER" />
<value value="adb-ZY22H7V3G7-Y7s4Km._adb-tls-connect._tcp" />
</Key>
</deviceKey>
</Target>
</runningDeviceTargetSelectedWithDropDown>
<timeTargetWasSelectedWithDropDown value="2024-07-07T11:33:14.803530838Z" />
</State>
</entry> </entry>
</value> </value>
</component> </component>

View File

@ -15,6 +15,9 @@
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/Theme.KidShift" android:theme="@style/Theme.KidShift"
tools:targetApi="31"> tools:targetApi="31">
<activity
android:name=".RegisterActivity"
android:exported="false" />
<activity <activity
android:name=".LoginActivity" android:name=".LoginActivity"
android:exported="false" /> android:exported="false" />

View File

@ -1,5 +1,6 @@
package one.nem.kidshift; package one.nem.kidshift;
import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.widget.EditText; import android.widget.EditText;
@ -17,10 +18,11 @@ import javax.inject.Inject;
import dagger.hilt.android.AndroidEntryPoint; import dagger.hilt.android.AndroidEntryPoint;
import one.nem.kidshift.data.UserSettings; import one.nem.kidshift.data.UserSettings;
import one.nem.kidshift.data.retrofit.KidShiftApiService; import one.nem.kidshift.data.retrofit.KidShiftApiService;
import one.nem.kidshift.data.retrofit.model.parent.auth.ParentLoginRequest; import one.nem.kidshift.data.retrofit.model.parent.auth.ParentAuthRequest;
import one.nem.kidshift.data.retrofit.model.parent.auth.ParentLoginResponse; import one.nem.kidshift.data.retrofit.model.parent.auth.ParentAuthResponse;
import one.nem.kidshift.utils.KSLogger; import one.nem.kidshift.utils.KSLogger;
import one.nem.kidshift.utils.factory.KSLoggerFactory; import one.nem.kidshift.utils.factory.KSLoggerFactory;
import retrofit2.Call;
import retrofit2.Response; import retrofit2.Response;
import retrofit2.Retrofit; import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory; import retrofit2.converter.gson.GsonConverterFactory;
@ -36,6 +38,9 @@ public class LoginActivity extends AppCompatActivity {
@Inject @Inject
UserSettings userSettings; UserSettings userSettings;
@Inject
KidShiftApiService kidShiftApiService;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
@ -49,61 +54,41 @@ public class LoginActivity extends AppCompatActivity {
logger = loggerFactory.create("LoginActivity"); logger = loggerFactory.create("LoginActivity");
// Retrofit init
KidShiftApiService apiService = new Retrofit.Builder()
.baseUrl("https://kidshift-beta.nem.one/")
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(KidShiftApiService.class);
EditText emailEditText = findViewById(R.id.emailEditText); EditText emailEditText = findViewById(R.id.emailEditText);
EditText passwordEditText = findViewById(R.id.passwordEditText); EditText passwordEditText = findViewById(R.id.passwordEditText);
findViewById(R.id.loginButton).setOnClickListener(v -> { findViewById(R.id.loginButton).setOnClickListener(v -> {
CompletableFuture.supplyAsync(() -> { String email = emailEditText.getText().toString(); // TODO: メールアドレスのバリデーション
String password = passwordEditText.getText().toString();
CompletableFuture.runAsync(() -> {
Call<ParentAuthResponse> call = kidShiftApiService.parentLogin(new ParentAuthRequest(email, password));
try { try {
Response<ParentLoginResponse> response = apiService.parentLogin( Response<ParentAuthResponse> response = call.execute();
new ParentLoginRequest( if (response.isSuccessful()) {
emailEditText.getText().toString(), ParentAuthResponse parentAuthResponse = response.body();
passwordEditText.getText().toString() if (parentAuthResponse == null || parentAuthResponse.getAccessToken() == null) {
)).execute(); // エラー処理
logger.error("ParentAuthResponseがnullまたはAccessTokenがnullです");
return response; return;
} catch (IOException e) { }
logger.error("IOException"); userSettings.getAppCommonSetting().setLoggedIn(true);
throw new RuntimeException(e); userSettings.getAppCommonSetting().setAccessToken(parentAuthResponse.getAccessToken());
} } else {
}).thenAccept(response -> { logger.error("リクエストに失敗しました");
if (response.isSuccessful()) { // エラー処理
logger.info("Login Success");
logger.debug("AccessToken: " + response.body().getAccessToken());
UserSettings.AppCommonSetting appCommonSetting = userSettings.getAppCommonSetting();
appCommonSetting.setLoggedIn(true);
appCommonSetting.setAccessToken(response.body().getAccessToken());
appCommonSetting.setChildMode(false);
finish();
} else {
logger.error("Login Failed");
try {
logger.debug("Response: " + response.errorBody().string());
} catch (IOException e) {
logger.error("IOException while reading error body");
} }
// ログイン失敗時の処理 } catch (Exception e) {
logger.error("リクエストに失敗しました: " + e.getMessage());
e.printStackTrace();
} }
}).exceptionally(e -> { }).thenRun(() -> {
logger.error("Exception occurred: " + e.getMessage()); startActivity(new Intent(this, MainActivity.class));
return null;
}); });
}); });
// for Debug findViewById(R.id.intentRegisterButton).setOnClickListener(v -> {
findViewById(R.id.loginButton).setOnLongClickListener(v -> { startActivity(new Intent(this, RegisterActivity.class));
// ログイン画面をバイパスしてメイン画面に遷移
finish();
return true;
}); });
} }
} }

View File

@ -0,0 +1,93 @@
package one.nem.kidshift;
import android.content.Intent;
import android.os.Bundle;
import android.widget.EditText;
import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import java.util.concurrent.CompletableFuture;
import javax.inject.Inject;
import dagger.hilt.android.AndroidEntryPoint;
import one.nem.kidshift.data.UserSettings;
import one.nem.kidshift.data.retrofit.KidShiftApiService;
import one.nem.kidshift.data.retrofit.model.parent.auth.ParentAuthRequest;
import one.nem.kidshift.data.retrofit.model.parent.auth.ParentAuthResponse;
import one.nem.kidshift.utils.KSLogger;
import one.nem.kidshift.utils.factory.KSLoggerFactory;
import retrofit2.Call;
import retrofit2.Response;
@AndroidEntryPoint
public class RegisterActivity extends AppCompatActivity {
@Inject
KidShiftApiService kidShiftApiService;
@Inject
UserSettings userSettings;
@Inject
KSLoggerFactory loggerFactory;
private KSLogger logger;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EdgeToEdge.enable(this);
setContentView(R.layout.activity_register);
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
return insets;
});
logger = loggerFactory.create("RegisterActivity");
EditText emailEditText = findViewById(R.id.emailEditText); // TODO: メールアドレスのバリデーション
EditText passwordEditText = findViewById(R.id.passwordEditText);
findViewById(R.id.registerButton).setOnClickListener(v -> {
String email = emailEditText.getText().toString();
String password = passwordEditText.getText().toString();
CompletableFuture.runAsync(() -> {
Call<ParentAuthResponse> call = kidShiftApiService.parentRegister(new ParentAuthRequest(email, password));
try {
Response<ParentAuthResponse> response = call.execute();
if (response.isSuccessful()) {
ParentAuthResponse parentAuthResponse = response.body();
if (parentAuthResponse == null || parentAuthResponse.getAccessToken() == null) {
// エラー処理
logger.error("ParentAuthResponseがnullまたはAccessTokenがnullです");
return;
}
userSettings.getAppCommonSetting().setLoggedIn(true);
userSettings.getAppCommonSetting().setAccessToken(parentAuthResponse.getAccessToken());
} else {
logger.error("リクエストに失敗しました");
// エラー処理
}
} catch (Exception e) {
logger.error("リクエストに失敗しました: " + e.getMessage());
e.printStackTrace();
}
}).thenRun(() -> {
startActivity(new Intent(this, MainActivity.class));
});
});
findViewById(R.id.intentLoginButton).setOnClickListener(v -> {
startActivity(new Intent(this, LoginActivity.class));
});
}
}

View File

@ -38,16 +38,33 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="※Loginボタン長押しでBypass" android:text="※Loginボタン長押しでBypass"
app:layout_constraintBottom_toTopOf="@+id/loginButton" app:layout_constraintBottom_toTopOf="@+id/linearLayout2"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" /> app:layout_constraintStart_toStartOf="parent" />
<Button <LinearLayout
android:id="@+id/loginButton" android:id="@+id/linearLayout2"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="0dp"
android:text="LOGIN" android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" /> app:layout_constraintStart_toStartOf="parent">
<Button
android:id="@+id/loginButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="LOGIN" />
<Button
android:id="@+id/intentRegisterButton"
style="@style/Widget.Material3.Button.IconButton.Outlined"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Register" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,70 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".RegisterActivity">
<LinearLayout
android:id="@+id/inputContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<EditText
android:id="@+id/emailEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textEmailAddress" />
<EditText
android:id="@+id/passwordEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textPassword" />
</LinearLayout>
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="※Registerボタン長押しでBypass"
app:layout_constraintBottom_toTopOf="@+id/linearLayout2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<LinearLayout
android:id="@+id/linearLayout2"
android:layout_width="match_parent"
android:layout_height="0dp"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<Button
android:id="@+id/registerButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="REGISTER" />
<Button
android:id="@+id/intentLoginButton"
style="@style/Widget.Material3.Button.IconButton.Outlined"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Login" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -6,8 +6,8 @@ import one.nem.kidshift.data.retrofit.model.child.ChildListResponse;
import one.nem.kidshift.data.retrofit.model.child.ChildLoginCodeResponse; import one.nem.kidshift.data.retrofit.model.child.ChildLoginCodeResponse;
import one.nem.kidshift.data.retrofit.model.child.ChildResponse; import one.nem.kidshift.data.retrofit.model.child.ChildResponse;
import one.nem.kidshift.data.retrofit.model.parent.ParentInfoResponse; import one.nem.kidshift.data.retrofit.model.parent.ParentInfoResponse;
import one.nem.kidshift.data.retrofit.model.parent.auth.ParentLoginRequest; import one.nem.kidshift.data.retrofit.model.parent.auth.ParentAuthRequest;
import one.nem.kidshift.data.retrofit.model.parent.auth.ParentLoginResponse; import one.nem.kidshift.data.retrofit.model.parent.auth.ParentAuthResponse;
import one.nem.kidshift.data.retrofit.model.task.TaskAddRequest; import one.nem.kidshift.data.retrofit.model.task.TaskAddRequest;
import one.nem.kidshift.data.retrofit.model.task.TaskListResponse; import one.nem.kidshift.data.retrofit.model.task.TaskListResponse;
import one.nem.kidshift.data.retrofit.model.task.TaskResponse; import one.nem.kidshift.data.retrofit.model.task.TaskResponse;
@ -15,7 +15,6 @@ import retrofit2.Call;
import retrofit2.http.Body; import retrofit2.http.Body;
import retrofit2.http.DELETE; import retrofit2.http.DELETE;
import retrofit2.http.GET; import retrofit2.http.GET;
import retrofit2.http.Header;
import retrofit2.http.Headers; import retrofit2.http.Headers;
import retrofit2.http.POST; import retrofit2.http.POST;
import retrofit2.http.PUT; import retrofit2.http.PUT;
@ -33,7 +32,15 @@ public interface KidShiftApiService {
* @return ParentLoginResponse * @return ParentLoginResponse
*/ */
@POST("/parent/auth/login") @POST("/parent/auth/login")
Call<ParentLoginResponse> parentLogin(@Body ParentLoginRequest request); Call<ParentAuthResponse> parentLogin(@Body ParentAuthRequest request);
/**
* 保護者登録処理
* @param request ParentRegisterRequest
* @return ParentRegisterResponse
*/
@POST("/parent/auth/register")
Call<ParentAuthResponse> parentRegister(@Body ParentAuthRequest request);
/** /**
* 保護者アカウント情報取得処理 * 保護者アカウント情報取得処理

View File

@ -1,6 +1,6 @@
package one.nem.kidshift.data.retrofit.model.parent.auth; package one.nem.kidshift.data.retrofit.model.parent.auth;
public class ParentLoginRequest { public class ParentAuthRequest {
private String email; private String email;
private String password; private String password;
@ -9,7 +9,7 @@ public class ParentLoginRequest {
* @param email メールアドレス * @param email メールアドレス
* @param password パスワード * @param password パスワード
*/ */
public ParentLoginRequest(String email, String password) { public ParentAuthRequest(String email, String password) {
this.email = email; this.email = email;
this.password = password; this.password = password;
} }

View File

@ -1,13 +1,13 @@
package one.nem.kidshift.data.retrofit.model.parent.auth; package one.nem.kidshift.data.retrofit.model.parent.auth;
public class ParentLoginResponse { public class ParentAuthResponse {
private String accessToken; private String accessToken;
/** /**
* コンストラクタ (全プロパティ) * コンストラクタ (全プロパティ)
* @param accessToken アクセストークン * @param accessToken アクセストークン
*/ */
public ParentLoginResponse(String accessToken) { public ParentAuthResponse(String accessToken) {
this.accessToken = accessToken; this.accessToken = accessToken;
} }