Compare commits
No commits in common. "main" and "feature/wallet" have entirely different histories.
main
...
feature/wa
21
LICENSE
|
@ -1,21 +0,0 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2024 グループワークチーム「シフトメイト」メンバー
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
36
README.md
|
@ -1,38 +1,8 @@
|
|||
# WIP
|
||||
|
||||
~~## メモ
|
||||
## メモ
|
||||
- リリース前(=提出前)には`DEBUG_ONLY`で検索してチェック(念のため)
|
||||
|
||||
## リリース前チェック
|
||||
- DBの破壊的マイグレーションを許可するオプションを無効に~~
|
||||
|
||||
#### 補足
|
||||
- カレンダーはCompactCalendarViewをそのまま使用する予定でしたが,AndroidX環境で使用するとクラス重複でビルドできないため,AndroidXに対応させるPRを取り込んだ物を専用Mavenリポジトリとして公開して使用しています
|
||||
- https://github.com/r-ca/CompactCalendarView
|
||||
|
||||
## 補足
|
||||
- 直前に大規模リファクタリングを始めていたため,未使用コード(ファイル)がいくつか残っています
|
||||
- `:feature:setting`, `:feature:parent` は廃止されており, 現在は使用されていません
|
||||
- `:feature:child` は子供管理画面のアクティビティのみ使用されています
|
||||
|
||||
- 親, 子供のタスク一覧画面はどちらも`:feature:common`の`CommonHomeFragment`を用いており, ナビゲーショングラフを切り替えることで表示モードを切り替えています
|
||||
|
||||
## 既知の問題
|
||||
- 初回起動時, ウォレットの表示に失敗する場合がある
|
||||
- 特定の操作を行った場合にナビゲーションが正常に動作しなくなる場合がある
|
||||
- 特定の状況で子供モード時に追加ウィンドウが開けてしまう場合がある(APIの権限チェックではじかれるため, 実際に追加することは不可能)
|
||||
- カレンダーの表示を切り替える際, RecyclerViewのアニメーションが一定範囲にしか反映されない
|
||||
- お手伝い履歴がローカルキャッシュされておらず,毎回サーバーから全データを取得している
|
||||
- ウォレット画面でPull-to-Refreshが動作しない
|
||||
- ウォレット画面にて非UIスレッドでUI更新を行ってしまっている?
|
||||
- オフライン時,ウォレットなど一部の画面でクラッシュする場合がある
|
||||
- 資格情報が間違ったままログインできてしまう
|
||||
- キャッシュとサーバーのマスターデータに差異があった場合, 再表示しないと表示に適応されない場合がある(コールバックの処理が適切に実装されていない画面がある)
|
||||
|
||||
## TODO
|
||||
- 全体的なUX改善
|
||||
- インメモリデータベースの活用(Related: 全体的なUX改善)
|
||||
- ViewModelの本格導入
|
||||
- タスクのアサイン機能への対応
|
||||
- 親モードで子供画面を表示したとき, 親モードへの移動にロックをかけられるようにする
|
||||
- 非DynamicColor機種で使用されるテーマの適用が中途半端なので完全に適用するように
|
||||
- DBの破壊的マイグレーションを許可するオプションを無効に
|
||||
-
|
|
@ -15,9 +15,6 @@
|
|||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.KidShift"
|
||||
tools:targetApi="31">
|
||||
<activity
|
||||
android:name=".ChildLoginActivity"
|
||||
android:exported="false" />
|
||||
<activity
|
||||
android:name=".RegisterActivity"
|
||||
android:exported="false" />
|
||||
|
|
Before Width: | Height: | Size: 9.3 KiB |
|
@ -1,154 +0,0 @@
|
|||
package one.nem.kidshift;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Toast;
|
||||
|
||||
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.ChildData;
|
||||
import one.nem.kidshift.data.UserSettings;
|
||||
import one.nem.kidshift.data.retrofit.KidShiftApiService;
|
||||
import one.nem.kidshift.data.retrofit.model.child.auth.ChildAuthRequest;
|
||||
import one.nem.kidshift.data.retrofit.model.child.auth.ChildAuthResponse;
|
||||
import one.nem.kidshift.utils.KSLogger;
|
||||
import one.nem.kidshift.utils.factory.KSLoggerFactory;
|
||||
import retrofit2.Call;
|
||||
|
||||
@AndroidEntryPoint
|
||||
public class ChildLoginActivity extends AppCompatActivity {
|
||||
|
||||
@Inject
|
||||
UserSettings userSettings;
|
||||
@Inject
|
||||
KSLoggerFactory loggerFactory;
|
||||
@Inject
|
||||
KidShiftApiService kidShiftApiService;
|
||||
|
||||
private KSLogger logger;
|
||||
|
||||
|
||||
private EditText loginCode1, loginCode2, loginCode3, loginCode4, loginCode5, loginCode6, loginCode7, loginCode8;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
EdgeToEdge.enable(this);
|
||||
setContentView(R.layout.activity_child_login);
|
||||
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("ChildLoginActivity");
|
||||
|
||||
// コードのフォーカスを自動で移動する
|
||||
loginCode1 = findViewById(R.id.loginCode_1);
|
||||
loginCode2 = findViewById(R.id.loginCode_2);
|
||||
loginCode3 = findViewById(R.id.loginCode_3);
|
||||
loginCode4 = findViewById(R.id.loginCode_4);
|
||||
loginCode5 = findViewById(R.id.loginCode_5);
|
||||
loginCode6 = findViewById(R.id.loginCode_6);
|
||||
loginCode7 = findViewById(R.id.loginCode_7);
|
||||
loginCode8 = findViewById(R.id.loginCode_8);
|
||||
|
||||
loginCode1.addTextChangedListener(new LoginCodeTextWatcher(loginCode1, loginCode2, null));
|
||||
loginCode2.addTextChangedListener(new LoginCodeTextWatcher(loginCode2, loginCode3, loginCode1));
|
||||
loginCode3.addTextChangedListener(new LoginCodeTextWatcher(loginCode3, loginCode4, loginCode2));
|
||||
loginCode4.addTextChangedListener(new LoginCodeTextWatcher(loginCode4, loginCode5, loginCode3));
|
||||
loginCode5.addTextChangedListener(new LoginCodeTextWatcher(loginCode5, loginCode6, loginCode4));
|
||||
loginCode6.addTextChangedListener(new LoginCodeTextWatcher(loginCode6, loginCode7, loginCode5));
|
||||
loginCode7.addTextChangedListener(new LoginCodeTextWatcher(loginCode7, loginCode8, loginCode6));
|
||||
loginCode8.addTextChangedListener(new LoginCodeTextWatcher(loginCode8, null, loginCode7));
|
||||
|
||||
// ログインボタンを押したときの処理
|
||||
findViewById(R.id.childLoginButton).setOnClickListener(v -> {
|
||||
logger.debug("ログインボタンが押されました");
|
||||
Call<ChildAuthResponse> call = kidShiftApiService.childLogin(new ChildAuthRequest(getLoginCode()));
|
||||
CompletableFuture.runAsync(() -> {
|
||||
try {
|
||||
ChildAuthResponse childAuthResponse = call.execute().body();
|
||||
if (childAuthResponse == null || childAuthResponse.getAccessToken() == null) {
|
||||
// エラー処理
|
||||
logger.error("ChildAuthResponseがnullまたはAccessTokenがnullです");
|
||||
return;
|
||||
}
|
||||
UserSettings.AppCommonSetting appCommonSetting = userSettings.getAppCommonSetting();
|
||||
appCommonSetting.setLoggedIn(true);
|
||||
appCommonSetting.setAccessToken(childAuthResponse.getAccessToken());
|
||||
appCommonSetting.setChildId(childAuthResponse.getChildId());
|
||||
appCommonSetting.setChildMode(true);
|
||||
} catch (Exception e) {
|
||||
logger.error("リクエストに失敗しました");
|
||||
Toast.makeText(this, "ログインに失敗しました", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}).thenRun(() -> {
|
||||
startActivity(new Intent(this, MainActivity.class));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private String getLoginCode() {
|
||||
return loginCode1.getText().toString() +
|
||||
loginCode2.getText().toString() +
|
||||
loginCode3.getText().toString() +
|
||||
loginCode4.getText().toString() +
|
||||
loginCode5.getText().toString() +
|
||||
loginCode6.getText().toString() +
|
||||
loginCode7.getText().toString() +
|
||||
loginCode8.getText().toString();
|
||||
}
|
||||
|
||||
private static class LoginCodeTextWatcher implements TextWatcher, View.OnKeyListener {
|
||||
private EditText currentView;
|
||||
private final EditText nextView;
|
||||
private final EditText previousView;
|
||||
|
||||
LoginCodeTextWatcher(EditText currentView, EditText nextView, EditText previousView) {
|
||||
this.currentView = currentView;
|
||||
this.nextView = nextView;
|
||||
this.previousView = previousView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) { }
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
if (s.length() == 1 && nextView != null) {
|
||||
nextView.requestFocus();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKey(View v, int keyCode, KeyEvent event) {
|
||||
// if (keyCode == KeyEvent.KEYCODE_DEL && event.getAction() == KeyEvent.ACTION_DOWN) { // TODO: バックスペースの処理
|
||||
// EditText currentView = (EditText) v;
|
||||
// if (currentView.getText().length() == 0 && previousView != null) {
|
||||
// previousView.requestFocus();
|
||||
// }
|
||||
// }
|
||||
// return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -54,10 +54,10 @@ public class LoginActivity extends AppCompatActivity {
|
|||
|
||||
logger = loggerFactory.create("LoginActivity");
|
||||
|
||||
EditText emailEditText = findViewById(R.id.parentLoginEmailEditText);
|
||||
EditText passwordEditText = findViewById(R.id.parentLoginPasswordEditText);
|
||||
EditText emailEditText = findViewById(R.id.emailEditText);
|
||||
EditText passwordEditText = findViewById(R.id.passwordEditText);
|
||||
|
||||
findViewById(R.id.parentLoginButton).setOnClickListener(v -> {
|
||||
findViewById(R.id.loginButton).setOnClickListener(v -> {
|
||||
String email = emailEditText.getText().toString(); // TODO: メールアドレスのバリデーション
|
||||
String password = passwordEditText.getText().toString();
|
||||
|
||||
|
@ -87,12 +87,8 @@ public class LoginActivity extends AppCompatActivity {
|
|||
});
|
||||
});
|
||||
|
||||
findViewById(R.id.toRegisterButton).setOnClickListener(v -> {
|
||||
findViewById(R.id.intentRegisterButton).setOnClickListener(v -> {
|
||||
startActivity(new Intent(this, RegisterActivity.class));
|
||||
});
|
||||
|
||||
findViewById(R.id.toChildLoginButton).setOnClickListener(v -> {
|
||||
startActivity(new Intent(this, ChildLoginActivity.class));
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,17 +1,9 @@
|
|||
package one.nem.kidshift;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.EditText;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ScrollView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.activity.EdgeToEdge;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.ActionBarDrawerToggle;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
|
@ -22,54 +14,35 @@ import androidx.drawerlayout.widget.DrawerLayout;
|
|||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.navigation.NavController;
|
||||
import androidx.navigation.fragment.NavHostFragment;
|
||||
import androidx.navigation.ui.AppBarConfiguration;
|
||||
import androidx.navigation.ui.NavigationUI;
|
||||
|
||||
import com.google.android.material.bottomnavigation.BottomNavigationView;
|
||||
import com.google.android.material.chip.Chip;
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
import com.google.android.material.divider.MaterialDivider;
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||
import com.google.android.material.navigation.NavigationView;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import dagger.hilt.android.AndroidEntryPoint;
|
||||
import one.nem.kidshift.data.ChildData;
|
||||
import one.nem.kidshift.data.ParentData;
|
||||
import one.nem.kidshift.data.UserSettings;
|
||||
import one.nem.kidshift.feature.child.ChildManageMainActivity;
|
||||
import one.nem.kidshift.model.ParentModel;
|
||||
import one.nem.kidshift.model.callback.ParentModelCallback;
|
||||
import one.nem.kidshift.utils.FabManager;
|
||||
import one.nem.kidshift.utils.FeatureFlag;
|
||||
import one.nem.kidshift.utils.KSLogger;
|
||||
import one.nem.kidshift.utils.ToolBarManager;
|
||||
import one.nem.kidshift.utils.factory.KSLoggerFactory;
|
||||
|
||||
@AndroidEntryPoint
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
|
||||
@Inject
|
||||
KSLoggerFactory ksLoggerFactory;
|
||||
KSLoggerFactory loggerFactory;
|
||||
|
||||
@Inject
|
||||
FabManager fabManager;
|
||||
@Inject
|
||||
ToolBarManager toolBarManager;
|
||||
@Inject
|
||||
FeatureFlag featureFlag;
|
||||
@Inject
|
||||
UserSettings userSettings;
|
||||
@Inject
|
||||
ParentData parentData;
|
||||
@Inject
|
||||
ChildData childData;
|
||||
|
||||
|
||||
private KSLogger logger;
|
||||
|
||||
private FloatingActionButton fab;
|
||||
private Toolbar toolbar;
|
||||
|
||||
|
||||
@Inject
|
||||
UserSettings userSettings;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
|
@ -82,46 +55,11 @@ public class MainActivity extends AppCompatActivity {
|
|||
return insets;
|
||||
});
|
||||
|
||||
logger = ksLoggerFactory.create("MainActivity");
|
||||
|
||||
// Check logged in
|
||||
if (userSettings.getAppCommonSetting().isLoggedIn()) {
|
||||
logger.info("User is logged in!");
|
||||
} else {
|
||||
logger.info("User is not logged in!");
|
||||
|
||||
Intent intent = new Intent(this, LoginActivity.class);
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
toolbar = findViewById(R.id.toolbar);
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
toolBarManager.setToolbar(toolbar);
|
||||
|
||||
DrawerLayout drawerLayout = findViewById(R.id.drawerLayout);
|
||||
|
||||
// アイテムが選択されたときの処理
|
||||
NavigationView navigationView = findViewById(R.id.navigationView);
|
||||
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
|
||||
@Override
|
||||
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
|
||||
logger.debug("Item selected: " + item.getItemId());
|
||||
if (item.getItemId() == R.id.manage_child_account) {
|
||||
Intent intent = new Intent(MainActivity.this, ChildManageMainActivity.class);
|
||||
startActivity(intent);
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.show_debug_dialog) {
|
||||
showDebugDialog();
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.show_account_dialog) {
|
||||
showAccountDialog();
|
||||
return true;
|
||||
} else {
|
||||
logger.warn("不明なアイテム: " + item.getItemId());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
drawerLayout.open();
|
||||
|
||||
ActionBarDrawerToggle actionBarDrawerToggle =
|
||||
new ActionBarDrawerToggle(
|
||||
|
@ -129,6 +67,10 @@ public class MainActivity extends AppCompatActivity {
|
|||
drawerLayout.addDrawerListener(actionBarDrawerToggle);
|
||||
actionBarDrawerToggle.syncState();
|
||||
|
||||
logger = loggerFactory.create("MainActivity");
|
||||
|
||||
logger.info("MainActivity started!");
|
||||
|
||||
BottomNavigationView bottomNavigationView = findViewById(R.id.bottom_nav);
|
||||
|
||||
// Init navigation
|
||||
|
@ -143,23 +85,14 @@ public class MainActivity extends AppCompatActivity {
|
|||
e.printStackTrace();
|
||||
}
|
||||
|
||||
UserSettings.AppCommonSetting appCommonSetting = userSettings.getAppCommonSetting();
|
||||
if (appCommonSetting.isChildMode()) {
|
||||
logger.info("Child mode is enabled!");
|
||||
// 保護者向けのナビゲーションを削除
|
||||
bottomNavigationView.getMenu().removeItem(R.id.feature_common_parent_child_navigation);
|
||||
bottomNavigationView.getMenu().removeItem(R.id.feature_common_parent_parent_navigation);
|
||||
|
||||
bottomNavigationView.getMenu().removeItem(R.id.feature_wallet_parent_navigation);
|
||||
// startDestinationを変更
|
||||
bottomNavigationView.setSelectedItemId(R.id.feature_common_child_child_navigation);
|
||||
|
||||
// manage_child_accountを削除
|
||||
navigationView.getMenu().removeItem(R.id.manage_child_account);
|
||||
// Check logged in
|
||||
if (userSettings.getAppCommonSetting().isLoggedIn()) {
|
||||
logger.info("User is logged in!");
|
||||
} else {
|
||||
logger.info("Child mode is disabled!");
|
||||
bottomNavigationView.getMenu().removeItem(R.id.feature_common_child_child_navigation);
|
||||
bottomNavigationView.getMenu().removeItem(R.id.feature_wallet_child_navigation);
|
||||
logger.info("User is not logged in!");
|
||||
|
||||
Intent intent = new Intent(this, LoginActivity.class);
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
fab = findViewById(R.id.mainFab);
|
||||
|
@ -172,122 +105,4 @@ public class MainActivity extends AppCompatActivity {
|
|||
private void startup() {
|
||||
|
||||
}
|
||||
|
||||
private void showAccountDialog() {
|
||||
boolean isEditMode = false;
|
||||
View view = getLayoutInflater().inflate(R.layout.user_info_dialog_layout, null);
|
||||
if (userSettings.getAppCommonSetting().isChildMode()) {
|
||||
childData.getChild(userSettings.getAppCommonSetting().getChildId()).thenAccept(childModel -> {
|
||||
((TextView) view.findViewById(R.id.userNameTextView)).setText(childModel.getName());
|
||||
logger.debug("ChildModel: " + childModel.getName());
|
||||
((TextView) view.findViewById(R.id.emailTextView)).setText("子供ユーザーはメールアドレスを設定できません");
|
||||
((Chip) view.findViewById(R.id.chip)).setText("子供/Child");
|
||||
}).join();
|
||||
} else {
|
||||
parentData.getParentDirect().thenAccept(parentModel -> {
|
||||
((TextView) view.findViewById(R.id.userNameTextView)).setText(parentModel.getName());
|
||||
logger.debug("ParentModel: " + parentModel.getName() + ", " + parentModel.getEmail());
|
||||
((TextView) view.findViewById(R.id.emailTextView)).setText(parentModel.getEmail());
|
||||
((Chip) view.findViewById(R.id.chip)).setText("保護者/Parent");
|
||||
}).join();
|
||||
}
|
||||
|
||||
// Workaround
|
||||
if (userSettings.getAppCommonSetting().isChildMode()) {
|
||||
view.findViewById(R.id.userNameEditButton).setVisibility(View.GONE);
|
||||
} else {
|
||||
view.findViewById(R.id.userNameEditButton).setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
view.findViewById(R.id.userNameEditButton).setOnClickListener(v -> {
|
||||
EditText editText = new EditText(this);
|
||||
editText.setText(((TextView) view.findViewById(R.id.userNameTextView)).getText());
|
||||
editText.setHint("ユーザー名");
|
||||
new MaterialAlertDialogBuilder(this)
|
||||
.setTitle("ユーザー名の変更")
|
||||
.setView(editText)
|
||||
.setPositiveButton("OK", (dialog, which) -> {
|
||||
((TextView) view.findViewById(R.id.userNameTextView)).setText(editText.getText());
|
||||
if (userSettings.getAppCommonSetting().isChildMode()) {
|
||||
// 子供モード
|
||||
childData.getChild(userSettings.getAppCommonSetting().getChildId()).thenAccept(childModel -> {
|
||||
childModel.setName(editText.getText().toString());
|
||||
childData.updateChild(childModel);
|
||||
});
|
||||
} else {
|
||||
// 保護者モード
|
||||
parentData.getParentDirect().thenAccept(parentModel -> {
|
||||
parentModel.setName(editText.getText().toString());
|
||||
parentData.updateParent(parentModel);
|
||||
});
|
||||
}
|
||||
})
|
||||
.setNegativeButton("キャンセル", (dialog, which) -> {
|
||||
// Do nothing
|
||||
})
|
||||
.show();
|
||||
});
|
||||
|
||||
new MaterialAlertDialogBuilder(this)
|
||||
.setTitle("アカウント情報")
|
||||
.setView(view)
|
||||
.setPositiveButton("OK", (dialog, which) -> {
|
||||
// Do nothing
|
||||
})
|
||||
.show();
|
||||
}
|
||||
|
||||
private void showDebugDialog() {
|
||||
|
||||
ScrollView scrollView = new ScrollView(this);
|
||||
scrollView.setPadding(32, 16, 32, 16);
|
||||
LinearLayout linearLayout = new LinearLayout(this);
|
||||
|
||||
TextView serverAddressTextView = new TextView(this);
|
||||
serverAddressTextView.setText("サーバーアドレス: " + userSettings.getApiSetting().getApiBaseUrl());
|
||||
serverAddressTextView.setTextSize(16);
|
||||
|
||||
TextView accessTokenTextView = new TextView(this);
|
||||
accessTokenTextView.setText("アクセストークン: " + userSettings.getAppCommonSetting().getAccessToken());
|
||||
accessTokenTextView.setTextSize(16);
|
||||
|
||||
TextView childModeTextView = new TextView(this);
|
||||
childModeTextView.setText("子供モード: " + userSettings.getAppCommonSetting().isChildMode());
|
||||
childModeTextView.setTextSize(16);
|
||||
|
||||
linearLayout.setOrientation(LinearLayout.VERTICAL);
|
||||
linearLayout.addView(serverAddressTextView);
|
||||
linearLayout.addView(createDivider(this));
|
||||
linearLayout.addView(accessTokenTextView);
|
||||
linearLayout.addView(createDivider(this));
|
||||
linearLayout.addView(childModeTextView);
|
||||
|
||||
scrollView.addView(linearLayout);
|
||||
|
||||
new MaterialAlertDialogBuilder(this)
|
||||
.setTitle("参考情報(評価用)")
|
||||
.setView(scrollView)
|
||||
.setPositiveButton("OK", (dialog, which) -> {
|
||||
// Do nothing
|
||||
})
|
||||
.show();
|
||||
|
||||
}
|
||||
|
||||
private MaterialDivider createDivider(Context context) {
|
||||
MaterialDivider divider = new MaterialDivider(context);
|
||||
// Margin (48, 16, 48, 16)
|
||||
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.MATCH_PARENT,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT
|
||||
);
|
||||
params.setMargins(48, 16, 48, 16);
|
||||
divider.setLayoutParams(params);
|
||||
return divider;
|
||||
}
|
||||
|
||||
public Toolbar getToolbar() { // TODO: toolbarのインスタンス自体を取得するのではなく,fabのように操作できるようにする
|
||||
return toolbar;
|
||||
}
|
||||
|
||||
}
|
|
@ -53,10 +53,10 @@ public class RegisterActivity extends AppCompatActivity {
|
|||
|
||||
logger = loggerFactory.create("RegisterActivity");
|
||||
|
||||
EditText emailEditText = findViewById(R.id.parentRegisterEmailEditText); // TODO: メールアドレスのバリデーション
|
||||
EditText passwordEditText = findViewById(R.id.parentRegisterPasswordEditText);
|
||||
EditText emailEditText = findViewById(R.id.emailEditText); // TODO: メールアドレスのバリデーション
|
||||
EditText passwordEditText = findViewById(R.id.passwordEditText);
|
||||
|
||||
findViewById(R.id.parentRegisterButton).setOnClickListener(v -> {
|
||||
findViewById(R.id.registerButton).setOnClickListener(v -> {
|
||||
String email = emailEditText.getText().toString();
|
||||
String password = passwordEditText.getText().toString();
|
||||
|
||||
|
@ -86,12 +86,8 @@ public class RegisterActivity extends AppCompatActivity {
|
|||
});
|
||||
});
|
||||
|
||||
findViewById(R.id.toLoginButton).setOnClickListener(v -> {
|
||||
findViewById(R.id.intentLoginButton).setOnClickListener(v -> {
|
||||
startActivity(new Intent(this, LoginActivity.class));
|
||||
});
|
||||
|
||||
findViewById(R.id.toChildLoginButton).setOnClickListener(v -> {
|
||||
startActivity(new Intent(this, ChildLoginActivity.class));
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,15 +1,30 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:aapt="http://schemas.android.com/aapt"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="#333333">
|
||||
<group android:scaleX="0.435"
|
||||
android:scaleY="0.435"
|
||||
android:translateX="6.78"
|
||||
android:translateY="6.78">
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:endX="85.84757"
|
||||
android:endY="92.4963"
|
||||
android:startX="42.9492"
|
||||
android:startY="49.59793"
|
||||
android:type="linear">
|
||||
<item
|
||||
android:color="#44000000"
|
||||
android:offset="0.0" />
|
||||
<item
|
||||
android:color="#00000000"
|
||||
android:offset="1.0" />
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M22,8c0,-0.55 -0.45,-1 -1,-1h-7c-0.55,0 -1,0.45 -1,1s0.45,1 1,1h7C21.55,9 22,8.55 22,8zM13,16c0,0.55 0.45,1 1,1h7c0.55,0 1,-0.45 1,-1c0,-0.55 -0.45,-1 -1,-1h-7C13.45,15 13,15.45 13,16zM10.47,4.63c0.39,0.39 0.39,1.02 0,1.41l-4.23,4.25c-0.39,0.39 -1.02,0.39 -1.42,0L2.7,8.16c-0.39,-0.39 -0.39,-1.02 0,-1.41c0.39,-0.39 1.02,-0.39 1.41,0l1.42,1.42l3.54,-3.54C9.45,4.25 10.09,4.25 10.47,4.63zM10.48,12.64c0.39,0.39 0.39,1.02 0,1.41l-4.23,4.25c-0.39,0.39 -1.02,0.39 -1.42,0L2.7,16.16c-0.39,-0.39 -0.39,-1.02 0,-1.41s1.02,-0.39 1.41,0l1.42,1.42l3.54,-3.54C9.45,12.25 10.09,12.25 10.48,12.64L10.48,12.64z"/>
|
||||
</group>
|
||||
</vector>
|
||||
android:fillColor="#FFFFFF"
|
||||
android:fillType="nonZero"
|
||||
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
|
||||
android:strokeWidth="1"
|
||||
android:strokeColor="#00000000" />
|
||||
</vector>
|
|
@ -1,160 +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:id="@+id/main"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".ChildLoginActivity">
|
||||
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/titleTextView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
android:text="KidShiftにログイン"
|
||||
android:textSize="32dp"
|
||||
app:layout_constraintBottom_toTopOf="@+id/inputContainer"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/inputContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="128dp"
|
||||
android:gravity="center_horizontal"
|
||||
android:orientation="horizontal"
|
||||
android:weightSum="10"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/titleTextView">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/loginCode_1"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center"
|
||||
android:inputType="number"
|
||||
android:maxWidth="48dp"
|
||||
android:maxLength="1"
|
||||
android:textSize="24sp"
|
||||
tools:ignore="Autofill,LabelFor" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/loginCode_2"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center"
|
||||
android:inputType="number"
|
||||
android:maxWidth="48dp"
|
||||
android:maxLength="1"
|
||||
android:textSize="24sp"
|
||||
tools:ignore="Autofill,LabelFor" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/loginCode_3"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center"
|
||||
android:inputType="number"
|
||||
android:maxWidth="48dp"
|
||||
android:maxLength="1"
|
||||
android:textSize="24sp"
|
||||
tools:ignore="Autofill,LabelFor" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/loginCode_4"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center"
|
||||
android:inputType="number"
|
||||
android:maxWidth="48dp"
|
||||
android:maxLength="1"
|
||||
android:textSize="24sp"
|
||||
tools:ignore="Autofill,LabelFor" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="40dp"
|
||||
android:layout_weight="0"
|
||||
android:gravity="center"
|
||||
android:text="-"
|
||||
android:textSize="34sp"
|
||||
tools:ignore="Autofill,LabelFor" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/loginCode_5"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center"
|
||||
android:inputType="number"
|
||||
android:maxWidth="48dp"
|
||||
android:maxLength="1"
|
||||
android:textSize="24sp"
|
||||
tools:ignore="Autofill,LabelFor" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/loginCode_6"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center"
|
||||
android:inputType="number"
|
||||
android:maxWidth="48dp"
|
||||
android:maxLength="1"
|
||||
android:textSize="24sp"
|
||||
tools:ignore="Autofill,LabelFor" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/loginCode_7"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center"
|
||||
android:inputType="number"
|
||||
android:maxWidth="48dp"
|
||||
android:maxLength="1"
|
||||
android:textSize="24sp"
|
||||
tools:ignore="Autofill,LabelFor" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/loginCode_8"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center"
|
||||
android:inputType="number"
|
||||
android:maxWidth="48dp"
|
||||
android:maxLength="1"
|
||||
android:textSize="24sp"
|
||||
tools:ignore="Autofill,LabelFor" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/childLoginButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="128dp"
|
||||
android:layout_weight="1"
|
||||
android:text="ログイン"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/inputContainer" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -7,85 +7,43 @@
|
|||
android:layout_height="match_parent"
|
||||
tools:context=".LoginActivity">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
<LinearLayout
|
||||
android:id="@+id/inputContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintBottom_toTopOf="@+id/linearLayout3"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/titleTextView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginBottom="128dp"
|
||||
android:text="KidShiftにログイン"
|
||||
android:textSize="32dp"
|
||||
app:layout_constraintBottom_toTopOf="@+id/inputContainer"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/inputContainer"
|
||||
<EditText
|
||||
android:id="@+id/emailEditText"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="24dp"
|
||||
android:layout_marginEnd="24dp"
|
||||
android:layout_marginBottom="128dp"
|
||||
android:gravity="center_horizontal"
|
||||
android:orientation="vertical"
|
||||
android:weightSum="10"
|
||||
app:layout_constraintBottom_toTopOf="@+id/parentLoginButton"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent">
|
||||
android:ems="10"
|
||||
android:inputType="textEmailAddress" />
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:hint="メールアドレス">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/parentLoginEmailEditText"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="textEmailAddress" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:hint="パスワード"
|
||||
app:passwordToggleEnabled="true">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/parentLoginPasswordEditText"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="textPassword" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/parentLoginButton"
|
||||
style="@style/Widget.Material3.Button"
|
||||
android:layout_width="wrap_content"
|
||||
<EditText
|
||||
android:id="@+id/passwordEditText"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="128dp"
|
||||
android:layout_weight="1"
|
||||
android:paddingHorizontal="48dp"
|
||||
android:text="ログイン"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/inputContainer" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
android:ems="10"
|
||||
android:inputType="textPassword" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="※Loginボタン長押しでBypass"
|
||||
app:layout_constraintBottom_toTopOf="@+id/linearLayout2"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/linearLayout3"
|
||||
android:id="@+id/linearLayout2"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:orientation="horizontal"
|
||||
|
@ -94,29 +52,19 @@
|
|||
app:layout_constraintStart_toStartOf="parent">
|
||||
|
||||
<Button
|
||||
android:id="@+id/toRegisterButton"
|
||||
style="@style/Widget.Material3.Button.TextButton"
|
||||
android:id="@+id/loginButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="12dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:layout_weight="1"
|
||||
android:padding="0dp"
|
||||
android:paddingLeft="0dp"
|
||||
android:paddingTop="0dp"
|
||||
android:text="新規登録" />
|
||||
android:text="LOGIN" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/toChildLoginButton"
|
||||
style="@style/Widget.Material3.Button.TextButton"
|
||||
android:id="@+id/intentRegisterButton"
|
||||
style="@style/Widget.Material3.Button.IconButton.Outlined"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="12dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:layout_weight="1"
|
||||
android:padding="0dp"
|
||||
android:paddingLeft="0dp"
|
||||
android:paddingTop="0dp"
|
||||
android:text="子供ログイン" />
|
||||
android:text="Register" />
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -20,14 +20,13 @@
|
|||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/colorSurface"
|
||||
android:background="?attr/colorPrimary"
|
||||
android:minHeight="?attr/actionBarSize"
|
||||
android:theme="?attr/actionBarTheme"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:title="@string/app_name"
|
||||
android:elevation="8dp" />
|
||||
app:title="@string/app_name" />
|
||||
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/fragmentContainerView"
|
||||
|
|
|
@ -7,85 +7,43 @@
|
|||
android:layout_height="match_parent"
|
||||
tools:context=".RegisterActivity">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
<LinearLayout
|
||||
android:id="@+id/inputContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintBottom_toTopOf="@+id/linearLayout3"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/titleTextView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginBottom="128dp"
|
||||
android:text="KidShiftに新規登録"
|
||||
android:textSize="32dp"
|
||||
app:layout_constraintBottom_toTopOf="@+id/inputContainer"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/inputContainer"
|
||||
<EditText
|
||||
android:id="@+id/emailEditText"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="24dp"
|
||||
android:layout_marginEnd="24dp"
|
||||
android:layout_marginBottom="128dp"
|
||||
android:gravity="center_horizontal"
|
||||
android:orientation="vertical"
|
||||
android:weightSum="10"
|
||||
app:layout_constraintBottom_toTopOf="@+id/parentRegisterButton"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent">
|
||||
android:ems="10"
|
||||
android:inputType="textEmailAddress" />
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:hint="メールアドレス">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/parentRegisterEmailEditText"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="textEmailAddress" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:hint="パスワード"
|
||||
app:passwordToggleEnabled="true">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/parentRegisterPasswordEditText"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="textPassword" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/parentRegisterButton"
|
||||
style="@style/Widget.Material3.Button"
|
||||
android:layout_width="wrap_content"
|
||||
<EditText
|
||||
android:id="@+id/passwordEditText"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="128dp"
|
||||
android:layout_weight="1"
|
||||
android:paddingHorizontal="48dp"
|
||||
android:text="新規登録"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/inputContainer" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
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/linearLayout3"
|
||||
android:id="@+id/linearLayout2"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:orientation="horizontal"
|
||||
|
@ -94,29 +52,19 @@
|
|||
app:layout_constraintStart_toStartOf="parent">
|
||||
|
||||
<Button
|
||||
android:id="@+id/toLoginButton"
|
||||
style="@style/Widget.Material3.Button.TextButton"
|
||||
android:id="@+id/registerButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="12dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:layout_weight="1"
|
||||
android:padding="0dp"
|
||||
android:paddingLeft="0dp"
|
||||
android:paddingTop="0dp"
|
||||
android:text="ログイン" />
|
||||
android:text="REGISTER" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/toChildLoginButton"
|
||||
style="@style/Widget.Material3.Button.TextButton"
|
||||
android:id="@+id/intentLoginButton"
|
||||
style="@style/Widget.Material3.Button.IconButton.Outlined"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="12dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:layout_weight="1"
|
||||
android:padding="0dp"
|
||||
android:paddingLeft="0dp"
|
||||
android:paddingTop="0dp"
|
||||
android:text="子供ログイン" />
|
||||
android:text="Login" />
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -2,15 +2,19 @@
|
|||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/colorSecondary"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp">
|
||||
android:padding="16dp"
|
||||
android:background="?attr/colorPrimaryDark">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@drawable/ic_launcher_foreground" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="48dp"
|
||||
android:text="KidShift"
|
||||
android:text="Header Title"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="34sp" />
|
||||
android:textSize="20sp" />
|
||||
</LinearLayout>
|
||||
|
|
|
@ -1,52 +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"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_margin="32dp"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/userNameTextView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center_vertical"
|
||||
android:text="UNAME_PHOLDER"
|
||||
android:textSize="24sp" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/userNameEditButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0"
|
||||
android:background="@android:color/transparent"
|
||||
android:padding="24px"
|
||||
app:srcCompat="@drawable/edit_24px" />
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/emailTextView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="huga@example.com" />
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/chip"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="保護者" />
|
||||
</LinearLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -1,31 +1,28 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<!-- TODO: アイコン再検討 -->
|
||||
<!-- 保護者モード / 保護者目線 -->
|
||||
<item
|
||||
android:id="@+id/feature_common_parent_parent_navigation"
|
||||
android:icon="@drawable/home_24px"
|
||||
android:title="ホーム" />
|
||||
android:id="@+id/feature_parent_navigation"
|
||||
android:icon="@drawable/pending_24px"
|
||||
android:title="Parent" />
|
||||
|
||||
<!-- 保護者モード / 子供目線 -->
|
||||
<item
|
||||
android:id="@+id/feature_common_parent_child_navigation"
|
||||
android:id="@+id/feature_child_navigation"
|
||||
android:icon="@drawable/child_care_24px"
|
||||
android:title="こども" />
|
||||
android:title="Child" />
|
||||
|
||||
<!-- 子供モード / 子供目線 -->
|
||||
<item
|
||||
android:id="@+id/feature_common_child_child_navigation"
|
||||
android:icon="@drawable/home_24px"
|
||||
android:title="ホーム" />
|
||||
android:id="@+id/feature_debug_navigation"
|
||||
android:icon="@drawable/developer_mode_24px"
|
||||
android:title="Debug" />
|
||||
|
||||
<item
|
||||
android:id="@+id/feature_setting_navigation"
|
||||
android:icon="@drawable/settings_24px"
|
||||
android:title="Setting" />
|
||||
|
||||
<item
|
||||
android:id="@+id/feature_wallet_parent_navigation"
|
||||
android:icon="@drawable/wallet_24px"
|
||||
android:title="ウォレット" />
|
||||
|
||||
<item
|
||||
android:id="@+id/feature_wallet_child_navigation"
|
||||
android:icon="@drawable/wallet_24px"
|
||||
android:title="ウォレット" />
|
||||
android:title="Wallet" />
|
||||
</menu>
|
|
@ -1,23 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item
|
||||
android:id="@+id/show_account_dialog"
|
||||
android:icon="@drawable/account_box_24px"
|
||||
android:title="ユーザー情報" />
|
||||
|
||||
android:id="@+id/nav_home"
|
||||
android:title="Home" />
|
||||
<item
|
||||
android:id="@+id/manage_child_account"
|
||||
android:icon="@drawable/manage_accounts_24px"
|
||||
android:title="子供アカウントの管理" />
|
||||
|
||||
<!-- Divider -->
|
||||
<item
|
||||
android:id="@+id/divider"
|
||||
android:title=""
|
||||
android:enabled="false" />
|
||||
|
||||
<item
|
||||
android:id="@+id/show_debug_dialog"
|
||||
android:icon="@drawable/developer_mode_24px"
|
||||
android:title="デバッグ情報" />
|
||||
android:id="@+id/nav_settings"
|
||||
android:title="Settings" />
|
||||
</menu>
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@color/ic_launcher_background"/>
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
|
||||
</adaptive-icon>
|
|
@ -1,5 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@color/ic_launcher_background"/>
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
|
||||
</adaptive-icon>
|
Before Width: | Height: | Size: 936 B After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 716 B After Width: | Height: | Size: 982 B |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 5.8 KiB |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 6.8 KiB After Width: | Height: | Size: 7.6 KiB |
|
@ -2,13 +2,11 @@
|
|||
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/main_nav"
|
||||
app:startDestination="@id/feature_common_parent_parent_navigation">
|
||||
app:startDestination="@id/feature_debug_navigation">
|
||||
|
||||
<include app:graph="@navigation/feature_debug_navigation" />
|
||||
<include app:graph="@navigation/feature_child_navigation" />
|
||||
<include app:graph="@navigation/feature_common_parent_parent_navigation" />
|
||||
<include app:graph="@navigation/feature_common_parent_child_navigation" />
|
||||
<include app:graph="@navigation/feature_common_child_child_navigation" />
|
||||
<include app:graph="@navigation/feature_parent_navigation" />
|
||||
<include app:graph="@navigation/feature_setting_navigation" />
|
||||
<include app:graph="@navigation/feature_wallet_parent_navigation" />
|
||||
<include app:graph="@navigation/feature_wallet_child_navigation" />
|
||||
</navigation>
|
|
@ -1,4 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="ic_launcher_background">#F1DEDE</color>
|
||||
</resources>
|
|
@ -1,10 +1,4 @@
|
|||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
buildscript {
|
||||
dependencies {
|
||||
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:2.7.7" // TODO: カタログと差異が出ないようにする
|
||||
}
|
||||
}
|
||||
|
||||
plugins {
|
||||
alias(libs.plugins.androidApplication) apply false
|
||||
id 'com.google.dagger.hilt.android' version '2.44' apply false
|
||||
|
|
|
@ -31,7 +31,7 @@ public interface ChildData {
|
|||
* 子ユーザー情報更新
|
||||
* @param child 子ユーザー情報
|
||||
*/
|
||||
CompletableFuture<ChildModel> updateChild(ChildModel child);
|
||||
void updateChild(ChildModel child);
|
||||
|
||||
/**
|
||||
* 子ユーザー追加
|
||||
|
@ -43,7 +43,7 @@ public interface ChildData {
|
|||
* 子ユーザー削除
|
||||
* @param childId 子ID
|
||||
*/
|
||||
CompletableFuture<Void> removeChild(String childId);
|
||||
void removeChild(String childId);
|
||||
|
||||
/**
|
||||
* 子ユーザーログインコード発行
|
||||
|
|
|
@ -14,22 +14,10 @@ public interface ParentData {
|
|||
*/
|
||||
CompletableFuture<ParentModel> getParent(ParentModelCallback callback);
|
||||
|
||||
/**
|
||||
* 親ユーザー情報取得
|
||||
* @return 親ユーザー情報
|
||||
*/
|
||||
CompletableFuture<ParentModel> getParentDirect();
|
||||
|
||||
/**
|
||||
* 親ユーザー情報取得
|
||||
* @return 親ユーザー情報
|
||||
*/
|
||||
CompletableFuture<ParentModel> getParentCache();
|
||||
|
||||
/**
|
||||
* 親ユーザー情報更新
|
||||
* @param parent 親ユーザー情報
|
||||
*/
|
||||
CompletableFuture<Void> updateParent(ParentModel parent);
|
||||
void updateParent(ParentModel parent);
|
||||
|
||||
}
|
||||
|
|
|
@ -1,22 +1,11 @@
|
|||
package one.nem.kidshift.data;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import one.nem.kidshift.model.HistoryModel;
|
||||
|
||||
public interface RewardData {
|
||||
/**
|
||||
* 現時点の合計報酬額を取得する
|
||||
* @return Integer 合計報酬額
|
||||
*/
|
||||
CompletableFuture<Integer> getTotalReward(String childId);
|
||||
|
||||
CompletableFuture<List<HistoryModel>> getRewardHistoryList();
|
||||
|
||||
CompletableFuture<List<HistoryModel>> getRewardHistoryList(String childId);
|
||||
|
||||
CompletableFuture<Void> payReward(String historyId);
|
||||
|
||||
CompletableFuture<Void> payReward(List<String> historyIds);
|
||||
}
|
||||
|
|
|
@ -37,9 +37,6 @@ public interface UserSettings {
|
|||
|
||||
boolean isChildMode();
|
||||
void setChildMode(boolean childMode);
|
||||
|
||||
String getChildId();
|
||||
void setChildId(String childId);
|
||||
}
|
||||
|
||||
interface SharedPrefCache {
|
||||
|
|
|
@ -36,21 +36,7 @@ public class ChildDataImpl implements ChildData {
|
|||
|
||||
@Override
|
||||
public CompletableFuture<ChildModel> getChild(String childId) {
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
Call<ChildResponse> call = kidShiftApiService.getChild(childId);
|
||||
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);
|
||||
}
|
||||
});
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -108,22 +94,8 @@ public class ChildDataImpl implements ChildData {
|
|||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<ChildModel> updateChild(ChildModel child) {
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
Call<ChildResponse> call = kidShiftApiService.updateChild(ChildModelConverter.childModelToChildAddRequest(child), child.getId());
|
||||
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);
|
||||
}
|
||||
});
|
||||
public void updateChild(ChildModel child) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -146,21 +118,8 @@ public class ChildDataImpl implements ChildData {
|
|||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> removeChild(String childId) {
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
Call<Void> call = kidShiftApiService.removeChild(childId);
|
||||
try {
|
||||
Response<Void> response = call.execute();
|
||||
if (response.isSuccessful()) {
|
||||
logger.info("子供削除成功(childId: " + childId + ")");
|
||||
return null;
|
||||
} else {
|
||||
throw new RuntimeException("HTTP Status: " + response.code());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
public void removeChild(String childId) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -159,7 +159,7 @@ public class KSActionsImpl implements KSActions {
|
|||
@Override
|
||||
public CompletableFuture<List<HistoryModel>> syncHistory(String childId) {
|
||||
CompletableFuture<HistoryListResponse> callHistoryApi = CompletableFuture.supplyAsync(() -> {
|
||||
Call<HistoryListResponse> call = kidShiftApiService.getHistory(childId, true); // TODO: containPaidを引数に
|
||||
Call<HistoryListResponse> call = kidShiftApiService.getHistory(childId);
|
||||
try {
|
||||
Response<HistoryListResponse> response = call.execute();
|
||||
if (!response.isSuccessful()) {
|
||||
|
|
|
@ -8,26 +8,21 @@ 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.data.retrofit.model.parent.ParentRenameRequest;
|
||||
import one.nem.kidshift.model.ParentModel;
|
||||
import one.nem.kidshift.model.callback.ParentModelCallback;
|
||||
import one.nem.kidshift.utils.KSLogger;
|
||||
import one.nem.kidshift.utils.factory.KSLoggerFactory;
|
||||
import retrofit2.Call;
|
||||
|
||||
public class ParentDataImpl implements ParentData {
|
||||
|
||||
private final UserSettings userSettings;
|
||||
private final KidShiftApiService kidShiftApiService;
|
||||
|
||||
private final KSLogger logger;
|
||||
|
||||
private final KSActions ksActions;
|
||||
|
||||
@Inject
|
||||
public ParentDataImpl(KidShiftApiService kidShiftApiService, UserSettings userSettings, KSLoggerFactory ksLoggerFactory, KSActions ksActions) {
|
||||
this.kidShiftApiService = kidShiftApiService;
|
||||
public ParentDataImpl(KidShiftApiService kidshiftApiService, UserSettings userSettings, KSLoggerFactory ksLoggerFactory, KSActions ksActions) {
|
||||
this.userSettings = userSettings;
|
||||
this.logger = ksLoggerFactory.create("ParentDataImpl");
|
||||
this.ksActions = ksActions;
|
||||
|
@ -51,27 +46,8 @@ public class ParentDataImpl implements ParentData {
|
|||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<ParentModel> getParentDirect() {
|
||||
return ksActions.syncParent();
|
||||
}
|
||||
public void updateParent(ParentModel parent) {
|
||||
|
||||
@Override
|
||||
public CompletableFuture<ParentModel> getParentCache() {
|
||||
return CompletableFuture.supplyAsync(() -> userSettings.getCache().getParent());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> updateParent(ParentModel parent) {
|
||||
Call<ParentInfoResponse> call = kidShiftApiService.renameParent(new ParentRenameRequest(parent.getName()));
|
||||
try {
|
||||
ParentInfoResponse response = call.execute().body();
|
||||
if (response == null) {
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
return CompletableFuture.completedFuture(null);
|
||||
} catch (Exception e) {
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,22 +1,16 @@
|
|||
package one.nem.kidshift.data.impl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import one.nem.kidshift.data.ChildData;
|
||||
import one.nem.kidshift.data.KSActions;
|
||||
import one.nem.kidshift.data.RewardData;
|
||||
import one.nem.kidshift.data.UserSettings;
|
||||
import one.nem.kidshift.data.retrofit.KidShiftApiService;
|
||||
import one.nem.kidshift.data.room.utils.CacheWrapper;
|
||||
import one.nem.kidshift.model.ChildModel;
|
||||
import one.nem.kidshift.model.HistoryModel;
|
||||
import one.nem.kidshift.utils.KSLogger;
|
||||
import one.nem.kidshift.utils.factory.KSLoggerFactory;
|
||||
import retrofit2.Call;
|
||||
|
||||
public class RewardDataImpl implements RewardData {
|
||||
|
||||
|
@ -24,62 +18,18 @@ public class RewardDataImpl implements RewardData {
|
|||
private final KSActions ksActions;
|
||||
private final CacheWrapper cacheWrapper;
|
||||
private final KSLogger logger;
|
||||
private final ChildData childData;
|
||||
private final KidShiftApiService kidShiftApiService;
|
||||
|
||||
|
||||
@Inject
|
||||
public RewardDataImpl(KSLoggerFactory ksLoggerFactory, CacheWrapper cacheWrapper, UserSettings userSettings, KSActions ksActions, ChildData childData, KidShiftApiService kidShiftApiService) {
|
||||
public RewardDataImpl(KSLoggerFactory ksLoggerFactory, CacheWrapper cacheWrapper, UserSettings userSettings, KSActions ksActions) {
|
||||
this.userSettings = userSettings;
|
||||
this.ksActions = ksActions;
|
||||
this.cacheWrapper = cacheWrapper;
|
||||
this.childData = childData;
|
||||
this.kidShiftApiService = kidShiftApiService;
|
||||
this.logger = ksLoggerFactory.create("RewardDataImpl");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Integer> getTotalReward(String childId) { // TODO: localCacheを使う
|
||||
public CompletableFuture<Integer> getTotalReward(String childId) {
|
||||
return CompletableFuture.supplyAsync(() -> ksActions.syncHistory(childId).join().stream().mapToInt(HistoryModel::getReward).sum());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<List<HistoryModel>> getRewardHistoryList() { // TODO: localCacheを使う
|
||||
List<HistoryModel> historyModels = new ArrayList<>();
|
||||
return childData.getChildListDirect().thenAccept(childModels -> {
|
||||
childModels.forEach(childModel -> {
|
||||
historyModels.addAll(ksActions.syncHistory(childModel.getId()).join());
|
||||
});
|
||||
}).thenApply(v -> historyModels);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<List<HistoryModel>> getRewardHistoryList(String childId) { // TODO: localCacheを使う
|
||||
return CompletableFuture.supplyAsync(() -> ksActions.syncHistory(childId).join());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> payReward(String historyId) {
|
||||
return CompletableFuture.runAsync(() -> {
|
||||
Call<Void> call = kidShiftApiService.payHistory(historyId, true);
|
||||
try {
|
||||
call.execute();
|
||||
} catch (Exception e) {
|
||||
logger.error("Failed to pay reward : " + e.getMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> payReward(List<String> historyIds) {
|
||||
return CompletableFuture.runAsync(() -> {
|
||||
historyIds.forEach(historyId -> { // TODO: API側でリストに対応する
|
||||
Call<Void> call = kidShiftApiService.payHistory(historyId, true);
|
||||
try {
|
||||
call.execute();
|
||||
} catch (Exception e) {
|
||||
logger.error("Failed to pay reward : " + e.getMessage());
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -77,7 +77,6 @@ public class UserSettingsImpl implements UserSettings {
|
|||
boolean loggedIn;
|
||||
String accessToken;
|
||||
boolean childMode;
|
||||
String childId;
|
||||
|
||||
AppCommonSettingImpl() {
|
||||
sharedPrefUtils = sharedPrefUtilsFactory.create("user_settings");
|
||||
|
@ -86,12 +85,10 @@ public class UserSettingsImpl implements UserSettings {
|
|||
loggedIn = appCommonSetting.isLoggedIn();
|
||||
accessToken = appCommonSetting.getAccessToken().isEmpty() ? "" : appCommonSetting.getAccessToken();
|
||||
childMode = appCommonSetting.isChildMode();
|
||||
childId = appCommonSetting.getChildId().isEmpty() ? "" : appCommonSetting.getChildId();
|
||||
} else {
|
||||
loggedIn = false;
|
||||
accessToken = "";
|
||||
childMode = false;
|
||||
childId = "";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -131,17 +128,6 @@ public class UserSettingsImpl implements UserSettings {
|
|||
this.childMode = childMode;
|
||||
save();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getChildId() {
|
||||
return childId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setChildId(String childId) {
|
||||
this.childId = childId;
|
||||
save();
|
||||
}
|
||||
}
|
||||
|
||||
public class ApiSettingImpl implements UserSettings.ApiSetting {
|
||||
|
|
|
@ -4,12 +4,11 @@ import dagger.Binds;
|
|||
import dagger.Module;
|
||||
import dagger.hilt.InstallIn;
|
||||
import dagger.hilt.android.components.FragmentComponent;
|
||||
import dagger.hilt.components.SingletonComponent;
|
||||
import one.nem.kidshift.data.ParentData;
|
||||
import one.nem.kidshift.data.impl.ParentDataImpl;
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent.class)
|
||||
@InstallIn(FragmentComponent.class)
|
||||
public abstract class ParentDataModule {
|
||||
|
||||
@Binds
|
||||
|
|
|
@ -5,10 +5,7 @@ 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.child.auth.ChildAuthRequest;
|
||||
import one.nem.kidshift.data.retrofit.model.child.auth.ChildAuthResponse;
|
||||
import one.nem.kidshift.data.retrofit.model.parent.ParentInfoResponse;
|
||||
import one.nem.kidshift.data.retrofit.model.parent.ParentRenameRequest;
|
||||
import one.nem.kidshift.data.retrofit.model.parent.auth.ParentAuthRequest;
|
||||
import one.nem.kidshift.data.retrofit.model.parent.auth.ParentAuthResponse;
|
||||
import one.nem.kidshift.data.retrofit.model.task.HistoryListResponse;
|
||||
|
@ -46,23 +43,6 @@ public interface KidShiftApiService {
|
|||
@POST("/parent/auth/register")
|
||||
Call<ParentAuthResponse> parentRegister(@Body ParentAuthRequest request);
|
||||
|
||||
/**
|
||||
* 保護者情報更新処理
|
||||
* @param request ParentRenameRequest
|
||||
* @return ParentInfoResponse
|
||||
*/
|
||||
@PUT("/parent/account")
|
||||
@Headers(AuthorizationInterceptor.HEADER_PLACEHOLDER)
|
||||
Call<ParentInfoResponse> renameParent(@Body ParentRenameRequest request);
|
||||
|
||||
/**
|
||||
* 子供ログイン処理
|
||||
* @param request ChildAuthRequest
|
||||
* @return ChildAuthResponse
|
||||
*/
|
||||
@POST("/child/auth/login")
|
||||
Call<ChildAuthResponse> childLogin(@Body ChildAuthRequest request);
|
||||
|
||||
/**
|
||||
* 保護者アカウント情報取得処理
|
||||
* @return ParentInfoResponse
|
||||
|
@ -77,7 +57,7 @@ public interface KidShiftApiService {
|
|||
* タスク一覧取得
|
||||
* @return TaskListResponse
|
||||
*/
|
||||
@GET("/task")
|
||||
@GET("/parent/task")
|
||||
@Headers(AuthorizationInterceptor.HEADER_PLACEHOLDER)
|
||||
Call<TaskListResponse> getTasks();
|
||||
|
||||
|
@ -86,7 +66,7 @@ public interface KidShiftApiService {
|
|||
* @param request TaskAddRequest
|
||||
* @return TaskResponse
|
||||
*/
|
||||
@POST("/task")
|
||||
@POST("/parent/task")
|
||||
@Headers(AuthorizationInterceptor.HEADER_PLACEHOLDER)
|
||||
Call<TaskResponse> addTask(@Body TaskAddRequest request);
|
||||
|
||||
|
@ -96,7 +76,7 @@ public interface KidShiftApiService {
|
|||
* @param id タスクID
|
||||
* @return TaskResponse
|
||||
*/
|
||||
@PUT("/task/{id}")
|
||||
@PUT("/parent/task/{id}")
|
||||
@Headers(AuthorizationInterceptor.HEADER_PLACEHOLDER)
|
||||
Call<TaskResponse> updateTask(@Body TaskAddRequest request, @Path("id") String id);
|
||||
|
||||
|
@ -105,7 +85,7 @@ public interface KidShiftApiService {
|
|||
* @param id タスクID
|
||||
* @return Void
|
||||
*/
|
||||
@DELETE("/task/{id}")
|
||||
@DELETE("/parent/task/{id}")
|
||||
@Headers(AuthorizationInterceptor.HEADER_PLACEHOLDER)
|
||||
Call<Void> removeTask(@Path("id") String id); // TODO-rca: OK responseをパース
|
||||
|
||||
|
@ -114,7 +94,7 @@ public interface KidShiftApiService {
|
|||
* @param id タスクID
|
||||
* @return TaskResponse
|
||||
*/
|
||||
@GET("/task/{id}")
|
||||
@GET("/parent/task/{id}")
|
||||
@Headers(AuthorizationInterceptor.HEADER_PLACEHOLDER)
|
||||
Call<TaskResponse> getTask(@Path("id") String id);
|
||||
|
||||
|
@ -123,7 +103,7 @@ public interface KidShiftApiService {
|
|||
* @param id タスクID
|
||||
* @return Void
|
||||
*/
|
||||
@POST("/task/{id}/complete")
|
||||
@POST("/parent/task/{id}/complete")
|
||||
@Headers(AuthorizationInterceptor.HEADER_PLACEHOLDER)
|
||||
Call<Void> completeTask(@Path("id") String id, @Query("childId") String childId);
|
||||
|
||||
|
@ -133,61 +113,30 @@ public interface KidShiftApiService {
|
|||
* 子供一覧取得
|
||||
* @return ChildListResponse
|
||||
*/
|
||||
@GET("/child")
|
||||
@GET("/parent/child")
|
||||
@Headers(AuthorizationInterceptor.HEADER_PLACEHOLDER)
|
||||
Call<ChildListResponse> getChildList();
|
||||
|
||||
/**
|
||||
* 子供情報取得
|
||||
* @param id 子供ID
|
||||
* @return ChildResponse
|
||||
*/
|
||||
@GET("/child/{id}")
|
||||
@Headers(AuthorizationInterceptor.HEADER_PLACEHOLDER)
|
||||
Call<ChildResponse> getChild(@Path("id") String id);
|
||||
|
||||
/**
|
||||
* 子供追加
|
||||
* @param request ChildAddRequest
|
||||
* @return ChildResponse
|
||||
*/
|
||||
@POST("/child")
|
||||
@POST("/parent/child")
|
||||
@Headers(AuthorizationInterceptor.HEADER_PLACEHOLDER)
|
||||
Call<ChildResponse> addChild(@Body ChildAddRequest request);
|
||||
|
||||
/**
|
||||
* 子供更新
|
||||
* @param request ChildAddRequest
|
||||
* @param id 子供ID
|
||||
* @return ChildResponse
|
||||
*/
|
||||
@PUT("/child/{id}")
|
||||
@Headers(AuthorizationInterceptor.HEADER_PLACEHOLDER)
|
||||
Call<ChildResponse> updateChild(@Body ChildAddRequest request, @Path("id") String id);
|
||||
|
||||
/**
|
||||
* 子供削除
|
||||
* @param id 子供ID
|
||||
* @return Void
|
||||
*/
|
||||
@DELETE("/child/{id}")
|
||||
@Headers(AuthorizationInterceptor.HEADER_PLACEHOLDER)
|
||||
Call<Void> removeChild(@Path("id") String id);
|
||||
|
||||
/**
|
||||
* 子供ログインコード発行
|
||||
* @param id 子供ID
|
||||
* @return ChildLoginCodeResponse
|
||||
*/
|
||||
@GET("/child/{id}/login")
|
||||
@GET("/parent/child/{id}/login")
|
||||
@Headers(AuthorizationInterceptor.HEADER_PLACEHOLDER)
|
||||
Call<ChildLoginCodeResponse> issueLoginCode(@Path("id") String id);
|
||||
|
||||
@GET("/task/history/{childId}")
|
||||
@Headers(AuthorizationInterceptor.HEADER_PLACEHOLDER)
|
||||
Call<HistoryListResponse> getHistory(@Path("childId") String childId, @Query("containPaid") boolean containPaid);
|
||||
Call<HistoryListResponse> getHistory(@Path("childId") String childId);
|
||||
|
||||
@POST("/task/history/{historyId}/paid")
|
||||
@Headers(AuthorizationInterceptor.HEADER_PLACEHOLDER)
|
||||
Call<Void> payHistory(@Path("historyId") String historyId, @Query("isPaid") boolean isPaid);
|
||||
}
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
package one.nem.kidshift.data.retrofit.model.child.auth;
|
||||
|
||||
public class ChildAuthRequest {
|
||||
private String loginCode;
|
||||
|
||||
public ChildAuthRequest(String loginCode) {
|
||||
this.loginCode = loginCode;
|
||||
}
|
||||
|
||||
public String getLoginCode() {
|
||||
return loginCode;
|
||||
}
|
||||
|
||||
public void setLoginCode(String loginCode) {
|
||||
this.loginCode = loginCode;
|
||||
}
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
package one.nem.kidshift.data.retrofit.model.child.auth;
|
||||
|
||||
public class ChildAuthResponse {
|
||||
private String accessToken;
|
||||
private String childId;
|
||||
|
||||
public ChildAuthResponse() {
|
||||
}
|
||||
|
||||
public ChildAuthResponse(String accessToken, String childId) {
|
||||
this.accessToken = accessToken;
|
||||
this.childId = childId;
|
||||
}
|
||||
|
||||
public String getChildId() {
|
||||
return childId;
|
||||
}
|
||||
|
||||
public void setChildId(String childId) {
|
||||
this.childId = childId;
|
||||
}
|
||||
|
||||
public String getAccessToken() {
|
||||
return accessToken;
|
||||
}
|
||||
|
||||
public void setAccessToken(String accessToken) {
|
||||
this.accessToken = accessToken;
|
||||
}
|
||||
}
|
|
@ -19,7 +19,6 @@ public class HistoryModelConverter { // TODO: JavaDoc
|
|||
historyModel.setTaskId(historyResponse.getTaskId());
|
||||
historyModel.setChildId(historyResponse.getChildId());
|
||||
historyModel.setRegisteredAt(historyResponse.getRegisteredAt());
|
||||
historyModel.setPaid(historyResponse.isPaid());
|
||||
return historyModel;
|
||||
}
|
||||
|
||||
|
@ -29,7 +28,6 @@ public class HistoryModelConverter { // TODO: JavaDoc
|
|||
historyResponse.setTaskId(historyModel.getTaskId());
|
||||
historyResponse.setChildId(historyModel.getChildId());
|
||||
historyResponse.setRegisteredAt(historyModel.getRegisteredAt());
|
||||
historyResponse.setPaid(historyModel.isPaid());
|
||||
return historyResponse;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ public class ParentModelConverter {
|
|||
* @return ParentModel
|
||||
*/
|
||||
public static ParentModel parentInfoResponseToParentModel(ParentInfoResponse parentInfoResponse) {
|
||||
return new ParentModel(parentInfoResponse.getId(), parentInfoResponse.getDisplay_name(), parentInfoResponse.getEmail());
|
||||
return new ParentModel(parentInfoResponse.getId(), parentInfoResponse.getDisplayName(), parentInfoResponse.getEmail());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -4,18 +4,18 @@ public class ParentInfoResponse {
|
|||
|
||||
private String id;
|
||||
private String email;
|
||||
private String display_name;
|
||||
private String displayName;
|
||||
|
||||
/**
|
||||
* コンストラクタ (全プロパティ)
|
||||
* @param id 親ID
|
||||
* @param email メールアドレス
|
||||
* @param display_name 表示名
|
||||
* @param displayName 表示名
|
||||
*/
|
||||
public ParentInfoResponse(String id, String email, String display_name) {
|
||||
public ParentInfoResponse(String id, String email, String displayName) {
|
||||
this.id = id;
|
||||
this.email = email;
|
||||
this.display_name = display_name;
|
||||
this.displayName = displayName;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
|
@ -26,8 +26,8 @@ public class ParentInfoResponse {
|
|||
return email;
|
||||
}
|
||||
|
||||
public String getDisplay_name() {
|
||||
return display_name;
|
||||
public String getDisplayName() {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
|
@ -38,7 +38,7 @@ public class ParentInfoResponse {
|
|||
this.email = email;
|
||||
}
|
||||
|
||||
public void setDisplay_name(String display_name) {
|
||||
this.display_name = display_name;
|
||||
public void setDisplayName(String displayName) {
|
||||
this.displayName = displayName;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
package one.nem.kidshift.data.retrofit.model.parent;
|
||||
|
||||
public class ParentRenameRequest {
|
||||
private String displayName;
|
||||
|
||||
/**
|
||||
* コンストラクタ (全プロパティ)
|
||||
* @param displayName 表示名
|
||||
*/
|
||||
public ParentRenameRequest(String displayName) {
|
||||
this.displayName = displayName;
|
||||
}
|
||||
|
||||
public String getDisplayName() {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
public void setDisplayName(String displayName) {
|
||||
this.displayName = displayName;
|
||||
}
|
||||
}
|
|
@ -7,14 +7,12 @@ public class HistoryBaseItem {
|
|||
private String taskId;
|
||||
private String childId;
|
||||
private Date registeredAt;
|
||||
private boolean isPaid;
|
||||
|
||||
public HistoryBaseItem(String id, String taskId, String childId, Date registeredAt, boolean isPaid) {
|
||||
public HistoryBaseItem(String id, String taskId, String childId, Date registeredAt) {
|
||||
this.id = id;
|
||||
this.taskId = taskId;
|
||||
this.childId = childId;
|
||||
this.registeredAt = registeredAt;
|
||||
this.isPaid = isPaid;
|
||||
}
|
||||
|
||||
public HistoryBaseItem() {
|
||||
|
@ -51,12 +49,4 @@ public class HistoryBaseItem {
|
|||
public void setRegisteredAt(Date registeredAt) {
|
||||
this.registeredAt = registeredAt;
|
||||
}
|
||||
|
||||
public boolean isPaid() {
|
||||
return isPaid;
|
||||
}
|
||||
|
||||
public void setPaid(boolean isPaid) {
|
||||
this.isPaid = isPaid;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,8 +32,6 @@ dependencies {
|
|||
implementation libs.material
|
||||
implementation libs.navigation.fragment
|
||||
implementation libs.navigation.ui
|
||||
implementation libs.activity
|
||||
implementation libs.constraintlayout
|
||||
testImplementation libs.junit
|
||||
androidTestImplementation libs.ext.junit
|
||||
androidTestImplementation libs.espresso.core
|
||||
|
@ -50,5 +48,4 @@ dependencies {
|
|||
implementation project(':model')
|
||||
implementation project(':utils')
|
||||
implementation project(':data')
|
||||
implementation project(':shared')
|
||||
}
|
|
@ -1,10 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<application>
|
||||
<activity
|
||||
android:name=".ChildManageMainActivity"
|
||||
android:exported="false" />
|
||||
</application>
|
||||
|
||||
</manifest>
|
|
@ -1,201 +0,0 @@
|
|||
package one.nem.kidshift.feature.child;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.os.Bundle;
|
||||
import android.print.PrintAttributes;
|
||||
import android.view.View;
|
||||
import android.widget.EditText;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.activity.EdgeToEdge;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.core.graphics.Insets;
|
||||
import androidx.core.view.ViewCompat;
|
||||
import androidx.core.view.WindowInsetsCompat;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import dagger.hilt.android.AndroidEntryPoint;
|
||||
import one.nem.kidshift.data.ChildData;
|
||||
import one.nem.kidshift.feature.child.adapter.ChildListAdapter;
|
||||
import one.nem.kidshift.model.ChildModel;
|
||||
import one.nem.kidshift.model.callback.ChildModelCallback;
|
||||
import one.nem.kidshift.utils.KSLogger;
|
||||
import one.nem.kidshift.utils.factory.KSLoggerFactory;
|
||||
|
||||
@AndroidEntryPoint
|
||||
public class ChildManageMainActivity extends AppCompatActivity {
|
||||
|
||||
@Inject
|
||||
ChildData childData;
|
||||
|
||||
@Inject
|
||||
KSLoggerFactory loggerFactory;
|
||||
|
||||
private KSLogger logger;
|
||||
|
||||
ChildListAdapter childListAdapter;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
EdgeToEdge.enable(this);
|
||||
setContentView(R.layout.activity_child_manage_main);
|
||||
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("ChildManageMainActivity");
|
||||
|
||||
// ToolBarのセットアップ
|
||||
Toolbar toolbar = findViewById(R.id.toolBar);
|
||||
// タイトル
|
||||
toolbar.setTitle("子供アカウント管理");
|
||||
// 閉じる
|
||||
toolbar.setNavigationIcon(one.nem.kidshift.shared.R.drawable.close_24px);
|
||||
toolbar.setNavigationOnClickListener(v -> finish());
|
||||
// 追加ボタン
|
||||
toolbar.inflateMenu(R.menu.child_manage_main_toolbar_item);
|
||||
toolbar.setOnMenuItemClickListener(item -> {
|
||||
if (item.getItemId() == R.id.add_child_account) {
|
||||
showAddChildDialog();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
RecyclerView recyclerView = findViewById(R.id.childListRecyclerView);
|
||||
childListAdapter = new ChildListAdapter();
|
||||
childListAdapter.setButtonEventCallback(new ChildListAdapter.ButtonEventCallback() {
|
||||
@Override
|
||||
public void onEditButtonClick(ChildModel childModel) {
|
||||
showEditChildDialog(childModel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoginButtonClick(ChildModel childModel) {
|
||||
childData.issueLoginCode(childModel.getId()).thenAccept(loginCode -> {
|
||||
logger.debug("ログインコード発行完了: " + loginCode);
|
||||
runOnUiThread(() -> showLoginCodeDialog(loginCode));
|
||||
});
|
||||
}
|
||||
});
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(this));
|
||||
recyclerView.setAdapter(childListAdapter);
|
||||
|
||||
updateList();
|
||||
}
|
||||
|
||||
private void showLoginCodeDialog(Integer loginCode) {
|
||||
View view = getLayoutInflater().inflate(R.layout.child_login_code_dialog_layout, null);
|
||||
TextView loginCodeTextView = view.findViewById(R.id.loginCode);
|
||||
// loginCodeをStringに変換して4桁 2つに分割してハイフンで繋げる
|
||||
loginCodeTextView.setText(loginCode.toString().substring(0, 4) + "-" + loginCode.toString().substring(4));
|
||||
|
||||
new MaterialAlertDialogBuilder(this)
|
||||
.setTitle("ログインコード")
|
||||
.setView(view)
|
||||
.setPositiveButton("閉じる", (dialog, which) -> dialog.dismiss())
|
||||
.show();
|
||||
}
|
||||
|
||||
private void showAddChildDialog() {
|
||||
// EditTextを作成
|
||||
EditText childNameEditText = new EditText(this);
|
||||
childNameEditText.setHint("子供の名前");
|
||||
// FrameLayoutに入れる
|
||||
FrameLayout container = new FrameLayout(this);
|
||||
container.addView(childNameEditText);
|
||||
FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) childNameEditText.getLayoutParams();
|
||||
params.setMargins(32, 16, 32, 16);
|
||||
childNameEditText.setLayoutParams(params);
|
||||
|
||||
new MaterialAlertDialogBuilder(this)
|
||||
.setTitle("子供アカウント追加")
|
||||
.setView(container)
|
||||
.setPositiveButton("追加", (dialog, which) -> {
|
||||
String childName = Objects.requireNonNull(childNameEditText.getText()).toString();
|
||||
if (childName.isEmpty()) {
|
||||
Toast.makeText(this, "名前を入力してください", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
childData.addChild(new ChildModel(childName))
|
||||
.thenRun(this::updateListDirectly);
|
||||
})
|
||||
.setNegativeButton("キャンセル", (dialog, which) -> dialog.dismiss())
|
||||
.show();
|
||||
}
|
||||
|
||||
private void showEditChildDialog(ChildModel childModel) {
|
||||
// EditTextを作成
|
||||
EditText childNameEditText = new EditText(this);
|
||||
childNameEditText.setHint("子供の名前");
|
||||
childNameEditText.setText(childModel.getName());
|
||||
// FrameLayoutに入れる
|
||||
FrameLayout container = new FrameLayout(this);
|
||||
container.addView(childNameEditText);
|
||||
FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) childNameEditText.getLayoutParams();
|
||||
params.setMargins(32, 16, 32, 16);
|
||||
childNameEditText.setLayoutParams(params);
|
||||
|
||||
new MaterialAlertDialogBuilder(this)
|
||||
.setTitle("子供アカウント編集")
|
||||
.setView(container)
|
||||
.setPositiveButton("保存", (dialog, which) -> {
|
||||
String childName = Objects.requireNonNull(childNameEditText.getText()).toString();
|
||||
if (childName.isEmpty()) {
|
||||
Toast.makeText(this, "名前を入力してください", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
childModel.setName(childName);
|
||||
childData.updateChild(childModel)
|
||||
.thenRun(this::updateListDirectly);
|
||||
})
|
||||
.setNegativeButton("キャンセル", (dialog, which) -> dialog.dismiss())
|
||||
// 削除ボタン
|
||||
.setNeutralButton("削除", (dialog, which) -> { // TODO: 確認ダイアログを表示する
|
||||
childData.removeChild(childModel.getId())
|
||||
.thenRun(this::updateListDirectly);
|
||||
})
|
||||
.show();
|
||||
}
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
private void updateList() {
|
||||
childData.getChildList(new ChildModelCallback() {
|
||||
@Override
|
||||
public void onUnchanged() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdated(List<ChildModel> childModelList) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailed(String message) {
|
||||
|
||||
}
|
||||
}).thenAccept(childListAdapter::setChildList).thenRun(() -> {
|
||||
runOnUiThread(() -> childListAdapter.notifyDataSetChanged());
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
private void updateListDirectly() {
|
||||
childData.getChildListDirect().thenAccept(childListAdapter::setChildList).thenRun(() -> {
|
||||
runOnUiThread(() -> childListAdapter.notifyDataSetChanged());
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,79 +0,0 @@
|
|||
package one.nem.kidshift.feature.child.adapter;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import one.nem.kidshift.feature.child.R;
|
||||
import one.nem.kidshift.model.ChildModel;
|
||||
|
||||
public class ChildListAdapter extends RecyclerView.Adapter<ChildListAdapter.ViewHolder>{
|
||||
|
||||
private List<ChildModel> childList;
|
||||
private ButtonEventCallback buttonEventCallback;
|
||||
|
||||
public ChildListAdapter() {
|
||||
}
|
||||
|
||||
public void setChildList(List<ChildModel> childList) {
|
||||
this.childList = childList;
|
||||
}
|
||||
|
||||
public void setButtonEventCallback(ButtonEventCallback buttonEventCallback) {
|
||||
this.buttonEventCallback = buttonEventCallback;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ChildListAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_child_manage_main, parent, false);
|
||||
return new ViewHolder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull ChildListAdapter.ViewHolder holder, int position) {
|
||||
ChildModel childModel = childList.get(position);
|
||||
holder.childNameTextView.setText(childModel.getName());
|
||||
holder.editButton.setOnClickListener(v -> {
|
||||
if (buttonEventCallback != null) {
|
||||
buttonEventCallback.onEditButtonClick(childModel);
|
||||
}
|
||||
});
|
||||
holder.loginButton.setOnClickListener(v -> {
|
||||
if (buttonEventCallback != null) {
|
||||
buttonEventCallback.onLoginButtonClick(childModel);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return childList == null ? 0 : childList.size();
|
||||
}
|
||||
|
||||
public class ViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
TextView childNameTextView;
|
||||
Button editButton;
|
||||
Button loginButton;
|
||||
|
||||
public ViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
childNameTextView = itemView.findViewById(R.id.childNameTextView);
|
||||
editButton = itemView.findViewById(R.id.editButton);
|
||||
loginButton = itemView.findViewById(R.id.loginButton);
|
||||
}
|
||||
}
|
||||
|
||||
public interface ButtonEventCallback {
|
||||
void onEditButtonClick(ChildModel childModel);
|
||||
void onLoginButtonClick(ChildModel childModel);
|
||||
}
|
||||
}
|
|
@ -1,33 +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:id="@+id/main"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".ChildManageMainActivity">
|
||||
|
||||
<com.google.android.material.appbar.MaterialToolbar
|
||||
android:id="@+id/toolBar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/colorPrimary"
|
||||
android:minHeight="?attr/actionBarSize"
|
||||
android:theme="?attr/actionBarTheme"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/childListRecyclerView"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginStart="1dp"
|
||||
android:layout_marginTop="1dp"
|
||||
android:layout_marginEnd="1dp"
|
||||
android:layout_marginBottom="1dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/toolBar" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -1,26 +0,0 @@
|
|||
<?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>
|
|
@ -1,47 +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"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginVertical="12dp"
|
||||
android:layout_marginHorizontal="16dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/childNameTextView"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Placeholder"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Display1"
|
||||
android:textSize="16sp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/linearLayout"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/linearLayout"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<Button
|
||||
android:id="@+id/editButton"
|
||||
style="@style/Widget.Material3.Button.OutlinedButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="編集"
|
||||
android:layout_marginRight="8px"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/loginButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="ログイン"
|
||||
android:layout_marginLeft="8px"/>
|
||||
</LinearLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -1,10 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item
|
||||
android:id="@+id/add_child_account"
|
||||
android:icon="@drawable/add_24px"
|
||||
app:showAsAction="ifRoom"
|
||||
android:title="子供アカウントの追加" />
|
||||
</menu>
|
|
@ -1,7 +1,6 @@
|
|||
plugins {
|
||||
alias(libs.plugins.androidLibrary)
|
||||
id 'com.google.dagger.hilt.android'
|
||||
id 'androidx.navigation.safeargs'
|
||||
}
|
||||
|
||||
android {
|
||||
|
|
|
@ -1,41 +1,21 @@
|
|||
package one.nem.kidshift.feature.common;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.view.MenuHost;
|
||||
import androidx.core.view.MenuProvider;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.Lifecycle;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.Animation;
|
||||
import android.view.animation.AnimationUtils;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ScrollView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.github.sundeepk.compactcalendarview.CompactCalendarView;
|
||||
import com.github.sundeepk.compactcalendarview.domain.Event;
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
|
@ -43,20 +23,13 @@ import javax.inject.Inject;
|
|||
|
||||
import dagger.hilt.android.AndroidEntryPoint;
|
||||
import one.nem.kidshift.data.ChildData;
|
||||
import one.nem.kidshift.data.RewardData;
|
||||
import one.nem.kidshift.data.TaskData;
|
||||
import one.nem.kidshift.data.UserSettings;
|
||||
import one.nem.kidshift.feature.common.adapter.ChildListItemAdapter;
|
||||
import one.nem.kidshift.feature.common.adapter.TaskListItemAdapter;
|
||||
import one.nem.kidshift.model.HistoryModel;
|
||||
import one.nem.kidshift.model.callback.TaskItemModelCallback;
|
||||
import one.nem.kidshift.model.tasks.TaskItemModel;
|
||||
import one.nem.kidshift.utils.FabManager;
|
||||
import one.nem.kidshift.utils.KSLogger;
|
||||
import one.nem.kidshift.utils.RecyclerViewAnimUtils;
|
||||
import one.nem.kidshift.utils.ToolBarManager;
|
||||
import one.nem.kidshift.utils.factory.KSLoggerFactory;
|
||||
import one.nem.kidshift.utils.models.FabEventCallback;
|
||||
|
||||
@AndroidEntryPoint
|
||||
public class CommonHomeFragment extends Fragment {
|
||||
|
@ -70,29 +43,14 @@ public class CommonHomeFragment extends Fragment {
|
|||
TaskData taskData;
|
||||
@Inject
|
||||
ChildData childData;
|
||||
@Inject
|
||||
FabManager fabManager;
|
||||
@Inject
|
||||
ToolBarManager toolBarManager;
|
||||
@Inject
|
||||
RewardData rewardData;
|
||||
@Inject
|
||||
RecyclerViewAnimUtils recyclerViewAnimUtils;
|
||||
@Inject
|
||||
UserSettings userSettings;
|
||||
|
||||
|
||||
private boolean isChildMode;
|
||||
private String childId;
|
||||
private KSLogger logger;
|
||||
|
||||
CompactCalendarView compactCalendarView;
|
||||
View calendarContainer;
|
||||
SwipeRefreshLayout swipeRefreshLayout;
|
||||
TaskListItemAdapter taskListItemAdapter;
|
||||
TextView calendarTitleTextView;
|
||||
ImageButton calendarPrevButton;
|
||||
ImageButton calendarNextButton;
|
||||
|
||||
public CommonHomeFragment() {
|
||||
// Required empty public constructor
|
||||
|
@ -104,7 +62,9 @@ public class CommonHomeFragment extends Fragment {
|
|||
CommonHomeFragment fragment = new CommonHomeFragment();
|
||||
Bundle args = new Bundle();
|
||||
args.putBoolean(ARG_IS_CHILD_MODE, isChildMode);
|
||||
args.putString(ARG_CHILD_ID, childId);
|
||||
if (isChildMode) {
|
||||
args.putString(ARG_CHILD_ID, childId);
|
||||
}
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
|
@ -112,31 +72,11 @@ public class CommonHomeFragment extends Fragment {
|
|||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
logger = ksLoggerFactory.create("CommonHomeFragment");
|
||||
|
||||
if (userSettings.getAppCommonSetting().isChildMode()) {
|
||||
logger.debug("子供モードで起動(子供ログイン)");
|
||||
isChildMode = true;
|
||||
childId = userSettings.getAppCommonSetting().getChildId();
|
||||
logger.debug("childId: " + childId);
|
||||
} else {
|
||||
if (getArguments() != null) {
|
||||
isChildMode = getArguments().getBoolean(ARG_IS_CHILD_MODE) && getArguments().getBoolean(ARG_IS_CHILD_MODE);
|
||||
childId = getArguments().getString(ARG_CHILD_ID) != null ? getArguments().getString(ARG_CHILD_ID) : "";
|
||||
}
|
||||
|
||||
if (childId != null && !childId.isEmpty()) {
|
||||
isChildMode = true;
|
||||
}
|
||||
|
||||
if (isChildMode) {
|
||||
logger.debug("子供モードで起動");
|
||||
logger.debug("childId: " + childId);
|
||||
} else {
|
||||
logger.debug("保護者モードで起動");
|
||||
}
|
||||
if (getArguments() != null) {
|
||||
isChildMode = getArguments().getBoolean(ARG_IS_CHILD_MODE);
|
||||
childId = getArguments().getString(ARG_CHILD_ID);
|
||||
}
|
||||
logger = ksLoggerFactory.create("CommonHomeFragment");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -149,7 +89,9 @@ public class CommonHomeFragment extends Fragment {
|
|||
taskListItemAdapter = new TaskListItemAdapter();
|
||||
taskListItemAdapter.setCallback((taskId, taskName) -> {
|
||||
if (isChildMode) {
|
||||
showConfirmDialog(taskId, taskName);
|
||||
if (showConfirmDialog(taskName)) {
|
||||
taskData.recordTaskCompletion(taskId, childId);
|
||||
}
|
||||
} else {
|
||||
showChildSelectDialog(taskId, taskName);
|
||||
}
|
||||
|
@ -158,169 +100,39 @@ public class CommonHomeFragment extends Fragment {
|
|||
RecyclerView taskListRecyclerView = view.findViewById(R.id.taskListRecyclerView);
|
||||
taskListRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||
taskListRecyclerView.setAdapter(taskListItemAdapter);
|
||||
taskListRecyclerView.setItemViewCacheSize(10);
|
||||
recyclerViewAnimUtils.setSlideUpAnimation(taskListRecyclerView);
|
||||
|
||||
swipeRefreshLayout = view.findViewById(R.id.swipeRefreshLayout);
|
||||
swipeRefreshLayout.setOnRefreshListener(this::updateData);
|
||||
|
||||
calendarTitleTextView = view.findViewById(R.id.calendarTitleTextView);
|
||||
calendarPrevButton = view.findViewById(R.id.calendarPrevButton);
|
||||
calendarNextButton = view.findViewById(R.id.calendarNextButton);
|
||||
calendarContainer = view.findViewById(R.id.calendarContainer);
|
||||
|
||||
initCalender();
|
||||
updateData();
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
private void recyclerViewRefresh() {
|
||||
requireActivity().runOnUiThread(() -> {
|
||||
taskListItemAdapter.notifyItemRangeRemoved(0, taskListItemAdapter.getItemCount());
|
||||
taskListItemAdapter.notifyItemRangeInserted(0, taskListItemAdapter.getItemCount());
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
if (isChildMode) {
|
||||
setupFabChild();
|
||||
} else {
|
||||
setupFabParent();
|
||||
}
|
||||
setupToolBar();
|
||||
updateData();
|
||||
}
|
||||
|
||||
/**
|
||||
* 親モードの場合(=子供モードではない場合)のFABの設定
|
||||
*/
|
||||
private void setupFabParent() {
|
||||
fabManager.show();
|
||||
fabManager.setFabEventCallback(new FabEventCallback() {
|
||||
@Override
|
||||
public void onClicked() {
|
||||
showAddTaskDialog();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLongClicked() {
|
||||
// Do nothing
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 子供モードの場合のFABの設定
|
||||
*/
|
||||
private void setupFabChild() {
|
||||
fabManager.hide();
|
||||
}
|
||||
|
||||
private void setupToolBar() {
|
||||
if (isChildMode) {
|
||||
toolBarManager.setTitle("ホーム");
|
||||
toolBarManager.setSubtitle("子供ビュー");
|
||||
} else {
|
||||
toolBarManager.setTitle("ホーム");
|
||||
toolBarManager.setSubtitle("保護者ビュー");
|
||||
}
|
||||
MenuHost menuHost = requireActivity();
|
||||
|
||||
menuHost.invalidateMenu();
|
||||
menuHost.addMenuProvider(new MenuProvider() {
|
||||
@Override
|
||||
public void onCreateMenu(@NonNull Menu menu, @NonNull MenuInflater menuInflater) {
|
||||
logger.debug("onCreateMenu, インフレート");
|
||||
menu.clear();
|
||||
menuInflater.inflate(R.menu.common_home_toolbar_menu, menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onMenuItemSelected(@NonNull MenuItem menuItem) {
|
||||
if (menuItem.getItemId() == R.id.toggle_calendar) {
|
||||
if (calendarContainer.getVisibility() == View.VISIBLE) {
|
||||
Animation slideUp = AnimationUtils.loadAnimation(getContext(), one.nem.kidshift.shared.R.anim.slide_up);
|
||||
calendarContainer.startAnimation(slideUp);
|
||||
slideUp.setAnimationListener(new Animation.AnimationListener() {
|
||||
@Override
|
||||
public void onAnimationStart(Animation animation) {
|
||||
recyclerViewRefresh();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animation animation) {
|
||||
calendarContainer.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationRepeat(Animation animation) {
|
||||
}
|
||||
});
|
||||
} else {
|
||||
Animation slideDown = AnimationUtils.loadAnimation(getContext(), one.nem.kidshift.shared.R.anim.slide_down);
|
||||
calendarContainer.startAnimation(slideDown);
|
||||
slideDown.setAnimationListener(new Animation.AnimationListener() {
|
||||
@Override
|
||||
public void onAnimationStart(Animation animation) {
|
||||
calendarContainer.setVisibility(View.VISIBLE);
|
||||
recyclerViewRefresh();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animation animation) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationRepeat(Animation animation) {
|
||||
}
|
||||
});
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}, this.getViewLifecycleOwner(), Lifecycle.State.RESUMED);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* タスク完了確認ダイアログを表示 (子供モード用)
|
||||
*
|
||||
* @param taskId タスクID
|
||||
* @param taskName タスク名
|
||||
*/
|
||||
private void showConfirmDialog(String taskId, String taskName) {
|
||||
private boolean showConfirmDialog(String taskName) {
|
||||
AtomicBoolean selection = new AtomicBoolean(false);
|
||||
new MaterialAlertDialogBuilder(requireContext())
|
||||
.setTitle("タスクを完了しますか?")
|
||||
.setMessage(taskName + "を完了しますか?")
|
||||
.setPositiveButton("はい", (dialog, which) -> {
|
||||
dialog.dismiss();
|
||||
taskData.recordTaskCompletion(taskId, childId);
|
||||
selection.set(true);
|
||||
})
|
||||
.setNegativeButton("いいえ", (dialog, which) -> {
|
||||
dialog.dismiss();
|
||||
taskData.recordTaskCompletion(taskId, childId);
|
||||
selection.set(false);
|
||||
})
|
||||
.show();
|
||||
return selection.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* タスク完了ダイアログ(子供選択画面)を表示 (親モード用)
|
||||
*
|
||||
* @param taskId タスクID
|
||||
* @param taskName タスク名
|
||||
*/
|
||||
private void showChildSelectDialog(String taskId, String taskName) { // TODO: Assignされている子供かどうかを考慮するように
|
||||
RecyclerView childListRecyclerView = new RecyclerView(requireContext());
|
||||
childListRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||
childListRecyclerView.setPadding(0, 48, 0, 0);
|
||||
// TODO: キャッシュから取得する方にする?
|
||||
childData.getChildListDirect().thenAccept(childModelList -> {
|
||||
ChildListItemAdapter childListItemAdapter = new ChildListItemAdapter(childModelList);
|
||||
|
@ -339,132 +151,43 @@ public class CommonHomeFragment extends Fragment {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* タスク情報を更新
|
||||
* @return CompletableFuture<Void>
|
||||
*/
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
private CompletableFuture<Void> updateTaskInfo() { // TODO: updatedの場合の処理など実装
|
||||
return taskData.getTasks(new TaskItemModelCallback() {
|
||||
@Override
|
||||
public void onUnchanged() {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdated(List<TaskItemModel> taskItem) { // Workaround
|
||||
taskListItemAdapter.notifyItemRangeRemoved(0, taskListItemAdapter.getItemCount());
|
||||
taskListItemAdapter.setTaskItemModelList(taskItem);
|
||||
taskListItemAdapter.notifyItemRangeInserted(0, taskItem.size());
|
||||
public void onUpdated(List<TaskItemModel> taskItem) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailed(String message) {
|
||||
// TODO: ユーザーに丁寧に通知
|
||||
Toast.makeText(requireContext(), "タスク情報の取得に失敗しました", Toast.LENGTH_SHORT).show(); // Workaround
|
||||
}
|
||||
}).thenAccept(taskItemModel -> {
|
||||
taskListItemAdapter.setTaskItemModelList(taskItemModel);
|
||||
requireActivity().runOnUiThread(() -> {
|
||||
// taskListItemAdapter.notifyItemRangeRemoved(0, taskListItemAdapter.getItemCount());
|
||||
// taskListItemAdapter.setTaskItemModelList(taskItemModel);
|
||||
// taskListItemAdapter.notifyItemRangeInserted(0, taskItemModel.size());
|
||||
taskListItemAdapter.setTaskItemModelList(taskItemModel);
|
||||
taskListItemAdapter.notifyItemRangeChanged(0, taskItemModel.size());
|
||||
taskListItemAdapter.notifyDataSetChanged();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* カレンダーを更新
|
||||
* @return CompletableFuture<Void>
|
||||
*/
|
||||
private CompletableFuture<Void> updateCalender() {
|
||||
return rewardData.getRewardHistoryList().thenAccept(historyModels -> {
|
||||
historyModels.forEach(historyModel -> {
|
||||
compactCalendarView.addEvent(new Event(Color.RED, historyModel.getRegisteredAt().getTime(), historyModel)); // debug
|
||||
});
|
||||
});
|
||||
// TODO: タスクの完了状況をカレンダーに表示
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
|
||||
private void initCalender() {
|
||||
compactCalendarView.setListener(new CompactCalendarView.CompactCalendarViewListener() {
|
||||
@Override
|
||||
public void onDayClick(Date date) { // Test
|
||||
List<Event> events = compactCalendarView.getEvents(date);
|
||||
|
||||
ScrollView scrollView = new ScrollView(requireContext());
|
||||
LinearLayout linearLayout = new LinearLayout(requireContext());
|
||||
linearLayout.setOrientation(LinearLayout.VERTICAL);
|
||||
linearLayout.setPadding(96, 24, 96, 24);
|
||||
scrollView.addView(linearLayout);
|
||||
|
||||
events.forEach(event -> {
|
||||
TextView textView = new TextView(requireContext());
|
||||
textView.setText(((HistoryModel) event.getData()).getTaskName() + " @ " + ((HistoryModel) event.getData()).getChildId());
|
||||
textView.setPadding(0, 0, 0, 24);
|
||||
linearLayout.addView(textView);
|
||||
});
|
||||
|
||||
new MaterialAlertDialogBuilder(requireContext())
|
||||
.setTitle("タスク一覧 (DEBUG)")
|
||||
.setMessage(events.size() + "件のタスクが登録されています")
|
||||
.setView(scrollView)
|
||||
.setNeutralButton("閉じる", (dialog, which) -> dialog.dismiss())
|
||||
.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMonthScroll(Date date) {
|
||||
// 0000年00月の形式に変換 getYear/getMonthは非推奨
|
||||
calendarTitleTextView.setText(String.format("%d年%d月", date.getYear() + 1900, date.getMonth() + 1)); // 統合
|
||||
}
|
||||
});
|
||||
|
||||
// 初回
|
||||
Date date = new Date();
|
||||
calendarTitleTextView.setText(String.format("%d年%d月", date.getYear() + 1900, date.getMonth() + 1)); // 統合
|
||||
|
||||
calendarPrevButton.setOnClickListener(v -> {
|
||||
compactCalendarView.scrollLeft();
|
||||
});
|
||||
|
||||
calendarNextButton.setOnClickListener(v -> {
|
||||
compactCalendarView.scrollRight();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* データを更新 (updateTaskInfoとupdateCalenderを並列実行)
|
||||
*/
|
||||
private void updateData() {
|
||||
requireActivity().runOnUiThread(() -> {
|
||||
swipeRefreshLayout.setRefreshing(true);
|
||||
});
|
||||
swipeRefreshLayout.setRefreshing(true);
|
||||
CompletableFuture.allOf(updateTaskInfo(), updateCalender()).thenRun(() -> {
|
||||
requireActivity().runOnUiThread(() -> {
|
||||
swipeRefreshLayout.setRefreshing(false);
|
||||
});
|
||||
// Workaround: リスト更新処理があまりにも重くてアニメーションが壊れるため
|
||||
try {
|
||||
Thread.sleep(500);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
swipeRefreshLayout.setRefreshing(false);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* タスク追加ダイアログを表示
|
||||
*/
|
||||
private void showAddTaskDialog() {
|
||||
View view = getLayoutInflater().inflate(R.layout.common_task_add_dialog_layout, null);
|
||||
view.setPadding(48, 24, 48, 24);
|
||||
new MaterialAlertDialogBuilder(requireContext())
|
||||
.setTitle("タスクを追加")
|
||||
.setView(view)
|
||||
.setPositiveButton("追加", (dialog, which) -> {
|
||||
EditText taskNameEditText = view.findViewById(R.id.addTaskNameEditText);
|
||||
EditText taskRewardEditText = view.findViewById(R.id.addTaskRewardEditText);
|
||||
TaskItemModel taskItemModel = new TaskItemModel();
|
||||
taskItemModel.setName(taskNameEditText.getText().toString());
|
||||
taskItemModel.setReward(Integer.parseInt(taskRewardEditText.getText().toString()));
|
||||
taskData.addTask(taskItemModel).thenRun(this::updateData);
|
||||
})
|
||||
.setNegativeButton("キャンセル", (dialog, which) -> dialog.dismiss())
|
||||
.show();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,90 +0,0 @@
|
|||
package one.nem.kidshift.feature.common;
|
||||
|
||||
import static androidx.navigation.Navigation.findNavController;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import dagger.hilt.android.AndroidEntryPoint;
|
||||
import one.nem.kidshift.data.ChildData;
|
||||
import one.nem.kidshift.feature.common.adapter.SelectShowChildListItemAdapter;
|
||||
import one.nem.kidshift.utils.FabManager;
|
||||
import one.nem.kidshift.utils.KSLogger;
|
||||
import one.nem.kidshift.utils.RecyclerViewAnimUtils;
|
||||
import one.nem.kidshift.utils.ToolBarManager;
|
||||
import one.nem.kidshift.utils.factory.KSLoggerFactory;
|
||||
|
||||
@AndroidEntryPoint
|
||||
public class CommonSelectChildFragment extends Fragment {
|
||||
|
||||
@Inject
|
||||
KSLoggerFactory loggerFactory;
|
||||
@Inject
|
||||
ChildData childData;
|
||||
@Inject
|
||||
FabManager fabManager;
|
||||
@Inject
|
||||
ToolBarManager toolBarManager;
|
||||
@Inject
|
||||
RecyclerViewAnimUtils recyclerViewAnimUtils;
|
||||
private KSLogger logger;
|
||||
|
||||
private SelectShowChildListItemAdapter adapter;
|
||||
|
||||
public CommonSelectChildFragment() {
|
||||
// Required empty public constructor
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
logger = loggerFactory.create("CommonSelectChildFragment");
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
// Inflate the layout for this fragment
|
||||
View view = inflater.inflate(R.layout.fragment_common_select_child, container, false);
|
||||
|
||||
RecyclerView childListRecyclerView = view.findViewById(R.id.selectShowChildListRecyclerView);
|
||||
childListRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||
recyclerViewAnimUtils.setSlideUpAnimation(childListRecyclerView);
|
||||
adapter = new SelectShowChildListItemAdapter();
|
||||
adapter.setCallback(childId -> {
|
||||
// 静的解析エラーが発生するのになぜか実行はできる↓
|
||||
findNavController(view).navigate(CommonSelectChildFragmentDirections.actionCommonSelectChildFragmentToCommonHomeFragmentParentChild(childId));
|
||||
});
|
||||
CompletableFuture.runAsync(() -> childListRecyclerView.setAdapter(adapter)).thenRun(() -> childData.getChildListDirect().thenAccept(childList -> {
|
||||
requireActivity().runOnUiThread(() -> {
|
||||
adapter.setChildDataList(childList);
|
||||
adapter.notifyItemRangeChanged(0, childList.size());
|
||||
});
|
||||
}).exceptionally(e -> {
|
||||
logger.error("Failed to load child list");
|
||||
return null;
|
||||
}));
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
fabManager.hide();
|
||||
toolBarManager.setTitle("子供選択");
|
||||
toolBarManager.setSubtitle(null);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
package one.nem.kidshift.feature.common.adapter;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
|
@ -38,7 +37,7 @@ public class ChildListItemAdapter extends RecyclerView.Adapter<ChildListItemAdap
|
|||
@NonNull
|
||||
@Override
|
||||
public ChildListItemAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_task_completion_child, parent, false);
|
||||
View view = View.inflate(parent.getContext(), R.layout.list_item_task_completion_child, null);
|
||||
return new ViewHolder(view);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,75 +0,0 @@
|
|||
package one.nem.kidshift.feature.common.adapter;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import one.nem.kidshift.feature.common.R;
|
||||
import one.nem.kidshift.model.ChildModel;
|
||||
|
||||
public class SelectShowChildListItemAdapter extends RecyclerView.Adapter<SelectShowChildListItemAdapter.ViewHolder> {
|
||||
|
||||
private List<ChildModel> childDataList;
|
||||
private CompleteButtonClickedCallback callback;
|
||||
|
||||
public SelectShowChildListItemAdapter() {
|
||||
// Empty constructor
|
||||
}
|
||||
|
||||
public SelectShowChildListItemAdapter(List<ChildModel> childDataList) {
|
||||
this.childDataList = childDataList;
|
||||
}
|
||||
|
||||
public void setChildDataList(List<ChildModel> childDataList) {
|
||||
this.childDataList = childDataList;
|
||||
}
|
||||
|
||||
public void setCallback(CompleteButtonClickedCallback callback) {
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public SelectShowChildListItemAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_select_show_child, parent, false);
|
||||
return new ViewHolder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull SelectShowChildListItemAdapter.ViewHolder holder, int position) {
|
||||
ChildModel childData = childDataList.get(position);
|
||||
holder.childName.setText(childData.getName());
|
||||
holder.selectButton.setOnClickListener(v -> {
|
||||
if (callback != null) {
|
||||
callback.onClicked(childData.getId());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return childDataList == null ? 0 : childDataList.size();
|
||||
}
|
||||
|
||||
public static class ViewHolder extends RecyclerView.ViewHolder {
|
||||
TextView childName;
|
||||
Button selectButton;
|
||||
|
||||
public ViewHolder(@NonNull android.view.View itemView) {
|
||||
super(itemView);
|
||||
childName = itemView.findViewById(R.id.childNameTextView);
|
||||
selectButton = itemView.findViewById(R.id.selectButton);
|
||||
}
|
||||
}
|
||||
|
||||
public interface CompleteButtonClickedCallback {
|
||||
void onClicked(String taskId);
|
||||
}
|
||||
}
|
|
@ -1,45 +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="wrap_content"
|
||||
android:layout_margin="0dp">
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/addTaskNameTextInputLayout"
|
||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="タスク名"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/addTaskNameEditText"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="text" />
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/addTaskRewardTextInputLayout"
|
||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:hint="金額"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/addTaskNameTextInputLayout">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/addTaskRewardEditText"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="number" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -11,72 +11,22 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
<com.github.sundeepk.compactcalendarview.CompactCalendarView
|
||||
android:id="@+id/calendar"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="250dp"
|
||||
android:paddingLeft="10dp"
|
||||
android:paddingRight="10dp"
|
||||
app:compactCalendarBackgroundColor="#ffe95451"
|
||||
app:compactCalendarCurrentDayBackgroundColor="#B71C1C"
|
||||
app:compactCalendarCurrentSelectedDayBackgroundColor="#E57373"
|
||||
app:compactCalendarMultiEventIndicatorColor="#fff"
|
||||
app:compactCalendarTargetHeight="250dp"
|
||||
app:compactCalendarTextColor="#fff"
|
||||
app:compactCalendarTextSize="12sp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
android:id="@+id/calendarContainer">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/colorSurface">
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/calendarPrevButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@android:color/transparent"
|
||||
android:src="@drawable/arrow_back_24px"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:tint="@color/colorOnSurface"
|
||||
android:padding="8dp"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/calendarTitleTextView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/colorOnSurface"
|
||||
android:textSize="20sp"
|
||||
android:text="2000年1月"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/calendarNextButton"
|
||||
app:layout_constraintStart_toEndOf="@+id/calendarPrevButton"
|
||||
app:layout_constraintTop_toTopOf="parent"/>
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/calendarNextButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@android:color/transparent"
|
||||
android:src="@drawable/arrow_forward_24px"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:tint="@color/colorOnSurface"
|
||||
android:padding="8dp"/>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<com.github.sundeepk.compactcalendarview.CompactCalendarView
|
||||
android:id="@+id/calendar"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="300dp"
|
||||
android:paddingLeft="10dp"
|
||||
android:paddingRight="10dp"
|
||||
app:compactCalendarBackgroundColor="@color/colorSurface"
|
||||
app:compactCalendarCurrentDayBackgroundColor="@color/colorSurfaceVariant"
|
||||
app:compactCalendarCurrentSelectedDayBackgroundColor="@color/colorSurfaceVariant"
|
||||
app:compactCalendarMultiEventIndicatorColor="@color/colorOnSurface"
|
||||
app:compactCalendarTextColor="@color/colorOnSurface"
|
||||
app:compactCalendarTextSize="12sp"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/taskListRecyclerView"
|
||||
|
@ -85,7 +35,7 @@
|
|||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/calendarContainer" />
|
||||
app:layout_constraintTop_toBottomOf="@+id/calendar" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
|
|
|
@ -1,30 +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=".CommonSelectChildFragment" >
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="128dp"
|
||||
android:text="使用するお子様を選択"
|
||||
android:textSize="20sp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/selectShowChildListRecyclerView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginTop="32dp"
|
||||
android:layout_marginBottom="128dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/textView2" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -4,8 +4,7 @@
|
|||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="24dp"
|
||||
android:layout_marginVertical="8dp">
|
||||
android:layout_margin="12dp">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/textContainer"
|
||||
|
@ -17,6 +16,7 @@
|
|||
android:id="@+id/task_title_text_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:text="お手伝い名"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Display1"
|
||||
android:textSize="20sp"
|
||||
|
@ -27,6 +27,7 @@
|
|||
android:id="@+id/task_contents_text_view"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginTop="13dp"
|
||||
android:text="円/回"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
|
|
|
@ -1,35 +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="wrap_content"
|
||||
android:layout_marginHorizontal="24dp"
|
||||
android:layout_marginVertical="4dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:orientation="horizontal"
|
||||
android:padding="8px"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/childNameTextView"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="PLACEHOLDER"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium" />
|
||||
|
||||
<!-- ImageButtonに変更? -->
|
||||
<Button
|
||||
android:id="@+id/selectButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="表示" />
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -3,9 +3,7 @@
|
|||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="24dp"
|
||||
android:layout_marginVertical="4dp">
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
@ -24,12 +22,11 @@
|
|||
android:text="PLACEHOLDER"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium" />
|
||||
|
||||
<!-- ImageButtonに変更? -->
|
||||
<Button
|
||||
android:id="@+id/completeButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="完了" />
|
||||
android:text="Button" />
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -1,11 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item
|
||||
android:id="@+id/toggle_calendar"
|
||||
android:icon="@drawable/calendar_month_24px"
|
||||
app:showAsAction="ifRoom"
|
||||
android:title="カレンダー表示切り替え" />
|
||||
|
||||
</menu>
|
|
@ -1,21 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<navigation 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/feature_common_child_child_navigation"
|
||||
app:startDestination="@id/commonHomeFragmentChildChild">
|
||||
|
||||
<fragment
|
||||
android:id="@+id/commonHomeFragmentChildChild"
|
||||
android:name="one.nem.kidshift.feature.common.CommonHomeFragment"
|
||||
android:label="fragment_common_home"
|
||||
tools:layout="@layout/fragment_common_home" >
|
||||
<argument
|
||||
android:name="childId"
|
||||
app:argType="string" />
|
||||
<argument
|
||||
android:name="isChildMode"
|
||||
app:argType="boolean"
|
||||
android:defaultValue="true" />
|
||||
</fragment>
|
||||
</navigation>
|
|
@ -2,11 +2,11 @@
|
|||
<navigation 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/feature_common_parent_parent_navigation"
|
||||
app:startDestination="@id/commonHomeFragmentParentParent">
|
||||
android:id="@+id/feature_common_navigation"
|
||||
app:startDestination="@id/commonHomeFragment">
|
||||
|
||||
<fragment
|
||||
android:id="@+id/commonHomeFragmentParentParent"
|
||||
android:id="@+id/commonHomeFragment"
|
||||
android:name="one.nem.kidshift.feature.common.CommonHomeFragment"
|
||||
android:label="fragment_common_home"
|
||||
tools:layout="@layout/fragment_common_home" />
|
|
@ -1,30 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<navigation 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/feature_common_parent_child_navigation"
|
||||
app:startDestination="@id/commonSelectChildFragment">
|
||||
|
||||
<fragment
|
||||
android:id="@+id/commonHomeFragmentParentChild"
|
||||
android:name="one.nem.kidshift.feature.common.CommonHomeFragment"
|
||||
android:label="fragment_common_home"
|
||||
tools:layout="@layout/fragment_common_home" />
|
||||
<fragment
|
||||
android:id="@+id/commonSelectChildFragment"
|
||||
android:name="one.nem.kidshift.feature.common.CommonSelectChildFragment"
|
||||
android:label="fragment_common_select_child"
|
||||
tools:layout="@layout/fragment_common_select_child" >
|
||||
<action
|
||||
android:id="@+id/action_commonSelectChildFragment_to_commonHomeFragmentParentChild"
|
||||
app:destination="@id/commonHomeFragmentParentChild" >
|
||||
<argument
|
||||
android:name="childId"
|
||||
app:argType="string" />
|
||||
<argument
|
||||
android:name="isChildMode"
|
||||
app:argType="boolean"
|
||||
android:defaultValue="true" />
|
||||
</action>
|
||||
</fragment>
|
||||
</navigation>
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<navigation 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/feature_parent_navigation"
|
||||
app:startDestination="@id/feature_common_navigation">
|
||||
<include app:graph="@navigation/feature_common_navigation" />
|
||||
</navigation>
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/internal_parent_navigation">
|
||||
|
||||
<include app:graph="@navigation/feature_common_navigation" />
|
||||
</navigation>
|
|
@ -1,253 +0,0 @@
|
|||
package one.nem.kidshift.wallet;
|
||||
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import one.nem.kidshift.model.HistoryModel;
|
||||
|
||||
public class HistoryItemListAdapter extends RecyclerView.Adapter<HistoryItemListAdapter.ViewHolder> {
|
||||
|
||||
enum ViewType {
|
||||
WITH_HEADER(1),
|
||||
ITEM(0);
|
||||
|
||||
private final int value;
|
||||
|
||||
ViewType(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
public static class HistoryModelExtended extends HistoryModel {
|
||||
private boolean isChecked;
|
||||
|
||||
public boolean isChecked() {
|
||||
return isChecked;
|
||||
}
|
||||
|
||||
public void setChecked(boolean checked) {
|
||||
isChecked = checked;
|
||||
}
|
||||
|
||||
// add isChecked to the constructor
|
||||
public HistoryModelExtended() {
|
||||
super();
|
||||
isChecked = false;
|
||||
}
|
||||
|
||||
// copy constructor
|
||||
public HistoryModelExtended(HistoryModel historyModel) {
|
||||
super();
|
||||
this.setId(historyModel.getId());
|
||||
this.setPaid(historyModel.isPaid());
|
||||
this.setChildId(historyModel.getChildId());
|
||||
this.setRegisteredAt(historyModel.getRegisteredAt());
|
||||
this.setTaskId(historyModel.getTaskId());
|
||||
this.setTaskName(historyModel.getTaskName());
|
||||
this.setReward(historyModel.getReward());
|
||||
this.setChecked(false);
|
||||
}
|
||||
}
|
||||
|
||||
public static class HistoryModelExtendedList {
|
||||
private List<HistoryModelExtended> list;
|
||||
|
||||
public List<HistoryModelExtended> getList() {
|
||||
return list;
|
||||
}
|
||||
|
||||
public void setList(List<HistoryModelExtended> list) {
|
||||
this.list = list;
|
||||
}
|
||||
|
||||
// clear all checked items
|
||||
public void clearChecked() {
|
||||
for (HistoryModelExtended item : list) {
|
||||
item.setChecked(false);
|
||||
}
|
||||
}
|
||||
|
||||
// constructor
|
||||
public HistoryModelExtendedList() {
|
||||
list = new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
public interface CheckBoxChangedCallback {
|
||||
void onCheckBoxChanged();
|
||||
}
|
||||
|
||||
public boolean hasChecked() {
|
||||
for (HistoryModelExtended historyModelExtended : historyDataList.getList()) {
|
||||
if (historyModelExtended.isChecked()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private HistoryModelExtendedList historyDataList;
|
||||
private CheckBoxChangedCallback callback;
|
||||
private boolean hideCheckBox; // for child mode
|
||||
|
||||
public void setHistoryDataList(List<HistoryModel> historyDataList) {
|
||||
this.historyDataList = new HistoryModelExtendedList();
|
||||
for (HistoryModel historyModel : historyDataList) {
|
||||
this.historyDataList.getList().add(new HistoryModelExtended(historyModel));
|
||||
}
|
||||
}
|
||||
|
||||
public void setCallback(CheckBoxChangedCallback callback) {
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
public void setHideCheckBox(boolean hideCheckBox) {
|
||||
this.hideCheckBox = hideCheckBox;
|
||||
}
|
||||
|
||||
public List<HistoryModel> getCheckedHistoryDataList() {
|
||||
List<HistoryModel> checkedHistoryDataList = new ArrayList<>();
|
||||
for (HistoryModelExtended historyModelExtended : historyDataList.getList()) {
|
||||
if (historyModelExtended.isChecked()) {
|
||||
checkedHistoryDataList.add(historyModelExtended);
|
||||
}
|
||||
}
|
||||
return checkedHistoryDataList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
if (position == 0) {
|
||||
return ViewType.WITH_HEADER.getValue();
|
||||
} else {
|
||||
if (isFirstOfMonth(historyDataList.getList().get(position))) {
|
||||
return ViewType.WITH_HEADER.getValue();
|
||||
} else {
|
||||
return ViewType.ITEM.getValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public HistoryItemListAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
if (viewType == ViewType.WITH_HEADER.getValue()) {
|
||||
LinearLayout view = new LinearLayout(parent.getContext());
|
||||
|
||||
view.setOrientation(LinearLayout.VERTICAL);
|
||||
view.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
|
||||
|
||||
view.addView(LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_history_month_header, parent, false));
|
||||
view.addView(LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_history_list_item, parent, false));
|
||||
return new MonthHeaderViewHolder(view);
|
||||
} else {
|
||||
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_history_list_item, parent, false);
|
||||
return new ViewHolder(view);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull HistoryItemListAdapter.ViewHolder holder, int position) {
|
||||
HistoryModelExtended historyData = this.historyDataList.getList().get(position);
|
||||
if (historyData.isPaid() || hideCheckBox) {
|
||||
holder.historyItemCheckBox.setVisibility(View.GONE);
|
||||
} else {
|
||||
holder.historyItemCheckBox.setVisibility(View.VISIBLE);
|
||||
}
|
||||
holder.historyItemNameTextView.setText(historyData.getTaskName());
|
||||
holder.historyItemRewardTextView.setText(historyData.getReward() + "円");
|
||||
holder.historyItemCheckBox.setChecked(historyData.isChecked());
|
||||
holder.historyItemCheckBox.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||
if (holder.historyItemCheckBox.isShown()) {
|
||||
historyData.setChecked(isChecked);
|
||||
callback.onCheckBoxChanged();
|
||||
}
|
||||
});
|
||||
if (holder instanceof MonthHeaderViewHolder) {
|
||||
((MonthHeaderViewHolder) holder).monthHeaderTitle.setText(historyData.getRegisteredAt().getMonth() + 1 + "月");
|
||||
// // DEBUG: 月をまたぐデータがないので
|
||||
// ((MonthHeaderViewHolder) holder).monthHeaderTitle.setText(historyData.getRegisteredAt().getDate() + "日");
|
||||
((MonthHeaderViewHolder) holder).monthTotalTextView.setText(getMonthTotal(historyData) + "円");
|
||||
((MonthHeaderViewHolder) holder).checkAllButton.setOnClickListener(v -> {
|
||||
Toast.makeText(v.getContext(), "実装中", Toast.LENGTH_SHORT).show();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isFirstOfMonth(HistoryModel historyModel) {
|
||||
// 1個前の要素と比較して月が変わったかどうかを判定する
|
||||
if (historyDataList.getList().indexOf(historyModel) == 0) {
|
||||
return true;
|
||||
} else {
|
||||
HistoryModel previousHistoryModel = historyDataList.getList().get(historyDataList.getList().indexOf(historyModel) - 1);
|
||||
// getMonth()はDeprecated TODO: やめる
|
||||
return historyModel.getRegisteredAt().getMonth() != previousHistoryModel.getRegisteredAt().getMonth();
|
||||
// DEBUG: 月をまたぐデータがないので
|
||||
// return historyModel.getRegisteredAt().getDate() != previousHistoryModel.getRegisteredAt().getDate();
|
||||
}
|
||||
}
|
||||
|
||||
private int getMonthTotal(HistoryModel historyModel) {
|
||||
int total = historyModel.getReward();
|
||||
int index = historyDataList.getList().indexOf(historyModel) + 1;
|
||||
try {
|
||||
while (!isFirstOfMonth(this.historyDataList.getList().get(index))) {
|
||||
total += historyModel.getReward();
|
||||
index++;
|
||||
}
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// 1個しかない場合 Workaround
|
||||
// TODO: 例外をひねり潰すのではなく,そもそも発生しないようにするべき
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return historyDataList == null ? 0 : historyDataList.getList().size();
|
||||
}
|
||||
|
||||
public static class ViewHolder extends RecyclerView.ViewHolder {
|
||||
TextView historyItemNameTextView;
|
||||
TextView historyItemRewardTextView;
|
||||
CheckBox historyItemCheckBox;
|
||||
public ViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
historyItemNameTextView = itemView.findViewById(R.id.historyItemNameTextView);
|
||||
historyItemRewardTextView = itemView.findViewById(R.id.historyItemRewardTextView);
|
||||
historyItemCheckBox = itemView.findViewById(R.id.checkBox);
|
||||
}
|
||||
}
|
||||
|
||||
public static class MonthHeaderViewHolder extends HistoryItemListAdapter.ViewHolder {
|
||||
// かなり邪道な方法だけど,とりあえず取得できるので
|
||||
|
||||
TextView monthHeaderTitle;
|
||||
TextView monthTotalTextView;
|
||||
ImageButton checkAllButton;
|
||||
|
||||
public MonthHeaderViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
monthHeaderTitle = itemView.findViewById(R.id.monthHeaderTitle);
|
||||
monthTotalTextView = itemView.findViewById(R.id.monthTotalTextView);
|
||||
checkAllButton = itemView.findViewById(R.id.checkAllButton);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,23 +11,15 @@ import javax.inject.Inject;
|
|||
import dagger.hilt.android.AndroidEntryPoint;
|
||||
import one.nem.kidshift.data.KSActions;
|
||||
import one.nem.kidshift.data.RewardData;
|
||||
import one.nem.kidshift.data.UserSettings;
|
||||
import one.nem.kidshift.model.HistoryModel;
|
||||
import one.nem.kidshift.utils.FabManager;
|
||||
import one.nem.kidshift.utils.KSLogger;
|
||||
import one.nem.kidshift.utils.RecyclerViewAnimUtils;
|
||||
import one.nem.kidshift.utils.ToolBarManager;
|
||||
import one.nem.kidshift.utils.factory.KSLoggerFactory;
|
||||
import one.nem.kidshift.utils.models.FabEventCallback;
|
||||
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||
|
||||
@AndroidEntryPoint
|
||||
public class WalletContentFragment extends Fragment {
|
||||
|
||||
private static final String ARG_CHILD_ID = "childId";
|
||||
|
||||
@Inject
|
||||
KSLoggerFactory loggerFactory;
|
||||
@Inject
|
||||
|
@ -35,21 +27,11 @@ public class WalletContentFragment extends Fragment {
|
|||
|
||||
@Inject
|
||||
FabManager fabManager;
|
||||
@Inject
|
||||
ToolBarManager toolBarManager;
|
||||
|
||||
@Inject
|
||||
UserSettings userSettings;
|
||||
@Inject
|
||||
RecyclerViewAnimUtils recyclerViewAnimUtils;
|
||||
|
||||
private KSLogger logger;
|
||||
private String childId;
|
||||
|
||||
private TextView totalRewardTextView;
|
||||
private SwipeRefreshLayout swipeRefreshLayout;
|
||||
|
||||
private HistoryItemListAdapter historyItemListAdapter;
|
||||
|
||||
public WalletContentFragment() {
|
||||
// Required empty public constructor
|
||||
|
@ -63,10 +45,6 @@ public class WalletContentFragment extends Fragment {
|
|||
return fragment;
|
||||
}
|
||||
|
||||
public static WalletContentFragment newInstance() {
|
||||
return new WalletContentFragment();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
@ -75,13 +53,6 @@ public class WalletContentFragment extends Fragment {
|
|||
}
|
||||
logger = loggerFactory.create("WalletMainFragment");
|
||||
logger.debug("Received parameter: " + childId);
|
||||
if (childId == null) {
|
||||
// 単品で呼び出されてる = 子供モードでログインされている
|
||||
childId = userSettings.getAppCommonSetting().getChildId();
|
||||
if (childId == null) {
|
||||
logger.error("Child ID is not set");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -92,114 +63,28 @@ public class WalletContentFragment extends Fragment {
|
|||
|
||||
totalRewardTextView = view.findViewById(R.id.totalRewardTextView);
|
||||
|
||||
swipeRefreshLayout = view.findViewById(R.id.swipeRefreshLayout);
|
||||
|
||||
swipeRefreshLayout.setOnRefreshListener(() -> {
|
||||
// updateTotalReward();
|
||||
updateItems();
|
||||
swipeRefreshLayout.setRefreshing(false);
|
||||
});
|
||||
|
||||
RecyclerView historyItemRecyclerView = view.findViewById(R.id.historyItemRecyclerView);
|
||||
recyclerViewAnimUtils.setSlideUpAnimation(historyItemRecyclerView);
|
||||
historyItemListAdapter = new HistoryItemListAdapter();
|
||||
historyItemRecyclerView.setAdapter(historyItemListAdapter);
|
||||
historyItemRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext()));
|
||||
|
||||
historyItemListAdapter.setHideCheckBox(userSettings.getAppCommonSetting().isChildMode());
|
||||
|
||||
historyItemListAdapter.setCallback(() -> {
|
||||
if (historyItemListAdapter.hasChecked()) {
|
||||
fabManager.show();
|
||||
initFab();
|
||||
} else {
|
||||
fabManager.hide();
|
||||
}
|
||||
});
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
private void initFab() {
|
||||
fabManager.setFabEventCallback(new FabEventCallback() {
|
||||
@Override
|
||||
public void onClicked() {
|
||||
historyItemListAdapter.getCheckedHistoryDataList().forEach(historyModel -> {
|
||||
rewardData.payReward(historyModel.getId()).thenRun(() -> {
|
||||
logger.debug("Paid reward: " + historyModel.getId());
|
||||
updateItems();
|
||||
}).exceptionally(throwable -> {
|
||||
logger.error("Failed to pay reward: " + throwable.getMessage());
|
||||
return null;
|
||||
});
|
||||
});
|
||||
|
||||
updateItems(); // workaround
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLongClicked() {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
|
||||
updateItems();
|
||||
}
|
||||
|
||||
private void updateItems() {
|
||||
swipeRefreshLayout.setRefreshing(true);
|
||||
rewardData.getRewardHistoryList(childId).thenAccept(historyList -> {
|
||||
historyItemListAdapter.setHistoryDataList(historyList);
|
||||
// totalRewardTextView.setText(String.valueOf(historyList.stream().mapToInt(HistoryModel::getReward).sum()) + "円");
|
||||
requireActivity().runOnUiThread(() -> {
|
||||
historyItemListAdapter.notifyDataSetChanged();
|
||||
totalRewardTextView.setText(String.valueOf(historyList.stream().filter(item -> !item.isPaid()).mapToInt(HistoryModel::getReward).sum()) + "円");
|
||||
});
|
||||
}).thenRun(() -> {
|
||||
requireActivity().runOnUiThread(() -> {
|
||||
swipeRefreshLayout.setRefreshing(false);
|
||||
});
|
||||
}).exceptionally(throwable -> {
|
||||
logger.error("Failed to get history list: " + throwable.getMessage());
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
private void updateTotalReward() {
|
||||
swipeRefreshLayout.setRefreshing(true);
|
||||
rewardData.getTotalReward(childId).thenAccept(totalReward -> {
|
||||
logger.debug("Total reward: " + totalReward);
|
||||
totalRewardTextView.setText(String.valueOf(totalReward) + "円");
|
||||
}).thenRun(() -> {
|
||||
requireActivity().runOnUiThread(() -> {
|
||||
swipeRefreshLayout.setRefreshing(false);
|
||||
});
|
||||
}).exceptionally(throwable -> {
|
||||
logger.error("Failed to get total reward: " + throwable.getMessage());
|
||||
return null;
|
||||
});
|
||||
|
||||
rewardData.getRewardHistoryList(childId).thenAccept(historyList -> { // test
|
||||
historyItemListAdapter.setHistoryDataList(historyList);
|
||||
historyItemListAdapter.notifyDataSetChanged();
|
||||
}).exceptionally(throwable -> {
|
||||
logger.error("Failed to get history list: " + throwable.getMessage());
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
// updateTotalReward();
|
||||
// updateItems();
|
||||
// fabManager.hide();
|
||||
toolBarManager.setTitle("ウォレット");
|
||||
toolBarManager.setSubtitle(null);
|
||||
updateTotalReward();
|
||||
fabManager.hide();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,10 +26,7 @@ import dagger.hilt.android.AndroidEntryPoint;
|
|||
import one.nem.kidshift.data.ChildData;
|
||||
import one.nem.kidshift.data.RewardData;
|
||||
import one.nem.kidshift.model.ChildModel;
|
||||
import one.nem.kidshift.model.callback.ChildModelCallback;
|
||||
import one.nem.kidshift.utils.FabManager;
|
||||
import one.nem.kidshift.utils.KSLogger;
|
||||
import one.nem.kidshift.utils.ToolBarManager;
|
||||
import one.nem.kidshift.utils.factory.KSLoggerFactory;
|
||||
|
||||
@AndroidEntryPoint
|
||||
|
@ -45,14 +42,9 @@ public class WalletParentWrapperFragment extends Fragment {
|
|||
|
||||
@Inject
|
||||
RewardData rewardData;
|
||||
@Inject
|
||||
FabManager fabManager;
|
||||
@Inject
|
||||
ToolBarManager toolBarManager;
|
||||
|
||||
private TabLayout tabLayout;
|
||||
private ViewPager2 viewPager;
|
||||
private TabAdapter tabAdapter;
|
||||
|
||||
public WalletParentWrapperFragment() {
|
||||
// Required empty public constructor
|
||||
|
@ -72,50 +64,22 @@ public class WalletParentWrapperFragment extends Fragment {
|
|||
tabLayout = view.findViewById(R.id.tabLayout);
|
||||
viewPager = view.findViewById(R.id.viewPager);
|
||||
|
||||
tabAdapter = new TabAdapter(requireActivity());
|
||||
TabAdapter tabAdapter = new TabAdapter(requireActivity());
|
||||
|
||||
// デバッグ用
|
||||
List<ChildModel> childList = childData.getChildListDirect().join();
|
||||
tabAdapter.setChildList(childList);
|
||||
|
||||
viewPager.setAdapter(tabAdapter);
|
||||
|
||||
setupViewPager();
|
||||
new TabLayoutMediator(tabLayout, viewPager, (tab, position) -> {
|
||||
tab.setText(childList.get(position).getName());
|
||||
}).attach();
|
||||
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
private void setupViewPager() {
|
||||
|
||||
// デバッグ用
|
||||
childData.getChildList(new ChildModelCallback() {
|
||||
@Override
|
||||
public void onUnchanged() {
|
||||
// TODO: impl
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdated(List<ChildModel> childModelList) {
|
||||
// TODO: impl
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailed(String message) {
|
||||
// TODO: impl
|
||||
}
|
||||
}).thenAccept(childModels -> {
|
||||
|
||||
// childData.getChildListDirect().thenAccept(childModels -> {
|
||||
|
||||
tabAdapter.setChildList(childModels);
|
||||
requireActivity().runOnUiThread(() -> {
|
||||
|
||||
tabAdapter.notifyDataSetChanged();
|
||||
|
||||
new TabLayoutMediator(tabLayout, viewPager, (tab, position) -> {
|
||||
tab.setText(childModels.get(position).getName());
|
||||
}).attach();
|
||||
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private static class TabAdapter extends FragmentStateAdapter {
|
||||
|
||||
private List<ChildModel> childList;
|
||||
|
@ -140,12 +104,4 @@ public class WalletParentWrapperFragment extends Fragment {
|
|||
return childList == null ? 0 : childList.size();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
fabManager.hide();
|
||||
toolBarManager.setTitle("ウォレット");
|
||||
toolBarManager.setSubtitle(null);
|
||||
}
|
||||
}
|
|
@ -16,12 +16,9 @@
|
|||
android:id="@+id/frameLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/colorSurface"
|
||||
android:backgroundTintMode="add"
|
||||
android:elevation="16px"
|
||||
android:layout_marginTop="24dp"
|
||||
android:layout_marginBottom="24dp"
|
||||
app:layout_constraintBottom_toTopOf="@+id/historyItemRecyclerView"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<LinearLayout
|
||||
|
@ -35,7 +32,6 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:text="今月の支払い総額"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Display1"
|
||||
android:textColor="@color/colorOnSurface"
|
||||
android:textSize="20sp" />
|
||||
|
||||
<TextView
|
||||
|
@ -44,8 +40,7 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:text="0000円"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Display2"
|
||||
android:textColor="@color/colorOnSurface" />
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Display2" />
|
||||
</LinearLayout>
|
||||
</FrameLayout>
|
||||
|
||||
|
|
|
@ -12,8 +12,7 @@
|
|||
android:layout_height="wrap_content"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:tabMode="scrollable">
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
</com.google.android.material.tabs.TabLayout>
|
||||
|
||||
|
|
|
@ -1,45 +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="wrap_content"
|
||||
android:padding="32px">
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/checkBox"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:layout_marginBottom="12dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16px"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/historyItemNameTextView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="TextView"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/historyItemRewardTextView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="TextView"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Small" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -1,48 +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="wrap_content"
|
||||
android:paddingHorizontal="48px"
|
||||
android:paddingVertical="24px">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/linearLayout"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/monthHeaderTitle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="ふが月"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Display1" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/monthTotalTextView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="0000000円"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/checkAllButton"
|
||||
style="@style/Widget.AppCompat.ImageButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@android:color/transparent"
|
||||
android:padding="24px"
|
||||
android:tint="@color/colorOnBackground"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:srcCompat="@drawable/done_all_24px" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -1,5 +1,5 @@
|
|||
[versions]
|
||||
agp = "8.0.2"
|
||||
agp = "8.3.2"
|
||||
gson = "2.11.0"
|
||||
javafaker = "1.0.2"
|
||||
junit = "4.13.2"
|
||||
|
|
|
@ -9,16 +9,14 @@ public class HistoryModel {
|
|||
private String childId;
|
||||
private Date registeredAt;
|
||||
private int reward;
|
||||
private boolean isPaid;
|
||||
|
||||
public HistoryModel(String id, String taskId, String taskName, String childId, Date registeredAt, int reward, boolean isPaid) {
|
||||
public HistoryModel(String id, String taskId, String taskName, String childId, Date registeredAt, int reward) {
|
||||
this.id = id;
|
||||
this.taskId = taskId;
|
||||
this.taskName = taskName;
|
||||
this.childId = childId;
|
||||
this.registeredAt = registeredAt;
|
||||
this.reward = reward;
|
||||
this.isPaid = isPaid;
|
||||
}
|
||||
|
||||
public HistoryModel(String id, String taskId, String childId, Date registeredAt) { // 他モデルとのマージが必要なので
|
||||
|
@ -78,12 +76,4 @@ public class HistoryModel {
|
|||
public void setReward(int reward) {
|
||||
this.reward = reward;
|
||||
}
|
||||
|
||||
public boolean isPaid() {
|
||||
return isPaid;
|
||||
}
|
||||
|
||||
public void setPaid(boolean isPaid) {
|
||||
this.isPaid = isPaid;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:duration="700"
|
||||
android:fillAfter="false"
|
||||
>
|
||||
|
||||
<translate
|
||||
android:interpolator="@android:anim/decelerate_interpolator"
|
||||
android:fromXDelta="100%p"
|
||||
android:toXDelta="0"
|
||||
/>
|
||||
|
||||
<alpha
|
||||
android:fromAlpha="0.5"
|
||||
android:toAlpha="1"
|
||||
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
|
||||
/>
|
||||
|
||||
</set>
|
|
@ -1,11 +0,0 @@
|
|||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<alpha
|
||||
android:fromAlpha="0.0"
|
||||
android:toAlpha="1.0"
|
||||
android:duration="300"/>
|
||||
<translate
|
||||
android:fromYDelta="-50%"
|
||||
android:toYDelta="0"
|
||||
android:duration="300"
|
||||
android:interpolator="@android:anim/accelerate_interpolator"/>
|
||||
</set>
|
|
@ -1,11 +0,0 @@
|
|||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<alpha
|
||||
android:fromAlpha="1.0"
|
||||
android:toAlpha="0.0"
|
||||
android:duration="300"/>
|
||||
<translate
|
||||
android:fromYDelta="0"
|
||||
android:toYDelta="-50%"
|
||||
android:duration="300"
|
||||
android:interpolator="@android:anim/decelerate_interpolator"/>
|
||||
</set>
|
|
@ -1,10 +0,0 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M200,721.69Q254,668.69 325.5,638.19Q397,607.69 480,607.69Q563,607.69 634.5,638.19Q706,668.69 760,721.69L760,212.31Q760,207.69 756.15,203.85Q752.31,200 747.69,200L212.31,200Q207.69,200 203.85,203.85Q200,207.69 200,212.31L200,721.69ZM480,521.54Q534.15,521.54 572.08,483.62Q610,445.69 610,391.54Q610,337.39 572.08,299.46Q534.15,261.54 480,261.54Q425.85,261.54 387.92,299.46Q350,337.39 350,391.54Q350,445.69 387.92,483.62Q425.85,521.54 480,521.54ZM212.31,820Q182,820 161,799Q140,778 140,747.69L140,212.31Q140,182 161,161Q182,140 212.31,140L747.69,140Q778,140 799,161Q820,182 820,212.31L820,747.69Q820,778 799,799Q778,820 747.69,820L212.31,820ZM257.69,760L702.31,760Q702.31,757.38 702.31,755.77Q702.31,754.15 702.31,751.54Q654.92,709.23 598.35,688.46Q541.77,667.69 480,667.69Q419,667.69 362.23,688.27Q305.46,708.85 257.69,750.77Q257.69,753.38 257.69,755.38Q257.69,757.38 257.69,760ZM480,461.54Q451.15,461.54 430.58,440.96Q410,420.39 410,391.54Q410,362.69 430.58,342.12Q451.15,321.54 480,321.54Q508.85,321.54 529.42,342.12Q550,362.69 550,391.54Q550,420.39 529.42,440.96Q508.85,461.54 480,461.54ZM480,460.85L480,460.85Q480,460.85 480,460.85Q480,460.85 480,460.85L480,460.85Q480,460.85 480,460.85Q480,460.85 480,460.85L480,460.85Q480,460.85 480,460.85Q480,460.85 480,460.85Q480,460.85 480,460.85Q480,460.85 480,460.85Z"/>
|
||||
</vector>
|
|
@ -1,11 +0,0 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960"
|
||||
android:tint="?attr/colorControlNormal"
|
||||
android:autoMirrored="true">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M313,520L537,744L480,800L160,480L480,160L537,216L313,440L800,440L800,520L313,520Z"/>
|
||||
</vector>
|
|
@ -1,11 +0,0 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960"
|
||||
android:tint="?attr/colorControlNormal"
|
||||
android:autoMirrored="true">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M647,520L160,520L160,440L647,440L423,216L480,160L800,480L480,800L423,744L647,520Z"/>
|
||||
</vector>
|
|
@ -1,10 +0,0 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M200,880Q167,880 143.5,856.5Q120,833 120,800L120,240Q120,207 143.5,183.5Q167,160 200,160L240,160L240,80L320,80L320,160L640,160L640,80L720,80L720,160L760,160Q793,160 816.5,183.5Q840,207 840,240L840,800Q840,833 816.5,856.5Q793,880 760,880L200,880ZM200,800L760,800Q760,800 760,800Q760,800 760,800L760,400L200,400L200,800Q200,800 200,800Q200,800 200,800ZM200,320L760,320L760,240Q760,240 760,240Q760,240 760,240L200,240Q200,240 200,240Q200,240 200,240L200,320ZM200,320L200,240Q200,240 200,240Q200,240 200,240L200,240Q200,240 200,240Q200,240 200,240L200,320ZM480,560Q463,560 451.5,548.5Q440,537 440,520Q440,503 451.5,491.5Q463,480 480,480Q497,480 508.5,491.5Q520,503 520,520Q520,537 508.5,548.5Q497,560 480,560ZM320,560Q303,560 291.5,548.5Q280,537 280,520Q280,503 291.5,491.5Q303,480 320,480Q337,480 348.5,491.5Q360,503 360,520Q360,537 348.5,548.5Q337,560 320,560ZM640,560Q623,560 611.5,548.5Q600,537 600,520Q600,503 611.5,491.5Q623,480 640,480Q657,480 668.5,491.5Q680,503 680,520Q680,537 668.5,548.5Q657,560 640,560ZM480,720Q463,720 451.5,708.5Q440,697 440,680Q440,663 451.5,651.5Q463,640 480,640Q497,640 508.5,651.5Q520,663 520,680Q520,697 508.5,708.5Q497,720 480,720ZM320,720Q303,720 291.5,708.5Q280,697 280,680Q280,663 291.5,651.5Q303,640 320,640Q337,640 348.5,651.5Q360,663 360,680Q360,697 348.5,708.5Q337,720 320,720ZM640,720Q623,720 611.5,708.5Q600,697 600,680Q600,663 611.5,651.5Q623,640 640,640Q657,640 668.5,651.5Q680,663 680,680Q680,697 668.5,708.5Q657,720 640,720Z"/>
|
||||
</vector>
|
|
@ -1,10 +0,0 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M480,522.15L277.08,725.08Q268.77,733.38 256.19,733.58Q243.62,733.77 234.92,725.08Q226.23,716.38 226.23,704Q226.23,691.62 234.92,682.92L437.85,480L234.92,277.08Q226.62,268.77 226.42,256.19Q226.23,243.62 234.92,234.92Q243.62,226.23 256,226.23Q268.38,226.23 277.08,234.92L480,437.85L682.92,234.92Q691.23,226.62 703.81,226.42Q716.38,226.23 725.08,234.92Q733.77,243.62 733.77,256Q733.77,268.38 725.08,277.08L522.15,480L725.08,682.92Q733.38,691.23 733.58,703.81Q733.77,716.38 725.08,725.08Q716.38,733.77 704,733.77Q691.62,733.77 682.92,725.08L480,522.15Z"/>
|
||||
</vector>
|
|
@ -1,10 +0,0 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M200,760L257,760L648,369L591,312L200,703L200,760ZM120,840L120,670L648,143Q660,132 674.5,126Q689,120 705,120Q721,120 736,126Q751,132 762,144L817,200Q829,211 834.5,226Q840,241 840,256Q840,272 834.5,286.5Q829,301 817,313L290,840L120,840ZM760,256L760,256L704,200L704,200L760,256ZM619,341L591,312L591,312L648,369L648,369L619,341Z"/>
|
||||
</vector>
|
|
@ -1,10 +0,0 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M240,760L373.85,760L373.85,558.46Q373.85,543.1 384.24,532.7Q394.64,522.31 410,522.31L550,522.31Q565.36,522.31 575.76,532.7Q586.15,543.1 586.15,558.46L586.15,760L720,760L720,406.15Q720,403.08 718.65,400.58Q717.31,398.08 715,396.15L487.31,225Q484.23,222.31 480,222.31Q475.77,222.31 472.69,225L245,396.15Q242.69,398.08 241.35,400.58Q240,403.08 240,406.15L240,760ZM180,760L180,406.15Q180,388.98 187.68,373.62Q195.37,358.25 208.92,348.31L436.62,176.77Q455.57,162.31 479.94,162.31Q504.31,162.31 523.38,176.77L751.08,348.31Q764.63,358.25 772.32,373.62Q780,388.98 780,406.15L780,760Q780,784.54 762.27,802.27Q744.54,820 720,820L562.31,820Q546.94,820 536.55,809.6Q526.15,799.21 526.15,783.84L526.15,582.31Q526.15,582.31 526.15,582.31Q526.15,582.31 526.15,582.31L433.85,582.31Q433.85,582.31 433.85,582.31Q433.85,582.31 433.85,582.31L433.85,783.84Q433.85,799.21 423.45,809.6Q413.06,820 397.69,820L240,820Q215.46,820 197.73,802.27Q180,784.54 180,760ZM480,490.77L480,490.77L480,490.77Q480,490.77 480,490.77Q480,490.77 480,490.77L480,490.77L480,490.77L480,490.77L480,490.77Q480,490.77 480,490.77Q480,490.77 480,490.77L480,490.77Q480,490.77 480,490.77Q480,490.77 480,490.77L480,490.77Z"/>
|
||||
</vector>
|
|
@ -1,10 +0,0 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M640,480L720,560L720,640L520,640L520,880L480,920L440,880L440,640L240,640L240,560L320,480L320,200L280,200L280,120L680,120L680,200L640,200L640,480ZM354,560L606,560L560,514L560,200L400,200L400,514L354,560ZM480,560L480,560L480,560L480,560L480,560L480,560Z"/>
|
||||
</vector>
|
|
@ -1,10 +0,0 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M680,120L680,200L640,200L640,527L560,447L560,200L400,200L400,287L313,200L280,167L280,167L280,120L680,120ZM480,920L440,880L440,640L240,640L240,560L320,480L320,434L56,168L112,112L848,848L790,904L526,640L520,640L520,880L480,920ZM354,560L446,560L402,516L400,514L354,560ZM480,367L480,367L480,367L480,367ZM402,516L402,516L402,516L402,516Z"/>
|
||||
</vector>
|
|
@ -1,11 +0,0 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960"
|
||||
android:tint="?attr/colorControlNormal"
|
||||
android:autoMirrored="true">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M200,840Q167,840 143.5,816.5Q120,793 120,760L120,200Q120,167 143.5,143.5Q167,120 200,120L480,120L480,200L200,200Q200,200 200,200Q200,200 200,200L200,760Q200,760 200,760Q200,760 200,760L480,760L480,840L200,840ZM640,680L585,622L687,520L360,520L360,440L687,440L585,338L640,280L840,480L640,680Z"/>
|
||||
</vector>
|
|
@ -1,10 +0,0 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M400,467.69Q342.25,467.69 301.13,426.57Q260,385.44 260,327.69Q260,269.94 301.13,228.82Q342.25,187.69 400,187.69Q457.75,187.69 498.87,228.82Q540,269.94 540,327.69Q540,385.44 498.87,426.57Q457.75,467.69 400,467.69ZM100,711.54L100,683.38Q100,653.08 115.66,628.5Q131.31,603.92 158.62,590.08Q212.77,562.62 270.86,547.46Q328.95,532.31 389.85,532.31L395.62,532.31Q408.37,532.31 416.99,541.28Q425.61,550.26 425.61,562.98Q425.61,575.69 416.99,584.31Q408.37,592.92 395.62,592.92Q394.08,592.92 392.73,592.92Q391.38,592.92 389.85,592.92Q335.72,592.92 284.98,605.96Q234.23,619 186.15,644Q174.62,650.15 167.31,660.31Q160,670.46 160,683.38L160,712.31L395.62,712.31Q408.37,712.31 416.99,720.94Q425.61,729.56 425.61,742.32Q425.61,755.08 416.99,763.69Q408.37,772.31 395.62,772.31L160.77,772.31Q135.46,772.31 117.73,754.58Q100,736.84 100,711.54ZM640.15,778.77L635.31,748.84Q621,744.61 608.38,737.77Q595.77,730.92 584.38,720.61L554.62,731.54Q545.08,734.77 536.18,731.14Q527.29,727.51 522.31,719.54L517,710.15Q511.92,701.61 513.36,691.54Q514.8,681.47 522.69,675L546.62,656Q542.31,640.46 542.31,625.38Q542.31,610.31 546.62,594.77L523.08,575Q515.16,568.69 513.54,559.04Q511.92,549.38 517,540.85L522.92,530.85Q528.01,522.87 536.74,519.24Q545.46,515.62 555,518.85L584.38,529.77Q595.38,519.46 608.19,512.81Q621,506.15 635.31,501.92L640.15,471.38Q642,461.23 649.62,455.04Q657.23,448.85 667.38,448.85L678,448.85Q688.15,448.85 695.77,455.35Q703.38,461.85 705.23,472L709.69,501.92Q724,506.15 736.81,513.12Q749.61,520.08 760.61,531L788.77,520.08Q798.92,516.23 808.08,519.88Q817.23,523.54 822.27,531.89L828.03,541.64Q833.07,550 831.46,559.96Q829.84,569.92 821.92,576.23L798.38,596Q802.69,610.43 802.69,626.06Q802.69,641.69 798.38,656L822.31,675Q830.23,681.31 831.65,691.15Q833.07,701 828,709.54L822.07,719.54Q817.07,727.51 808.5,731.14Q799.92,734.77 790.38,731.54L760.61,720.61Q749.23,730.92 736.61,737.77Q724,744.61 709.69,748.84L705.23,779.38Q703.38,789.54 695.77,795.73Q688.15,801.92 678,801.92L667.38,801.92Q657.23,801.92 649.62,795.42Q642,788.92 640.15,778.77ZM672.34,701.54Q703.77,701.54 726.11,679.16Q748.46,656.78 748.46,625.35Q748.46,593.92 726.08,571.58Q703.7,549.23 672.27,549.23Q640.85,549.23 618.5,571.61Q596.15,593.99 596.15,625.42Q596.15,656.84 618.53,679.19Q640.91,701.54 672.34,701.54ZM400,407.69Q433,407.69 456.5,384.19Q480,360.69 480,327.69Q480,294.69 456.5,271.19Q433,247.69 400,247.69Q367,247.69 343.5,271.19Q320,294.69 320,327.69Q320,360.69 343.5,384.19Q367,407.69 400,407.69ZM400,327.69Q400,327.69 400,327.69Q400,327.69 400,327.69Q400,327.69 400,327.69Q400,327.69 400,327.69Q400,327.69 400,327.69Q400,327.69 400,327.69Q400,327.69 400,327.69Q400,327.69 400,327.69ZM412,712.31L412,712.31L412,712.31Q412,712.31 412,712.31Q412,712.31 412,712.31Q412,712.31 412,712.31Q412,712.31 412,712.31Q412,712.31 412,712.31Q412,712.31 412,712.31Q412,712.31 412,712.31Q412,712.31 412,712.31Z"/>
|
||||
</vector>
|
|
@ -1,10 +0,0 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M280,840L280,760L440,760L440,636Q391,625 352.5,594.5Q314,564 296,518Q221,509 170.5,452.5Q120,396 120,320L120,280Q120,247 143.5,223.5Q167,200 200,200L280,200L280,120L680,120L680,200L760,200Q793,200 816.5,223.5Q840,247 840,280L840,320Q840,396 789.5,452.5Q739,509 664,518Q646,564 607.5,594.5Q569,625 520,636L520,760L680,760L680,840L280,840ZM280,432L280,280L200,280L200,320Q200,358 222,388.5Q244,419 280,432ZM480,560Q530,560 565,525Q600,490 600,440L600,200L360,200L360,440Q360,490 395,525Q430,560 480,560ZM680,432Q716,419 738,388.5Q760,358 760,320L760,280L680,280L680,432ZM480,380Q480,380 480,380Q480,380 480,380L480,380L480,380L480,380Q480,380 480,380Q480,380 480,380Z"/>
|
||||
</vector>
|
|
@ -38,8 +38,6 @@ dependencies {
|
|||
implementation libs.com.google.dagger.hilt.android
|
||||
annotationProcessor libs.com.google.dagger.hilt.compiler
|
||||
|
||||
implementation 'jp.wasabeef:recyclerview-animators:4.0.2'
|
||||
|
||||
// Gson
|
||||
implementation libs.gson
|
||||
}
|