ViewModel refactoring.
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
<component name="InspectionProjectProfileManager">
|
<component name="InspectionProjectProfileManager">
|
||||||
<profile version="1.0">
|
<profile version="1.0">
|
||||||
<option name="myName" value="Project Default" />
|
<option name="myName" value="Project Default" />
|
||||||
|
<inspection_tool class="FieldCanBeLocal" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
<inspection_tool class="TrivialIf" enabled="false" level="WARNING" enabled_by_default="false" />
|
<inspection_tool class="TrivialIf" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
</profile>
|
</profile>
|
||||||
</component>
|
</component>
|
||||||
@@ -8,20 +8,19 @@ import android.widget.TextView;
|
|||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.fragment.app.Fragment;
|
|
||||||
import androidx.lifecycle.Observer;
|
import androidx.lifecycle.Observer;
|
||||||
import androidx.lifecycle.ViewModelProviders;
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
|
|
||||||
import com.majinnaibu.monstercards.R;
|
import com.majinnaibu.monstercards.R;
|
||||||
|
import com.majinnaibu.monstercards.ui.shared.MCFragment;
|
||||||
|
|
||||||
public class CollectionsFragment extends Fragment {
|
public class CollectionsFragment extends MCFragment {
|
||||||
|
|
||||||
private CollectionsViewModel collectionsViewModel;
|
private CollectionsViewModel collectionsViewModel;
|
||||||
|
|
||||||
public View onCreateView(@NonNull LayoutInflater inflater,
|
public View onCreateView(@NonNull LayoutInflater inflater,
|
||||||
ViewGroup container, Bundle savedInstanceState) {
|
ViewGroup container, Bundle savedInstanceState) {
|
||||||
collectionsViewModel =
|
collectionsViewModel = new ViewModelProvider(this).get(CollectionsViewModel.class);
|
||||||
ViewModelProviders.of(this).get(CollectionsViewModel.class);
|
|
||||||
View root = inflater.inflate(R.layout.fragment_collections, container, false);
|
View root = inflater.inflate(R.layout.fragment_collections, container, false);
|
||||||
final TextView textView = root.findViewById(R.id.text_collections);
|
final TextView textView = root.findViewById(R.id.text_collections);
|
||||||
collectionsViewModel.getText().observe(getViewLifecycleOwner(), new Observer<String>() {
|
collectionsViewModel.getText().observe(getViewLifecycleOwner(), new Observer<String>() {
|
||||||
|
|||||||
@@ -7,29 +7,21 @@ import android.view.ViewGroup;
|
|||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
import androidx.fragment.app.Fragment;
|
|
||||||
import androidx.lifecycle.Observer;
|
|
||||||
import androidx.lifecycle.ViewModelProviders;
|
|
||||||
|
|
||||||
import com.majinnaibu.monstercards.R;
|
import com.majinnaibu.monstercards.R;
|
||||||
|
import com.majinnaibu.monstercards.ui.shared.MCFragment;
|
||||||
|
|
||||||
public class DashboardFragment extends Fragment {
|
public class DashboardFragment extends MCFragment {
|
||||||
|
|
||||||
private DashboardViewModel dashboardViewModel;
|
private DashboardViewModel dashboardViewModel;
|
||||||
|
|
||||||
public View onCreateView(@NonNull LayoutInflater inflater,
|
public View onCreateView(@NonNull LayoutInflater inflater,
|
||||||
ViewGroup container, Bundle savedInstanceState) {
|
ViewGroup container, Bundle savedInstanceState) {
|
||||||
dashboardViewModel =
|
dashboardViewModel = new ViewModelProvider(this).get(DashboardViewModel.class);
|
||||||
ViewModelProviders.of(this).get(DashboardViewModel.class);
|
|
||||||
View root = inflater.inflate(R.layout.fragment_dashboard, container, false);
|
View root = inflater.inflate(R.layout.fragment_dashboard, container, false);
|
||||||
final TextView textView = root.findViewById(R.id.text_dashboard);
|
final TextView textView = root.findViewById(R.id.text_dashboard);
|
||||||
dashboardViewModel.getText().observe(getViewLifecycleOwner(), new Observer<String>() {
|
dashboardViewModel.getText().observe(getViewLifecycleOwner(), textView::setText);
|
||||||
@Override
|
|
||||||
public void onChanged(@Nullable String s) {
|
|
||||||
textView.setText(s);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,8 +5,7 @@ import androidx.lifecycle.MutableLiveData;
|
|||||||
import androidx.lifecycle.ViewModel;
|
import androidx.lifecycle.ViewModel;
|
||||||
|
|
||||||
public class DashboardViewModel extends ViewModel {
|
public class DashboardViewModel extends ViewModel {
|
||||||
|
private final MutableLiveData<String> mText;
|
||||||
private MutableLiveData<String> mText;
|
|
||||||
|
|
||||||
public DashboardViewModel() {
|
public DashboardViewModel() {
|
||||||
mText = new MutableLiveData<>();
|
mText = new MutableLiveData<>();
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import androidx.navigation.Navigation;
|
|||||||
|
|
||||||
import com.majinnaibu.monstercards.R;
|
import com.majinnaibu.monstercards.R;
|
||||||
import com.majinnaibu.monstercards.ui.components.Stepper;
|
import com.majinnaibu.monstercards.ui.components.Stepper;
|
||||||
|
import com.majinnaibu.monstercards.ui.shared.MCFragment;
|
||||||
|
|
||||||
public class EditAbilityScoresFragment extends Fragment {
|
public class EditAbilityScoresFragment extends Fragment {
|
||||||
private final String ABILITY_SCORE_FORMAT = "%d (%+d)";
|
private final String ABILITY_SCORE_FORMAT = "%d (%+d)";
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import android.widget.TextView;
|
|||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.appcompat.widget.SwitchCompat;
|
import androidx.appcompat.widget.SwitchCompat;
|
||||||
import androidx.fragment.app.Fragment;
|
|
||||||
import androidx.lifecycle.ViewModelProvider;
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
import androidx.navigation.NavBackStackEntry;
|
import androidx.navigation.NavBackStackEntry;
|
||||||
import androidx.navigation.NavController;
|
import androidx.navigation.NavController;
|
||||||
@@ -22,10 +21,10 @@ import androidx.navigation.Navigation;
|
|||||||
import com.majinnaibu.monstercards.R;
|
import com.majinnaibu.monstercards.R;
|
||||||
import com.majinnaibu.monstercards.data.enums.ArmorType;
|
import com.majinnaibu.monstercards.data.enums.ArmorType;
|
||||||
import com.majinnaibu.monstercards.helpers.ArrayHelper;
|
import com.majinnaibu.monstercards.helpers.ArrayHelper;
|
||||||
|
import com.majinnaibu.monstercards.ui.shared.MCFragment;
|
||||||
import com.majinnaibu.monstercards.utils.TextChangedListener;
|
import com.majinnaibu.monstercards.utils.TextChangedListener;
|
||||||
|
|
||||||
@SuppressWarnings("FieldCanBeLocal")
|
public class EditArmorFragment extends MCFragment {
|
||||||
public class EditArmorFragment extends Fragment {
|
|
||||||
private EditMonsterViewModel mViewModel;
|
private EditMonsterViewModel mViewModel;
|
||||||
private ViewHolder mHolder;
|
private ViewHolder mHolder;
|
||||||
|
|
||||||
|
|||||||
@@ -13,10 +13,9 @@ import androidx.navigation.Navigation;
|
|||||||
|
|
||||||
import com.google.android.material.switchmaterial.SwitchMaterial;
|
import com.google.android.material.switchmaterial.SwitchMaterial;
|
||||||
import com.majinnaibu.monstercards.R;
|
import com.majinnaibu.monstercards.R;
|
||||||
import com.majinnaibu.monstercards.ui.MCFragment;
|
import com.majinnaibu.monstercards.ui.shared.MCFragment;
|
||||||
import com.majinnaibu.monstercards.utils.TextChangedListener;
|
import com.majinnaibu.monstercards.utils.TextChangedListener;
|
||||||
|
|
||||||
@SuppressWarnings("FieldCanBeLocal")
|
|
||||||
public class EditBasicInfoFragment extends MCFragment {
|
public class EditBasicInfoFragment extends MCFragment {
|
||||||
private EditMonsterViewModel mViewModel;
|
private EditMonsterViewModel mViewModel;
|
||||||
private ViewHolder mHolder;
|
private ViewHolder mHolder;
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import android.widget.TextView;
|
|||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.fragment.app.Fragment;
|
|
||||||
import androidx.lifecycle.ViewModelProvider;
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
import androidx.navigation.NavBackStackEntry;
|
import androidx.navigation.NavBackStackEntry;
|
||||||
import androidx.navigation.NavController;
|
import androidx.navigation.NavController;
|
||||||
@@ -21,9 +20,10 @@ import androidx.navigation.Navigation;
|
|||||||
import com.majinnaibu.monstercards.R;
|
import com.majinnaibu.monstercards.R;
|
||||||
import com.majinnaibu.monstercards.data.enums.ChallengeRating;
|
import com.majinnaibu.monstercards.data.enums.ChallengeRating;
|
||||||
import com.majinnaibu.monstercards.helpers.ArrayHelper;
|
import com.majinnaibu.monstercards.helpers.ArrayHelper;
|
||||||
|
import com.majinnaibu.monstercards.ui.shared.MCFragment;
|
||||||
import com.majinnaibu.monstercards.utils.TextChangedListener;
|
import com.majinnaibu.monstercards.utils.TextChangedListener;
|
||||||
|
|
||||||
public class EditChallengeRatingFragment extends Fragment {
|
public class EditChallengeRatingFragment extends MCFragment {
|
||||||
private EditMonsterViewModel mViewModel;
|
private EditMonsterViewModel mViewModel;
|
||||||
private ViewHolder mHolder;
|
private ViewHolder mHolder;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,95 @@
|
|||||||
|
package com.majinnaibu.monstercards.ui.editmonster;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
|
import androidx.navigation.NavBackStackEntry;
|
||||||
|
import androidx.navigation.NavController;
|
||||||
|
import androidx.navigation.NavDirections;
|
||||||
|
import androidx.navigation.Navigation;
|
||||||
|
import androidx.recyclerview.widget.DividerItemDecoration;
|
||||||
|
import androidx.recyclerview.widget.ItemTouchHelper;
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||||
|
import com.majinnaibu.monstercards.R;
|
||||||
|
import com.majinnaibu.monstercards.ui.shared.SwipeToDeleteCallback;
|
||||||
|
import com.majinnaibu.monstercards.utils.Logger;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A fragment representing a list of Items.
|
||||||
|
*/
|
||||||
|
public class EditConditionImmunitiesFragment extends Fragment {
|
||||||
|
private EditMonsterViewModel mViewModel;
|
||||||
|
private ViewHolder mHolder;
|
||||||
|
|
||||||
|
private void navigateToEditConditionImmunity(String condition) {
|
||||||
|
NavDirections action = EditConditionImmunitiesFragmentDirections.actionEditConditionImmunitiesFragmentToEditConditionImmunity(condition);
|
||||||
|
View view = getView();
|
||||||
|
assert view != null;
|
||||||
|
Navigation.findNavController(view).navigate(action);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public View onCreateView(@NonNull @NotNull LayoutInflater inflater, @Nullable @org.jetbrains.annotations.Nullable ViewGroup container, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) {
|
||||||
|
NavController navController = Navigation.findNavController(requireActivity(), R.id.nav_host_fragment);
|
||||||
|
NavBackStackEntry backStackEntry = navController.getBackStackEntry(R.id.edit_monster_navigation);
|
||||||
|
mViewModel = new ViewModelProvider(backStackEntry).get(EditMonsterViewModel.class);
|
||||||
|
View root = inflater.inflate(R.layout.fragment_edit_condition_immunities_list, container, false);
|
||||||
|
mHolder = new ViewHolder(root);
|
||||||
|
setupRecyclerView(mHolder.list);
|
||||||
|
setupAddConditionImmunityButton(mHolder.addConditionImmunity);
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupRecyclerView(@NonNull RecyclerView recyclerView) {
|
||||||
|
Context context = requireContext();
|
||||||
|
LinearLayoutManager layoutManager = new LinearLayoutManager(context);
|
||||||
|
recyclerView.setLayoutManager(layoutManager);
|
||||||
|
|
||||||
|
mViewModel.getConditionImmunities().observe(getViewLifecycleOwner(), conditionImmunities -> {
|
||||||
|
EditConditionImmunitiesRecyclerViewAdapter adapter = new EditConditionImmunitiesRecyclerViewAdapter(mViewModel.getConditionImmunitiesArray(), condition -> {
|
||||||
|
if (condition != null) {
|
||||||
|
navigateToEditConditionImmunity(condition);
|
||||||
|
} else {
|
||||||
|
Logger.logError("Can't navigate to EditConditionImmunityFragment with a null condition");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
recyclerView.setAdapter(adapter);
|
||||||
|
});
|
||||||
|
|
||||||
|
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(context, layoutManager.getOrientation());
|
||||||
|
recyclerView.addItemDecoration(dividerItemDecoration);
|
||||||
|
|
||||||
|
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new SwipeToDeleteCallback(context, mViewModel::removeConditionImmunity));
|
||||||
|
itemTouchHelper.attachToRecyclerView(recyclerView);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupAddConditionImmunityButton(@NonNull FloatingActionButton fab) {
|
||||||
|
fab.setOnClickListener(view -> {
|
||||||
|
String condition = mViewModel.addNewConditionImmunity();
|
||||||
|
navigateToEditConditionImmunity(condition);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ViewHolder {
|
||||||
|
RecyclerView list;
|
||||||
|
FloatingActionButton addConditionImmunity;
|
||||||
|
|
||||||
|
ViewHolder(View root) {
|
||||||
|
list = root.findViewById(R.id.list);
|
||||||
|
addConditionImmunity = root.findViewById(R.id.add_condition_immunity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -20,8 +20,8 @@ import com.google.android.material.snackbar.Snackbar;
|
|||||||
import com.majinnaibu.monstercards.R;
|
import com.majinnaibu.monstercards.R;
|
||||||
import com.majinnaibu.monstercards.data.MonsterRepository;
|
import com.majinnaibu.monstercards.data.MonsterRepository;
|
||||||
import com.majinnaibu.monstercards.models.Monster;
|
import com.majinnaibu.monstercards.models.Monster;
|
||||||
import com.majinnaibu.monstercards.ui.MCFragment;
|
|
||||||
import com.majinnaibu.monstercards.ui.monster.MonsterDetailFragmentArgs;
|
import com.majinnaibu.monstercards.ui.monster.MonsterDetailFragmentArgs;
|
||||||
|
import com.majinnaibu.monstercards.ui.shared.MCFragment;
|
||||||
import com.majinnaibu.monstercards.utils.Logger;
|
import com.majinnaibu.monstercards.utils.Logger;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@@ -32,7 +32,6 @@ import io.reactivex.rxjava3.observers.DisposableCompletableObserver;
|
|||||||
import io.reactivex.rxjava3.observers.DisposableSingleObserver;
|
import io.reactivex.rxjava3.observers.DisposableSingleObserver;
|
||||||
import io.reactivex.rxjava3.schedulers.Schedulers;
|
import io.reactivex.rxjava3.schedulers.Schedulers;
|
||||||
|
|
||||||
@SuppressWarnings("FieldCanBeLocal")
|
|
||||||
public class EditMonsterFragment extends MCFragment {
|
public class EditMonsterFragment extends MCFragment {
|
||||||
|
|
||||||
private EditMonsterViewModel mViewModel;
|
private EditMonsterViewModel mViewModel;
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package com.majinnaibu.monstercards.ui.editmonster;
|
|||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.lifecycle.LiveData;
|
import androidx.lifecycle.LiveData;
|
||||||
import androidx.lifecycle.MutableLiveData;
|
import androidx.lifecycle.MutableLiveData;
|
||||||
import androidx.lifecycle.ViewModel;
|
|
||||||
|
|
||||||
import com.majinnaibu.monstercards.data.enums.AbilityScore;
|
import com.majinnaibu.monstercards.data.enums.AbilityScore;
|
||||||
import com.majinnaibu.monstercards.data.enums.AdvantageType;
|
import com.majinnaibu.monstercards.data.enums.AdvantageType;
|
||||||
@@ -15,22 +14,22 @@ import com.majinnaibu.monstercards.models.Language;
|
|||||||
import com.majinnaibu.monstercards.models.Monster;
|
import com.majinnaibu.monstercards.models.Monster;
|
||||||
import com.majinnaibu.monstercards.models.Skill;
|
import com.majinnaibu.monstercards.models.Skill;
|
||||||
import com.majinnaibu.monstercards.models.Trait;
|
import com.majinnaibu.monstercards.models.Trait;
|
||||||
|
import com.majinnaibu.monstercards.ui.shared.ChangeTrackedViewModel;
|
||||||
import com.majinnaibu.monstercards.utils.ChangeTrackedLiveData;
|
import com.majinnaibu.monstercards.utils.ChangeTrackedLiveData;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@SuppressWarnings({"ConstantConditions", "unused"})
|
@SuppressWarnings({"ConstantConditions", "unused"})
|
||||||
public class EditMonsterViewModel extends ViewModel {
|
public class EditMonsterViewModel extends ChangeTrackedViewModel {
|
||||||
private final ChangeTrackedLiveData<UUID> mMonsterId;
|
private final ChangeTrackedLiveData<UUID> mMonsterId;
|
||||||
private final MutableLiveData<Boolean> mHasError;
|
private final MutableLiveData<Boolean> mHasError;
|
||||||
private final MutableLiveData<Boolean> mHasLoaded;
|
private final MutableLiveData<Boolean> mHasLoaded;
|
||||||
private final MutableLiveData<Boolean> mHasChanges;
|
|
||||||
private final ChangeTrackedLiveData<Boolean> mHasCustomHitPoints;
|
private final ChangeTrackedLiveData<Boolean> mHasCustomHitPoints;
|
||||||
private final ChangeTrackedLiveData<Boolean> mHasShield;
|
private final ChangeTrackedLiveData<Boolean> mHasShield;
|
||||||
private final ChangeTrackedLiveData<Boolean> mCanHover;
|
private final ChangeTrackedLiveData<Boolean> mCanHover;
|
||||||
@@ -78,83 +77,82 @@ public class EditMonsterViewModel extends ViewModel {
|
|||||||
private final ChangeTrackedLiveData<String> mUnderstandsButDescription;
|
private final ChangeTrackedLiveData<String> mUnderstandsButDescription;
|
||||||
private final ChangeTrackedLiveData<List<Skill>> mSkills;
|
private final ChangeTrackedLiveData<List<Skill>> mSkills;
|
||||||
private final ChangeTrackedLiveData<List<String>> mSenses;
|
private final ChangeTrackedLiveData<List<String>> mSenses;
|
||||||
private final ChangeTrackedLiveData<Set<String>> mDamageImmunities;
|
private final ChangeTrackedLiveData<List<String>> mDamageImmunities;
|
||||||
private final ChangeTrackedLiveData<Set<String>> mDamageResistances;
|
private final ChangeTrackedLiveData<List<String>> mDamageResistances;
|
||||||
private final ChangeTrackedLiveData<Set<String>> mDamageVulnerabilities;
|
private final ChangeTrackedLiveData<List<String>> mDamageVulnerabilities;
|
||||||
private final ChangeTrackedLiveData<Set<String>> mConditionImmunities;
|
private final ChangeTrackedLiveData<List<String>> mConditionImmunities;
|
||||||
private final ChangeTrackedLiveData<Set<Language>> mLanguages;
|
private final ChangeTrackedLiveData<List<Language>> mLanguages;
|
||||||
private final ChangeTrackedLiveData<Set<Trait>> mAbilities;
|
private final ChangeTrackedLiveData<List<Trait>> mAbilities;
|
||||||
private final ChangeTrackedLiveData<Set<Trait>> mActions;
|
private final ChangeTrackedLiveData<List<Trait>> mActions;
|
||||||
private final ChangeTrackedLiveData<Set<Trait>> mReactions;
|
private final ChangeTrackedLiveData<List<Trait>> mReactions;
|
||||||
private final ChangeTrackedLiveData<Set<Trait>> mLairActions;
|
private final ChangeTrackedLiveData<List<Trait>> mLairActions;
|
||||||
private final ChangeTrackedLiveData<Set<Trait>> mLegendaryActions;
|
private final ChangeTrackedLiveData<List<Trait>> mLegendaryActions;
|
||||||
private final ChangeTrackedLiveData<Set<Trait>> mRegionalActions;
|
private final ChangeTrackedLiveData<List<Trait>> mRegionalActions;
|
||||||
|
|
||||||
public EditMonsterViewModel() {
|
public EditMonsterViewModel() {
|
||||||
|
super();
|
||||||
mErrorMessage = new MutableLiveData<>("");
|
mErrorMessage = new MutableLiveData<>("");
|
||||||
mHasError = new MutableLiveData<>(false);
|
mHasError = new MutableLiveData<>(false);
|
||||||
mHasLoaded = new MutableLiveData<>(false);
|
mHasLoaded = new MutableLiveData<>(false);
|
||||||
mHasChanges = new MutableLiveData<>(false);
|
|
||||||
ChangeTrackedLiveData.OnValueDirtiedCallback onDirtied = () -> mHasChanges.setValue(true);
|
|
||||||
|
|
||||||
mName = new ChangeTrackedLiveData<>("", onDirtied);
|
mName = new ChangeTrackedLiveData<>("", this::makeDirty);
|
||||||
mMonsterId = new ChangeTrackedLiveData<>(UUID.randomUUID(), onDirtied);
|
mMonsterId = new ChangeTrackedLiveData<>(UUID.randomUUID(), this::makeDirty);
|
||||||
mSize = new ChangeTrackedLiveData<>("", onDirtied);
|
mSize = new ChangeTrackedLiveData<>("", this::makeDirty);
|
||||||
mType = new ChangeTrackedLiveData<>("", onDirtied);
|
mType = new ChangeTrackedLiveData<>("", this::makeDirty);
|
||||||
mSubtype = new ChangeTrackedLiveData<>("", onDirtied);
|
mSubtype = new ChangeTrackedLiveData<>("", this::makeDirty);
|
||||||
mAlignment = new ChangeTrackedLiveData<>("", onDirtied);
|
mAlignment = new ChangeTrackedLiveData<>("", this::makeDirty);
|
||||||
mCustomHitPoints = new ChangeTrackedLiveData<>("", onDirtied);
|
mCustomHitPoints = new ChangeTrackedLiveData<>("", this::makeDirty);
|
||||||
mHitDice = new ChangeTrackedLiveData<>(0, onDirtied);
|
mHitDice = new ChangeTrackedLiveData<>(0, this::makeDirty);
|
||||||
mNaturalArmorBonus = new ChangeTrackedLiveData<>(0, onDirtied);
|
mNaturalArmorBonus = new ChangeTrackedLiveData<>(0, this::makeDirty);
|
||||||
mHasCustomHitPoints = new ChangeTrackedLiveData<>(false, onDirtied);
|
mHasCustomHitPoints = new ChangeTrackedLiveData<>(false, this::makeDirty);
|
||||||
mArmorType = new ChangeTrackedLiveData<>(ArmorType.NONE, onDirtied);
|
mArmorType = new ChangeTrackedLiveData<>(ArmorType.NONE, this::makeDirty);
|
||||||
mHasShield = new ChangeTrackedLiveData<>(false, onDirtied);
|
mHasShield = new ChangeTrackedLiveData<>(false, this::makeDirty);
|
||||||
mShieldBonus = new ChangeTrackedLiveData<>(0, onDirtied);
|
mShieldBonus = new ChangeTrackedLiveData<>(0, this::makeDirty);
|
||||||
mCustomArmor = new ChangeTrackedLiveData<>("", onDirtied);
|
mCustomArmor = new ChangeTrackedLiveData<>("", this::makeDirty);
|
||||||
mWalkSpeed = new ChangeTrackedLiveData<>(0, onDirtied);
|
mWalkSpeed = new ChangeTrackedLiveData<>(0, this::makeDirty);
|
||||||
mBurrowSpeed = new ChangeTrackedLiveData<>(0, onDirtied);
|
mBurrowSpeed = new ChangeTrackedLiveData<>(0, this::makeDirty);
|
||||||
mClimbSpeed = new ChangeTrackedLiveData<>(0, onDirtied);
|
mClimbSpeed = new ChangeTrackedLiveData<>(0, this::makeDirty);
|
||||||
mFlySpeed = new ChangeTrackedLiveData<>(0, onDirtied);
|
mFlySpeed = new ChangeTrackedLiveData<>(0, this::makeDirty);
|
||||||
mSwimSpeed = new ChangeTrackedLiveData<>(0, onDirtied);
|
mSwimSpeed = new ChangeTrackedLiveData<>(0, this::makeDirty);
|
||||||
mCanHover = new ChangeTrackedLiveData<>(false, onDirtied);
|
mCanHover = new ChangeTrackedLiveData<>(false, this::makeDirty);
|
||||||
mHasCustomSpeed = new ChangeTrackedLiveData<>(false, onDirtied);
|
mHasCustomSpeed = new ChangeTrackedLiveData<>(false, this::makeDirty);
|
||||||
mCustomSpeed = new ChangeTrackedLiveData<>("", onDirtied);
|
mCustomSpeed = new ChangeTrackedLiveData<>("", this::makeDirty);
|
||||||
mStrength = new ChangeTrackedLiveData<>(10, onDirtied);
|
mStrength = new ChangeTrackedLiveData<>(10, this::makeDirty);
|
||||||
mDexterity = new ChangeTrackedLiveData<>(10, onDirtied);
|
mDexterity = new ChangeTrackedLiveData<>(10, this::makeDirty);
|
||||||
mConstitution = new ChangeTrackedLiveData<>(10, onDirtied);
|
mConstitution = new ChangeTrackedLiveData<>(10, this::makeDirty);
|
||||||
mIntelligence = new ChangeTrackedLiveData<>(10, onDirtied);
|
mIntelligence = new ChangeTrackedLiveData<>(10, this::makeDirty);
|
||||||
mWisdom = new ChangeTrackedLiveData<>(10, onDirtied);
|
mWisdom = new ChangeTrackedLiveData<>(10, this::makeDirty);
|
||||||
mCharisma = new ChangeTrackedLiveData<>(10, onDirtied);
|
mCharisma = new ChangeTrackedLiveData<>(10, this::makeDirty);
|
||||||
mStrengthProficiency = new ChangeTrackedLiveData<>(ProficiencyType.NONE, onDirtied);
|
mStrengthProficiency = new ChangeTrackedLiveData<>(ProficiencyType.NONE, this::makeDirty);
|
||||||
mStrengthAdvantage = new ChangeTrackedLiveData<>(AdvantageType.NONE, onDirtied);
|
mStrengthAdvantage = new ChangeTrackedLiveData<>(AdvantageType.NONE, this::makeDirty);
|
||||||
mDexterityProficiency = new ChangeTrackedLiveData<>(ProficiencyType.NONE, onDirtied);
|
mDexterityProficiency = new ChangeTrackedLiveData<>(ProficiencyType.NONE, this::makeDirty);
|
||||||
mDexterityAdvantage = new ChangeTrackedLiveData<>(AdvantageType.NONE, onDirtied);
|
mDexterityAdvantage = new ChangeTrackedLiveData<>(AdvantageType.NONE, this::makeDirty);
|
||||||
mConstitutionProficiency = new ChangeTrackedLiveData<>(ProficiencyType.NONE, onDirtied);
|
mConstitutionProficiency = new ChangeTrackedLiveData<>(ProficiencyType.NONE, this::makeDirty);
|
||||||
mConstitutionAdvantage = new ChangeTrackedLiveData<>(AdvantageType.NONE, onDirtied);
|
mConstitutionAdvantage = new ChangeTrackedLiveData<>(AdvantageType.NONE, this::makeDirty);
|
||||||
mIntelligenceProficiency = new ChangeTrackedLiveData<>(ProficiencyType.NONE, onDirtied);
|
mIntelligenceProficiency = new ChangeTrackedLiveData<>(ProficiencyType.NONE, this::makeDirty);
|
||||||
mIntelligenceAdvantage = new ChangeTrackedLiveData<>(AdvantageType.NONE, onDirtied);
|
mIntelligenceAdvantage = new ChangeTrackedLiveData<>(AdvantageType.NONE, this::makeDirty);
|
||||||
mWisdomProficiency = new ChangeTrackedLiveData<>(ProficiencyType.NONE, onDirtied);
|
mWisdomProficiency = new ChangeTrackedLiveData<>(ProficiencyType.NONE, this::makeDirty);
|
||||||
mWisdomAdvantage = new ChangeTrackedLiveData<>(AdvantageType.NONE, onDirtied);
|
mWisdomAdvantage = new ChangeTrackedLiveData<>(AdvantageType.NONE, this::makeDirty);
|
||||||
mCharismaProficiency = new ChangeTrackedLiveData<>(ProficiencyType.NONE, onDirtied);
|
mCharismaProficiency = new ChangeTrackedLiveData<>(ProficiencyType.NONE, this::makeDirty);
|
||||||
mCharismaAdvantage = new ChangeTrackedLiveData<>(AdvantageType.NONE, onDirtied);
|
mCharismaAdvantage = new ChangeTrackedLiveData<>(AdvantageType.NONE, this::makeDirty);
|
||||||
mChallengeRating = new ChangeTrackedLiveData<>(ChallengeRating.ONE_EIGHTH, onDirtied);
|
mChallengeRating = new ChangeTrackedLiveData<>(ChallengeRating.ONE_EIGHTH, this::makeDirty);
|
||||||
mCustomChallengeRatingDescription = new ChangeTrackedLiveData<>("", onDirtied);
|
mCustomChallengeRatingDescription = new ChangeTrackedLiveData<>("", this::makeDirty);
|
||||||
mCustomProficiencyBonus = new ChangeTrackedLiveData<>(0, onDirtied);
|
mCustomProficiencyBonus = new ChangeTrackedLiveData<>(0, this::makeDirty);
|
||||||
mTelepathyRange = new ChangeTrackedLiveData<>(0, onDirtied);
|
mTelepathyRange = new ChangeTrackedLiveData<>(0, this::makeDirty);
|
||||||
mUnderstandsButDescription = new ChangeTrackedLiveData<>("", onDirtied);
|
mUnderstandsButDescription = new ChangeTrackedLiveData<>("", this::makeDirty);
|
||||||
mSkills = new ChangeTrackedLiveData<>(new ArrayList<>(), onDirtied);
|
mSkills = new ChangeTrackedLiveData<>(new ArrayList<>(), this::makeDirty);
|
||||||
mSenses = new ChangeTrackedLiveData<>(new ArrayList<>(), onDirtied);
|
mSenses = new ChangeTrackedLiveData<>(new ArrayList<>(), this::makeDirty);
|
||||||
mDamageImmunities = new ChangeTrackedLiveData<>(new HashSet<>(), onDirtied);
|
mDamageImmunities = new ChangeTrackedLiveData<>(new ArrayList<>(), this::makeDirty);
|
||||||
mDamageResistances = new ChangeTrackedLiveData<>(new HashSet<>(), onDirtied);
|
mDamageResistances = new ChangeTrackedLiveData<>(new ArrayList<>(), this::makeDirty);
|
||||||
mDamageVulnerabilities = new ChangeTrackedLiveData<>(new HashSet<>(), onDirtied);
|
mDamageVulnerabilities = new ChangeTrackedLiveData<>(new ArrayList<>(), this::makeDirty);
|
||||||
mConditionImmunities = new ChangeTrackedLiveData<>(new HashSet<>(), onDirtied);
|
mConditionImmunities = new ChangeTrackedLiveData<>(new ArrayList<>(), this::makeDirty);
|
||||||
mLanguages = new ChangeTrackedLiveData<>(new HashSet<>(), onDirtied);
|
mLanguages = new ChangeTrackedLiveData<>(new ArrayList<>(), this::makeDirty);
|
||||||
mAbilities = new ChangeTrackedLiveData<>(new HashSet<>(), onDirtied);
|
mAbilities = new ChangeTrackedLiveData<>(new ArrayList<>(), this::makeDirty);
|
||||||
mActions = new ChangeTrackedLiveData<>(new HashSet<>(), onDirtied);
|
mActions = new ChangeTrackedLiveData<>(new ArrayList<>(), this::makeDirty);
|
||||||
mReactions = new ChangeTrackedLiveData<>(new HashSet<>(), onDirtied);
|
mReactions = new ChangeTrackedLiveData<>(new ArrayList<>(), this::makeDirty);
|
||||||
mLairActions = new ChangeTrackedLiveData<>(new HashSet<>(), onDirtied);
|
mLairActions = new ChangeTrackedLiveData<>(new ArrayList<>(), this::makeDirty);
|
||||||
mLegendaryActions = new ChangeTrackedLiveData<>(new HashSet<>(), onDirtied);
|
mLegendaryActions = new ChangeTrackedLiveData<>(new ArrayList<>(), this::makeDirty);
|
||||||
mRegionalActions = new ChangeTrackedLiveData<>(new HashSet<>(), onDirtied);
|
mRegionalActions = new ChangeTrackedLiveData<>(new ArrayList<>(), this::makeDirty);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void copyFromMonster(Monster monster) {
|
public void copyFromMonster(Monster monster) {
|
||||||
@@ -210,18 +208,28 @@ public class EditMonsterViewModel extends ViewModel {
|
|||||||
ArrayList<String> senses = new ArrayList<>(monster.senses);
|
ArrayList<String> senses = new ArrayList<>(monster.senses);
|
||||||
Collections.sort(senses, String::compareToIgnoreCase);
|
Collections.sort(senses, String::compareToIgnoreCase);
|
||||||
mSenses.resetValue(senses);
|
mSenses.resetValue(senses);
|
||||||
mDamageImmunities.resetValue(monster.damageImmunities);
|
ArrayList<String> damageImmunities = new ArrayList<>(monster.damageImmunities);
|
||||||
mDamageResistances.resetValue(monster.damageResistances);
|
Collections.sort(damageImmunities, String::compareToIgnoreCase);
|
||||||
mDamageVulnerabilities.resetValue(monster.damageVulnerabilities);
|
mDamageImmunities.resetValue(damageImmunities);
|
||||||
mConditionImmunities.resetValue(monster.conditionImmunities);
|
ArrayList<String> damageResistances = new ArrayList<>(monster.damageResistances);
|
||||||
mLanguages.resetValue(monster.languages);
|
Collections.sort(damageResistances, String::compareToIgnoreCase);
|
||||||
mAbilities.resetValue(monster.abilities);
|
mDamageResistances.resetValue(damageResistances);
|
||||||
mActions.resetValue(monster.actions);
|
ArrayList<String> damageVulnerabilities = new ArrayList<>(monster.damageVulnerabilities);
|
||||||
mReactions.resetValue(monster.reactions);
|
Collections.sort(damageVulnerabilities, String::compareToIgnoreCase);
|
||||||
mLairActions.resetValue(monster.lairActions);
|
mDamageVulnerabilities.resetValue(damageVulnerabilities);
|
||||||
mLegendaryActions.resetValue(monster.legendaryActions);
|
ArrayList<String> conditionImmunities = new ArrayList<>(monster.conditionImmunities);
|
||||||
mRegionalActions.resetValue(monster.regionalActions);
|
Collections.sort(conditionImmunities, String::compareToIgnoreCase);
|
||||||
mHasChanges.setValue(false);
|
mConditionImmunities.resetValue(conditionImmunities);
|
||||||
|
ArrayList<Language> languages = new ArrayList<>(monster.languages);
|
||||||
|
Collections.sort(languages, (lang1, lang2) -> lang1.getName().compareToIgnoreCase(lang2.getName()));
|
||||||
|
mLanguages.resetValue(languages);
|
||||||
|
mAbilities.resetValue(new ArrayList<>(monster.abilities));
|
||||||
|
mActions.resetValue(new ArrayList<>(monster.actions));
|
||||||
|
mReactions.resetValue(new ArrayList<>(monster.reactions));
|
||||||
|
mLairActions.resetValue(new ArrayList<>(monster.lairActions));
|
||||||
|
mLegendaryActions.resetValue(new ArrayList<>(monster.legendaryActions));
|
||||||
|
mRegionalActions.resetValue(new ArrayList<>(monster.regionalActions));
|
||||||
|
makeClean();
|
||||||
}
|
}
|
||||||
|
|
||||||
public LiveData<String> getName() {
|
public LiveData<String> getName() {
|
||||||
@@ -308,14 +316,6 @@ public class EditMonsterViewModel extends ViewModel {
|
|||||||
mCustomHitPoints.setValue(customHitPoints);
|
mCustomHitPoints.setValue(customHitPoints);
|
||||||
}
|
}
|
||||||
|
|
||||||
public LiveData<Boolean> getHasChanges() {
|
|
||||||
return mHasChanges;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasChanges() {
|
|
||||||
return mHasChanges.getValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
public LiveData<Integer> getHitDice() {
|
public LiveData<Integer> getHitDice() {
|
||||||
return mHitDice;
|
return mHitDice;
|
||||||
}
|
}
|
||||||
@@ -756,13 +756,295 @@ public class EditMonsterViewModel extends ViewModel {
|
|||||||
return mSkills;
|
return mSkills;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Skill> getSkillsArray() {
|
||||||
|
return mSkills.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Skill addNewSkill() {
|
||||||
|
Skill newSkill = new Skill("Unnamed Skill", AbilityScore.DEXTERITY);
|
||||||
|
ArrayList<Skill> newSkills = new ArrayList<>(mSkills.getValue());
|
||||||
|
newSkills.add(newSkill);
|
||||||
|
Collections.sort(newSkills, (skill1, skill2) -> skill1.name.compareToIgnoreCase(skill2.name));
|
||||||
|
mSkills.setValue(newSkills);
|
||||||
|
return newSkill;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeSkill(int position) {
|
||||||
|
List<Skill> skills = mSkills.getValue();
|
||||||
|
ArrayList<Skill> newSkills = new ArrayList<>(skills);
|
||||||
|
newSkills.remove(position);
|
||||||
|
mSkills.setValue(newSkills);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void replaceSkill(Skill newSkill, Skill oldSkill) {
|
||||||
|
List<Skill> oldSkills = mSkills.getValue();
|
||||||
|
if (oldSkills == null) {
|
||||||
|
oldSkills = new ArrayList<>();
|
||||||
|
}
|
||||||
|
boolean hasReplaced = false;
|
||||||
|
ArrayList<Skill> newSkills = new ArrayList<>(oldSkills.size());
|
||||||
|
for (Skill skill : oldSkills) {
|
||||||
|
if (Objects.equals(skill, oldSkill)) {
|
||||||
|
newSkills.add(newSkill);
|
||||||
|
hasReplaced = true;
|
||||||
|
} else {
|
||||||
|
newSkills.add(skill);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!hasReplaced) {
|
||||||
|
newSkills.add(newSkill);
|
||||||
|
}
|
||||||
|
Collections.sort(newSkills, (skill1, skill2) -> skill1.name.compareToIgnoreCase(skill2.name));
|
||||||
|
mSkills.setValue(newSkills);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<List<String>> getSenses() {
|
||||||
|
return mSenses;
|
||||||
|
}
|
||||||
|
|
||||||
public List<String> getSensesArray() {
|
public List<String> getSensesArray() {
|
||||||
return mSenses.getValue();
|
return mSenses.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: add getters and setters for lists of strings (Senses, Damage Immunities, Damage Resistances, Damage Vulnerabilities, and Condition Immunities)
|
public String addNewSense() {
|
||||||
// TODO: add getters and setters for Languages
|
return Helpers.addItemToList(mSenses, "", String::compareToIgnoreCase);
|
||||||
// TODO: add getters and setters for traits (Abilities, Actions, Reactions, Lair Actions, Legendary Actions, and Regional Actions)
|
}
|
||||||
|
|
||||||
|
public void removeSense(int position) {
|
||||||
|
Helpers.removeFromList(mSenses, position);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void replaceSense(String oldSense, String newSense) {
|
||||||
|
Helpers.replaceItemInList(mSenses, oldSense, newSense, String::compareToIgnoreCase);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<List<String>> getDamageImmunities() {
|
||||||
|
return mDamageImmunities;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getDamageImmunitiesArray() {
|
||||||
|
return mDamageImmunities.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String addNewDamageImmunity() {
|
||||||
|
return Helpers.addStringToList("", mDamageImmunities);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeDamageImmunity(int position) {
|
||||||
|
Helpers.removeFromList(mDamageImmunities, position);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void replaceDamageImmunity(String oldDamageType, String newDamageType) {
|
||||||
|
Helpers.replaceItemInList(mDamageImmunities, oldDamageType, newDamageType, String::compareToIgnoreCase);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<List<String>> getDamageResistances() {
|
||||||
|
return mDamageResistances;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getDamageResistancesArray() {
|
||||||
|
return mDamageResistances.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String addNewDamageResistance() {
|
||||||
|
return Helpers.addStringToList("", mDamageResistances);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeDamageResistance(int position) {
|
||||||
|
Helpers.removeFromList(mDamageResistances, position);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void replaceDamageResistance(String oldDamageType, String newDamageType) {
|
||||||
|
Helpers.replaceItemInList(mDamageResistances, oldDamageType, newDamageType, String::compareToIgnoreCase);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<List<String>> getDamageVulnerabilities() {
|
||||||
|
return mDamageVulnerabilities;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getDamageVulnerabilitiesArray() {
|
||||||
|
return mDamageVulnerabilities.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String addNewDamageVulnerability() {
|
||||||
|
return Helpers.addStringToList("", mDamageVulnerabilities);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeDamageVulnerability(int position) {
|
||||||
|
Helpers.removeFromList(mDamageVulnerabilities, position);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void replaceDamageVulnerability(String oldDamageType, String newDamageType) {
|
||||||
|
Helpers.replaceItemInList(mDamageVulnerabilities, oldDamageType, newDamageType, String::compareToIgnoreCase);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<List<String>> getConditionImmunities() {
|
||||||
|
return mConditionImmunities;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getConditionImmunitiesArray() {
|
||||||
|
return mConditionImmunities.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String addNewConditionImmunity() {
|
||||||
|
return Helpers.addStringToList("", mConditionImmunities);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeConditionImmunity(int position) {
|
||||||
|
Helpers.removeFromList(mConditionImmunities, position);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void replaceConditionImmunity(String oldDamageType, String newDamageType) {
|
||||||
|
Helpers.replaceItemInList(mConditionImmunities, oldDamageType, newDamageType, String::compareToIgnoreCase);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<List<Language>> getLanguages() {
|
||||||
|
return mLanguages;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Language> getLanguagesArray() {
|
||||||
|
return mLanguages.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Language addNewLanguage() {
|
||||||
|
Language newLanguage = new Language("", true);
|
||||||
|
return Helpers.addItemToList(mLanguages, newLanguage, Language::compareTo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeLanguage(int position) {
|
||||||
|
Helpers.removeFromList(mLanguages, position);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void replaceLanguage(Language oldLanguage, Language newLanguage) {
|
||||||
|
Helpers.replaceItemInList(mLanguages, oldLanguage, newLanguage, Language::compareTo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<List<Trait>> getAbilities() {
|
||||||
|
return mAbilities;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Trait> getAbilitiesArray() {
|
||||||
|
return mAbilities.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Trait addNewAbility() {
|
||||||
|
Trait newAbility = new Trait("", "");
|
||||||
|
return Helpers.addItemToList(mAbilities, newAbility, Trait::compareTo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeAbility(int position) {
|
||||||
|
Helpers.removeFromList(mAbilities, position);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void replaceAbility(Trait oldAbility, Trait newAbility) {
|
||||||
|
Helpers.replaceItemInList(mAbilities, oldAbility, newAbility);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public LiveData<List<Trait>> getActions() {
|
||||||
|
return mActions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Trait> getActionsArray() {
|
||||||
|
return mActions.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Trait addNewAction() {
|
||||||
|
Trait newAction = new Trait("", "");
|
||||||
|
return Helpers.addItemToList(mActions, newAction, Trait::compareTo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeAction(int position) {
|
||||||
|
Helpers.removeFromList(mActions, position);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void replaceAction(Trait oldAction, Trait newAction) {
|
||||||
|
Helpers.replaceItemInList(mActions, oldAction, newAction);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<List<Trait>> getReactions() {
|
||||||
|
return mReactions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Trait> getReactionsArray() {
|
||||||
|
return mReactions.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Trait addNewReaction() {
|
||||||
|
Trait newReaction = new Trait("", "");
|
||||||
|
return Helpers.addItemToList(mReactions, newReaction, Trait::compareTo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeReaction(int position) {
|
||||||
|
Helpers.removeFromList(mReactions, position);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void replaceReaction(Trait oldReaction, Trait newReaction) {
|
||||||
|
Helpers.replaceItemInList(mReactions, oldReaction, newReaction);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<List<Trait>> getLairActions() {
|
||||||
|
return mLairActions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Trait> getLairActionsArray() {
|
||||||
|
return mLairActions.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Trait addNewLairAction() {
|
||||||
|
Trait newLairAction = new Trait("", "");
|
||||||
|
return Helpers.addItemToList(mLairActions, newLairAction, Trait::compareTo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeLairAction(int position) {
|
||||||
|
Helpers.removeFromList(mLairActions, position);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void replaceLairAction(Trait oldLairAction, Trait newLairAction) {
|
||||||
|
Helpers.replaceItemInList(mLairActions, oldLairAction, newLairAction);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<List<Trait>> getLegendaryActions() {
|
||||||
|
return mLegendaryActions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Trait> getLegendaryActionsArray() {
|
||||||
|
return mLegendaryActions.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Trait addNewLegendaryAction() {
|
||||||
|
Trait newLegendaryAction = new Trait("", "");
|
||||||
|
return Helpers.addItemToList(mLegendaryActions, newLegendaryAction, Trait::compareTo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeLegendaryAction(int position) {
|
||||||
|
Helpers.removeFromList(mLegendaryActions, position);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void replaceLegendaryAction(Trait oldLegendaryAction, Trait newLegendaryAction) {
|
||||||
|
Helpers.replaceItemInList(mLegendaryActions, oldLegendaryAction, newLegendaryAction);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<List<Trait>> getRegionalActions() {
|
||||||
|
return mRegionalActions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Trait> getRegionalActionsArray() {
|
||||||
|
return mRegionalActions.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Trait addNewRegionalAction() {
|
||||||
|
Trait newRegionalAction = new Trait("", "");
|
||||||
|
return Helpers.addItemToList(mRegionalActions, newRegionalAction, Trait::compareTo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeRegionalAction(int position) {
|
||||||
|
Helpers.removeFromList(mRegionalActions, position);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void replaceRegionalAction(Trait oldRegionalAction, Trait newRegionalAction) {
|
||||||
|
Helpers.replaceItemInList(mRegionalActions, oldRegionalAction, newRegionalAction);
|
||||||
|
}
|
||||||
|
|
||||||
public Monster buildMonster() {
|
public Monster buildMonster() {
|
||||||
Monster monster = new Monster();
|
Monster monster = new Monster();
|
||||||
@@ -813,60 +1095,99 @@ public class EditMonsterViewModel extends ViewModel {
|
|||||||
monster.understandsButDescription = mUnderstandsButDescription.getValue();
|
monster.understandsButDescription = mUnderstandsButDescription.getValue();
|
||||||
monster.skills = new HashSet<>(mSkills.getValue());
|
monster.skills = new HashSet<>(mSkills.getValue());
|
||||||
monster.senses = new HashSet<>(mSenses.getValue());
|
monster.senses = new HashSet<>(mSenses.getValue());
|
||||||
monster.damageImmunities = mDamageImmunities.getValue();
|
monster.damageImmunities = new HashSet<>(mDamageImmunities.getValue());
|
||||||
monster.damageResistances = mDamageResistances.getValue();
|
monster.damageResistances = new HashSet<>(mDamageResistances.getValue());
|
||||||
monster.damageVulnerabilities = mDamageVulnerabilities.getValue();
|
monster.damageVulnerabilities = new HashSet<>(mDamageVulnerabilities.getValue());
|
||||||
monster.conditionImmunities = mConditionImmunities.getValue();
|
monster.conditionImmunities = new HashSet<>(mConditionImmunities.getValue());
|
||||||
monster.languages = mLanguages.getValue();
|
monster.languages = new HashSet<>(mLanguages.getValue());
|
||||||
monster.abilities = mAbilities.getValue();
|
monster.abilities = new HashSet<>(mAbilities.getValue());
|
||||||
monster.actions = mActions.getValue();
|
monster.actions = new HashSet<>(mActions.getValue());
|
||||||
monster.reactions = mReactions.getValue();
|
monster.reactions = new HashSet<>(mReactions.getValue());
|
||||||
monster.lairActions = mLairActions.getValue();
|
monster.lairActions = new HashSet<>(mLairActions.getValue());
|
||||||
monster.legendaryActions = mLegendaryActions.getValue();
|
monster.legendaryActions = new HashSet<>(mLegendaryActions.getValue());
|
||||||
monster.regionalActions = mRegionalActions.getValue();
|
monster.regionalActions = new HashSet<>(mRegionalActions.getValue());
|
||||||
|
|
||||||
return monster;
|
return monster;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Skill> getSkillsArray() {
|
@SuppressWarnings("SameParameterValue")
|
||||||
return mSkills.getValue();
|
private static class Helpers {
|
||||||
}
|
static String addStringToList(String newString, MutableLiveData<List<String>> strings) {
|
||||||
|
return addItemToList(strings, newString, String::compareToIgnoreCase);
|
||||||
public Skill addNewSkill() {
|
|
||||||
Skill newSkill = new Skill("Unnamed Skill", AbilityScore.DEXTERITY);
|
|
||||||
ArrayList<Skill> newSkills = new ArrayList<>(mSkills.getValue());
|
|
||||||
newSkills.add(newSkill);
|
|
||||||
Collections.sort(newSkills, (skill1, skill2) -> skill1.name.compareToIgnoreCase(skill2.name));
|
|
||||||
mSkills.setValue(newSkills);
|
|
||||||
return newSkill;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeSkill(int position) {
|
|
||||||
List<Skill> skills = mSkills.getValue();
|
|
||||||
ArrayList<Skill> newSkills = new ArrayList<>(skills);
|
|
||||||
newSkills.remove(position);
|
|
||||||
mSkills.setValue(newSkills);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void replaceSkill(Skill newSkill, Skill oldSkill) {
|
|
||||||
List<Skill> oldSkills = mSkills.getValue();
|
|
||||||
if (oldSkills == null) {
|
|
||||||
oldSkills = new ArrayList<>();
|
|
||||||
}
|
}
|
||||||
boolean hasReplaced = false;
|
|
||||||
ArrayList<Skill> newSkills = new ArrayList<>(oldSkills.size());
|
static <T> T addItemToList(MutableLiveData<List<T>> listData, T newItem, Comparator<? super T> comparator) {
|
||||||
for (Skill skill : oldSkills) {
|
ArrayList<T> newList = new ArrayList<>(listData.getValue());
|
||||||
if (Objects.equals(skill, oldSkill)) {
|
newList.add(newItem);
|
||||||
newSkills.add(newSkill);
|
if (comparator != null) {
|
||||||
hasReplaced = true;
|
Collections.sort(newList, comparator);
|
||||||
} else {
|
|
||||||
newSkills.add(skill);
|
|
||||||
}
|
}
|
||||||
|
listData.setValue(newList);
|
||||||
|
return newItem;
|
||||||
}
|
}
|
||||||
if (!hasReplaced) {
|
|
||||||
newSkills.add(newSkill);
|
static <T> void removeFromList(MutableLiveData<List<T>> listData, int position) {
|
||||||
|
List<T> oldList = listData.getValue();
|
||||||
|
ArrayList<T> newList = new ArrayList<>(oldList);
|
||||||
|
newList.remove(position);
|
||||||
|
listData.setValue(newList);
|
||||||
|
}
|
||||||
|
|
||||||
|
static <T> void replaceItemInList(MutableLiveData<List<T>> listData, int position, T newItem, Comparator<? super T> comparator) {
|
||||||
|
List<T> oldList = listData.getValue();
|
||||||
|
if (oldList == null) {
|
||||||
|
oldList = new ArrayList<>();
|
||||||
|
}
|
||||||
|
int size = oldList.size();
|
||||||
|
boolean hasReplaced = false;
|
||||||
|
ArrayList<T> newList = new ArrayList<>(size);
|
||||||
|
for (int index = 0; index < size; index++) {
|
||||||
|
if (index == position) {
|
||||||
|
newList.add(newItem);
|
||||||
|
hasReplaced = true;
|
||||||
|
} else {
|
||||||
|
newList.add(oldList.get(index));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!hasReplaced) {
|
||||||
|
newList.add(newItem);
|
||||||
|
}
|
||||||
|
if (comparator != null) {
|
||||||
|
Collections.sort(newList, comparator);
|
||||||
|
}
|
||||||
|
listData.setValue(newList);
|
||||||
|
}
|
||||||
|
|
||||||
|
static <T> void replaceItemInList(MutableLiveData<List<T>> listData, int position, T newItem) {
|
||||||
|
replaceItemInList(listData, position, newItem, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
static <T> void replaceItemInList(MutableLiveData<List<T>> listData, T oldItem, T newItem, Comparator<? super T> comparator) {
|
||||||
|
List<T> oldList = listData.getValue();
|
||||||
|
if (oldList == null) {
|
||||||
|
oldList = new ArrayList<>();
|
||||||
|
}
|
||||||
|
boolean hasReplaced = false;
|
||||||
|
ArrayList<T> newList = new ArrayList<>(oldList.size());
|
||||||
|
for (T item : oldList) {
|
||||||
|
if (Objects.equals(item, oldItem)) {
|
||||||
|
newList.add(newItem);
|
||||||
|
hasReplaced = true;
|
||||||
|
} else {
|
||||||
|
newList.add(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!hasReplaced) {
|
||||||
|
newList.add(newItem);
|
||||||
|
}
|
||||||
|
if (comparator != null) {
|
||||||
|
Collections.sort(newList, comparator);
|
||||||
|
}
|
||||||
|
listData.setValue(newList);
|
||||||
|
}
|
||||||
|
|
||||||
|
static <T> void replaceItemInList(MutableLiveData<List<T>> listData, T oldItem, T newItem) {
|
||||||
|
replaceItemInList(listData, oldItem, newItem, null);
|
||||||
}
|
}
|
||||||
Collections.sort(newSkills, (skill1, skill2) -> skill1.name.compareToIgnoreCase(skill2.name));
|
|
||||||
mSkills.setValue(newSkills);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import androidx.navigation.Navigation;
|
|||||||
import com.majinnaibu.monstercards.R;
|
import com.majinnaibu.monstercards.R;
|
||||||
import com.majinnaibu.monstercards.ui.components.AdvantagePicker;
|
import com.majinnaibu.monstercards.ui.components.AdvantagePicker;
|
||||||
import com.majinnaibu.monstercards.ui.components.ProficiencyPicker;
|
import com.majinnaibu.monstercards.ui.components.ProficiencyPicker;
|
||||||
|
import com.majinnaibu.monstercards.ui.shared.MCFragment;
|
||||||
|
|
||||||
public class EditSavingThrowsFragment extends Fragment {
|
public class EditSavingThrowsFragment extends Fragment {
|
||||||
private EditMonsterViewModel mViewModel;
|
private EditMonsterViewModel mViewModel;
|
||||||
|
|||||||
@@ -0,0 +1,77 @@
|
|||||||
|
package com.majinnaibu.monstercards.ui.editmonster;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.EditText;
|
||||||
|
|
||||||
|
import androidx.activity.OnBackPressedCallback;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
|
import androidx.navigation.NavBackStackEntry;
|
||||||
|
import androidx.navigation.NavController;
|
||||||
|
import androidx.navigation.Navigation;
|
||||||
|
|
||||||
|
import com.majinnaibu.monstercards.R;
|
||||||
|
import com.majinnaibu.monstercards.ui.shared.MCFragment;
|
||||||
|
import com.majinnaibu.monstercards.utils.Logger;
|
||||||
|
import com.majinnaibu.monstercards.utils.TextChangedListener;
|
||||||
|
|
||||||
|
public class EditSenseFragment extends MCFragment {
|
||||||
|
private EditMonsterViewModel mEditMonsterViewModel;
|
||||||
|
private EditStringViewModel mViewModel;
|
||||||
|
private ViewHolder mHolder;
|
||||||
|
private String mOldSense;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
|
mViewModel = new ViewModelProvider(this).get(EditStringViewModel.class);
|
||||||
|
if (getArguments() != null) {
|
||||||
|
EditSenseFragmentArgs args = EditSenseFragmentArgs.fromBundle(getArguments());
|
||||||
|
mOldSense = args.getSense();
|
||||||
|
mViewModel.resetValue(mOldSense);
|
||||||
|
} else {
|
||||||
|
Logger.logWTF("EditSenseFragment needs arguments");
|
||||||
|
mOldSense = null;
|
||||||
|
}
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||||
|
@Nullable Bundle savedInstanceState) {
|
||||||
|
NavController navController = Navigation.findNavController(requireActivity(), R.id.nav_host_fragment);
|
||||||
|
NavBackStackEntry backStackEntry = navController.getBackStackEntry(R.id.edit_monster_navigation);
|
||||||
|
mEditMonsterViewModel = new ViewModelProvider(backStackEntry).get(EditMonsterViewModel.class);
|
||||||
|
|
||||||
|
View root = inflater.inflate(R.layout.fragment_edit_sense, container, false);
|
||||||
|
|
||||||
|
mHolder = new ViewHolder(root);
|
||||||
|
|
||||||
|
mHolder.description.setText(mViewModel.getValueAsString());
|
||||||
|
mHolder.description.addTextChangedListener(new TextChangedListener((TextChangedListener.OnTextChangedCallback) (s, start, before, count) -> mViewModel.setValue(s.toString())));
|
||||||
|
|
||||||
|
requireActivity().getOnBackPressedDispatcher().addCallback(getViewLifecycleOwner(), new OnBackPressedCallback(true) {
|
||||||
|
@Override
|
||||||
|
public void handleOnBackPressed() {
|
||||||
|
if (mViewModel.hasChanges()) {
|
||||||
|
mEditMonsterViewModel.replaceSense(mOldSense, mViewModel.getValueAsString());
|
||||||
|
}
|
||||||
|
Navigation.findNavController(requireView()).navigateUp();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ViewHolder {
|
||||||
|
EditText description;
|
||||||
|
|
||||||
|
ViewHolder(View root) {
|
||||||
|
description = root.findViewById(R.id.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
package com.majinnaibu.monstercards.ui.editmonster;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
|
import androidx.navigation.NavBackStackEntry;
|
||||||
|
import androidx.navigation.NavController;
|
||||||
|
import androidx.navigation.NavDirections;
|
||||||
|
import androidx.navigation.Navigation;
|
||||||
|
import androidx.recyclerview.widget.DividerItemDecoration;
|
||||||
|
import androidx.recyclerview.widget.ItemTouchHelper;
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||||
|
import com.majinnaibu.monstercards.R;
|
||||||
|
import com.majinnaibu.monstercards.ui.shared.MCFragment;
|
||||||
|
import com.majinnaibu.monstercards.ui.shared.SwipeToDeleteCallback;
|
||||||
|
import com.majinnaibu.monstercards.utils.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A fragment representing a list of Items.
|
||||||
|
*/
|
||||||
|
public class EditSensesFragment extends MCFragment {
|
||||||
|
private EditMonsterViewModel mViewModel;
|
||||||
|
private ViewHolder mHolder;
|
||||||
|
|
||||||
|
private void navigateToEditSense(String sense) {
|
||||||
|
NavDirections action = EditSensesFragmentDirections.actionEditSensesFragmentToEditSenseFragment(sense);
|
||||||
|
View view = getView();
|
||||||
|
assert view != null;
|
||||||
|
Navigation.findNavController(view).navigate(action);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||||
|
Bundle savedInstanceState) {
|
||||||
|
NavController navController = Navigation.findNavController(requireActivity(), R.id.nav_host_fragment);
|
||||||
|
NavBackStackEntry backStackEntry = navController.getBackStackEntry(R.id.edit_monster_navigation);
|
||||||
|
mViewModel = new ViewModelProvider(backStackEntry).get(EditMonsterViewModel.class);
|
||||||
|
View root = inflater.inflate(R.layout.fragment_edit_senses_list, container, false);
|
||||||
|
mHolder = new ViewHolder(root);
|
||||||
|
setupRecyclerView(mHolder.list);
|
||||||
|
setupAddSenseButton(mHolder.addSense);
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupRecyclerView(@NonNull RecyclerView recyclerView) {
|
||||||
|
Context context = requireContext();
|
||||||
|
LinearLayoutManager layoutManager = new LinearLayoutManager(context);
|
||||||
|
recyclerView.setLayoutManager(layoutManager);
|
||||||
|
|
||||||
|
mViewModel.getSenses().observe(getViewLifecycleOwner(), senses -> {
|
||||||
|
EditSensesRecyclerViewAdapter adapter = new EditSensesRecyclerViewAdapter(mViewModel.getSensesArray(), sense -> {
|
||||||
|
if (sense != null) {
|
||||||
|
navigateToEditSense(sense);
|
||||||
|
} else {
|
||||||
|
Logger.logError("Can't navigate to EditSense with a null sense");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
recyclerView.setAdapter(adapter);
|
||||||
|
});
|
||||||
|
|
||||||
|
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(context, layoutManager.getOrientation());
|
||||||
|
recyclerView.addItemDecoration(dividerItemDecoration);
|
||||||
|
|
||||||
|
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new SwipeToDeleteCallback(context, mViewModel::removeSense));
|
||||||
|
itemTouchHelper.attachToRecyclerView(recyclerView);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupAddSenseButton(@NonNull FloatingActionButton fab) {
|
||||||
|
fab.setOnClickListener(view -> {
|
||||||
|
String newSense = mViewModel.addNewSense();
|
||||||
|
navigateToEditSense(newSense);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ViewHolder {
|
||||||
|
RecyclerView list;
|
||||||
|
FloatingActionButton addSense;
|
||||||
|
|
||||||
|
ViewHolder(View root) {
|
||||||
|
list = root.findViewById(R.id.list);
|
||||||
|
addSense = root.findViewById(R.id.add_sense);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -20,6 +20,7 @@ import com.majinnaibu.monstercards.models.Skill;
|
|||||||
import com.majinnaibu.monstercards.ui.components.AbilityScorePicker;
|
import com.majinnaibu.monstercards.ui.components.AbilityScorePicker;
|
||||||
import com.majinnaibu.monstercards.ui.components.AdvantagePicker;
|
import com.majinnaibu.monstercards.ui.components.AdvantagePicker;
|
||||||
import com.majinnaibu.monstercards.ui.components.ProficiencyPicker;
|
import com.majinnaibu.monstercards.ui.components.ProficiencyPicker;
|
||||||
|
import com.majinnaibu.monstercards.ui.shared.MCFragment;
|
||||||
import com.majinnaibu.monstercards.utils.Logger;
|
import com.majinnaibu.monstercards.utils.Logger;
|
||||||
import com.majinnaibu.monstercards.utils.TextChangedListener;
|
import com.majinnaibu.monstercards.utils.TextChangedListener;
|
||||||
|
|
||||||
@@ -37,7 +38,7 @@ public class EditSkillFragment extends Fragment {
|
|||||||
mViewModel.copyFromSkill(args.getName(), args.getAbilityScore(), args.getProficiency(), args.getAdvantage());
|
mViewModel.copyFromSkill(args.getName(), args.getAbilityScore(), args.getProficiency(), args.getAdvantage());
|
||||||
mOldSkill = new Skill(args.getName(), args.getAbilityScore(), args.getAdvantage(), args.getProficiency());
|
mOldSkill = new Skill(args.getName(), args.getAbilityScore(), args.getAdvantage(), args.getProficiency());
|
||||||
} else {
|
} else {
|
||||||
Logger.logWTF("This should never happen. EditSkillFragment needs arguments.");
|
Logger.logWTF("EditSkillFragment needs arguments.");
|
||||||
mOldSkill = null;
|
mOldSkill = null;
|
||||||
}
|
}
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|||||||
@@ -1,43 +1,28 @@
|
|||||||
package com.majinnaibu.monstercards.ui.editmonster;
|
package com.majinnaibu.monstercards.ui.editmonster;
|
||||||
|
|
||||||
import androidx.lifecycle.LiveData;
|
import androidx.lifecycle.LiveData;
|
||||||
import androidx.lifecycle.MutableLiveData;
|
|
||||||
import androidx.lifecycle.ViewModel;
|
|
||||||
|
|
||||||
import com.majinnaibu.monstercards.data.enums.AbilityScore;
|
import com.majinnaibu.monstercards.data.enums.AbilityScore;
|
||||||
import com.majinnaibu.monstercards.data.enums.AdvantageType;
|
import com.majinnaibu.monstercards.data.enums.AdvantageType;
|
||||||
import com.majinnaibu.monstercards.data.enums.ProficiencyType;
|
import com.majinnaibu.monstercards.data.enums.ProficiencyType;
|
||||||
import com.majinnaibu.monstercards.models.Skill;
|
import com.majinnaibu.monstercards.models.Skill;
|
||||||
|
import com.majinnaibu.monstercards.ui.shared.ChangeTrackedViewModel;
|
||||||
import com.majinnaibu.monstercards.utils.ChangeTrackedLiveData;
|
import com.majinnaibu.monstercards.utils.ChangeTrackedLiveData;
|
||||||
|
|
||||||
public class EditSkillViewModel extends ViewModel {
|
public class EditSkillViewModel extends ChangeTrackedViewModel {
|
||||||
private final ChangeTrackedLiveData<AbilityScore> mAbilityScore;
|
private final ChangeTrackedLiveData<AbilityScore> mAbilityScore;
|
||||||
private final ChangeTrackedLiveData<AdvantageType> mAdvantageType;
|
private final ChangeTrackedLiveData<AdvantageType> mAdvantageType;
|
||||||
private final MutableLiveData<Boolean> mHasChanges;
|
|
||||||
private final ChangeTrackedLiveData<ProficiencyType> mProficiencyType;
|
private final ChangeTrackedLiveData<ProficiencyType> mProficiencyType;
|
||||||
private final ChangeTrackedLiveData<String> mName;
|
private final ChangeTrackedLiveData<String> mName;
|
||||||
private final ChangeTrackedLiveData<Skill> mSkill;
|
private final ChangeTrackedLiveData<Skill> mSkill;
|
||||||
|
|
||||||
public EditSkillViewModel() {
|
public EditSkillViewModel() {
|
||||||
mHasChanges = new MutableLiveData<>(false);
|
super();
|
||||||
ChangeTrackedLiveData.OnValueDirtiedCallback onDirtied = () -> mHasChanges.setValue(true);
|
mAbilityScore = new ChangeTrackedLiveData<>(AbilityScore.STRENGTH, this::makeDirty);
|
||||||
|
mAdvantageType = new ChangeTrackedLiveData<>(AdvantageType.NONE, this::makeDirty);
|
||||||
mAbilityScore = new ChangeTrackedLiveData<>(AbilityScore.STRENGTH, onDirtied);
|
mProficiencyType = new ChangeTrackedLiveData<>(ProficiencyType.NONE, this::makeDirty);
|
||||||
mAdvantageType = new ChangeTrackedLiveData<>(AdvantageType.NONE, onDirtied);
|
mName = new ChangeTrackedLiveData<>("Unknown Skill", this::makeDirty);
|
||||||
mProficiencyType = new ChangeTrackedLiveData<>(ProficiencyType.NONE, onDirtied);
|
mSkill = new ChangeTrackedLiveData<>(makeSkill(), this::makeDirty);
|
||||||
mName = new ChangeTrackedLiveData<>("Unknown Skill", onDirtied);
|
|
||||||
mSkill = new ChangeTrackedLiveData<>(makeSkill(), onDirtied);
|
|
||||||
}
|
|
||||||
|
|
||||||
public EditSkillViewModel(Skill skill) {
|
|
||||||
mHasChanges = new MutableLiveData<>(false);
|
|
||||||
ChangeTrackedLiveData.OnValueDirtiedCallback onDirtied = () -> mHasChanges.setValue(true);
|
|
||||||
|
|
||||||
mAbilityScore = new ChangeTrackedLiveData<>(skill.abilityScore, onDirtied);
|
|
||||||
mAdvantageType = new ChangeTrackedLiveData<>(skill.advantageType, onDirtied);
|
|
||||||
mProficiencyType = new ChangeTrackedLiveData<>(skill.proficiencyType, onDirtied);
|
|
||||||
mName = new ChangeTrackedLiveData<>(skill.name, onDirtied);
|
|
||||||
mSkill = new ChangeTrackedLiveData<>(makeSkill(), onDirtied);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void copyFromSkill(Skill skill) {
|
public void copyFromSkill(Skill skill) {
|
||||||
@@ -47,13 +32,6 @@ public class EditSkillViewModel extends ViewModel {
|
|||||||
mName.resetValue(skill.name);
|
mName.resetValue(skill.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void copyFromSkill(String name, AbilityScore abilityScore, ProficiencyType proficiency, AdvantageType advantage) {
|
|
||||||
mAbilityScore.resetValue(abilityScore);
|
|
||||||
mAdvantageType.resetValue(advantage);
|
|
||||||
mProficiencyType.resetValue(proficiency);
|
|
||||||
mName.resetValue(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public LiveData<Skill> getSkill() {
|
public LiveData<Skill> getSkill() {
|
||||||
return mSkill;
|
return mSkill;
|
||||||
}
|
}
|
||||||
@@ -94,14 +72,6 @@ public class EditSkillViewModel extends ViewModel {
|
|||||||
mSkill.setValue(makeSkill());
|
mSkill.setValue(makeSkill());
|
||||||
}
|
}
|
||||||
|
|
||||||
public LiveData<Boolean> getHasChanges() {
|
|
||||||
return mHasChanges;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasChanges() {
|
|
||||||
return mHasChanges.getValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Skill makeSkill() {
|
private Skill makeSkill() {
|
||||||
return new Skill(mName.getValue(), mAbilityScore.getValue(), mAdvantageType.getValue(), mProficiencyType.getValue());
|
return new Skill(mName.getValue(), mAbilityScore.getValue(), mAdvantageType.getValue(), mProficiencyType.getValue());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import android.view.View;
|
|||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.fragment.app.Fragment;
|
|
||||||
import androidx.lifecycle.ViewModelProvider;
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
import androidx.navigation.NavBackStackEntry;
|
import androidx.navigation.NavBackStackEntry;
|
||||||
import androidx.navigation.NavController;
|
import androidx.navigation.NavController;
|
||||||
@@ -21,14 +20,14 @@ import androidx.recyclerview.widget.RecyclerView;
|
|||||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||||
import com.majinnaibu.monstercards.R;
|
import com.majinnaibu.monstercards.R;
|
||||||
import com.majinnaibu.monstercards.models.Skill;
|
import com.majinnaibu.monstercards.models.Skill;
|
||||||
|
import com.majinnaibu.monstercards.ui.shared.MCFragment;
|
||||||
import com.majinnaibu.monstercards.ui.shared.SwipeToDeleteCallback;
|
import com.majinnaibu.monstercards.ui.shared.SwipeToDeleteCallback;
|
||||||
import com.majinnaibu.monstercards.utils.Logger;
|
import com.majinnaibu.monstercards.utils.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A fragment representing a list of Items.
|
* A fragment representing a list of Items.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("FieldCanBeLocal")
|
public class EditSkillsFragment extends MCFragment {
|
||||||
public class EditSkillsFragment extends Fragment {
|
|
||||||
private EditMonsterViewModel mViewModel;
|
private EditMonsterViewModel mViewModel;
|
||||||
private ViewHolder mHolder;
|
private ViewHolder mHolder;
|
||||||
|
|
||||||
@@ -67,7 +66,7 @@ public class EditSkillsFragment extends Fragment {
|
|||||||
} else {
|
} else {
|
||||||
Logger.logError("Can't navigate to EditSkill with a null skill");
|
Logger.logError("Can't navigate to EditSkill with a null skill");
|
||||||
}
|
}
|
||||||
}, null);
|
});
|
||||||
recyclerView.setAdapter(adapter);
|
recyclerView.setAdapter(adapter);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import androidx.navigation.Navigation;
|
|||||||
|
|
||||||
import com.majinnaibu.monstercards.R;
|
import com.majinnaibu.monstercards.R;
|
||||||
import com.majinnaibu.monstercards.ui.components.Stepper;
|
import com.majinnaibu.monstercards.ui.components.Stepper;
|
||||||
|
import com.majinnaibu.monstercards.ui.shared.MCFragment;
|
||||||
import com.majinnaibu.monstercards.utils.TextChangedListener;
|
import com.majinnaibu.monstercards.utils.TextChangedListener;
|
||||||
|
|
||||||
public class EditSpeedFragment extends Fragment {
|
public class EditSpeedFragment extends Fragment {
|
||||||
|
|||||||
@@ -9,49 +9,45 @@ import android.widget.EditText;
|
|||||||
import androidx.activity.OnBackPressedCallback;
|
import androidx.activity.OnBackPressedCallback;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.lifecycle.ViewModelProvider;
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
import androidx.navigation.NavBackStackEntry;
|
import androidx.navigation.NavBackStackEntry;
|
||||||
import androidx.navigation.NavController;
|
import androidx.navigation.NavController;
|
||||||
import androidx.navigation.Navigation;
|
import androidx.navigation.Navigation;
|
||||||
|
|
||||||
import com.majinnaibu.monstercards.R;
|
import com.majinnaibu.monstercards.R;
|
||||||
import com.majinnaibu.monstercards.data.enums.StringType;
|
|
||||||
import com.majinnaibu.monstercards.ui.shared.MCFragment;
|
|
||||||
import com.majinnaibu.monstercards.utils.Logger;
|
import com.majinnaibu.monstercards.utils.Logger;
|
||||||
import com.majinnaibu.monstercards.utils.TextChangedListener;
|
import com.majinnaibu.monstercards.utils.TextChangedListener;
|
||||||
|
|
||||||
public class EditStringFragment extends MCFragment {
|
public class EditConditionImmunityFragment extends Fragment {
|
||||||
private EditMonsterViewModel mEditMonsterViewModel;
|
private EditMonsterViewModel mEditMonsterViewModel;
|
||||||
private EditStringViewModel mViewModel;
|
private EditStringViewModel mViewModel;
|
||||||
private ViewHolder mHolder;
|
private ViewHolder mHolder;
|
||||||
private String mOldValue;
|
private String mOldValue;
|
||||||
private StringType mStringType;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
mViewModel = new ViewModelProvider(this).get(EditStringViewModel.class);
|
mViewModel = new ViewModelProvider(this).get(EditStringViewModel.class);
|
||||||
if (getArguments() != null) {
|
if (getArguments() != null) {
|
||||||
EditStringFragmentArgs args = EditStringFragmentArgs.fromBundle(getArguments());
|
EditConditionImmunityFragmentArgs args = EditConditionImmunityFragmentArgs.fromBundle(getArguments());
|
||||||
mOldValue = args.getValue();
|
mOldValue = args.getCondition();
|
||||||
mViewModel.setValue(mOldValue);
|
mViewModel.resetValue(mOldValue);
|
||||||
mStringType = args.getStringType();
|
|
||||||
} else {
|
} else {
|
||||||
Logger.logWTF("EditStringFragment needs arguments");
|
Logger.logWTF("EditConditionImmunityFragment needs arguments");
|
||||||
mOldValue = null;
|
mOldValue = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||||
|
@Nullable Bundle savedInstanceState) {
|
||||||
NavController navController = Navigation.findNavController(requireActivity(), R.id.nav_host_fragment);
|
NavController navController = Navigation.findNavController(requireActivity(), R.id.nav_host_fragment);
|
||||||
NavBackStackEntry backStackEntry = navController.getBackStackEntry(R.id.edit_monster_navigation);
|
NavBackStackEntry backStackEntry = navController.getBackStackEntry(R.id.edit_monster_navigation);
|
||||||
mEditMonsterViewModel = new ViewModelProvider(backStackEntry).get(EditMonsterViewModel.class);
|
mEditMonsterViewModel = new ViewModelProvider(backStackEntry).get(EditMonsterViewModel.class);
|
||||||
View root = inflater.inflate(R.layout.fragment_edit_string, container, false);
|
View root = inflater.inflate(R.layout.fragment_edit_condition_immunity, container, false);
|
||||||
mHolder = new ViewHolder(root);
|
mHolder = new ViewHolder(root);
|
||||||
setTitle(getTitleForStringType(mStringType));
|
|
||||||
|
|
||||||
mHolder.description.setText(mViewModel.getValueAsString());
|
mHolder.description.setText(mViewModel.getValueAsString());
|
||||||
mHolder.description.addTextChangedListener(new TextChangedListener((TextChangedListener.OnTextChangedCallback) (s, start, before, count) -> mViewModel.setValue(s.toString())));
|
mHolder.description.addTextChangedListener(new TextChangedListener((TextChangedListener.OnTextChangedCallback) (s, start, before, count) -> mViewModel.setValue(s.toString())));
|
||||||
|
|
||||||
@@ -59,7 +55,7 @@ public class EditStringFragment extends MCFragment {
|
|||||||
@Override
|
@Override
|
||||||
public void handleOnBackPressed() {
|
public void handleOnBackPressed() {
|
||||||
if (mViewModel.hasChanges()) {
|
if (mViewModel.hasChanges()) {
|
||||||
mEditMonsterViewModel.replaceString(mStringType, mOldValue, mViewModel.getValueAsString());
|
mEditMonsterViewModel.replaceConditionImmunity(mOldValue, mViewModel.getValueAsString());
|
||||||
}
|
}
|
||||||
Navigation.findNavController(requireView()).navigateUp();
|
Navigation.findNavController(requireView()).navigateUp();
|
||||||
}
|
}
|
||||||
@@ -68,35 +64,11 @@ public class EditStringFragment extends MCFragment {
|
|||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
|
||||||
private String getTitleForStringType(@NonNull StringType type) {
|
|
||||||
switch (type) {
|
|
||||||
case CONDITION_IMMUNITY:
|
|
||||||
return getString(R.string.title_editConditionImmunity);
|
|
||||||
case DAMAGE_IMMUNITY:
|
|
||||||
return getString(R.string.title_editDamageImmunity);
|
|
||||||
case DAMAGE_RESISTANCE:
|
|
||||||
return getString(R.string.title_editDamageResistance);
|
|
||||||
case DAMAGE_VULNERABILITY:
|
|
||||||
return getString(R.string.title_editDamageVulnerability);
|
|
||||||
case SENSE:
|
|
||||||
return getString(R.string.title_editSense);
|
|
||||||
default:
|
|
||||||
return getString(R.string.title_editString);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStart() {
|
|
||||||
super.onStart();
|
|
||||||
mHolder.description.requestFocus();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class ViewHolder {
|
private static class ViewHolder {
|
||||||
EditText description;
|
EditText description;
|
||||||
|
|
||||||
ViewHolder(@NonNull View root) {
|
ViewHolder(View root) {
|
||||||
description = root.findViewById(R.id.description);
|
description = root.findViewById(R.id.description);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4,30 +4,34 @@ import android.view.LayoutInflater;
|
|||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
import com.majinnaibu.monstercards.databinding.FragmentEditStringsListItemBinding;
|
import com.majinnaibu.monstercards.databinding.FragmentEditConditionImmunitiesListItemBinding;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class EditStringsRecyclerViewAdapter extends RecyclerView.Adapter<EditStringsRecyclerViewAdapter.ViewHolder> {
|
/**
|
||||||
|
* {@link RecyclerView.Adapter} that can display a {@link String}.
|
||||||
|
*/
|
||||||
|
public class EditConditionImmunitiesRecyclerViewAdapter extends RecyclerView.Adapter<EditConditionImmunitiesRecyclerViewAdapter.ViewHolder> {
|
||||||
private final List<String> mValues;
|
private final List<String> mValues;
|
||||||
private final ItemCallback mOnClick;
|
private final ItemCallback mOnClick;
|
||||||
|
|
||||||
public EditStringsRecyclerViewAdapter(List<String> items, ItemCallback onClick) {
|
public EditConditionImmunitiesRecyclerViewAdapter(List<String> items, ItemCallback onClick) {
|
||||||
mValues = items;
|
mValues = items;
|
||||||
mOnClick = onClick;
|
mOnClick = onClick;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
public ViewHolder onCreateViewHolder(@NotNull ViewGroup parent, int viewType) {
|
||||||
return new ViewHolder(FragmentEditStringsListItemBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false));
|
return new ViewHolder(FragmentEditConditionImmunitiesListItemBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBindViewHolder(@NonNull final ViewHolder holder, int position) {
|
public void onBindViewHolder(final ViewHolder holder, int position) {
|
||||||
holder.mItem = mValues.get(position);
|
holder.mItem = mValues.get(position);
|
||||||
holder.mContentView.setText(mValues.get(position));
|
holder.mContentView.setText(mValues.get(position));
|
||||||
holder.itemView.setOnClickListener(v -> {
|
holder.itemView.setOnClickListener(v -> {
|
||||||
@@ -43,22 +47,22 @@ public class EditStringsRecyclerViewAdapter extends RecyclerView.Adapter<EditStr
|
|||||||
}
|
}
|
||||||
|
|
||||||
public interface ItemCallback {
|
public interface ItemCallback {
|
||||||
void onItemCallback(String value);
|
void onItemCallback(String condition);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ViewHolder extends RecyclerView.ViewHolder {
|
public static class ViewHolder extends RecyclerView.ViewHolder {
|
||||||
public final TextView mContentView;
|
public final TextView mContentView;
|
||||||
public String mItem;
|
public String mItem;
|
||||||
|
|
||||||
public ViewHolder(@NonNull FragmentEditStringsListItemBinding binding) {
|
public ViewHolder(FragmentEditConditionImmunitiesListItemBinding binding) {
|
||||||
super(binding.getRoot());
|
super(binding.getRoot());
|
||||||
mContentView = binding.content;
|
mContentView = binding.content;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return super.toString() + " '" + mContentView.getText() + "'";
|
return super.toString() + " '" + mContentView.getText() + "'";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.majinnaibu.monstercards.ui.library;
|
package com.majinnaibu.monstercards.ui.library;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
@@ -8,6 +9,7 @@ import android.view.ViewGroup;
|
|||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.navigation.NavDirections;
|
import androidx.navigation.NavDirections;
|
||||||
import androidx.navigation.Navigation;
|
import androidx.navigation.Navigation;
|
||||||
|
import androidx.recyclerview.widget.DividerItemDecoration;
|
||||||
import androidx.recyclerview.widget.ItemTouchHelper;
|
import androidx.recyclerview.widget.ItemTouchHelper;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
@@ -17,14 +19,14 @@ import com.google.android.material.snackbar.Snackbar;
|
|||||||
import com.majinnaibu.monstercards.R;
|
import com.majinnaibu.monstercards.R;
|
||||||
import com.majinnaibu.monstercards.data.MonsterRepository;
|
import com.majinnaibu.monstercards.data.MonsterRepository;
|
||||||
import com.majinnaibu.monstercards.models.Monster;
|
import com.majinnaibu.monstercards.models.Monster;
|
||||||
import com.majinnaibu.monstercards.ui.MCFragment;
|
import com.majinnaibu.monstercards.ui.shared.MCFragment;
|
||||||
import com.majinnaibu.monstercards.ui.MonsterListRecyclerViewAdapter;
|
|
||||||
import com.majinnaibu.monstercards.ui.shared.SwipeToDeleteCallback;
|
import com.majinnaibu.monstercards.ui.shared.SwipeToDeleteCallback;
|
||||||
import com.majinnaibu.monstercards.utils.Logger;
|
import com.majinnaibu.monstercards.utils.Logger;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
|
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
|
||||||
|
import io.reactivex.rxjava3.observers.DisposableCompletableObserver;
|
||||||
import io.reactivex.rxjava3.schedulers.Schedulers;
|
import io.reactivex.rxjava3.schedulers.Schedulers;
|
||||||
|
|
||||||
public class LibraryFragment extends MCFragment {
|
public class LibraryFragment extends MCFragment {
|
||||||
@@ -45,57 +47,77 @@ public class LibraryFragment extends MCFragment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void setupRecyclerView(@NonNull RecyclerView recyclerView) {
|
private void setupRecyclerView(@NonNull RecyclerView recyclerView) {
|
||||||
|
Context context = requireContext();
|
||||||
MonsterRepository repository = this.getMonsterRepository();
|
MonsterRepository repository = this.getMonsterRepository();
|
||||||
boolean mTwoPane = false;
|
|
||||||
MonsterListRecyclerViewAdapter adapter = new MonsterListRecyclerViewAdapter(
|
MonsterListRecyclerViewAdapter adapter = new MonsterListRecyclerViewAdapter(
|
||||||
this,
|
context,
|
||||||
repository.getMonsters(),
|
repository.getMonsters(),
|
||||||
(monster) -> {
|
(monster) -> navigateToMonsterDetail(monster.id),
|
||||||
repository
|
(monster) -> repository
|
||||||
.deleteMonster(monster)
|
.deleteMonster(monster)
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe(() -> {
|
.subscribe(new DisposableCompletableObserver() {
|
||||||
Logger.logDebug("deleted");
|
@Override
|
||||||
}, Logger::logError);
|
public void onComplete() {
|
||||||
},
|
}
|
||||||
mTwoPane);
|
|
||||||
|
@Override
|
||||||
|
public void onError(@io.reactivex.rxjava3.annotations.NonNull Throwable e) {
|
||||||
|
Logger.logError(e);
|
||||||
|
}
|
||||||
|
}));
|
||||||
recyclerView.setAdapter(adapter);
|
recyclerView.setAdapter(adapter);
|
||||||
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
|
|
||||||
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new SwipeToDeleteCallback(getContext(), (position) -> {
|
LinearLayoutManager layoutManager = new LinearLayoutManager(context);
|
||||||
adapter.deleteItem(position);
|
recyclerView.setLayoutManager(layoutManager);
|
||||||
}));
|
|
||||||
|
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(context, layoutManager.getOrientation());
|
||||||
|
recyclerView.addItemDecoration(dividerItemDecoration);
|
||||||
|
|
||||||
|
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new SwipeToDeleteCallback(requireContext(), adapter::deleteItem));
|
||||||
itemTouchHelper.attachToRecyclerView(recyclerView);
|
itemTouchHelper.attachToRecyclerView(recyclerView);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupAddMonsterButton(@NonNull FloatingActionButton fab) {
|
private void setupAddMonsterButton(@NonNull FloatingActionButton fab) {
|
||||||
fab.setOnClickListener(view -> {
|
fab.setOnClickListener(view -> {
|
||||||
Monster monster = new Monster();
|
Monster monster = new Monster();
|
||||||
monster.name = "Unnamed Monster";
|
monster.name = getString(R.string.default_monster_name);
|
||||||
MonsterRepository repository = this.getMonsterRepository();
|
MonsterRepository repository = this.getMonsterRepository();
|
||||||
repository.addMonster(monster)
|
repository.addMonster(monster)
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe(() -> {
|
.subscribe(
|
||||||
Snackbar.make(
|
new DisposableCompletableObserver() {
|
||||||
getView(),
|
@Override
|
||||||
String.format("%s created", monster.name),
|
public void onComplete() {
|
||||||
Snackbar.LENGTH_LONG)
|
View view = getView();
|
||||||
.setAction("Action", (_view) -> {
|
assert view != null;
|
||||||
navigateToMonsterDetail(monster.id);
|
Snackbar.make(
|
||||||
})
|
view,
|
||||||
.show();
|
getString(R.string.snackbar_monster_created, monster.name),
|
||||||
}, throwable -> {
|
Snackbar.LENGTH_LONG)
|
||||||
Logger.logError("Error creating monster", throwable);
|
.setAction("Action", (_view) -> navigateToMonsterDetail(monster.id))
|
||||||
Snackbar.make(getView(), "Failed to create monster", Snackbar.LENGTH_LONG)
|
.show();
|
||||||
.setAction("Action", null).show();
|
}
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(@io.reactivex.rxjava3.annotations.NonNull Throwable e) {
|
||||||
|
Logger.logError("Error creating monster", e);
|
||||||
|
View view = getView();
|
||||||
|
assert view != null;
|
||||||
|
Snackbar.make(view, getString(R.string.snackbar_failed_to_create_monster), Snackbar.LENGTH_LONG)
|
||||||
|
.setAction("Action", null).show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void navigateToMonsterDetail(UUID monsterId) {
|
protected void navigateToMonsterDetail(UUID monsterId) {
|
||||||
NavDirections action = LibraryFragmentDirections.actionNavigationLibraryToNavigationMonster(monsterId.toString());
|
NavDirections action = LibraryFragmentDirections.actionNavigationLibraryToNavigationMonster(monsterId.toString());
|
||||||
Navigation.findNavController(getView()).navigate(action);
|
View view = getView();
|
||||||
|
assert view != null;
|
||||||
|
Navigation.findNavController(view).navigate(action);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ import com.majinnaibu.monstercards.data.MonsterRepository;
|
|||||||
import com.majinnaibu.monstercards.helpers.CommonMarkHelper;
|
import com.majinnaibu.monstercards.helpers.CommonMarkHelper;
|
||||||
import com.majinnaibu.monstercards.helpers.StringHelper;
|
import com.majinnaibu.monstercards.helpers.StringHelper;
|
||||||
import com.majinnaibu.monstercards.models.Monster;
|
import com.majinnaibu.monstercards.models.Monster;
|
||||||
import com.majinnaibu.monstercards.ui.MCFragment;
|
import com.majinnaibu.monstercards.ui.shared.MCFragment;
|
||||||
import com.majinnaibu.monstercards.utils.Logger;
|
import com.majinnaibu.monstercards.utils.Logger;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
@@ -241,10 +241,15 @@ public class MonsterDetailFragment extends MCFragment {
|
|||||||
@Override
|
@Override
|
||||||
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
||||||
if (item.getItemId() == R.id.menu_action_edit_monster) {
|
if (item.getItemId() == R.id.menu_action_edit_monster) {
|
||||||
NavDirections action = MonsterDetailFragmentDirections.actionNavigationMonsterToEditMonsterFragment(monsterDetailViewModel.getId().toString());
|
UUID monsterId = monsterDetailViewModel.getId().getValue();
|
||||||
View view = getView();
|
if (monsterId != null) {
|
||||||
assert view != null;
|
NavDirections action = MonsterDetailFragmentDirections.actionNavigationMonsterToEditMonsterFragment(monsterId.toString());
|
||||||
Navigation.findNavController(view).navigate(action);
|
View view = getView();
|
||||||
|
assert view != null;
|
||||||
|
Navigation.findNavController(view).navigate(action);
|
||||||
|
} else {
|
||||||
|
Logger.logWTF("monsterId cannot be null.");
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return super.onOptionsItemSelected(item);
|
return super.onOptionsItemSelected(item);
|
||||||
|
|||||||
@@ -14,12 +14,10 @@ import androidx.recyclerview.widget.RecyclerView;
|
|||||||
|
|
||||||
import com.majinnaibu.monstercards.R;
|
import com.majinnaibu.monstercards.R;
|
||||||
import com.majinnaibu.monstercards.data.MonsterRepository;
|
import com.majinnaibu.monstercards.data.MonsterRepository;
|
||||||
import com.majinnaibu.monstercards.ui.MCFragment;
|
import com.majinnaibu.monstercards.ui.shared.MCFragment;
|
||||||
|
|
||||||
public class SearchFragment extends MCFragment {
|
public class SearchFragment extends MCFragment {
|
||||||
|
|
||||||
private SearchViewModel searchViewModel;
|
|
||||||
|
|
||||||
public View onCreateView(@NonNull LayoutInflater inflater,
|
public View onCreateView(@NonNull LayoutInflater inflater,
|
||||||
ViewGroup container, Bundle savedInstanceState) {
|
ViewGroup container, Bundle savedInstanceState) {
|
||||||
View root = inflater.inflate(R.layout.fragment_search, container, false);
|
View root = inflater.inflate(R.layout.fragment_search, container, false);
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ import com.majinnaibu.monstercards.data.MonsterRepository;
|
|||||||
import com.majinnaibu.monstercards.models.Monster;
|
import com.majinnaibu.monstercards.models.Monster;
|
||||||
import com.majinnaibu.monstercards.utils.Logger;
|
import com.majinnaibu.monstercards.utils.Logger;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -20,16 +22,11 @@ import io.reactivex.rxjava3.core.Flowable;
|
|||||||
import io.reactivex.rxjava3.disposables.Disposable;
|
import io.reactivex.rxjava3.disposables.Disposable;
|
||||||
|
|
||||||
public class SearchResultsRecyclerViewAdapter extends RecyclerView.Adapter<SearchResultsRecyclerViewAdapter.ViewHolder> {
|
public class SearchResultsRecyclerViewAdapter extends RecyclerView.Adapter<SearchResultsRecyclerViewAdapter.ViewHolder> {
|
||||||
public interface ItemCallback {
|
|
||||||
void onItem(Monster monster);
|
|
||||||
}
|
|
||||||
|
|
||||||
private final MonsterRepository mRepository;
|
private final MonsterRepository mRepository;
|
||||||
|
private final ItemCallback mOnClickHandler;
|
||||||
private String mSearchText;
|
private String mSearchText;
|
||||||
private List<Monster> mValues;
|
private List<Monster> mValues;
|
||||||
private Disposable mSubscriptionHandler;
|
private Disposable mSubscriptionHandler;
|
||||||
private final ItemCallback mOnClickHandler;
|
|
||||||
|
|
||||||
public SearchResultsRecyclerViewAdapter(MonsterRepository repository,
|
public SearchResultsRecyclerViewAdapter(MonsterRepository repository,
|
||||||
ItemCallback onClick) {
|
ItemCallback onClick) {
|
||||||
mRepository = repository;
|
mRepository = repository;
|
||||||
@@ -54,6 +51,7 @@ public class SearchResultsRecyclerViewAdapter extends RecyclerView.Adapter<Searc
|
|||||||
throwable -> Logger.logError("Error performing search", throwable));
|
throwable -> Logger.logError("Error performing search", throwable));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||||
View view = LayoutInflater.from(parent.getContext())
|
View view = LayoutInflater.from(parent.getContext())
|
||||||
@@ -79,7 +77,11 @@ public class SearchResultsRecyclerViewAdapter extends RecyclerView.Adapter<Searc
|
|||||||
return mValues.size();
|
return mValues.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
class ViewHolder extends RecyclerView.ViewHolder {
|
public interface ItemCallback {
|
||||||
|
void onItem(Monster monster);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ViewHolder extends RecyclerView.ViewHolder {
|
||||||
final TextView mIdView;
|
final TextView mIdView;
|
||||||
final TextView mContentView;
|
final TextView mContentView;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user