Merge branch 'main' into feature/updateupdate
This commit is contained in:
commit
bb1196a26a
|
@ -35,6 +35,7 @@ dependencies {
|
|||
implementation libs.material
|
||||
implementation libs.activity
|
||||
implementation libs.constraintlayout
|
||||
implementation project(':model')
|
||||
testImplementation libs.junit
|
||||
androidTestImplementation libs.ext.junit
|
||||
androidTestImplementation libs.espresso.core
|
||||
|
|
|
@ -14,11 +14,13 @@ import androidx.navigation.fragment.NavHostFragment;
|
|||
import androidx.navigation.ui.NavigationUI;
|
||||
|
||||
import com.google.android.material.bottomnavigation.BottomNavigationView;
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import dagger.hilt.android.AndroidEntryPoint;
|
||||
import one.nem.kidshift.data.UserSettings;
|
||||
import one.nem.kidshift.utils.FabManager;
|
||||
import one.nem.kidshift.utils.KSLogger;
|
||||
import one.nem.kidshift.utils.factory.KSLoggerFactory;
|
||||
|
||||
|
@ -28,8 +30,13 @@ public class MainActivity extends AppCompatActivity {
|
|||
@Inject
|
||||
KSLoggerFactory loggerFactory;
|
||||
|
||||
@Inject
|
||||
FabManager fabManager;
|
||||
|
||||
private KSLogger logger;
|
||||
|
||||
private FloatingActionButton fab;
|
||||
|
||||
@Inject
|
||||
UserSettings userSettings;
|
||||
|
||||
|
@ -71,6 +78,9 @@ public class MainActivity extends AppCompatActivity {
|
|||
Intent intent = new Intent(this, LoginActivity.class);
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
fab = findViewById(R.id.mainFab);
|
||||
fabManager.setFab(fab);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -27,4 +27,15 @@
|
|||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:menu="@menu/main_nav_menu" />
|
||||
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/mainFab"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="24dp"
|
||||
android:layout_marginBottom="24dp"
|
||||
android:clickable="true"
|
||||
app:layout_constraintBottom_toTopOf="@id/bottom_nav"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:srcCompat="@drawable/add_24px" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -31,7 +31,7 @@ public interface ChildData {
|
|||
* 子ユーザー追加
|
||||
* @param child 子ユーザー情報
|
||||
*/
|
||||
void addChild(ChildModel child);
|
||||
CompletableFuture<ChildModel> addChild(ChildModel child);
|
||||
|
||||
/**
|
||||
* 子ユーザー削除
|
||||
|
|
|
@ -27,19 +27,19 @@ public interface TaskData {
|
|||
* タスクを追加する
|
||||
* @param task タスク
|
||||
*/
|
||||
void addTask(TaskItemModel task);
|
||||
CompletableFuture<TaskItemModel> addTask(TaskItemModel task);
|
||||
|
||||
/**
|
||||
* タスクを削除する
|
||||
* @param taskId タスクID
|
||||
*/
|
||||
void removeTask(String taskId);
|
||||
CompletableFuture<Void> removeTask(String taskId);
|
||||
|
||||
/**
|
||||
* タスクを更新する
|
||||
* @param task タスク
|
||||
*/
|
||||
void updateTask(TaskItemModel task);
|
||||
CompletableFuture<Void> updateTask(TaskItemModel task);
|
||||
|
||||
// 子側
|
||||
|
||||
|
@ -55,5 +55,5 @@ public interface TaskData {
|
|||
* @param taskId タスクID
|
||||
* @param childId 子ID
|
||||
*/
|
||||
void recordTaskCompletion(String taskId, String childId);
|
||||
CompletableFuture<Void> recordTaskCompletion(String taskId, String childId);
|
||||
}
|
||||
|
|
|
@ -1,17 +1,16 @@
|
|||
package one.nem.kidshift.data.impl;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import one.nem.kidshift.data.ChildData;
|
||||
import one.nem.kidshift.data.KSActions;
|
||||
import one.nem.kidshift.data.retrofit.KidShiftApiService;
|
||||
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.ChildResponse;
|
||||
import one.nem.kidshift.data.retrofit.model.converter.ChildModelConverter;
|
||||
import one.nem.kidshift.data.room.utils.CacheWrapper;
|
||||
import one.nem.kidshift.model.ChildModel;
|
||||
|
@ -22,13 +21,14 @@ import retrofit2.Call;
|
|||
import retrofit2.Response;
|
||||
|
||||
public class ChildDataImpl implements ChildData {
|
||||
|
||||
private final KidShiftApiService kidShiftApiService;
|
||||
private final KSActions ksActions;
|
||||
private final CacheWrapper cacheWrapper;
|
||||
private final KSLogger logger;
|
||||
|
||||
@Inject
|
||||
public ChildDataImpl(KSActions ksActions, CacheWrapper cacheWrapper, KSLoggerFactory loggerFactory) {
|
||||
public ChildDataImpl(KidShiftApiService kidShiftApiService, KSActions ksActions, CacheWrapper cacheWrapper, KSLoggerFactory loggerFactory) {
|
||||
this.kidShiftApiService = kidShiftApiService;
|
||||
this.ksActions = ksActions;
|
||||
this.cacheWrapper = cacheWrapper;
|
||||
this.logger = loggerFactory.create("ChildDataImpl");
|
||||
|
@ -44,33 +44,31 @@ public class ChildDataImpl implements ChildData {
|
|||
return CompletableFuture.supplyAsync(() -> {
|
||||
logger.debug("子供リスト取得開始");
|
||||
AtomicReference<List<ChildModel>> childListTmp = new AtomicReference<>();
|
||||
Thread thread = new Thread(() -> {
|
||||
ksActions.syncChildList().thenAccept(childList -> {
|
||||
if (childListTmp.get() == null || childListTmp.get().isEmpty()) {
|
||||
logger.debug("子供リスト取得完了: キャッシュよりはやく取得完了 or キャッシュ無し");
|
||||
if (childList == null || childList.isEmpty()) {
|
||||
callback.onUnchanged();
|
||||
} else {
|
||||
callback.onUpdated(childList);
|
||||
}
|
||||
Thread thread = new Thread(() -> ksActions.syncChildList().thenAccept(childList -> {
|
||||
if (childListTmp.get() == null || childListTmp.get().isEmpty()) {
|
||||
logger.debug("子供リスト取得完了: キャッシュよりはやく取得完了 or キャッシュ無し");
|
||||
if (childList == null || childList.isEmpty()) {
|
||||
callback.onUnchanged();
|
||||
} else {
|
||||
boolean isChanged =
|
||||
childList.size() != childListTmp.get().size() ||
|
||||
childList.stream().anyMatch(child -> childListTmp.get().stream().noneMatch(childTmp -> child.getId().equals(childTmp.getId())));
|
||||
if (isChanged) {
|
||||
logger.debug("子供リスト取得完了: キャッシュと比較して変更あり");
|
||||
callback.onUpdated(childList);
|
||||
} else {
|
||||
logger.debug("子供リスト取得完了: キャッシュと比較して変更なし");
|
||||
callback.onUnchanged();
|
||||
}
|
||||
callback.onUpdated(childList);
|
||||
}
|
||||
}).exceptionally(e -> {
|
||||
logger.error("子供リスト取得失敗: " + e.getMessage());
|
||||
callback.onFailed(e.getMessage());
|
||||
return null;
|
||||
});
|
||||
});
|
||||
} else {
|
||||
boolean isChanged =
|
||||
childList.size() != childListTmp.get().size() ||
|
||||
childList.stream().anyMatch(child -> childListTmp.get().stream().noneMatch(childTmp -> child.getId().equals(childTmp.getId())));
|
||||
if (isChanged) {
|
||||
logger.debug("子供リスト取得完了: キャッシュと比較して変更あり");
|
||||
callback.onUpdated(childList);
|
||||
} else {
|
||||
logger.debug("子供リスト取得完了: キャッシュと比較して変更なし");
|
||||
callback.onUnchanged();
|
||||
}
|
||||
}
|
||||
}).exceptionally(e -> {
|
||||
logger.error("子供リスト取得失敗: " + e.getMessage());
|
||||
callback.onFailed(e.getMessage());
|
||||
return null;
|
||||
}));
|
||||
thread.start();
|
||||
return cacheWrapper.getChildList().thenApply(childList -> {
|
||||
if (childList == null || childList.isEmpty()) {
|
||||
|
@ -96,8 +94,22 @@ public class ChildDataImpl implements ChildData {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void addChild(ChildModel child) {
|
||||
|
||||
public CompletableFuture<ChildModel> addChild(ChildModel child) {
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
Call<ChildResponse> call = kidShiftApiService.addChild(ChildModelConverter.childModelToChildAddRequest(child));
|
||||
try {
|
||||
Response<ChildResponse> response = call.execute();
|
||||
if (response.isSuccessful()) {
|
||||
assert response.body() != null;
|
||||
logger.info("子供追加成功(childId: " + response.body().getId() + ")");
|
||||
return ChildModelConverter.childResponseToChildModel(response.body());
|
||||
} else {
|
||||
throw new RuntimeException("HTTP Status: " + response.code());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -107,6 +119,19 @@ public class ChildDataImpl implements ChildData {
|
|||
|
||||
@Override
|
||||
public CompletableFuture<Integer> issueLoginCode(String childId) {
|
||||
return null;
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
Call<ChildLoginCodeResponse> call = kidShiftApiService.issueLoginCode(childId);
|
||||
try {
|
||||
Response<ChildLoginCodeResponse> response = call.execute();
|
||||
if (response.isSuccessful()) {
|
||||
assert response.body() != null;
|
||||
return response.body().getCode();
|
||||
} else {
|
||||
throw new RuntimeException("HTTP Status: " + response.code());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,21 +8,28 @@ import javax.inject.Inject;
|
|||
|
||||
import one.nem.kidshift.data.KSActions;
|
||||
import one.nem.kidshift.data.TaskData;
|
||||
import one.nem.kidshift.data.retrofit.KidShiftApiService;
|
||||
import one.nem.kidshift.data.retrofit.model.converter.TaskModelConverter;
|
||||
import one.nem.kidshift.data.retrofit.model.task.TaskResponse;
|
||||
import one.nem.kidshift.data.room.utils.CacheWrapper;
|
||||
import one.nem.kidshift.model.callback.TaskItemModelCallback;
|
||||
import one.nem.kidshift.model.tasks.TaskItemModel;
|
||||
import one.nem.kidshift.utils.KSLogger;
|
||||
import one.nem.kidshift.utils.factory.KSLoggerFactory;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Response;
|
||||
|
||||
public class TaskDataImpl implements TaskData {
|
||||
|
||||
private final KSActions ksActions;
|
||||
private final KidShiftApiService kidShiftApiService;
|
||||
private final CacheWrapper cacheWrapper;
|
||||
private final KSLogger logger;
|
||||
|
||||
@Inject
|
||||
public TaskDataImpl(KSActions ksActions, CacheWrapper cacheWrapper, KSLoggerFactory loggerFactory) {
|
||||
public TaskDataImpl(KSActions ksActions, KidShiftApiService kidShiftApiService, CacheWrapper cacheWrapper, KSLoggerFactory loggerFactory) {
|
||||
this.ksActions = ksActions;
|
||||
this.kidShiftApiService = kidShiftApiService;
|
||||
this.cacheWrapper = cacheWrapper;
|
||||
this.logger = loggerFactory.create("TaskDataImpl");
|
||||
}
|
||||
|
@ -32,34 +39,32 @@ public class TaskDataImpl implements TaskData {
|
|||
return CompletableFuture.supplyAsync(() -> {
|
||||
logger.debug("タスク取得開始");
|
||||
AtomicReference<List<TaskItemModel>> taskListTmp = new AtomicReference<>();
|
||||
Thread thread = new Thread(() -> {
|
||||
ksActions.syncTasks().thenAccept(taskList -> {
|
||||
if (taskListTmp.get() == null || taskListTmp.get().isEmpty()) {
|
||||
logger.debug("タスク取得完了: キャッシュよりはやく取得完了 or キャッシュ無し");
|
||||
if (taskList == null || taskList.isEmpty()) {
|
||||
callback.onUnchanged();
|
||||
} else {
|
||||
callback.onUpdated(taskList);
|
||||
}
|
||||
Thread thread = new Thread(() -> ksActions.syncTasks().thenAccept(taskList -> {
|
||||
if (taskListTmp.get() == null || taskListTmp.get().isEmpty()) {
|
||||
logger.debug("タスク取得完了: キャッシュよりはやく取得完了 or キャッシュ無し");
|
||||
if (taskList == null || taskList.isEmpty()) {
|
||||
callback.onUnchanged();
|
||||
} else {
|
||||
// キャッシュと比較して変更の有無を確認
|
||||
boolean isChanged =
|
||||
taskList.size() != taskListTmp.get().size() ||
|
||||
taskList.stream().anyMatch(task -> taskListTmp.get().stream().noneMatch(taskTmp -> task.getId().equals(taskTmp.getId())));
|
||||
if (isChanged) {
|
||||
logger.debug("タスク取得完了: キャッシュと比較して変更あり");
|
||||
callback.onUpdated(taskList);
|
||||
} else {
|
||||
logger.debug("タスク取得完了: キャッシュと比較して変更なし");
|
||||
callback.onUnchanged();
|
||||
}
|
||||
callback.onUpdated(taskList);
|
||||
}
|
||||
}).exceptionally(e -> {
|
||||
logger.error("タスク取得失敗: " + e.getMessage());
|
||||
callback.onFailed(e.getMessage());
|
||||
return null;
|
||||
});
|
||||
});
|
||||
} else {
|
||||
// キャッシュと比較して変更の有無を確認
|
||||
boolean isChanged =
|
||||
taskList.size() != taskListTmp.get().size() ||
|
||||
taskList.stream().anyMatch(task -> taskListTmp.get().stream().noneMatch(taskTmp -> task.getId().equals(taskTmp.getId())));
|
||||
if (isChanged) {
|
||||
logger.debug("タスク取得完了: キャッシュと比較して変更あり");
|
||||
callback.onUpdated(taskList);
|
||||
} else {
|
||||
logger.debug("タスク取得完了: キャッシュと比較して変更なし");
|
||||
callback.onUnchanged();
|
||||
}
|
||||
}
|
||||
}).exceptionally(e -> {
|
||||
logger.error("タスク取得失敗: " + e.getMessage());
|
||||
callback.onFailed(e.getMessage());
|
||||
return null;
|
||||
}));
|
||||
thread.start();
|
||||
return cacheWrapper.getTaskList().thenApply(taskList -> {
|
||||
if (taskList == null || taskList.isEmpty()) {
|
||||
|
@ -85,18 +90,62 @@ public class TaskDataImpl implements TaskData {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void addTask(TaskItemModel task) {
|
||||
|
||||
public CompletableFuture<TaskItemModel> addTask(TaskItemModel task) {
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
Call<TaskResponse> call = kidShiftApiService.addTask(TaskModelConverter.taskItemModelToTaskAddRequest(task));
|
||||
try {
|
||||
Response<TaskResponse> response = call.execute();
|
||||
if (response.isSuccessful()) {
|
||||
assert response.body() != null;
|
||||
logger.info("タスク追加成功(taskId: " + response.body().getId() + ")");
|
||||
return TaskModelConverter.taskResponseToTaskItemModel(response.body());
|
||||
} else {
|
||||
logger.error("タスク追加失敗: HTTP Status: " + response.code());
|
||||
throw new RuntimeException("HTTP Status: " + response.code());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeTask(String taskId) {
|
||||
|
||||
public CompletableFuture<Void> removeTask(String taskId) {
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
Call<Void> call = kidShiftApiService.removeTask(taskId);
|
||||
try {
|
||||
Response<Void> response = call.execute();
|
||||
if (response.isSuccessful()) {
|
||||
logger.info("タスク削除成功(taskId: " + taskId + ")");
|
||||
return null;
|
||||
} else {
|
||||
logger.error("タスク削除失敗: HTTP Status: " + response.code());
|
||||
throw new RuntimeException("HTTP Status: " + response.code());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTask(TaskItemModel task) {
|
||||
|
||||
public CompletableFuture<Void> updateTask(TaskItemModel task) {
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
Call<TaskResponse> call = kidShiftApiService.updateTask(TaskModelConverter.taskItemModelToTaskAddRequest(task), task.getId());
|
||||
try {
|
||||
Response<TaskResponse> response = call.execute();
|
||||
if (response.isSuccessful()) {
|
||||
logger.info("タスク更新成功(taskId: " + task.getId() + ")");
|
||||
// return response.body();
|
||||
return null;
|
||||
} else {
|
||||
logger.error("タスク更新失敗: HTTP Status: " + response.code());
|
||||
throw new RuntimeException("HTTP Status: " + response.code());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -105,7 +154,21 @@ public class TaskDataImpl implements TaskData {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void recordTaskCompletion(String taskId, String childId) {
|
||||
|
||||
public CompletableFuture<Void> recordTaskCompletion(String taskId, String childId) {
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
Call<Void> call = kidShiftApiService.completeTask(taskId, childId);
|
||||
try {
|
||||
Response<Void> response = call.execute();
|
||||
if (response.isSuccessful()) {
|
||||
logger.info("タスク完了処理成功(taskId: " + taskId + ", childId: " + childId + ")");
|
||||
return null;
|
||||
} else {
|
||||
logger.error("タスク完了処理失敗: HTTP Status: " + response.code());
|
||||
throw new RuntimeException("HTTP Status: " + response.code());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package one.nem.kidshift.data.retrofit;
|
|||
import one.nem.kidshift.data.retrofit.interceptor.AuthorizationInterceptor;
|
||||
import one.nem.kidshift.data.retrofit.model.child.ChildAddRequest;
|
||||
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.ChildResponse;
|
||||
import one.nem.kidshift.data.retrofit.model.parent.ParentInfoResponse;
|
||||
import one.nem.kidshift.data.retrofit.model.parent.auth.ParentLoginRequest;
|
||||
|
@ -19,6 +20,7 @@ import retrofit2.http.Headers;
|
|||
import retrofit2.http.POST;
|
||||
import retrofit2.http.PUT;
|
||||
import retrofit2.http.Path;
|
||||
import retrofit2.http.Query;
|
||||
|
||||
public interface KidShiftApiService {
|
||||
|
||||
|
@ -95,7 +97,7 @@ public interface KidShiftApiService {
|
|||
*/
|
||||
@POST("/parent/task/{id}/complete")
|
||||
@Headers(AuthorizationInterceptor.HEADER_PLACEHOLDER)
|
||||
Call<Void> completeTask(@Path("id") String id); // TODO-rca: OK responseをパース
|
||||
Call<Void> completeTask(@Path("id") String id, @Query("childId") String childId);
|
||||
|
||||
// Child APIs
|
||||
|
||||
|
@ -116,4 +118,13 @@ public interface KidShiftApiService {
|
|||
@Headers(AuthorizationInterceptor.HEADER_PLACEHOLDER)
|
||||
Call<ChildResponse> addChild(@Body ChildAddRequest request);
|
||||
|
||||
/**
|
||||
* 子供ログインコード発行
|
||||
* @param id 子供ID
|
||||
* @return ChildLoginCodeResponse
|
||||
*/
|
||||
@GET("/parent/child/{id}/login")
|
||||
@Headers(AuthorizationInterceptor.HEADER_PLACEHOLDER)
|
||||
Call<ChildLoginCodeResponse> issueLoginCode(@Path("id") String id);
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
package one.nem.kidshift.data.retrofit.model.child;
|
||||
|
||||
public class ChildLoginCodeResponse {
|
||||
private int code;
|
||||
|
||||
public ChildLoginCodeResponse(int code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public ChildLoginCodeResponse() {
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(int code) {
|
||||
this.code = code;
|
||||
}
|
||||
}
|
|
@ -3,6 +3,7 @@ package one.nem.kidshift.data.retrofit.model.converter;
|
|||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
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.TaskResponse;
|
||||
import one.nem.kidshift.model.tasks.TaskItemModel;
|
||||
|
@ -47,4 +48,13 @@ public class TaskModelConverter {
|
|||
public static List<TaskItemModel> taskListResponseToTaskItemModelList(TaskListResponse taskListResponse) {
|
||||
return taskListResponse.getList().stream().map(TaskModelConverter::taskResponseToTaskItemModel).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public static TaskAddRequest taskItemModelToTaskAddRequest(TaskItemModel taskItemModel) {
|
||||
TaskAddRequest request = new TaskAddRequest();
|
||||
request.setName(taskItemModel.getName());
|
||||
request.setReward(taskItemModel.getReward());
|
||||
request.setBgColor(taskItemModel.getBgColor());
|
||||
request.setIconEmoji(taskItemModel.getIconEmoji());
|
||||
return request;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -121,19 +121,7 @@ public class DebugCommandProcessor {
|
|||
commandArray = shiftArray(commandArray);
|
||||
switch (commandArray[0]) {
|
||||
case "get":
|
||||
commandArray = shiftArray(commandArray);
|
||||
switch (commandArray[0]) {
|
||||
case "all":
|
||||
List<LogModel> logs = ksLogger.getHistory();
|
||||
StringBuilder logString = new StringBuilder();
|
||||
for (LogModel log : logs) {
|
||||
logString.append(log.getMessage());
|
||||
logString.append("\n");
|
||||
}
|
||||
return logString.toString();
|
||||
default:
|
||||
return "TODO";
|
||||
}
|
||||
return "Removed for performance reasons";
|
||||
case "insert":
|
||||
commandArray = shiftArray(commandArray);
|
||||
String[] logArray = Arrays.copyOfRange(commandArray, 1, commandArray.length);
|
||||
|
|
|
@ -4,6 +4,7 @@ import android.inputmethodservice.Keyboard;
|
|||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
@ -15,8 +16,14 @@ import one.nem.kidshift.model.ChildModel;
|
|||
|
||||
public class SettingAdapter extends RecyclerView.Adapter<SettingAdapter.MainViewHolder> {
|
||||
|
||||
public interface LoginButtonCallback {
|
||||
void onLoginButtonClicked(String childId);
|
||||
}
|
||||
|
||||
private List<ChildModel> childDataList;
|
||||
|
||||
private LoginButtonCallback loginButtonCallback;
|
||||
|
||||
SettingAdapter() {
|
||||
|
||||
}
|
||||
|
@ -25,13 +32,19 @@ public class SettingAdapter extends RecyclerView.Adapter<SettingAdapter.MainView
|
|||
this.childDataList = childDataList;
|
||||
}
|
||||
|
||||
public void setLoginButtonCallback(LoginButtonCallback loginButtonCallback) {
|
||||
this.loginButtonCallback = loginButtonCallback;
|
||||
}
|
||||
|
||||
|
||||
static class MainViewHolder extends RecyclerView.ViewHolder{
|
||||
TextView childname;
|
||||
Button loginButton;
|
||||
|
||||
MainViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
childname = itemView.findViewById(R.id.childname);
|
||||
loginButton = itemView.findViewById(R.id.loginButton);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -46,6 +59,11 @@ public class SettingAdapter extends RecyclerView.Adapter<SettingAdapter.MainView
|
|||
public void onBindViewHolder(@NonNull MainViewHolder holder, int position){
|
||||
ChildModel childData = this.childDataList.get(position);
|
||||
holder.childname.setText(childData.getName());
|
||||
holder.loginButton.setOnClickListener(v -> {
|
||||
if (this.loginButtonCallback != null) {
|
||||
this.loginButtonCallback.onLoginButtonClicked(childData.getId());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -3,7 +3,6 @@ package one.nem.kidshift.feature.setting;
|
|||
import android.annotation.SuppressLint;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
@ -14,11 +13,12 @@ import android.view.View;
|
|||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
@ -30,8 +30,10 @@ import one.nem.kidshift.model.ChildModel;
|
|||
import one.nem.kidshift.model.ParentModel;
|
||||
import one.nem.kidshift.model.callback.ChildModelCallback;
|
||||
import one.nem.kidshift.model.callback.ParentModelCallback;
|
||||
import one.nem.kidshift.utils.FabManager;
|
||||
import one.nem.kidshift.utils.KSLogger;
|
||||
import one.nem.kidshift.utils.factory.KSLoggerFactory;
|
||||
import one.nem.kidshift.utils.models.FabEventCallback;
|
||||
|
||||
@AndroidEntryPoint
|
||||
public class SettingMainFragment extends Fragment {
|
||||
|
@ -45,11 +47,14 @@ public class SettingMainFragment extends Fragment {
|
|||
@Inject
|
||||
KSLoggerFactory ksLoggerFactory;
|
||||
|
||||
@Inject
|
||||
FabManager fabManager;
|
||||
|
||||
private KSLogger logger;
|
||||
|
||||
TextView username;
|
||||
|
||||
TextView useradress;
|
||||
TextView userMailAddress;
|
||||
|
||||
SettingAdapter mainAdapter;
|
||||
SwipeRefreshLayout swipeRefreshLayout;
|
||||
|
@ -65,7 +70,12 @@ public class SettingMainFragment extends Fragment {
|
|||
logger = ksLoggerFactory.create("SettingMainFragment");
|
||||
}
|
||||
|
||||
private CompletableFuture<Void> updateParentInfo(){
|
||||
/**
|
||||
* 親情報を更新する
|
||||
*
|
||||
* @return CompletableFuture<Void>
|
||||
*/
|
||||
private CompletableFuture<Void> updateParentInfo() {
|
||||
return parentData.getParent(new ParentModelCallback() {
|
||||
@Override
|
||||
public void onUnchanged() {
|
||||
|
@ -83,13 +93,18 @@ public class SettingMainFragment extends Fragment {
|
|||
}
|
||||
}).thenAccept(parentModel -> {
|
||||
username.setText(parentModel.getName() != null ? parentModel.getName() : "親の名前");
|
||||
useradress.setText(parentModel.getEmail() != null ? parentModel.getEmail() : "親のアドレス");
|
||||
userMailAddress.setText(parentModel.getEmail() != null ? parentModel.getEmail() : "親のアドレス");
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 子供情報を更新する
|
||||
*
|
||||
* @return CompletableFuture<Void>
|
||||
*/
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
private CompletableFuture<Void> updateChildInfo(){
|
||||
private CompletableFuture<Void> updateChildInfo() {
|
||||
return childData.getChildList(new ChildModelCallback() {
|
||||
@Override
|
||||
public void onUnchanged() {
|
||||
|
@ -115,6 +130,9 @@ public class SettingMainFragment extends Fragment {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* ユーザー情報を更新するラッパー
|
||||
*/
|
||||
private void updateInfo() {
|
||||
CompletableFuture<Void> updateParent = updateParentInfo();
|
||||
CompletableFuture<Void> updateChildList = updateChildInfo();
|
||||
|
@ -127,6 +145,10 @@ public class SettingMainFragment extends Fragment {
|
|||
updateParent.thenCombine(updateChildList, (res1, res2) -> null).thenRun(() -> {
|
||||
logger.debug("アップデート完了");
|
||||
swipeRefreshLayout.setRefreshing(false);
|
||||
}).exceptionally(e -> {
|
||||
logger.error("アップデート失敗: " + e.getMessage());
|
||||
swipeRefreshLayout.setRefreshing(false);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -137,61 +159,116 @@ public class SettingMainFragment extends Fragment {
|
|||
|
||||
View view = inflater.inflate(R.layout.fragment_setting_main, container, false);
|
||||
|
||||
// ビューの取得
|
||||
username = view.findViewById(R.id.username);
|
||||
useradress = view.findViewById(R.id.useradress);
|
||||
|
||||
userMailAddress = view.findViewById(R.id.useradress);
|
||||
swipeRefreshLayout = view.findViewById(R.id.swipe_refresh_layout);
|
||||
RecyclerView recyclerView = view.findViewById(R.id.childrecyclerview);
|
||||
|
||||
// RecyclerViewの設定
|
||||
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getContext());
|
||||
recyclerView.setLayoutManager(layoutManager);
|
||||
|
||||
mainAdapter = new SettingAdapter();
|
||||
recyclerView.setAdapter(mainAdapter);
|
||||
|
||||
// Pull-to-refresh(スワイプで更新)
|
||||
swipeRefreshLayout = view.findViewById(R.id.swipe_refresh_layout);
|
||||
|
||||
try {
|
||||
|
||||
/*
|
||||
TODO:
|
||||
- コールバックの処理を実装
|
||||
- 結果に応じてRecyclerViewを更新する
|
||||
- キャッシュ受け取りの時にjoinでUIスレッドをブロックしないように
|
||||
- Placeholderの表示?
|
||||
- エラーハンドリング try catch文
|
||||
- onFailed時にそれを通知
|
||||
*/
|
||||
|
||||
// ユーザー情報の更新(初回)
|
||||
updateInfo();
|
||||
|
||||
swipeRefreshLayout.setOnRefreshListener(() ->{
|
||||
|
||||
updateInfo();
|
||||
|
||||
// スワイプリフレッシュのリスナー
|
||||
swipeRefreshLayout.setOnRefreshListener(() -> {
|
||||
updateInfo(); // ユーザー情報の更新
|
||||
});
|
||||
|
||||
} catch (Exception e) {
|
||||
//
|
||||
}
|
||||
// ダイアログの設定
|
||||
LayoutInflater dialogInflater = requireActivity().getLayoutInflater();
|
||||
|
||||
LayoutInflater inflater1 = requireActivity().getLayoutInflater();
|
||||
View view1 = inflater1.inflate(R.layout.add_child_list_dialog,null);
|
||||
View addChildDialogView = dialogInflater.inflate(R.layout.fragment_login_dialog_view, null);
|
||||
|
||||
//子供の名前追加のダイアログ
|
||||
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(getContext());
|
||||
builder.setTitle("お子様の名前を入力してください。")
|
||||
.setView(view1)
|
||||
.setPositiveButton("追加",null)
|
||||
.setNeutralButton("閉じる",null);
|
||||
builder.create();
|
||||
View childListItemView = inflater.inflate(R.layout.list_item_child_name_list, container, false);
|
||||
|
||||
view.findViewById(R.id.addchildname).setOnClickListener(v -> {
|
||||
builder.show();
|
||||
mainAdapter.setLoginButtonCallback(new SettingAdapter.LoginButtonCallback() {
|
||||
@Override
|
||||
public void onLoginButtonClicked(String childId) {
|
||||
// Toast.makeText(getContext(), "ボタンがクリックされました(" + childId + ")", Toast.LENGTH_LONG).show();
|
||||
int loginCode = childData.issueLoginCode(childId).join();
|
||||
TextView loginCodeTextView = addChildDialogView.findViewById(R.id.loginCode);
|
||||
new StringBuilder(Integer.toString(loginCode)).insert(3, "-");
|
||||
|
||||
loginCodeTextView.setText(
|
||||
new StringBuilder(Integer.toString(loginCode)).insert(3, "-")
|
||||
);
|
||||
|
||||
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(requireContext());
|
||||
builder.setTitle("ログインコード")
|
||||
.setView(addChildDialogView)
|
||||
.setNeutralButton("閉じる", null);
|
||||
builder.create();
|
||||
|
||||
// childListItemView.findViewById(R.id.loginButton).setOnClickListener(v -> {
|
||||
builder.show();
|
||||
// });
|
||||
}
|
||||
});
|
||||
|
||||
// int loginCode = childData.issueLoginCode("543256").join();
|
||||
// TextView loginCodeTextView = addChildDialogView.findViewById(R.id.loginCode);
|
||||
// new StringBuilder(Integer.toString(loginCode)).insert(3,"-");
|
||||
//
|
||||
// loginCodeTextView.setText(
|
||||
// new StringBuilder(Integer.toString(loginCode)).insert(3,"-"));
|
||||
|
||||
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(requireContext());
|
||||
builder.setTitle("ログインコード")
|
||||
.setView(addChildDialogView)
|
||||
.setNeutralButton("閉じる", null);
|
||||
builder.create();
|
||||
//
|
||||
// childListItemView.findViewById(R.id.loginButton).setOnClickListener(v -> {
|
||||
// builder.show();
|
||||
// });
|
||||
|
||||
|
||||
|
||||
|
||||
// ダイアログの表示
|
||||
|
||||
if (!fabManager.isShown()) fabManager.show();
|
||||
|
||||
fabManager.setFabEventCallback(new FabEventCallback() {
|
||||
@Override
|
||||
public void onClicked() {
|
||||
//子供の名前追加のダイアログ
|
||||
View dialogView = dialogInflater.inflate(R.layout.add_child_list_dialog, null);
|
||||
new MaterialAlertDialogBuilder(requireContext())
|
||||
.setTitle("お子様の名前を入力してください。")
|
||||
.setView(dialogView)
|
||||
.setPositiveButton("追加", (dialog, which) -> {
|
||||
ChildModel childModel = new ChildModel();
|
||||
childModel.setName(Objects.requireNonNull(((TextView) dialogView.findViewById(R.id.childNameEditText)).getText()).toString());
|
||||
childData.addChild(childModel).thenAccept(childModel1 -> { // Debug
|
||||
logger.debug("子供を追加しました: " + childModel1.getName());
|
||||
}).thenRun(() -> {
|
||||
updateChildInfo();
|
||||
});
|
||||
})
|
||||
.setNeutralButton("閉じる", (dialog, which) -> {
|
||||
dialog.cancel();
|
||||
}).show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLongClicked() {
|
||||
// Do nothing
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
// TODO: 更新する?
|
||||
}
|
||||
}
|
|
@ -6,7 +6,7 @@
|
|||
android:layout_height="match_parent">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/editTextText"
|
||||
android:id="@+id/childNameEditText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ems="10"
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/loginCode"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="30dp"
|
||||
android:paddingBottom="25dp"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Display3" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -8,7 +8,7 @@
|
|||
android:id="@+id/swipe_refresh_layout">
|
||||
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
|
|
55
utils/src/main/java/one/nem/kidshift/utils/FabManager.java
Normal file
55
utils/src/main/java/one/nem/kidshift/utils/FabManager.java
Normal file
|
@ -0,0 +1,55 @@
|
|||
package one.nem.kidshift.utils;
|
||||
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import one.nem.kidshift.utils.factory.KSLoggerFactory;
|
||||
import one.nem.kidshift.utils.models.FabEventCallback;
|
||||
|
||||
@Singleton
|
||||
public class FabManager {
|
||||
private FloatingActionButton fab;
|
||||
private final KSLogger logger;
|
||||
|
||||
@Inject
|
||||
public FabManager(KSLoggerFactory loggerFactory) {
|
||||
this.logger = loggerFactory.create("FabManager");
|
||||
}
|
||||
|
||||
public void setFab(FloatingActionButton fab) {
|
||||
this.fab = fab;
|
||||
}
|
||||
|
||||
private void checkFab() {
|
||||
if (fab == null) {
|
||||
logger.error("Fab is not set");
|
||||
throw new IllegalStateException("Fab is not set");
|
||||
}
|
||||
}
|
||||
|
||||
public void show() {
|
||||
checkFab();
|
||||
fab.show();
|
||||
}
|
||||
|
||||
public void hide() {
|
||||
checkFab();
|
||||
fab.hide();
|
||||
}
|
||||
|
||||
public boolean isShown() {
|
||||
checkFab();
|
||||
return fab.isShown();
|
||||
}
|
||||
|
||||
public void setFabEventCallback(FabEventCallback callback) {
|
||||
checkFab();
|
||||
fab.setOnClickListener(v -> callback.onClicked());
|
||||
fab.setOnLongClickListener(v -> {
|
||||
callback.onLongClicked();
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
|
@ -6,7 +6,6 @@ import one.nem.kidshift.utils.models.LogModel;
|
|||
|
||||
public interface KSLogger {
|
||||
KSLogger addTag(String tag);
|
||||
List<LogModel> getHistory();
|
||||
void info(String message);
|
||||
void warn(String message);
|
||||
void error(String message);
|
||||
|
|
|
@ -1,32 +1,19 @@
|
|||
package one.nem.kidshift.utils.impl;
|
||||
|
||||
import static one.nem.kidshift.utils.enums.LogLevelEnum.INFO;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import dagger.assisted.Assisted;
|
||||
import dagger.assisted.AssistedInject;
|
||||
import one.nem.kidshift.utils.KSLogger;
|
||||
import one.nem.kidshift.utils.SharedPrefUtils;
|
||||
import one.nem.kidshift.utils.enums.LogLevelEnum;
|
||||
import one.nem.kidshift.utils.factory.SharedPrefUtilsFactory;
|
||||
import one.nem.kidshift.utils.models.LogModel;
|
||||
|
||||
public class KSLoggerImpl implements KSLogger {
|
||||
|
||||
private ArrayList<String> tags = new ArrayList<String>();
|
||||
|
||||
private SharedPrefUtils sharedPrefUtils;
|
||||
|
||||
@AssistedInject
|
||||
public KSLoggerImpl(SharedPrefUtilsFactory sharedPrefUtilsFactory, @Assisted String name) {
|
||||
sharedPrefUtils = sharedPrefUtilsFactory.create("KSLogger");
|
||||
public KSLoggerImpl(@Assisted String name) {
|
||||
tags.clear();
|
||||
tags.add(name);
|
||||
}
|
||||
|
@ -37,11 +24,6 @@ public class KSLoggerImpl implements KSLogger {
|
|||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LogModel> getHistory() {
|
||||
return sharedPrefUtils.getObjects(LogModel.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void info(String message) {
|
||||
log(new LogModel(LogLevelEnum.INFO, tags.toArray(new String[0]), message));
|
||||
|
@ -73,14 +55,9 @@ public class KSLoggerImpl implements KSLogger {
|
|||
}
|
||||
|
||||
private void log(LogModel log) {
|
||||
addLog(log);
|
||||
outputLog(log);
|
||||
}
|
||||
|
||||
private void addLog(LogModel log) {
|
||||
sharedPrefUtils.saveObject(log);
|
||||
}
|
||||
|
||||
private void outputLog(LogModel log) {
|
||||
// ,区切りで出力
|
||||
String tags = log.getTags().length > 0 ? String.join(",", log.getTags()) : "UNTAGGED";
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
package one.nem.kidshift.utils.models;
|
||||
|
||||
public interface FabEventCallback {
|
||||
void onClicked();
|
||||
void onLongClicked();
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package one.nem.kidshift.utils.modules;
|
||||
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
import dagger.hilt.InstallIn;
|
||||
import dagger.hilt.components.SingletonComponent;
|
||||
import one.nem.kidshift.utils.FabManager;
|
||||
import one.nem.kidshift.utils.factory.KSLoggerFactory;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent.class)
|
||||
public class FabManagerModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
public FabManager provideFabManager(KSLoggerFactory loggerFactory) {
|
||||
return new FabManager(loggerFactory);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user