タスクリストがバックエンドから取得されるように #87

Merged
Fujimatsu merged 40 commits from feature/task_be into main 2024-06-26 07:18:06 +00:00
23 changed files with 428 additions and 277 deletions

View File

@ -2,6 +2,7 @@ package one.nem.kidshift.data;
import java.util.concurrent.CompletableFuture;
import one.nem.kidshift.data.retrofit.model.task.TaskListResponse;
import one.nem.kidshift.model.ParentModel;
/**
@ -9,7 +10,7 @@ import one.nem.kidshift.model.ParentModel;
*/
public interface KSActions {
void syncTasks();
CompletableFuture<TaskListResponse> syncTasks();
void syncChildList();

View File

@ -1,6 +1,7 @@
package one.nem.kidshift.data;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import one.nem.kidshift.model.tasks.TaskItemModel;
@ -10,9 +11,16 @@ public interface TaskData {
/**
* 存在する全てのタスクを取得する
* @return List<TaskItemModel> タスクリスト
* @return CompletableFuture<List<TaskItemModel>> タスクリスト
*/
List<TaskItemModel> getTasks();
CompletableFuture<List<TaskItemModel>> getTasks();
/**
* アタッチされている全てのタスクを取得する
* @param childId 子ID
* @return CompletableFuture<List<TaskItemModel>> タスクリスト
*/
CompletableFuture<List<TaskItemModel>> getTasks(String childId);
/**
* タスクを追加する

View File

@ -8,6 +8,7 @@ import one.nem.kidshift.data.KSActions;
import one.nem.kidshift.data.UserSettings;
import one.nem.kidshift.data.retrofit.KidShiftApiService;
import one.nem.kidshift.data.retrofit.model.parent.ParentInfoResponse;
import one.nem.kidshift.data.retrofit.model.task.TaskListResponse;
import one.nem.kidshift.model.ParentModel;
import one.nem.kidshift.utils.KSLogger;
import retrofit2.Call;
@ -28,8 +29,27 @@ public class KSActionsImpl implements KSActions {
}
@Override
public void syncTasks() {
public CompletableFuture<TaskListResponse> syncTasks() {
return CompletableFuture.supplyAsync(() -> {
Call<TaskListResponse> call = kidShiftApiService.getTasks();
try {
Response<TaskListResponse> response = call.execute();
if (!response.isSuccessful()) {
logger.error("Error fetching tasks: " + response.errorBody().string());
throw new RuntimeException("Error fetching tasks: " + response.errorBody().string());
}
TaskListResponse responseBody = response.body();
logger.info("Tasks fetched with status: " + response.code());
logger.debug("Tasks: " + responseBody.getList());
// // Save to cache
// userSettings.getCache().setTasks(responseBody.getList());
// logger.info("Tasks saved to cache");
return responseBody;
} catch (Exception e) {
logger.error("Error fetching tasks");
throw new RuntimeException(e);
}
});
}
@Override

View File

@ -1,78 +0,0 @@
package one.nem.kidshift.data.impl;
import com.github.javafaker.Faker;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import javax.inject.Inject;
import one.nem.kidshift.data.TaskData;
import one.nem.kidshift.model.tasks.TaskItemModel;
import one.nem.kidshift.model.tasks.condition.TaskConditionBaseModel;
import one.nem.kidshift.model.tasks.condition.TaskConditionNoneModel;
import one.nem.kidshift.utils.KSLogger;
public class TaskDataDummyImpl implements TaskData {
private Faker faker;
@Inject
KSLogger logger;
@Inject
public TaskDataDummyImpl() {
faker = new Faker();
// logger.setTag("TaskDataDummyImpl");
}
@Override
public List<TaskItemModel> getTasks() {
// logger.info("getTotalReward called");
List<TaskItemModel> tasks = new ArrayList<>();
int totalTasks = faker.number().numberBetween(1, 15);
// logger.info("Returning total tasks: " + totalTasks);
for (int i = 0; i < totalTasks; i++) {
tasks.add(new TaskItemModel(
UUID.randomUUID().toString(),
faker.lorem().sentence(), UUID.randomUUID().toString(),
new TaskConditionNoneModel(),
faker.number().numberBetween(1, 1000)));
}
// logger.info("Returning tasks: " + tasks);
return tasks;
}
@Override
public void addTask(TaskItemModel task) {
logger.info("addTask called");
logger.info("Task: " + task);
}
@Override
public void removeTask(String taskId) {
logger.info("removeTask called");
logger.info("Task ID: " + taskId);
}
@Override
public void updateTask(TaskItemModel task) {
logger.info("updateTask called");
logger.info("Task: " + task);
}
@Override
public TaskItemModel getTask(String taskId) {
List<TaskItemModel> tasks = getTasks();
// return random task
return tasks.get(faker.number().numberBetween(0, tasks.size()));
}
@Override
public void recordTaskCompletion(String taskId, String childId) {
logger.info("recordTaskCompletion called");
logger.info("Task ID: " + taskId);
logger.info("Child ID: " + childId);
}
}

View File

@ -0,0 +1,68 @@
package one.nem.kidshift.data.impl;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
import javax.inject.Inject;
import one.nem.kidshift.data.KSActions;
import one.nem.kidshift.data.TaskData;
import one.nem.kidshift.data.retrofit.model.task.TaskListResponse;
import one.nem.kidshift.model.tasks.TaskItemModel;
public class TaskDataImpl implements TaskData {
KSActions ksActions;
@Inject
public TaskDataImpl(KSActions ksActions) {
this.ksActions = ksActions;
}
@Override
public CompletableFuture<List<TaskItemModel>> getTasks() {
return CompletableFuture.supplyAsync(() -> {
TaskListResponse data = ksActions.syncTasks().join();
return data.getList().stream().map(task -> {
// Convert TaskItemModel
TaskItemModel model = new TaskItemModel();
model.setInternalId(task.getId());
model.setDisplayName(task.getName());
model.setReward(task.getReward());
return model;
}).collect(Collectors.toList());
});
}
@Override
public CompletableFuture<List<TaskItemModel>> getTasks(String childId) {
return null;
}
@Override
public void addTask(TaskItemModel task) {
}
@Override
public void removeTask(String taskId) {
}
@Override
public void updateTask(TaskItemModel task) {
}
@Override
public TaskItemModel getTask(String taskId) {
return null;
}
@Override
public void recordTaskCompletion(String taskId, String childId) {
}
}

View File

@ -5,12 +5,12 @@ import dagger.Module;
import dagger.hilt.InstallIn;
import dagger.hilt.android.components.FragmentComponent;
import one.nem.kidshift.data.TaskData;
import one.nem.kidshift.data.impl.TaskDataDummyImpl;
import one.nem.kidshift.data.impl.TaskDataImpl;
@Module
@InstallIn(FragmentComponent.class)
abstract public class TaskDataDummyModule {
public abstract class TaskDataModule {
@Binds
public abstract TaskData bindTaskData(TaskDataDummyImpl taskDataDummyImpl);
public abstract TaskData bindTaskData(TaskDataImpl taskDataImpl);
}

View File

@ -4,6 +4,7 @@ import one.nem.kidshift.data.retrofit.interceptor.AuthorizationInterceptor;
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.ParentLoginResponse;
import one.nem.kidshift.data.retrofit.model.task.TaskListResponse;
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.GET;
@ -20,4 +21,7 @@ public interface KidShiftApiService {
@Headers(AuthorizationInterceptor.HEADER_PLACEHOLDER)
Call<ParentInfoResponse> getParentInfo();
@GET("/parent/task")
@Headers(AuthorizationInterceptor.HEADER_PLACEHOLDER)
Call<TaskListResponse> getTasks();
}

View File

@ -0,0 +1,23 @@
package one.nem.kidshift.data.retrofit.model.child;
// Request to add a child
public class ChildAddRequest {
private String name;
// Constructor
public ChildAddRequest(String name) {
this.name = name;
}
public ChildAddRequest() {
}
// Getters and setters
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View File

@ -0,0 +1,33 @@
package one.nem.kidshift.data.retrofit.model.child;
// Base class for children
public class ChildBaseItem {
private String id;
private String name;
// Constructor
public ChildBaseItem(String id, String name) {
this.id = id;
this.name = name;
}
public ChildBaseItem() {
}
// Getters and setters
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View File

@ -0,0 +1,36 @@
package one.nem.kidshift.data.retrofit.model.child;
import java.util.Date;
// Response for detailed information about a child
public class ChildDetailsResponse extends ChildBaseItem {
private Date createdAt;
private String homeGroupId;
// Constructor
public ChildDetailsResponse(String id, String name, Date createdAt, String homeGroupId) {
super(id, name);
this.createdAt = createdAt;
this.homeGroupId = homeGroupId;
}
public ChildDetailsResponse() {
}
// Getters and setters
public Date getCreatedAt() {
return createdAt;
}
public void setCreatedAt(Date createdAt) {
this.createdAt = createdAt;
}
public String getHomeGroupId() {
return homeGroupId;
}
public void setHomeGroupId(String homeGroupId) {
this.homeGroupId = homeGroupId;
}
}

View File

@ -0,0 +1,25 @@
package one.nem.kidshift.data.retrofit.model.child;
import java.util.List;
// Response for a list of children
public class ChildListResponse {
private List<ChildResponse> list;
// Constructor
public ChildListResponse(List<ChildResponse> list) {
this.list = list;
}
public ChildListResponse() {
}
// Getters and setters
public List<ChildResponse> getList() {
return list;
}
public void setList(List<ChildResponse> list) {
this.list = list;
}
}

View File

@ -0,0 +1,4 @@
package one.nem.kidshift.data.retrofit.model.child;
public class ChildRequest extends ChildBaseItem {
}

View File

@ -0,0 +1,4 @@
package one.nem.kidshift.data.retrofit.model.child;
public class ChildResponse extends ChildBaseItem {
}

View File

@ -0,0 +1,39 @@
package one.nem.kidshift.data.retrofit.model.task;
import java.util.List;
// Request to add a task, with optional attached children
public class TaskAddRequest extends TaskBaseItem {
private List<String> attachedChildren;
// Full
public TaskAddRequest(String name, String iconEmoji, String bgColor, int reward, List<String> attachedChildren) {
super(name, iconEmoji, bgColor, reward);
this.attachedChildren = attachedChildren;
}
// Required
public TaskAddRequest(String name, int reward, List<String> attachedChildren) {
super(name, reward);
this.attachedChildren = attachedChildren;
}
// Empty
public TaskAddRequest() {
}
// Extend
public TaskAddRequest(TaskBaseItem taskBaseItem, List<String> attachedChildren) {
super(taskBaseItem.getName(), taskBaseItem.getIconEmoji(), taskBaseItem.getBgColor(), taskBaseItem.getReward());
this.attachedChildren = attachedChildren;
}
// Getters and setters
public List<String> getAttachedChildren() {
return attachedChildren;
}
public void setAttachedChildren(List<String> attachedChildren) {
this.attachedChildren = attachedChildren;
}
}

View File

@ -0,0 +1,85 @@
package one.nem.kidshift.data.retrofit.model.task;
// Base class for tasks
public class TaskBaseItem {
private String id;
private String name;
private String iconEmoji; // Optional
private String bgColor; // Optional
private int reward;
// Full
public TaskBaseItem(String id, String name, String iconEmoji, String bgColor, int reward) {
this.id = id;
this.name = name;
this.iconEmoji = iconEmoji;
this.bgColor = bgColor;
this.reward = reward;
}
// Without id
public TaskBaseItem(String name, String iconEmoji, String bgColor, int reward) {
this.name = name;
this.iconEmoji = iconEmoji;
this.bgColor = bgColor;
this.reward = reward;
}
// Required
public TaskBaseItem(String id, String name, int reward) {
this.id = id;
this.name = name;
this.reward = reward;
}
// Without id and optional fields
public TaskBaseItem(String name, int reward) {
this.name = name;
this.reward = reward;
}
// Empty
public TaskBaseItem() {
}
// Getters and setters
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getIconEmoji() {
return iconEmoji;
}
public void setIconEmoji(String iconEmoji) {
this.iconEmoji = iconEmoji;
}
public String getBgColor() {
return bgColor;
}
public void setBgColor(String bgColor) {
this.bgColor = bgColor;
}
public int getReward() {
return reward;
}
public void setReward(int reward) {
this.reward = reward;
}
}

View File

@ -0,0 +1,26 @@
package one.nem.kidshift.data.retrofit.model.task;
import java.util.List;
// Response for a list of tasks
public class TaskListResponse {
private List<TaskBaseItem> list;
// Full
public TaskListResponse(List<TaskBaseItem> list) {
this.list = list;
}
// Empty
public TaskListResponse() {
}
// Getters and setters
public List<TaskBaseItem> getList() {
return list;
}
public void setList(List<TaskBaseItem> list) {
this.list = list;
}
}

View File

@ -0,0 +1,39 @@
package one.nem.kidshift.data.retrofit.model.task;
import java.util.List;
// Response for a single task with attached children
public class TaskResponse extends TaskBaseItem {
private List<String> attachedChildren;
// Full
public TaskResponse(String id, String name, String iconEmoji, String bgColor, int reward, List<String> attachedChildren) {
super(id, name, iconEmoji, bgColor, reward);
this.attachedChildren = attachedChildren;
}
// Required
public TaskResponse(String id, String name, int reward, List<String> attachedChildren) {
super(id, name, reward);
this.attachedChildren = attachedChildren;
}
// Empty
public TaskResponse() {
}
// Extend
public TaskResponse(TaskBaseItem taskBaseItem, List<String> attachedChildren) {
super(taskBaseItem.getId(), taskBaseItem.getName(), taskBaseItem.getIconEmoji(), taskBaseItem.getBgColor(), taskBaseItem.getReward());
this.attachedChildren = attachedChildren;
}
// Getters and setters
public List<String> getAttachedChildren() {
return attachedChildren;
}
public void setAttachedChildren(List<String> attachedChildren) {
this.attachedChildren = attachedChildren;
}
}

View File

@ -1,62 +0,0 @@
package one.nem.kidshift.feature.debug;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import javax.inject.Inject;
import dagger.hilt.android.AndroidEntryPoint;
import one.nem.kidshift.data.RewardData;
import one.nem.kidshift.data.TaskData;
@AndroidEntryPoint
public class DebugMockTestFragment extends Fragment {
@Inject
TaskData taskData;
@Inject
RewardData rewardData;
public DebugMockTestFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_debug_mock_test, container, false);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// TaskData
TextView taskDataStatus = view.findViewById(R.id.taskData_mockedStatusTextView);
taskDataStatus.setText("isMocked: true"); // TODO: 固定値やめる
TextView taskDataResult = view.findViewById(R.id.taskData_resultTextView);
view.findViewById(R.id.taskData_getTasksButton).setOnClickListener(v -> {
taskDataResult.setText(taskData.getTasks().stream().map(Object::toString).reduce("", (a, b) -> a + b + "\n"));
});
// RewardData
TextView rewardDataStatus = view.findViewById(R.id.rewardData_mockedStatusTextView);
rewardDataStatus.setText("isMocked: true"); // TODO: 固定値やめる
TextView rewardDataResult = view.findViewById(R.id.rewardData_resultTextView);
view.findViewById(R.id.rewardData_getTotalRewardButton).setOnClickListener(v -> {
rewardDataResult.setText(rewardData.getTotalReward().toString());
});
}
}

View File

@ -31,7 +31,6 @@ public class DebugTopMenuFragment extends Fragment {
recyclerView.setLayoutManager(new androidx.recyclerview.widget.LinearLayoutManager(getContext()));
List<DebugMenuListItemModel> debugMenuListItems = new ArrayList<>();
debugMenuListItems.add(new DebugMenuListItemModel("Data mock tester", "データモジュールの取得処理のモックをテストします", R.id.action_debugTopMenuFragment_to_debugMockTestFragment, true));
debugMenuListItems.add(new DebugMenuListItemModel("Debug console", "デバッグコマンドを実行します", R.id.action_debugTopMenuFragment_to_debugDebugConsoleFragment, true));
debugMenuListItems.add(new DebugMenuListItemModel("Temp login", "仮置きログイン画面を表示", R.id.action_debugTopMenuFragment_to_debugTempLoginFragment, true));
debugMenuListItems.add(new DebugMenuListItemModel("Temp register", "仮置き登録画面を表示", R.id.action_debugTopMenuFragment_to_debugTempRegisterFragment, true));

View File

@ -1,119 +0,0 @@
<?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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".DebugMockTestFragment">
<!-- TODO: Update blank fragment layout -->
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="TaskData"
android:textAppearance="@style/TextAppearance.AppCompat.Medium" />
<TextView
android:id="@+id/taskData_mockedStatusTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="isMocked:" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<Button
android:id="@+id/taskData_getTasksButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="getTasks()"
android:textAppearance="@style/TextAppearance.AppCompat.Body1" />
<Button
android:id="@+id/taskData_placeholderButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="-----" />
</LinearLayout>
<TextView
android:id="@+id/taskData_resultTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="result..." />
</LinearLayout>
<View
android:id="@+id/divider"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginVertical="16dp"
android:background="?android:attr/listDivider" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="RewardData"
android:textAppearance="@style/TextAppearance.AppCompat.Medium" />
<TextView
android:id="@+id/rewardData_mockedStatusTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="isMocked:" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<Button
android:id="@+id/rewardData_getTotalRewardButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="getTotalReward()"
android:textAppearance="@style/TextAppearance.AppCompat.Body1" />
</LinearLayout>
<TextView
android:id="@+id/rewardData_resultTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="result..." />
</LinearLayout>
</LinearLayout>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -10,9 +10,6 @@
android:name="one.nem.kidshift.feature.debug.DebugTopMenuFragment"
android:label="fragment_debug_top_menu"
tools:layout="@layout/fragment_debug_top_menu" >
<action
android:id="@+id/action_debugTopMenuFragment_to_debugMockTestFragment"
app:destination="@id/debugMockTestFragment" />
<action
android:id="@+id/action_debugTopMenuFragment_to_debugDebugConsoleFragment"
app:destination="@id/debugDebugConsoleFragment" />
@ -23,11 +20,6 @@
android:id="@+id/action_debugTopMenuFragment_to_debugTempRegisterFragment"
app:destination="@id/debugTempRegisterFragment" />
</fragment>
<fragment
android:id="@+id/debugMockTestFragment"
android:name="one.nem.kidshift.feature.debug.DebugMockTestFragment"
android:label="fragment_debug_mock_test"
tools:layout="@layout/fragment_debug_mock_test" />
<fragment
android:id="@+id/debugDebugConsoleFragment"
android:name="one.nem.kidshift.feature.debug.DebugDebugConsoleFragment"

View File

@ -44,7 +44,7 @@ public class ParentMainFragment extends Fragment {
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getContext());
recyclerView.setLayoutManager(layoutManager);
List<TaskItemModel> task = taskData.getTasks();
List<TaskItemModel> task = taskData.getTasks().join();
RecyclerView.Adapter mainAdapter = new ParentAdapter(task);
recyclerView.setAdapter(mainAdapter);

View File

@ -44,6 +44,10 @@ public class TaskItemModel {
this.reward = reward;
}
public TaskItemModel() {
}
// getter setter
public String getInternalId() {