diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 57a954b..eaa2137 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -5,19 +5,22 @@
+ android:name=".MainActivity"
+ android:label="@string/app_name"
+ android:launchMode="singleTask">
+
+
+
+
+
@@ -45,15 +48,8 @@
android:mimeType="text/plain"
android:scheme="file" />
-
-
-
-
-
-
+
setupLabeledTextView(mHolder.armorClass, armorText, R.string.label_armor_class));
+ mViewModel.getHitPoints().observe(getViewLifecycleOwner(), hitPoints -> setupLabeledTextView(mHolder.hitPoints, hitPoints, R.string.label_hit_points));
+ mViewModel.getSpeed().observe(getViewLifecycleOwner(), speed -> setupLabeledTextView(mHolder.speed, speed, R.string.label_speed));
+ mViewModel.getStrength().observe(getViewLifecycleOwner(), mHolder.strength::setText);
+ mViewModel.getDexterity().observe(getViewLifecycleOwner(), mHolder.dexterity::setText);
+ mViewModel.getConstitution().observe(getViewLifecycleOwner(), mHolder.constitution::setText);
+ mViewModel.getIntelligence().observe(getViewLifecycleOwner(), mHolder.intelligence::setText);
+ mViewModel.getWisdom().observe(getViewLifecycleOwner(), mHolder.wisdom::setText);
+ mViewModel.getCharisma().observe(getViewLifecycleOwner(), mHolder.charisma::setText);
+ mViewModel.getSavingThrows().observe(getViewLifecycleOwner(), savingThrows -> setupOptionalTextView(mHolder.savingThrows, savingThrows, R.string.label_saving_throws));
+ mViewModel.getSkills().observe(getViewLifecycleOwner(), skills -> setupOptionalTextView(mHolder.skills, skills, R.string.label_skills));
+ mViewModel.getDamageVulnerabilities().observe(getViewLifecycleOwner(), damageTypes -> setupOptionalTextView(mHolder.damageVulnerabilities, damageTypes, R.string.label_damage_vulnerabilities));
+ mViewModel.getDamageResistances().observe(getViewLifecycleOwner(), damageTypes -> setupOptionalTextView(mHolder.damageResistances, damageTypes, R.string.label_damage_resistances));
+ mViewModel.getDamageImmunities().observe(getViewLifecycleOwner(), damageTypes -> setupOptionalTextView(mHolder.damageImmunities, damageTypes, R.string.label_damage_immunities));
+ mViewModel.getConditionImmunities().observe(getViewLifecycleOwner(), conditionImmunities -> setupOptionalTextView(mHolder.conditionImmunities, conditionImmunities, R.string.label_condition_immunities));
+ mViewModel.getSenses().observe(getViewLifecycleOwner(), senses -> setupOptionalTextView(mHolder.senses, senses, R.string.label_senses));
+ mViewModel.getLanguages().observe(getViewLifecycleOwner(), languages -> setupOptionalTextView(mHolder.languages, languages, R.string.label_languages));
+ mViewModel.getChallenge().observe(getViewLifecycleOwner(), challengeRating -> setupLabeledTextView(mHolder.challenge, challengeRating, R.string.label_challenge_rating));
+ mViewModel.getAbilities().observe(getViewLifecycleOwner(), abilities -> setupTraitList(mHolder.abilities, abilities));
+ mViewModel.getActions().observe(getViewLifecycleOwner(), actions -> setupTraitList(mHolder.actions, actions, mHolder.actions_label, mHolder.actions_divider));
+ mViewModel.getReactions().observe(getViewLifecycleOwner(), reactions -> setupTraitList(mHolder.reactions, reactions, mHolder.reactions_label, mHolder.reactions_divider));
+ mViewModel.getRegionalEffects().observe(getViewLifecycleOwner(), regionalEffects -> setupTraitList(mHolder.regionalEffects, regionalEffects, mHolder.regionalEffects_label, mHolder.regionalEffects_divider));
+ mViewModel.getLairActions().observe(getViewLifecycleOwner(), lairActions -> setupTraitList(mHolder.lairActions, lairActions, mHolder.lairActions_label, mHolder.lairActions_divider));
+ mViewModel.getLegendaryActions().observe(getViewLifecycleOwner(), legendaryActions -> setupTraitList(mHolder.legendaryActions, legendaryActions, mHolder.legendaryActions_label, mHolder.legendaryActions_divider));
- mViewModel.getName().observe(this, mHolder.name::setText);
- mViewModel.getMeta().observe(this, mHolder.meta::setText);
- mViewModel.getArmorClass().observe(this, armorText -> setupLabeledTextView(mHolder.armorClass, armorText, R.string.label_armor_class));
- mViewModel.getHitPoints().observe(this, hitPoints -> setupLabeledTextView(mHolder.hitPoints, hitPoints, R.string.label_hit_points));
- mViewModel.getSpeed().observe(this, speed -> setupLabeledTextView(mHolder.speed, speed, R.string.label_speed));
- mViewModel.getStrength().observe(this, mHolder.strength::setText);
- mViewModel.getDexterity().observe(this, mHolder.dexterity::setText);
- mViewModel.getConstitution().observe(this, mHolder.constitution::setText);
- mViewModel.getIntelligence().observe(this, mHolder.intelligence::setText);
- mViewModel.getWisdom().observe(this, mHolder.wisdom::setText);
- mViewModel.getCharisma().observe(this, mHolder.charisma::setText);
- mViewModel.getSavingThrows().observe(this, savingThrows -> setupOptionalTextView(mHolder.savingThrows, savingThrows, R.string.label_saving_throws));
- mViewModel.getSkills().observe(this, skills -> setupOptionalTextView(mHolder.skills, skills, R.string.label_skills));
- mViewModel.getDamageVulnerabilities().observe(this, damageTypes -> setupOptionalTextView(mHolder.damageVulnerabilities, damageTypes, R.string.label_damage_vulnerabilities));
- mViewModel.getDamageResistances().observe(this, damageTypes -> setupOptionalTextView(mHolder.damageResistances, damageTypes, R.string.label_damage_resistances));
- mViewModel.getDamageImmunities().observe(this, damageTypes -> setupOptionalTextView(mHolder.damageImmunities, damageTypes, R.string.label_damage_immunities));
- mViewModel.getConditionImmunities().observe(this, conditionImmunities -> setupOptionalTextView(mHolder.conditionImmunities, conditionImmunities, R.string.label_condition_immunities));
- mViewModel.getSenses().observe(this, senses -> setupOptionalTextView(mHolder.senses, senses, R.string.label_senses));
- mViewModel.getLanguages().observe(this, languages -> setupOptionalTextView(mHolder.languages, languages, R.string.label_languages));
- mViewModel.getChallenge().observe(this, challengeRating -> setupLabeledTextView(mHolder.challenge, challengeRating, R.string.label_challenge_rating));
- mViewModel.getAbilities().observe(this, abilities -> setupTraitList(mHolder.abilities, abilities));
- mViewModel.getActions().observe(this, actions -> setupTraitList(mHolder.actions, actions, mHolder.actions_label, mHolder.actions_divider));
- mViewModel.getReactions().observe(this, reactions -> setupTraitList(mHolder.reactions, reactions, mHolder.reactions_label, mHolder.reactions_divider));
- mViewModel.getRegionalEffects().observe(this, regionalEffects -> setupTraitList(mHolder.regionalEffects, regionalEffects, mHolder.regionalEffects_label, mHolder.regionalEffects_divider));
- mViewModel.getLairActions().observe(this, lairActions -> setupTraitList(mHolder.lairActions, lairActions, mHolder.lairActions_label, mHolder.lairActions_divider));
- mViewModel.getLegendaryActions().observe(this, legendaryActions -> setupTraitList(mHolder.legendaryActions, legendaryActions, mHolder.legendaryActions_label, mHolder.legendaryActions_divider));
- }
-
- @Override
- protected void onResume() {
- super.onResume();
- Logger.logDebug("onCreateView");
- Monster monster = readMonsterFromIntent(getIntent());
- if (monster != null) {
- mViewModel.setMonster(monster);
- }
- }
-
- private Monster readMonsterFromIntent(Intent intent) {
- String action = intent.getAction();
- Bundle extras = intent.getExtras();
- String type = intent.getType();
- String json;
- Uri uri = null;
- if ("android.intent.action.SEND".equals(action) && "text/plain".equals(type)) {
- uri = extras.getParcelable("android.intent.extra.STREAM");
- } else if ("android.intent.action.VIEW".equals(action) && ("text/plain".equals(type) || "application/octet-stream".equals(type))) {
- uri = intent.getData();
- } else {
- Logger.logError(String.format("unexpected launch configuration action: %s, type: %s, uri: %s", action, type, uri));
- }
- if (uri == null) {
- return null;
- }
- json = readContentsOfUri(uri);
- if (StringHelper.isNullOrEmpty(json)) {
- return null;
- }
- return MonsterImportHelper.fromJSON(json);
- }
-
- private String readContentsOfUri(Uri uri) {
- StringBuilder builder = new StringBuilder();
- try (InputStream inputStream =
- getContentResolver().openInputStream(uri);
- BufferedReader reader = new BufferedReader(
- new InputStreamReader(Objects.requireNonNull(inputStream)))) {
- String line;
- while ((line = reader.readLine()) != null) {
- builder.append(line);
- }
- } catch (IOException e) {
- Logger.logError("error reading file", e);
- return null;
- }
- return builder.toString();
- }
-
- @Override
- protected void onNewIntent(Intent intent) {
- super.onNewIntent(intent);
- setIntent(intent);
+ return root;
}
private void setupLabeledTextView(TextView view, String text, int titleId) {
@@ -167,14 +116,17 @@ public class ImportMonsterActivity extends AppCompatActivity {
private void setupTraitList(@NonNull LinearLayout root, @NonNull List traits, View label, View divider) {
int visibility = traits.size() > 0 ? View.VISIBLE : View.GONE;
+ Context context = getContext();
DisplayMetrics displayMetrics = null;
- Resources resources = getResources();
- if (resources != null) {
- displayMetrics = resources.getDisplayMetrics();
+ if (context != null) {
+ Resources resources = context.getResources();
+ if (resources != null) {
+ displayMetrics = resources.getDisplayMetrics();
+ }
}
root.removeAllViews();
for (String action : traits) {
- TextView tvAction = new TextView(this);
+ TextView tvAction = new TextView(getContext());
// TODO: Handle multiline block quotes specially so they stay multiline.
// TODO: Replace QuoteSpans in the result of fromHtml with something like this https://stackoverflow.com/questions/7717567/how-to-style-blockquotes-in-android-textviews to make them indent as expected
tvAction.setText(Html.fromHtml(CommonMarkHelper.toHtml(action)));
@@ -193,9 +145,9 @@ public class ImportMonsterActivity extends AppCompatActivity {
}
@Override
- public boolean onCreateOptionsMenu(@NonNull Menu menu) {
- getMenuInflater().inflate(R.menu.import_monster, menu);
- return true;
+ public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
+ inflater.inflate(R.menu.import_monster, menu);
+ super.onCreateOptionsMenu(menu, inflater);
}
@Override
@@ -233,7 +185,14 @@ public class ImportMonsterActivity extends AppCompatActivity {
}
private void navigateToEditMonster(UUID monsterId) {
- Logger.logUnimplementedFeature(String.format("navigate to editing the monster %s", monsterId));
+ NavController navController = Navigation.findNavController(requireView());
+ NavDirections action;
+ action = MonsterImportFragmentDirections.actionMonsterImportFragmentToNavigationLibrary();
+ navController.navigate(action);
+ action = LibraryFragmentDirections.actionNavigationLibraryToNavigationMonster(monsterId.toString());
+ navController.navigate(action);
+ action = MonsterDetailFragmentDirections.actionNavigationMonsterToEditMonsterFragment(monsterId.toString());
+ navController.navigate(action);
}
private static class ViewHolder {
@@ -315,4 +274,5 @@ public class ImportMonsterActivity extends AppCompatActivity {
regionalEffects_label = root.findViewById(R.id.regionalEffects_label);
}
}
+
}
diff --git a/app/src/main/java/com/majinnaibu/monstercards/ui/monster/MonsterImportViewModel.java b/app/src/main/java/com/majinnaibu/monstercards/ui/monster/MonsterImportViewModel.java
new file mode 100644
index 0000000..31e1a80
--- /dev/null
+++ b/app/src/main/java/com/majinnaibu/monstercards/ui/monster/MonsterImportViewModel.java
@@ -0,0 +1,216 @@
+package com.majinnaibu.monstercards.ui.monster;
+
+import androidx.lifecycle.LiveData;
+import androidx.lifecycle.MutableLiveData;
+import androidx.lifecycle.ViewModel;
+
+import com.majinnaibu.monstercards.models.Monster;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+public class MonsterImportViewModel extends ViewModel {
+ private final MutableLiveData> mAbilities;
+ private final MutableLiveData> mActions;
+ private final MutableLiveData mArmorClass;
+ private final MutableLiveData mChallenge;
+ private final MutableLiveData mCharisma;
+ private final MutableLiveData mConditionImmunities;
+ private final MutableLiveData mConstitution;
+ private final MutableLiveData mDamageResistances;
+ private final MutableLiveData mDamageImmunities;
+ private final MutableLiveData mDamageVulnerabilities;
+ private final MutableLiveData mDexterity;
+ private final MutableLiveData mHitPoints;
+ private final MutableLiveData mIntelligence;
+ private final MutableLiveData> mLairActions;
+ private final MutableLiveData mLanguages;
+ private final MutableLiveData> mLegendaryActions;
+ private final MutableLiveData mMeta;
+ private final MutableLiveData mName;
+ private final MutableLiveData> mReactions;
+ private final MutableLiveData> mRegionalEffects;
+ private final MutableLiveData mSavingThrows;
+ private final MutableLiveData mSenses;
+ private final MutableLiveData mSkills;
+ private final MutableLiveData mSpeed;
+ private final MutableLiveData mStrength;
+ private final MutableLiveData mWisdom;
+ private final MutableLiveData mMonsterId;
+ private Monster mMonster;
+
+ public MonsterImportViewModel() {
+ mMonster = null;
+ mAbilities = new MutableLiveData<>(new ArrayList<>());
+ mActions = new MutableLiveData<>(new ArrayList<>());
+ mArmorClass = new MutableLiveData<>("");
+ mChallenge = new MutableLiveData<>("");
+ mCharisma = new MutableLiveData<>("");
+ mConditionImmunities = new MutableLiveData<>("");
+ mConstitution = new MutableLiveData<>("");
+ mDamageImmunities = new MutableLiveData<>("");
+ mDamageResistances = new MutableLiveData<>("");
+ mDamageVulnerabilities = new MutableLiveData<>("");
+ mDexterity = new MutableLiveData<>("");
+ mHitPoints = new MutableLiveData<>("");
+ mIntelligence = new MutableLiveData<>("");
+ mLairActions = new MutableLiveData<>(new ArrayList<>());
+ mLanguages = new MutableLiveData<>("");
+ mLegendaryActions = new MutableLiveData<>(new ArrayList<>());
+ mMeta = new MutableLiveData<>("");
+ mName = new MutableLiveData<>("");
+ mReactions = new MutableLiveData<>(new ArrayList<>());
+ mRegionalEffects = new MutableLiveData<>(new ArrayList<>());
+ mSavingThrows = new MutableLiveData<>("");
+ mSenses = new MutableLiveData<>("");
+ mSkills = new MutableLiveData<>("");
+ mSpeed = new MutableLiveData<>("");
+ mStrength = new MutableLiveData<>("");
+ mWisdom = new MutableLiveData<>("");
+ mMonsterId = new MutableLiveData<>(UUID.fromString("00000000-0000-0000-0000-000000000000"));
+ }
+
+ public LiveData> getAbilities() {
+ return mAbilities;
+ }
+
+ public LiveData> getActions() {
+ return mActions;
+ }
+
+ public LiveData> getReactions() {
+ return mReactions;
+ }
+
+ public LiveData> getLegendaryActions() {
+ return mLegendaryActions;
+ }
+
+ public LiveData> getLairActions() {
+ return mLairActions;
+ }
+
+ public LiveData> getRegionalEffects() {
+ return mRegionalEffects;
+ }
+
+ public LiveData getArmorClass() {
+ return mArmorClass;
+ }
+
+ public LiveData getChallenge() {
+ return mChallenge;
+ }
+
+ public LiveData getCharisma() {
+ return mCharisma;
+ }
+
+ public LiveData getConditionImmunities() {
+ return mConditionImmunities;
+ }
+
+ public LiveData getConstitution() {
+ return mConstitution;
+ }
+
+ public LiveData getDamageResistances() {
+ return mDamageResistances;
+ }
+
+ public LiveData getDamageImmunities() {
+ return mDamageImmunities;
+ }
+
+ public LiveData getDamageVulnerabilities() {
+ return mDamageVulnerabilities;
+ }
+
+ public LiveData getDexterity() {
+ return mDexterity;
+ }
+
+ public LiveData getHitPoints() {
+ return mHitPoints;
+ }
+
+ public LiveData getIntelligence() {
+ return mIntelligence;
+ }
+
+ public LiveData getLanguages() {
+ return mLanguages;
+ }
+
+ public LiveData getMeta() {
+ return mMeta;
+ }
+
+ public LiveData getName() {
+ return mName;
+ }
+
+ public LiveData getSavingThrows() {
+ return mSavingThrows;
+ }
+
+ public LiveData getSenses() {
+ return mSenses;
+ }
+
+ public LiveData getSkills() {
+ return mSkills;
+ }
+
+ public LiveData getSpeed() {
+ return mSpeed;
+ }
+
+ public LiveData getStrength() {
+ return mStrength;
+ }
+
+ public LiveData getWisdom() {
+ return mWisdom;
+ }
+
+ public LiveData getId() {
+ return mMonsterId;
+ }
+
+ public Monster getMonster() {
+ return mMonster;
+ }
+
+ public void setMonster(Monster monster) {
+ mMonster = monster;
+ mAbilities.setValue(mMonster.getAbilityDescriptions());
+ mActions.setValue(mMonster.getActionDescriptions());
+ mArmorClass.setValue(mMonster.getArmorClass());
+ mChallenge.setValue(mMonster.getChallengeRatingDescription());
+ mCharisma.setValue(monster.getCharismaDescription());
+ mConditionImmunities.setValue(mMonster.getConditionImmunitiesDescription());
+ mConstitution.setValue(monster.getConstitutionDescription());
+ mDamageImmunities.setValue(mMonster.getDamageImmunitiesDescription());
+ mDamageResistances.setValue(mMonster.getDamageResistancesDescription());
+ mDamageVulnerabilities.setValue(mMonster.getDamageVulnerabilitiesDescription());
+ mDexterity.setValue(monster.getDexterityDescription());
+ mHitPoints.setValue(mMonster.getHitPoints());
+ mIntelligence.setValue(monster.getIntelligenceDescription());
+ mLairActions.setValue(mMonster.getLairActionDescriptions());
+ mLanguages.setValue(mMonster.getLanguagesDescription());
+ mLegendaryActions.setValue(mMonster.getLegendaryActionDescriptions());
+ mMeta.setValue(mMonster.getMeta());
+ mMonsterId.setValue(mMonster.id);
+ mName.setValue(mMonster.name);
+ mReactions.setValue(monster.getReactionDescriptions());
+ mRegionalEffects.setValue(monster.getRegionalActionDescriptions());
+ mSavingThrows.setValue(monster.getSavingThrowsDescription());
+ mSenses.setValue(monster.getSensesDescription());
+ mSkills.setValue(monster.getSkillsDescription());
+ mSpeed.setValue(mMonster.getSpeedText());
+ mStrength.setValue(monster.getStrengthDescription());
+ mWisdom.setValue(monster.getWisdomDescription());
+ }
+}
diff --git a/app/src/main/res/navigation/mobile_navigation.xml b/app/src/main/res/navigation/mobile_navigation.xml
index 893f689..71cb792 100644
--- a/app/src/main/res/navigation/mobile_navigation.xml
+++ b/app/src/main/res/navigation/mobile_navigation.xml
@@ -228,4 +228,21 @@
app:argType="string" />
+
+
+
+
+
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index e0e919e..dc5d036 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -121,6 +121,7 @@
Senses
Skill
Skills
+ Import Monster
Library
Search
WIS