Makes monster importing a fragment in the main activity.
Makes the edit action work when editing an imported monster.
This commit is contained in:
@@ -5,19 +5,22 @@
|
|||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
|
android:name=".MonsterCardsApplication"
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:name=".MonsterCardsApplication"
|
|
||||||
android:roundIcon="@mipmap/ic_launcher_round"
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/AppTheme">
|
android:theme="@style/AppTheme">
|
||||||
<activity
|
<activity
|
||||||
android:name=".ImportMonsterActivity"
|
android:name=".MainActivity"
|
||||||
android:icon="@mipmap/ic_launcher"
|
android:label="@string/app_name"
|
||||||
android:label="Import Monster"
|
android:launchMode="singleTask">
|
||||||
android:launchMode="singleTask"
|
<intent-filter>
|
||||||
android:priority="50">
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
|
||||||
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
|
</intent-filter>
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.SEND" />
|
<action android:name="android.intent.action.SEND" />
|
||||||
|
|
||||||
@@ -45,15 +48,8 @@
|
|||||||
android:mimeType="text/plain"
|
android:mimeType="text/plain"
|
||||||
android:scheme="file" />
|
android:scheme="file" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
|
||||||
<activity
|
|
||||||
android:name=".MainActivity"
|
|
||||||
android:label="@string/app_name">
|
|
||||||
<intent-filter>
|
|
||||||
<action android:name="android.intent.action.MAIN" />
|
|
||||||
|
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<nav-graph android:value="@navigation/mobile_navigation" />
|
||||||
</intent-filter>
|
|
||||||
</activity>
|
</activity>
|
||||||
<activity
|
<activity
|
||||||
android:name="com.facebook.flipper.android.diagnostics.FlipperDiagnosticActivity"
|
android:name="com.facebook.flipper.android.diagnostics.FlipperDiagnosticActivity"
|
||||||
|
|||||||
@@ -1,18 +1,29 @@
|
|||||||
package com.majinnaibu.monstercards;
|
package com.majinnaibu.monstercards;
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
import androidx.navigation.NavController;
|
import androidx.navigation.NavController;
|
||||||
|
import androidx.navigation.NavDirections;
|
||||||
import androidx.navigation.fragment.NavHostFragment;
|
import androidx.navigation.fragment.NavHostFragment;
|
||||||
import androidx.navigation.ui.AppBarConfiguration;
|
import androidx.navigation.ui.AppBarConfiguration;
|
||||||
import androidx.navigation.ui.NavigationUI;
|
import androidx.navigation.ui.NavigationUI;
|
||||||
|
|
||||||
import com.google.android.material.bottomnavigation.BottomNavigationView;
|
import com.google.android.material.bottomnavigation.BottomNavigationView;
|
||||||
|
import com.majinnaibu.monstercards.helpers.StringHelper;
|
||||||
import com.majinnaibu.monstercards.init.AppCenterInitializer;
|
import com.majinnaibu.monstercards.init.AppCenterInitializer;
|
||||||
import com.majinnaibu.monstercards.init.FlipperInitializer;
|
import com.majinnaibu.monstercards.init.FlipperInitializer;
|
||||||
|
import com.majinnaibu.monstercards.utils.Logger;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
public class MainActivity extends AppCompatActivity {
|
public class MainActivity extends AppCompatActivity {
|
||||||
|
|
||||||
@@ -48,5 +59,59 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
});
|
});
|
||||||
NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
|
NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
|
||||||
NavigationUI.setupWithNavController(navView, navController);
|
NavigationUI.setupWithNavController(navView, navController);
|
||||||
|
onNewIntent(getIntent());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onNewIntent(Intent intent) {
|
||||||
|
super.onNewIntent(intent);
|
||||||
|
|
||||||
|
String json = readMonsterJSONFromIntent(intent);
|
||||||
|
if (!StringHelper.isNullOrEmpty(json)) {
|
||||||
|
NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.nav_host_fragment);
|
||||||
|
NavController navController = navHostFragment.getNavController();
|
||||||
|
NavDirections action = MobileNavigationDirections.actionGlobalMonsterImportFragment(json);
|
||||||
|
navController.navigate(action);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String readMonsterJSONFromIntent(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 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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -180,10 +180,6 @@ public class MonsterDetailViewModel extends ViewModel {
|
|||||||
return mMonsterId;
|
return mMonsterId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Monster getMonster() {
|
|
||||||
return mMonster;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMonster(Monster monster) {
|
public void setMonster(Monster monster) {
|
||||||
mMonster = monster;
|
mMonster = monster;
|
||||||
mAbilities.setValue(mMonster.getAbilityDescriptions());
|
mAbilities.setValue(mMonster.getAbilityDescriptions());
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||
package com.majinnaibu.monstercards;
|
package com.majinnaibu.monstercards.ui.monster;
|
||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Context;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.text.Html;
|
import android.text.Html;
|
||||||
import android.text.Spanned;
|
import android.text.Spanned;
|
||||||
import android.util.DisplayMetrics;
|
import android.util.DisplayMetrics;
|
||||||
import android.util.TypedValue;
|
import android.util.TypedValue;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
|
import android.view.MenuInflater;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
@@ -17,126 +18,74 @@ import android.widget.LinearLayout;
|
|||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
|
||||||
import androidx.lifecycle.ViewModelProvider;
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
|
import androidx.navigation.NavController;
|
||||||
|
import androidx.navigation.NavDirections;
|
||||||
|
import androidx.navigation.Navigation;
|
||||||
|
|
||||||
import com.google.android.material.snackbar.Snackbar;
|
import com.google.android.material.snackbar.Snackbar;
|
||||||
|
import com.majinnaibu.monstercards.MonsterCardsApplication;
|
||||||
|
import com.majinnaibu.monstercards.R;
|
||||||
import com.majinnaibu.monstercards.data.MonsterRepository;
|
import com.majinnaibu.monstercards.data.MonsterRepository;
|
||||||
import com.majinnaibu.monstercards.helpers.CommonMarkHelper;
|
import com.majinnaibu.monstercards.helpers.CommonMarkHelper;
|
||||||
import com.majinnaibu.monstercards.helpers.MonsterImportHelper;
|
import com.majinnaibu.monstercards.helpers.MonsterImportHelper;
|
||||||
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.monster.MonsterDetailViewModel;
|
import com.majinnaibu.monstercards.ui.library.LibraryFragmentDirections;
|
||||||
|
import com.majinnaibu.monstercards.ui.shared.MCFragment;
|
||||||
import com.majinnaibu.monstercards.utils.Logger;
|
import com.majinnaibu.monstercards.utils.Logger;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
|
||||||
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.observers.DisposableCompletableObserver;
|
||||||
import io.reactivex.rxjava3.schedulers.Schedulers;
|
import io.reactivex.rxjava3.schedulers.Schedulers;
|
||||||
|
|
||||||
public class ImportMonsterActivity extends AppCompatActivity {
|
public class MonsterImportFragment extends MCFragment {
|
||||||
|
|
||||||
private ViewHolder mHolder;
|
private ViewHolder mHolder;
|
||||||
|
private MonsterImportViewModel mViewModel;
|
||||||
|
|
||||||
private MonsterDetailViewModel mViewModel;
|
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||||
|
Logger.logDebug("MonsterCards: loading monster for import");
|
||||||
@Override
|
Bundle arguments = getArguments();
|
||||||
protected void onCreate(@Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) {
|
assert arguments != null;
|
||||||
super.onCreate(savedInstanceState);
|
String json = MonsterImportFragmentArgs.fromBundle(arguments).getJson();
|
||||||
setContentView(R.layout.fragment_monster);
|
setHasOptionsMenu(true);
|
||||||
mHolder = new ViewHolder(findViewById(android.R.id.content));
|
Monster monster = MonsterImportHelper.fromJSON(json);
|
||||||
mViewModel = new ViewModelProvider(this).get(MonsterDetailViewModel.class);
|
mViewModel = new ViewModelProvider(this).get(MonsterImportViewModel.class);
|
||||||
|
|
||||||
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);
|
mViewModel.setMonster(monster);
|
||||||
}
|
View root = inflater.inflate(R.layout.fragment_monster, container, false);
|
||||||
}
|
mHolder = new ViewHolder(root);
|
||||||
|
|
||||||
private Monster readMonsterFromIntent(Intent intent) {
|
mViewModel.getName().observe(getViewLifecycleOwner(), mHolder.name::setText);
|
||||||
String action = intent.getAction();
|
mViewModel.getMeta().observe(getViewLifecycleOwner(), mHolder.meta::setText);
|
||||||
Bundle extras = intent.getExtras();
|
mViewModel.getArmorClass().observe(getViewLifecycleOwner(), armorText -> setupLabeledTextView(mHolder.armorClass, armorText, R.string.label_armor_class));
|
||||||
String type = intent.getType();
|
mViewModel.getHitPoints().observe(getViewLifecycleOwner(), hitPoints -> setupLabeledTextView(mHolder.hitPoints, hitPoints, R.string.label_hit_points));
|
||||||
String json;
|
mViewModel.getSpeed().observe(getViewLifecycleOwner(), speed -> setupLabeledTextView(mHolder.speed, speed, R.string.label_speed));
|
||||||
Uri uri = null;
|
mViewModel.getStrength().observe(getViewLifecycleOwner(), mHolder.strength::setText);
|
||||||
if ("android.intent.action.SEND".equals(action) && "text/plain".equals(type)) {
|
mViewModel.getDexterity().observe(getViewLifecycleOwner(), mHolder.dexterity::setText);
|
||||||
uri = extras.getParcelable("android.intent.extra.STREAM");
|
mViewModel.getConstitution().observe(getViewLifecycleOwner(), mHolder.constitution::setText);
|
||||||
} else if ("android.intent.action.VIEW".equals(action) && ("text/plain".equals(type) || "application/octet-stream".equals(type))) {
|
mViewModel.getIntelligence().observe(getViewLifecycleOwner(), mHolder.intelligence::setText);
|
||||||
uri = intent.getData();
|
mViewModel.getWisdom().observe(getViewLifecycleOwner(), mHolder.wisdom::setText);
|
||||||
} else {
|
mViewModel.getCharisma().observe(getViewLifecycleOwner(), mHolder.charisma::setText);
|
||||||
Logger.logError(String.format("unexpected launch configuration action: %s, type: %s, uri: %s", action, type, uri));
|
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));
|
||||||
if (uri == null) {
|
mViewModel.getDamageVulnerabilities().observe(getViewLifecycleOwner(), damageTypes -> setupOptionalTextView(mHolder.damageVulnerabilities, damageTypes, R.string.label_damage_vulnerabilities));
|
||||||
return null;
|
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));
|
||||||
json = readContentsOfUri(uri);
|
mViewModel.getConditionImmunities().observe(getViewLifecycleOwner(), conditionImmunities -> setupOptionalTextView(mHolder.conditionImmunities, conditionImmunities, R.string.label_condition_immunities));
|
||||||
if (StringHelper.isNullOrEmpty(json)) {
|
mViewModel.getSenses().observe(getViewLifecycleOwner(), senses -> setupOptionalTextView(mHolder.senses, senses, R.string.label_senses));
|
||||||
return null;
|
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));
|
||||||
return MonsterImportHelper.fromJSON(json);
|
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));
|
||||||
|
|
||||||
private String readContentsOfUri(Uri uri) {
|
return root;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupLabeledTextView(TextView view, String text, int titleId) {
|
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<String> traits, View label, View divider) {
|
private void setupTraitList(@NonNull LinearLayout root, @NonNull List<String> traits, View label, View divider) {
|
||||||
int visibility = traits.size() > 0 ? View.VISIBLE : View.GONE;
|
int visibility = traits.size() > 0 ? View.VISIBLE : View.GONE;
|
||||||
|
Context context = getContext();
|
||||||
DisplayMetrics displayMetrics = null;
|
DisplayMetrics displayMetrics = null;
|
||||||
Resources resources = getResources();
|
if (context != null) {
|
||||||
|
Resources resources = context.getResources();
|
||||||
if (resources != null) {
|
if (resources != null) {
|
||||||
displayMetrics = resources.getDisplayMetrics();
|
displayMetrics = resources.getDisplayMetrics();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
root.removeAllViews();
|
root.removeAllViews();
|
||||||
for (String action : traits) {
|
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: 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
|
// 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)));
|
tvAction.setText(Html.fromHtml(CommonMarkHelper.toHtml(action)));
|
||||||
@@ -193,9 +145,9 @@ public class ImportMonsterActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCreateOptionsMenu(@NonNull Menu menu) {
|
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
|
||||||
getMenuInflater().inflate(R.menu.import_monster, menu);
|
inflater.inflate(R.menu.import_monster, menu);
|
||||||
return true;
|
super.onCreateOptionsMenu(menu, inflater);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -233,7 +185,14 @@ public class ImportMonsterActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void navigateToEditMonster(UUID monsterId) {
|
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 {
|
private static class ViewHolder {
|
||||||
@@ -315,4 +274,5 @@ public class ImportMonsterActivity extends AppCompatActivity {
|
|||||||
regionalEffects_label = root.findViewById(R.id.regionalEffects_label);
|
regionalEffects_label = root.findViewById(R.id.regionalEffects_label);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -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<List<String>> mAbilities;
|
||||||
|
private final MutableLiveData<List<String>> mActions;
|
||||||
|
private final MutableLiveData<String> mArmorClass;
|
||||||
|
private final MutableLiveData<String> mChallenge;
|
||||||
|
private final MutableLiveData<String> mCharisma;
|
||||||
|
private final MutableLiveData<String> mConditionImmunities;
|
||||||
|
private final MutableLiveData<String> mConstitution;
|
||||||
|
private final MutableLiveData<String> mDamageResistances;
|
||||||
|
private final MutableLiveData<String> mDamageImmunities;
|
||||||
|
private final MutableLiveData<String> mDamageVulnerabilities;
|
||||||
|
private final MutableLiveData<String> mDexterity;
|
||||||
|
private final MutableLiveData<String> mHitPoints;
|
||||||
|
private final MutableLiveData<String> mIntelligence;
|
||||||
|
private final MutableLiveData<List<String>> mLairActions;
|
||||||
|
private final MutableLiveData<String> mLanguages;
|
||||||
|
private final MutableLiveData<List<String>> mLegendaryActions;
|
||||||
|
private final MutableLiveData<String> mMeta;
|
||||||
|
private final MutableLiveData<String> mName;
|
||||||
|
private final MutableLiveData<List<String>> mReactions;
|
||||||
|
private final MutableLiveData<List<String>> mRegionalEffects;
|
||||||
|
private final MutableLiveData<String> mSavingThrows;
|
||||||
|
private final MutableLiveData<String> mSenses;
|
||||||
|
private final MutableLiveData<String> mSkills;
|
||||||
|
private final MutableLiveData<String> mSpeed;
|
||||||
|
private final MutableLiveData<String> mStrength;
|
||||||
|
private final MutableLiveData<String> mWisdom;
|
||||||
|
private final MutableLiveData<UUID> 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<List<String>> getAbilities() {
|
||||||
|
return mAbilities;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<List<String>> getActions() {
|
||||||
|
return mActions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<List<String>> getReactions() {
|
||||||
|
return mReactions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<List<String>> getLegendaryActions() {
|
||||||
|
return mLegendaryActions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<List<String>> getLairActions() {
|
||||||
|
return mLairActions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<List<String>> getRegionalEffects() {
|
||||||
|
return mRegionalEffects;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<String> getArmorClass() {
|
||||||
|
return mArmorClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<String> getChallenge() {
|
||||||
|
return mChallenge;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<String> getCharisma() {
|
||||||
|
return mCharisma;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<String> getConditionImmunities() {
|
||||||
|
return mConditionImmunities;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<String> getConstitution() {
|
||||||
|
return mConstitution;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<String> getDamageResistances() {
|
||||||
|
return mDamageResistances;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<String> getDamageImmunities() {
|
||||||
|
return mDamageImmunities;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<String> getDamageVulnerabilities() {
|
||||||
|
return mDamageVulnerabilities;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<String> getDexterity() {
|
||||||
|
return mDexterity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<String> getHitPoints() {
|
||||||
|
return mHitPoints;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<String> getIntelligence() {
|
||||||
|
return mIntelligence;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<String> getLanguages() {
|
||||||
|
return mLanguages;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<String> getMeta() {
|
||||||
|
return mMeta;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<String> getName() {
|
||||||
|
return mName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<String> getSavingThrows() {
|
||||||
|
return mSavingThrows;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<String> getSenses() {
|
||||||
|
return mSenses;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<String> getSkills() {
|
||||||
|
return mSkills;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<String> getSpeed() {
|
||||||
|
return mSpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<String> getStrength() {
|
||||||
|
return mStrength;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<String> getWisdom() {
|
||||||
|
return mWisdom;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<UUID> 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());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -228,4 +228,21 @@
|
|||||||
app:argType="string" />
|
app:argType="string" />
|
||||||
</fragment>
|
</fragment>
|
||||||
</navigation>
|
</navigation>
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/monsterImportFragment"
|
||||||
|
android:name="com.majinnaibu.monstercards.ui.monster.MonsterImportFragment"
|
||||||
|
android:label="@string/title_importMonster"
|
||||||
|
tools:layout="@layout/fragment_monster">
|
||||||
|
<argument
|
||||||
|
android:name="json"
|
||||||
|
app:argType="string" />
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_monsterImportFragment_to_navigation_library"
|
||||||
|
app:destination="@id/navigation_library"
|
||||||
|
app:popUpTo="@id/monsterImportFragment"
|
||||||
|
app:popUpToInclusive="true" />
|
||||||
|
</fragment>
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_global_monsterImportFragment"
|
||||||
|
app:destination="@id/monsterImportFragment" />
|
||||||
</navigation>
|
</navigation>
|
||||||
|
|||||||
@@ -121,6 +121,7 @@
|
|||||||
<string name="title_edit_senses">Senses</string>
|
<string name="title_edit_senses">Senses</string>
|
||||||
<string name="title_edit_skill">Skill</string>
|
<string name="title_edit_skill">Skill</string>
|
||||||
<string name="title_edit_skills">Skills</string>
|
<string name="title_edit_skills">Skills</string>
|
||||||
|
<string name="title_importMonster">Import Monster</string>
|
||||||
<string name="title_library">Library</string>
|
<string name="title_library">Library</string>
|
||||||
<string name="title_search">Search</string>
|
<string name="title_search">Search</string>
|
||||||
<string name="wisdom_abbreviation">WIS</string>
|
<string name="wisdom_abbreviation">WIS</string>
|
||||||
|
|||||||
Reference in New Issue
Block a user