Merge pull request 'ユーザーデータをキャッシュするように' (#86) from feature/cache_parent_data into main
Reviewed-on: #86
This commit is contained in:
commit
a312dcffa7
|
@ -1,5 +1,9 @@
|
|||
package one.nem.kidshift.data;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import one.nem.kidshift.model.ParentModel;
|
||||
|
||||
/**
|
||||
* データの同期など, ユーザーからの操作に基づかない処理を行う
|
||||
*/
|
||||
|
@ -12,6 +16,6 @@ public interface KSActions {
|
|||
/**
|
||||
* 親ユーザー情報同期
|
||||
*/
|
||||
void syncParent();
|
||||
CompletableFuture<ParentModel> syncParent();
|
||||
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package one.nem.kidshift.data;
|
|||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import one.nem.kidshift.model.ParentModel;
|
||||
import one.nem.kidshift.model.callback.ParentModelCallback;
|
||||
|
||||
public interface ParentData {
|
||||
|
||||
|
@ -11,7 +12,7 @@ public interface ParentData {
|
|||
* 親ユーザー情報取得
|
||||
* @return 親ユーザー情報
|
||||
*/
|
||||
CompletableFuture<ParentModel> getParent();
|
||||
CompletableFuture<ParentModel> getParent(ParentModelCallback callback);
|
||||
|
||||
/**
|
||||
* 親ユーザー情報更新
|
||||
|
|
|
@ -7,6 +7,7 @@ public interface UserSettings {
|
|||
ApiSetting getApiSetting();
|
||||
TaskSetting getTaskSetting();
|
||||
AppCommonSetting getAppCommonSetting();
|
||||
SharedPrefCache getCache();
|
||||
|
||||
interface AppCommonSetting {
|
||||
boolean isLoggedIn();
|
||||
|
@ -19,6 +20,11 @@ public interface UserSettings {
|
|||
void setChildMode(boolean childMode);
|
||||
}
|
||||
|
||||
interface SharedPrefCache {
|
||||
ParentModel getParent();
|
||||
void setParent(ParentModel parent);
|
||||
}
|
||||
|
||||
interface ApiSetting {
|
||||
String getApiBaseUrl();
|
||||
void setApiBaseUrl(String url);
|
||||
|
|
|
@ -1,17 +1,30 @@
|
|||
package one.nem.kidshift.data.impl;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
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.model.ParentModel;
|
||||
import one.nem.kidshift.utils.KSLogger;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Response;
|
||||
|
||||
public class KSActionsImpl implements KSActions {
|
||||
|
||||
private UserSettings userSettings;
|
||||
private KidShiftApiService kidShiftApiService;
|
||||
private KSLogger logger;
|
||||
|
||||
@Inject
|
||||
public KSActionsImpl(UserSettings userSettings) {
|
||||
public KSActionsImpl(UserSettings userSettings, KidShiftApiService kidShiftApiService, KSLogger logger) {
|
||||
this.userSettings = userSettings;
|
||||
this.kidShiftApiService = kidShiftApiService;
|
||||
this.logger = logger;
|
||||
logger.setTag("KSActions");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -25,7 +38,33 @@ public class KSActionsImpl implements KSActions {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void syncParent() {
|
||||
|
||||
public CompletableFuture<ParentModel> syncParent() {
|
||||
logger.info("syncParent called and started");
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
logger.info("fetching...");
|
||||
Call<ParentInfoResponse> call = kidShiftApiService.getParentInfo();
|
||||
try {
|
||||
Response<ParentInfoResponse> response = call.execute();
|
||||
if (!response.isSuccessful()) {
|
||||
logger.error("Error fetching parent info: " + response.errorBody().string());
|
||||
throw new RuntimeException("Error fetching parent info: " + response.errorBody().string());
|
||||
}
|
||||
ParentInfoResponse responseBody = response.body();
|
||||
ParentModel parent = new ParentModel();
|
||||
// TODO: 詰め替えをどこかにまとめる, 他のプロパティも処理する
|
||||
parent.setInternalId(responseBody.getId());
|
||||
parent.setEmail(responseBody.getEmail());
|
||||
parent.setDisplayName(responseBody.getEmail()); // Workaround
|
||||
logger.info("Parent fetched with status: " + response.code());
|
||||
logger.debug("Parent: " + parent);
|
||||
// Save to cache
|
||||
userSettings.getCache().setParent(parent);
|
||||
logger.info("Parent saved to cache");
|
||||
return parent;
|
||||
} catch (Exception e) {
|
||||
logger.error("Error fetching parent info");
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,11 +7,14 @@ import java.util.concurrent.CompletableFuture;
|
|||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import one.nem.kidshift.data.KSActions;
|
||||
import one.nem.kidshift.data.ParentData;
|
||||
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.model.ParentModel;
|
||||
import one.nem.kidshift.model.callback.ParentModelCallback;
|
||||
import one.nem.kidshift.utils.KSLogger;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Response;
|
||||
|
||||
|
@ -21,35 +24,40 @@ public class ParentDataImpl implements ParentData {
|
|||
|
||||
private UserSettings userSettings;
|
||||
|
||||
private KSLogger logger;
|
||||
|
||||
private KSActions ksActions;
|
||||
|
||||
@Inject
|
||||
public ParentDataImpl(KidShiftApiService kidshiftApiService, UserSettings userSettings) {
|
||||
public ParentDataImpl(KidShiftApiService kidshiftApiService, UserSettings userSettings, KSLogger logger, KSActions ksActions) {
|
||||
this.kidshiftApiService = kidshiftApiService;
|
||||
this.userSettings = userSettings;
|
||||
this.logger = logger;
|
||||
this.ksActions = ksActions;
|
||||
|
||||
logger.setTag("ParentData");
|
||||
}
|
||||
|
||||
// 一旦キャッシュを返して, その後非同期でAPIから取得→更新があればコールバックで通知
|
||||
@Override
|
||||
public CompletableFuture<ParentModel> getParent() {
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
Response<ParentInfoResponse> parentInfoResponse;
|
||||
Call<ParentInfoResponse> response = kidshiftApiService.getParentInfo();
|
||||
try {
|
||||
parentInfoResponse = response.execute();
|
||||
ParentInfoResponse responseBody = parentInfoResponse.body();
|
||||
ParentModel parent = new ParentModel();
|
||||
assert parentInfoResponse != null;
|
||||
parent.setInternalId(responseBody.getId());
|
||||
parent.setEmail(responseBody.getEmail());
|
||||
parent.setDisplayName(responseBody.getEmail()); // Workaround
|
||||
// TODO: 他のプロパティも処理する
|
||||
return parent;
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
public CompletableFuture<ParentModel> getParent(ParentModelCallback callback) {
|
||||
// Start thread to fetch parent info
|
||||
new Thread(() -> {
|
||||
logger.info("Fetching parent info...");
|
||||
ParentModel refreshedParent = ksActions.syncParent().join();
|
||||
if (refreshedParent == null) {
|
||||
callback.onFailed("Failed to fetch parent info");
|
||||
} else {
|
||||
// Workaround, TODO: Compare with existing parent
|
||||
callback.onUpdated(refreshedParent);
|
||||
}
|
||||
});
|
||||
}).start();
|
||||
return CompletableFuture.supplyAsync(() -> userSettings.getCache().getParent());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateParent(ParentModel parent) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import java.util.Objects;
|
|||
import javax.inject.Inject;
|
||||
|
||||
import one.nem.kidshift.data.UserSettings;
|
||||
import one.nem.kidshift.model.ParentModel;
|
||||
import one.nem.kidshift.utils.SharedPrefUtils;
|
||||
import one.nem.kidshift.utils.factory.SharedPrefUtilsFactory;
|
||||
|
||||
|
@ -35,6 +36,44 @@ public class UserSettingsImpl implements UserSettings {
|
|||
return new AppCommonSettingImpl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SharedPrefCache getCache() {
|
||||
return new SharedPrefCacheImpl();
|
||||
}
|
||||
|
||||
public class SharedPrefCacheImpl implements UserSettings.SharedPrefCache {
|
||||
|
||||
transient
|
||||
SharedPrefUtils sharedPrefUtils;
|
||||
|
||||
ParentModel parent;
|
||||
|
||||
SharedPrefCacheImpl() {
|
||||
sharedPrefUtils = sharedPrefUtilsFactory.create("user_settings");
|
||||
SharedPrefCacheImpl sharedPrefCache = sharedPrefUtils.getObject("shared_pref_cache", SharedPrefCacheImpl.class);
|
||||
if (sharedPrefCache != null) {
|
||||
parent = sharedPrefCache.getParent();
|
||||
} else {
|
||||
parent = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void save() {
|
||||
sharedPrefUtils.saveObject("shared_pref_cache", this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParentModel getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setParent(ParentModel parent) {
|
||||
this.parent = parent;
|
||||
save();
|
||||
}
|
||||
}
|
||||
|
||||
public class AppCommonSettingImpl implements UserSettings.AppCommonSetting {
|
||||
|
||||
transient
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
package one.nem.kidshift.data.modules;
|
||||
|
||||
import dagger.Binds;
|
||||
import dagger.Module;
|
||||
import dagger.hilt.InstallIn;
|
||||
import dagger.hilt.components.SingletonComponent;
|
||||
import one.nem.kidshift.data.KSActions;
|
||||
import one.nem.kidshift.data.impl.KSActionsImpl;
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent.class)
|
||||
public abstract class KSActionsModule {
|
||||
|
||||
@Binds
|
||||
public abstract KSActions bindKSActions(KSActionsImpl impl);
|
||||
}
|
|
@ -16,6 +16,7 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
|
@ -24,6 +25,7 @@ import one.nem.kidshift.data.ChildData;
|
|||
import one.nem.kidshift.data.ParentData;
|
||||
import one.nem.kidshift.model.ChildModel;
|
||||
import one.nem.kidshift.model.ParentModel;
|
||||
import one.nem.kidshift.model.callback.ParentModelCallback;
|
||||
|
||||
/**
|
||||
* A simple {@link Fragment} subclass.
|
||||
|
@ -85,8 +87,35 @@ public class SettingMainFragment extends Fragment {
|
|||
Bundle savedInstanceState) {
|
||||
// Inflate the layout for this fragment
|
||||
|
||||
//親の名前、アドレス表示
|
||||
ParentModel parent = parentData.getParent().join();
|
||||
CompletableFuture<ParentModel> completableFuture = parentData.getParent(new ParentModelCallback() {
|
||||
|
||||
@Override
|
||||
public void onUnchanged() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdated(ParentModel parent) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailed(String message) {
|
||||
// TODO
|
||||
}
|
||||
});
|
||||
|
||||
/*
|
||||
TODO:
|
||||
- コールバックの処理を実装
|
||||
- 結果に応じてRecyclerViewを更新する
|
||||
- キャッシュ受け取りの時にjoinでUIスレッドをブロックしないように
|
||||
- Placeholderの表示?
|
||||
- エラーハンドリング
|
||||
- onFailed時にそれを通知
|
||||
*/
|
||||
|
||||
ParentModel parent = completableFuture.join();
|
||||
|
||||
if (parent == null) {
|
||||
parent = new ParentModel(); // Workaround(非ログインデバッグ用)
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
package one.nem.kidshift.model.callback;
|
||||
|
||||
import one.nem.kidshift.model.ParentModel;
|
||||
|
||||
public interface ParentModelCallback {
|
||||
void onUnchanged();
|
||||
void onUpdated(ParentModel parent);
|
||||
void onFailed(String message);
|
||||
}
|
Loading…
Reference in New Issue
Block a user