This commit is contained in:
2020-08-31 21:54:31 -07:00
committed by Tom Hicks
parent 985c2fb730
commit 07f81a5f6d
29 changed files with 283 additions and 859 deletions

3
Android/.gitignore vendored
View File

@@ -7,11 +7,8 @@
/.idea/workspace.xml /.idea/workspace.xml
/.idea/navEditor.xml /.idea/navEditor.xml
/.idea/assetWizardSettings.xml /.idea/assetWizardSettings.xml
/.idea/dictionaries
.DS_Store .DS_Store
/build /build
/captures /captures
.externalNativeBuild .externalNativeBuild
.cxx .cxx
/app/debug
/app/release

View File

@@ -1,13 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings"> <component name="GradleSettings">
<option name="linkedExternalProjectsSettings"> <option name="linkedExternalProjectsSettings">
<GradleProjectSettings> <GradleProjectSettings>
<option name="testRunner" value="GRADLE" /> <option name="testRunner" value="PLATFORM" />
<option name="distributionType" value="DEFAULT_WRAPPED" /> <option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" /> <option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="Android Studio java home" /> <option name="gradleJvm" value="1.8" />
<option name="modules"> <option name="modules">
<set> <set>
<option value="$PROJECT_DIR$" /> <option value="$PROJECT_DIR$" />

View File

@@ -21,10 +21,5 @@
<option name="name" value="Google" /> <option name="name" value="Google" />
<option name="url" value="https://dl.google.com/dl/android/maven2/" /> <option name="url" value="https://dl.google.com/dl/android/maven2/" />
</remote-repository> </remote-repository>
<remote-repository>
<option name="id" value="MavenRepo" />
<option name="name" value="MavenRepo" />
<option name="url" value="https://repo.maven.apache.org/maven2/" />
</remote-repository>
</component> </component>
</project> </project>

46
Android/.idea/misc.xml generated
View File

@@ -1,50 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="NullableNotNullManager"> <component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<option name="myDefaultNullable" value="androidx.annotation.Nullable" />
<option name="myDefaultNotNull" value="androidx.annotation.NonNull" />
<option name="myNullables">
<value>
<list size="14">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
<item index="1" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
<item index="2" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
<item index="3" class="java.lang.String" itemvalue="androidx.annotation.Nullable" />
<item index="4" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNullable" />
<item index="5" class="java.lang.String" itemvalue="com.android.annotations.Nullable" />
<item index="6" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
<item index="7" class="java.lang.String" itemvalue="javax.annotation.CheckForNull" />
<item index="8" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.qual.Nullable" />
<item index="9" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NullableDecl" />
<item index="10" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NullableType" />
<item index="11" class="java.lang.String" itemvalue="org.eclipse.jdt.annotation.Nullable" />
<item index="12" class="java.lang.String" itemvalue="io.reactivex.annotations.Nullable" />
<item index="13" class="java.lang.String" itemvalue="io.reactivex.rxjava3.annotations.Nullable" />
</list>
</value>
</option>
<option name="myNotNulls">
<value>
<list size="14">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
<item index="1" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
<item index="2" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
<item index="3" class="java.lang.String" itemvalue="androidx.annotation.NonNull" />
<item index="4" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNonNull" />
<item index="5" class="java.lang.String" itemvalue="com.android.annotations.NonNull" />
<item index="6" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
<item index="7" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.qual.NonNull" />
<item index="8" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NonNullDecl" />
<item index="9" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NonNullType" />
<item index="10" class="java.lang.String" itemvalue="org.eclipse.jdt.annotation.NonNull" />
<item index="11" class="java.lang.String" itemvalue="io.reactivex.annotations.NonNull" />
<item index="12" class="java.lang.String" itemvalue="io.reactivex.rxjava3.annotations.NonNull" />
<item index="13" class="java.lang.String" itemvalue="lombok.NonNull" />
</list>
</value>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_X" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" /> <output url="file://$PROJECT_DIR$/build/classes" />
</component> </component>
<component name="ProjectType"> <component name="ProjectType">

12
Android/.idea/runConfigurations.xml generated Normal file
View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
</set>
</option>
</component>
</project>

View File

@@ -1,105 +1,37 @@
plugins { apply plugin: 'com.android.application'
id 'com.android.application'
id 'androidx.navigation.safeargs'
}
Properties properties = new Properties()
def propertiesFile = project.rootProject.file('local.properties')
if (propertiesFile.exists()) {
properties.load(propertiesFile.newDataInputStream())
}
def appCenterLocalSecret = properties.getProperty('appCenter.localSecret')
def appCenterEnvSecret = System.getenv('APPCENTER_SECRET')
def appCenterSecret = appCenterLocalSecret != null ? appCenterLocalSecret : appCenterEnvSecret != null ? appCenterEnvSecret : ""
android { android {
compileSdkVersion 31 compileSdkVersion 29
buildToolsVersion '30.0.3' buildToolsVersion "29.0.3"
defaultConfig { defaultConfig {
applicationId "com.majinnaibu.monstercards" applicationId "com.majinnaibu.monstercards"
minSdkVersion 22 minSdkVersion 22
targetSdkVersion 31 targetSdkVersion 29
versionCode 1 versionCode 1
versionName "1.0" versionName "1.0"
buildConfigField "String", "APPCENTER_SECRET", "\"${appCenterSecret}\""
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
javaCompileOptions {
annotationProcessorOptions {
arguments += ["room.schemaLocation": "$projectDir/schemas".toString()]
}
}
} }
buildTypes { buildTypes {
release { release {
// Enables code shrinking, obfuscation, and optimization for only minifyEnabled false
// your project's release build type.
minifyEnabled true
// Enables resource shrinking, which is performed by the
// Android Gradle plugin.
shrinkResources true
// Includes the default ProGuard rules files that are packaged with
// the Android Gradle plugin. To learn more, go to the section about
// R8 configuration files.
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
} }
} }
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
buildFeatures {
viewBinding true
}
lintOptions {
checkDependencies true
}
} }
dependencies { dependencies {
// Included libs
implementation fileTree(dir: "libs", include: ["*.jar"]) implementation fileTree(dir: "libs", include: ["*.jar"])
implementation 'androidx.appcompat:appcompat:1.2.0'
// Google implementation 'com.google.android.material:material:1.2.0'
implementation 'androidx.appcompat:appcompat:1.3.1' implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
implementation 'com.google.android.material:material:1.4.0' implementation 'androidx.navigation:navigation-fragment:2.3.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.0' implementation 'androidx.navigation:navigation-ui:2.3.0'
implementation "androidx.navigation:navigation-fragment:2.3.5"
implementation "androidx.navigation:navigation-ui:2.3.5"
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
implementation 'androidx.legacy:legacy-support-v4:1.0.0' testImplementation 'junit:junit:4.12'
implementation 'androidx.recyclerview:recyclerview:1.2.1' androidTestImplementation 'androidx.test.ext:junit:1.1.2'
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1'
// Testing }
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
// Room DB
implementation 'io.reactivex.rxjava3:rxjava:3.1.0'
implementation "io.reactivex.rxjava3:rxandroid:3.0.0"
implementation "androidx.room:room-runtime:2.3.0"
annotationProcessor "androidx.room:room-compiler:2.3.0"
implementation "androidx.room:room-rxjava3:2.3.0"
//testImplementation "androidx.room:room-testing:2.3.0"
// AppCenter
debugImplementation 'com.microsoft.appcenter:appcenter-analytics:4.2.0'
debugImplementation 'com.microsoft.appcenter:appcenter-crashes:4.2.0'
// Flipper
debugImplementation 'com.facebook.flipper:flipper:0.102.0'
debugImplementation "com.facebook.soloader:soloader:0.10.1"
releaseImplementation 'com.facebook.flipper:flipper-noop:0.102.0'
// Other 3rd Party
implementation 'com.atlassian.commonmark:commonmark:0.17.0'
implementation 'com.google.code.gson:gson:2.8.7'
}

View File

@@ -18,15 +18,4 @@
# If you keep the line number information, uncomment this to # If you keep the line number information, uncomment this to
# hide the original source file name. # hide the original source file name.
#-renamesourcefileattribute SourceFile #-renamesourcefileattribute SourceFile
-keep enum com.majinnaibu.monstercards.data.enums.AbilityScore
-keep enum com.majinnaibu.monstercards.data.enums.ProficiencyType
-keep enum com.majinnaibu.monstercards.data.enums.AdvantageType
-keep enum com.majinnaibu.monstercards.data.enums.TraitType
-keep enum com.majinnaibu.monstercards.data.enums.StringType
-keepclassmembers,allowoptimization enum * {
<fields>;
public static **[] values();
public static ** valueOf(java.lang.String);
}

View File

@@ -2,12 +2,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.majinnaibu.monstercards"> package="com.majinnaibu.monstercards">
<uses-permission android:name="android.permission.INTERNET" />
<application <application
android:name=".MonsterCardsApplication"
android:allowBackup="true" android:allowBackup="true"
android:fullBackupOnly="true"
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
android:label="@string/app_name" android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round" android:roundIcon="@mipmap/ic_launcher_round"
@@ -15,47 +11,13 @@
android:theme="@style/AppTheme"> android:theme="@style/AppTheme">
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:exported="true" android:label="@string/app_name">
android:label="@string/app_name"
android:launchMode="singleTask">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.EDIT" />
<action android:name="android.intent.action.PICK" />
<action android:name="android.intent.action.INSERT" />
<action android:name="android.intent.action.INSERT_OR_EDIT" />
<category android:name="android.intent.category.ALTERNATIVE" />
<category android:name="android.intent.category.SELECTED_ALTERNATIVE" />
<category android:name="android.intent.category.DEFAULT" />
<data
android:mimeType="text/plain"
android:scheme="content" />
<data
android:mimeType="application/octet-stream"
android:scheme="content" />
<data
android:mimeType="text/plain"
android:scheme="file" />
</intent-filter>
<nav-graph android:value="@navigation/mobile_navigation" />
</activity> </activity>
<activity
android:name="com.facebook.flipper.android.diagnostics.FlipperDiagnosticActivity"
android:exported="true" />
</application> </application>
</manifest> </manifest>

View File

@@ -1,156 +1,30 @@
package com.majinnaibu.monstercards; package com.majinnaibu.monstercards;
import android.content.ContentResolver;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.provider.DocumentsContract;
import android.view.MenuItem;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.navigation.NavController;
import androidx.navigation.NavDirections;
import androidx.navigation.fragment.NavHostFragment;
import androidx.navigation.ui.AppBarConfiguration;
import androidx.navigation.ui.NavigationUI;
import com.google.android.material.bottomnavigation.BottomNavigationView; import com.google.android.material.bottomnavigation.BottomNavigationView;
import com.majinnaibu.monstercards.helpers.StringHelper;
import com.majinnaibu.monstercards.init.AppCenterInitializer;
import com.majinnaibu.monstercards.init.FlipperInitializer;
import com.majinnaibu.monstercards.utils.Logger;
import java.io.BufferedReader; import androidx.appcompat.app.AppCompatActivity;
import java.io.FileNotFoundException; import androidx.navigation.NavController;
import java.io.IOException; import androidx.navigation.Navigation;
import java.io.InputStream; import androidx.navigation.ui.AppBarConfiguration;
import java.io.InputStreamReader; import androidx.navigation.ui.NavigationUI;
import java.util.Objects;
public class MainActivity extends AppCompatActivity { public class MainActivity extends AppCompatActivity {
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
if (item.getItemId() == android.R.id.home) {
getOnBackPressedDispatcher().onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
@SuppressWarnings("ConstantConditions")
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
AppCenterInitializer.init(getApplication());
setContentView(R.layout.activity_main); setContentView(R.layout.activity_main);
BottomNavigationView navView = findViewById(R.id.nav_view); BottomNavigationView navView = findViewById(R.id.nav_view);
// Passing each menu ID as a set of Ids because each // Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations. // menu should be considered as top level destinations.
AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder( AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder(
R.id.navigation_search, R.id.navigation_home, R.id.navigation_dashboard, R.id.navigation_notifications)
R.id.navigation_dashboard,
R.id.navigation_collections,
R.id.navigation_library)
.build(); .build();
NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.nav_host_fragment); NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
NavController navController = navHostFragment.getNavController();
navController.addOnDestinationChangedListener(FlipperInitializer::sendNavigationEvent);
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 = Objects.requireNonNull((NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.nav_host_fragment));
NavController navController = navHostFragment.getNavController();
NavDirections action = MobileNavigationDirections.actionGlobalMonsterImportFragment(json);
navController.navigate(action);
}
}
@Nullable
private String readMonsterJSONFromIntent(@NonNull Intent intent) {
String action = intent.getAction();
Bundle extras = intent.getExtras();
String type = intent.getType();
String json;
Uri uri = null;
if ("android.intent.action.MAIN".equals(action)) {
return null;
} else 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", action, type));
}
if (uri == null) {
return null;
}
json = readContentsOfUri(uri);
if (StringHelper.isNullOrEmpty(json)) {
return null;
}
return json;
}
@Nullable
private String readContentsOfUri(Uri uri) {
StringBuilder builder = new StringBuilder();
try (
InputStream inputStream = 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();
}
private boolean isVirtualFile(Uri uri) {
if (!DocumentsContract.isDocumentUri(this, uri)) {
return false;
}
Cursor cursor = getContentResolver().query(
uri,
new String[]{DocumentsContract.Document.COLUMN_FLAGS},
null, null, null);
int flags = 0;
if (cursor.moveToFirst()) {
flags = cursor.getInt(0);
}
cursor.close();
return (flags & DocumentsContract.Document.FLAG_VIRTUAL_DOCUMENT) != 0;
}
private InputStream openInputStream(Uri uri) throws IOException {
ContentResolver resolver = getContentResolver();
if (isVirtualFile(uri)) {
String[] openableMimeTypes = resolver.getStreamTypes(uri, "*/*");
if (openableMimeTypes == null || openableMimeTypes.length <= 0) {
throw new FileNotFoundException();
}
return resolver.openTypedAssetFileDescriptor(uri, openableMimeTypes[0], null).createInputStream();
} else {
return resolver.openInputStream(uri);
}
}
}

View File

@@ -1,83 +1,35 @@
package com.majinnaibu.monstercards.ui.dashboard; package com.majinnaibu.monstercards.ui.dashboard;
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;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.lifecycle.LiveData; import androidx.annotation.Nullable;
import androidx.lifecycle.ViewModelProvider; import androidx.fragment.app.Fragment;
import androidx.navigation.NavDirections; import androidx.lifecycle.Observer;
import androidx.navigation.Navigation; import androidx.lifecycle.ViewModelProviders;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.majinnaibu.monstercards.R; import com.majinnaibu.monstercards.R;
import com.majinnaibu.monstercards.models.Monster;
import com.majinnaibu.monstercards.ui.shared.MCFragment;
import com.majinnaibu.monstercards.utils.Logger;
import java.util.List; public class DashboardFragment extends Fragment {
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; private DashboardViewModel dashboardViewModel;
import io.reactivex.rxjava3.schedulers.Schedulers;
public class DashboardFragment extends MCFragment {
private DashboardViewModel mViewModel;
private ViewHolder mHolder;
private DashboardRecyclerViewAdapter mAdapter;
public View onCreateView(@NonNull LayoutInflater inflater, public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) { ViewGroup container, Bundle savedInstanceState) {
mViewModel = new ViewModelProvider(this).get(DashboardViewModel.class); dashboardViewModel =
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);
mHolder = new ViewHolder(root); final TextView textView = root.findViewById(R.id.text_dashboard);
dashboardViewModel.getText().observe(getViewLifecycleOwner(), new Observer<String>() {
setupRecyclerView(mHolder.list); @Override
public void onChanged(@Nullable String s) {
// TODO: subscribe better textView.setText(s);
getMonsterRepository()
.getMonsters()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(monsters -> mViewModel.setMonsters(monsters));
return root;
}
private void setupRecyclerView(@NonNull RecyclerView recyclerView) {
int columnCount = Math.max(1, getResources().getConfiguration().screenWidthDp / 396);
Context context = requireContext();
GridLayoutManager layoutManager = new GridLayoutManager(context, columnCount);
recyclerView.setLayoutManager(layoutManager);
LiveData<List<Monster>> monsterData = mViewModel.getMonsters();
mAdapter = new DashboardRecyclerViewAdapter(monster -> {
if (monster != null) {
navigateToMonsterDetail(monster);
} else {
Logger.logError("Can't navigate to MonsterDetailFragment with a null monster");
} }
}); });
if (monsterData != null) { return root;
monsterData.observe(getViewLifecycleOwner(), monsters -> mAdapter.submitList(monsters));
}
recyclerView.setAdapter(mAdapter);
} }
}
private void navigateToMonsterDetail(Monster monster) {
NavDirections action = DashboardFragmentDirections.actionNavigationDashboardToNavigationMonster(monster.id.toString());
Navigation.findNavController(requireView()).navigate(action);
}
private static class ViewHolder {
final RecyclerView list;
ViewHolder(View root) {
list = root.findViewById(R.id.list);
}
}
}

View File

@@ -4,23 +4,16 @@ import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel; import androidx.lifecycle.ViewModel;
import com.majinnaibu.monstercards.models.Monster;
import java.util.ArrayList;
import java.util.List;
public class DashboardViewModel extends ViewModel { public class DashboardViewModel extends ViewModel {
private final MutableLiveData<List<Monster>> mMonsters;
private MutableLiveData<String> mText;
public DashboardViewModel() { public DashboardViewModel() {
mMonsters = new MutableLiveData<>(new ArrayList<>()); mText = new MutableLiveData<>();
mText.setValue("This is dashboard fragment");
} }
public LiveData<List<Monster>> getMonsters() { public LiveData<String> getText() {
return mMonsters; return mText;
} }
}
public void setMonsters(List<Monster> monsters) {
mMonsters.setValue(monsters);
}
}

View File

@@ -0,0 +1,35 @@
package com.majinnaibu.monstercards.ui.home;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
import com.majinnaibu.monstercards.R;
public class HomeFragment extends Fragment {
private HomeViewModel homeViewModel;
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
homeViewModel =
ViewModelProviders.of(this).get(HomeViewModel.class);
View root = inflater.inflate(R.layout.fragment_home, container, false);
final TextView textView = root.findViewById(R.id.text_home);
homeViewModel.getText().observe(getViewLifecycleOwner(), new Observer<String>() {
@Override
public void onChanged(@Nullable String s) {
textView.setText(s);
}
});
return root;
}
}

View File

@@ -0,0 +1,19 @@
package com.majinnaibu.monstercards.ui.home;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
public class HomeViewModel extends ViewModel {
private MutableLiveData<String> mText;
public HomeViewModel() {
mText = new MutableLiveData<>();
mText.setValue("This is home fragment");
}
public LiveData<String> getText() {
return mText;
}
}

View File

@@ -0,0 +1,35 @@
package com.majinnaibu.monstercards.ui.notifications;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
import com.majinnaibu.monstercards.R;
public class NotificationsFragment extends Fragment {
private NotificationsViewModel notificationsViewModel;
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
notificationsViewModel =
ViewModelProviders.of(this).get(NotificationsViewModel.class);
View root = inflater.inflate(R.layout.fragment_notifications, container, false);
final TextView textView = root.findViewById(R.id.text_notifications);
notificationsViewModel.getText().observe(getViewLifecycleOwner(), new Observer<String>() {
@Override
public void onChanged(@Nullable String s) {
textView.setText(s);
}
});
return root;
}
}

View File

@@ -0,0 +1,19 @@
package com.majinnaibu.monstercards.ui.notifications;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
public class NotificationsViewModel extends ViewModel {
private MutableLiveData<String> mText;
public NotificationsViewModel() {
mText = new MutableLiveData<>();
mText.setValue("This is notifications fragment");
}
public LiveData<String> getText() {
return mText;
}
}

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M10,20v-6h4v6h5v-8h3L12,3 2,12h3v8z" />
</vector>

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M12,22c1.1,0 2,-0.9 2,-2h-4c0,1.1 0.89,2 2,2zM18,16v-5c0,-3.07 -1.64,-5.64 -4.5,-6.32L13.5,4c0,-0.83 -0.67,-1.5 -1.5,-1.5s-1.5,0.67 -1.5,1.5v0.68C7.63,5.36 6,7.92 6,11v5l-2,2v1h16v-1l-2,-2z" />
</vector>

View File

@@ -3,7 +3,8 @@
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/container" android:id="@+id/container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent"
android:paddingTop="?attr/actionBarSize">
<com.google.android.material.bottomnavigation.BottomNavigationView <com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/nav_view" android:id="@+id/nav_view"
@@ -17,19 +18,16 @@
app:layout_constraintRight_toRightOf="parent" app:layout_constraintRight_toRightOf="parent"
app:menu="@menu/bottom_nav_menu" /> app:menu="@menu/bottom_nav_menu" />
<androidx.fragment.app.FragmentContainerView <fragment
android:id="@+id/nav_host_fragment" android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment" android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp" android:layout_width="match_parent"
android:layout_height="0dp" android:layout_height="match_parent"
app:defaultNavHost="true" app:defaultNavHost="true"
app:layout_constraintBottom_toTopOf="@id/nav_view" app:layout_constraintBottom_toTopOf="@id/nav_view"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0"
app:navGraph="@navigation/mobile_navigation" /> app:navGraph="@navigation/mobile_navigation" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -6,18 +6,17 @@
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context=".ui.dashboard.DashboardFragment"> tools:context=".ui.dashboard.DashboardFragment">
<androidx.recyclerview.widget.RecyclerView <TextView
android:id="@+id/list" android:id="@+id/text_dashboard"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="wrap_content"
android:clipToPadding="false" android:layout_marginStart="8dp"
android:divider="?android:attr/dividerVertical" android:layout_marginTop="8dp"
android:dividerPadding="@dimen/text_margin" android:layout_marginEnd="8dp"
android:padding="@dimen/padding_normal" android:textAlignment="center"
app:layoutManager="LinearLayoutManager" android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent" />
tools:listitem="@layout/card_monster" /> </androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.home.HomeFragment">
<TextView
android:id="@+id/text_home"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:textAlignment="center"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.notifications.NotificationsFragment">
<TextView
android:id="@+id/text_notifications"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:textAlignment="center"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -2,9 +2,9 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android"> <menu xmlns:android="http://schemas.android.com/apk/res/android">
<item <item
android:id="@+id/navigation_search" android:id="@+id/navigation_home"
android:icon="@drawable/ic_search_black_24dp" android:icon="@drawable/ic_home_black_24dp"
android:title="@string/title_search" /> android:title="@string/title_home" />
<item <item
android:id="@+id/navigation_dashboard" android:id="@+id/navigation_dashboard"
@@ -12,13 +12,8 @@
android:title="@string/title_dashboard" /> android:title="@string/title_dashboard" />
<item <item
android:id="@+id/navigation_collections" android:id="@+id/navigation_notifications"
android:icon="@drawable/ic_collections_black_24dp" android:icon="@drawable/ic_notifications_black_24dp"
android:title="@string/title_collections" /> android:title="@string/title_notifications" />
<item
android:id="@+id/navigation_library"
android:icon="@drawable/ic_library_black_24dp"
android:title="@string/title_library" />
</menu> </menu>

View File

@@ -3,242 +3,23 @@
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/mobile_navigation" android:id="@+id/mobile_navigation"
app:startDestination="@+id/navigation_dashboard"> app:startDestination="@+id/navigation_home">
<fragment <fragment
android:id="@+id/navigation_search" android:id="@+id/navigation_home"
android:name="com.majinnaibu.monstercards.ui.search.SearchFragment" android:name="com.majinnaibu.monstercards.ui.home.HomeFragment"
android:label="@string/title_search" android:label="@string/title_home"
tools:layout="@layout/fragment_search"> tools:layout="@layout/fragment_home" />
<action
android:id="@+id/action_navigation_search_to_navigation_monster"
app:destination="@id/navigation_monster" />
</fragment>
<fragment <fragment
android:id="@+id/navigation_dashboard" android:id="@+id/navigation_dashboard"
android:name="com.majinnaibu.monstercards.ui.dashboard.DashboardFragment" android:name="com.majinnaibu.monstercards.ui.dashboard.DashboardFragment"
android:label="@string/title_dashboard" android:label="@string/title_dashboard"
tools:layout="@layout/fragment_dashboard"> tools:layout="@layout/fragment_dashboard" />
<action
android:id="@+id/action_navigation_dashboard_to_navigation_monster"
app:destination="@id/navigation_monster" />
</fragment>
<fragment
android:id="@+id/navigation_collections"
android:name="com.majinnaibu.monstercards.ui.collections.CollectionsFragment"
android:label="@string/title_collections"
tools:layout="@layout/fragment_collections">
<action
android:id="@+id/action_navigation_collections_to_navigation_monster"
app:destination="@id/navigation_monster" />
</fragment>
<fragment
android:id="@+id/navigation_library"
android:name="com.majinnaibu.monstercards.ui.library.LibraryFragment"
android:label="@string/title_library"
tools:layout="@layout/fragment_library">
<action
android:id="@+id/action_navigation_library_to_navigation_monster"
app:destination="@id/navigation_monster" />
</fragment>
<fragment
android:id="@+id/navigation_monster"
android:name="com.majinnaibu.monstercards.ui.monster.MonsterDetailFragment"
android:label="@string/title_monsterDetails"
tools:layout="@layout/fragment_monster">
<argument
android:name="monster_id"
app:argType="string" />
<action
android:id="@+id/action_navigation_monster_to_editMonsterFragment"
app:destination="@id/edit_monster_navigation" />
</fragment>
<navigation
android:id="@+id/edit_monster_navigation"
app:startDestination="@id/editMonsterFragment">
<argument
android:name="monster_id"
app:argType="string" />
<fragment
android:id="@+id/editMonsterFragment"
android:name="com.majinnaibu.monstercards.ui.editmonster.EditMonsterFragment"
android:label="@string/title_editMonster"
tools:layout="@layout/fragment_edit_monster">
<argument
android:name="monster_id"
app:argType="string" />
<action
android:id="@+id/action_editMonsterFragment_to_editBasicInfoFragment"
app:destination="@id/editBasicInfoFragment" />
<action
android:id="@+id/action_editMonsterFragment_to_editArmorFragment"
app:destination="@id/editArmorFragment" />
<action
android:id="@+id/action_editMonsterFragment_to_editSpeedFragment"
app:destination="@id/editSpeedFragment" />
<action
android:id="@+id/action_editMonsterFragment_to_editAbilityScoresFragment"
app:destination="@id/editAbilityScoresFragment" />
<action
android:id="@+id/action_editMonsterFragment_to_editSavingThrowsFragment"
app:destination="@id/editSavingThrowsFragment" />
<action
android:id="@+id/action_editMonsterFragment_to_editChallengeRatingFragment"
app:destination="@id/editChallengeRatingFragment" />
<action
android:id="@+id/action_editMonsterFragment_to_editSkillsFragment"
app:destination="@id/editSkillsFragment" />
<action
android:id="@+id/action_editMonsterFragment_to_editLanguagesFragment"
app:destination="@id/editLanguagesFragment" />
<action
android:id="@+id/action_editMonsterFragment_to_editTraitListFragment"
app:destination="@id/editTraitListFragment" />
<action
android:id="@+id/action_editMonsterFragment_to_editStringsFragment"
app:destination="@id/editStringsFragment" />
</fragment>
<fragment
android:id="@+id/editBasicInfoFragment"
android:name="com.majinnaibu.monstercards.ui.editmonster.EditBasicInfoFragment"
android:label="@string/title_editBasicInfo"
tools:layout="@layout/fragment_edit_basic_info" />
<fragment
android:id="@+id/editArmorFragment"
android:name="com.majinnaibu.monstercards.ui.editmonster.EditArmorFragment"
android:label="@string/title_editArmor"
tools:layout="@layout/fragment_edit_armor" />
<fragment
android:id="@+id/editSpeedFragment"
android:name="com.majinnaibu.monstercards.ui.editmonster.EditSpeedFragment"
android:label="@string/title_editSpeed"
tools:layout="@layout/fragment_edit_speed" />
<fragment
android:id="@+id/editAbilityScoresFragment"
android:name="com.majinnaibu.monstercards.ui.editmonster.EditAbilityScoresFragment"
android:label="@string/title_editAbilityScores" />
<fragment
android:id="@+id/editSavingThrowsFragment"
android:name="com.majinnaibu.monstercards.ui.editmonster.EditSavingThrowsFragment"
android:label="@string/title_editSavingThrows"
tools:layout="@layout/fragment_edit_saving_throws" />
<fragment
android:id="@+id/editChallengeRatingFragment"
android:name="com.majinnaibu.monstercards.ui.editmonster.EditChallengeRatingFragment"
android:label="@string/title_editChallengeRating"
tools:layout="@layout/fragment_edit_challenge_rating" />
<fragment
android:id="@+id/editSkillsFragment"
android:name="com.majinnaibu.monstercards.ui.editmonster.EditSkillsFragment"
android:label="@string/title_editSkills"
tools:layout="@layout/fragment_edit_skills_list">
<action
android:id="@+id/action_editSkillsFragment_to_editSkillFragment"
app:destination="@id/editSkillFragment" />
</fragment>
<fragment
android:id="@+id/editSkillFragment"
android:name="com.majinnaibu.monstercards.ui.editmonster.EditSkillFragment"
android:label="@string/title_editSkill"
tools:layout="@layout/fragment_edit_skill">
<argument
android:name="name"
app:argType="string" />
<argument
android:name="abilityScore"
app:argType="com.majinnaibu.monstercards.data.enums.AbilityScore" />
<argument
android:name="proficiency"
app:argType="com.majinnaibu.monstercards.data.enums.ProficiencyType" />
<argument
android:name="advantage"
app:argType="com.majinnaibu.monstercards.data.enums.AdvantageType" />
</fragment>
<fragment
android:id="@+id/editLanguagesFragment"
android:name="com.majinnaibu.monstercards.ui.editmonster.EditLanguagesFragment"
android:label="@string/title_editLanguages"
tools:layout="@layout/fragment_edit_languages_list">
<action
android:id="@+id/action_editLanguagesFragment_to_editLanguageFragment"
app:destination="@id/editLanguageFragment" />
</fragment>
<fragment
android:id="@+id/editLanguageFragment"
android:name="com.majinnaibu.monstercards.ui.editmonster.EditLanguageFragment"
android:label="@string/title_editLanguage"
tools:layout="@layout/fragment_edit_language">
<argument
android:name="name"
app:argType="string" />
<argument
android:name="canSpeak"
app:argType="boolean" />
</fragment>
<fragment
android:id="@+id/editTraitFragment"
android:name="com.majinnaibu.monstercards.ui.editmonster.EditTraitFragment"
android:label="@string/title_editTrait">
<argument
android:name="description"
app:argType="string" />
<argument
android:name="name"
app:argType="string" />
<argument
android:name="traitType"
app:argType="com.majinnaibu.monstercards.data.enums.TraitType" />
</fragment>
<fragment
android:id="@+id/editTraitListFragment"
android:name="com.majinnaibu.monstercards.ui.editmonster.EditTraitsFragment"
android:label="@string/title_editTraits">
<action
android:id="@+id/action_editTraitListFragment_to_editTraitFragment"
app:destination="@id/editTraitFragment" />
<argument
android:name="traitType"
app:argType="com.majinnaibu.monstercards.data.enums.TraitType" />
</fragment>
<fragment
android:id="@+id/editStringsFragment"
android:name="com.majinnaibu.monstercards.ui.editmonster.EditStringsFragment"
android:label="EditStringsFragment">
<action
android:id="@+id/action_editStringsFragment_to_editStringFragment"
app:destination="@id/editStringFragment" />
<argument
android:name="stringType"
app:argType="com.majinnaibu.monstercards.data.enums.StringType" />
</fragment>
<fragment
android:id="@+id/editStringFragment"
android:name="com.majinnaibu.monstercards.ui.editmonster.EditStringFragment"
android:label="@string/title_editString">
<argument
android:name="stringType"
app:argType="com.majinnaibu.monstercards.data.enums.StringType" />
<argument
android:name="value"
app:argType="string" />
</fragment>
</navigation>
<fragment <fragment
android:id="@+id/monsterImportFragment" android:id="@+id/navigation_notifications"
android:name="com.majinnaibu.monstercards.ui.monster.MonsterImportFragment" android:name="com.majinnaibu.monstercards.ui.notifications.NotificationsFragment"
android:label="@string/title_importMonster" android:label="@string/title_notifications"
tools:layout="@layout/fragment_monster"> tools:layout="@layout/fragment_notifications" />
<argument </navigation>
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>

View File

@@ -1,26 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<!-- From palette here https://material.io/resources/color/#!/?view.left=1&view.right=1&primary.color=9b2818&secondary.color=ea7e00 --> <color name="colorPrimary">#6200EE</color>
<color name="colorPrimary">#9b2818</color> <color name="colorPrimaryDark">#3700B3</color>
<color name="colorPrimaryLight">#d25941</color> <color name="colorAccent">#03DAC5</color>
<color name="colorPrimaryDark">#660000</color> </resources>
<color name="colorSecondary">#ea7e00</color>
<color name="colorSecondaryLight">#ffae41</color>
<color name="colorSecondaryDark">#b15000</color>
<color name="colorOnPrimary">#ffffff</color>
<color name="colorOnSecondary">#000000</color>
<color name="colorOnLight">#ffffff</color>
<color name="colorOnDark">#000000</color>
<color name="colorAccent">#995500</color>
<!-- fruit system colors -->
<color name="red">#FF3B30</color>
<color name="orange">#FF9500</color>
<color name="yellow">#FFCC00</color>
<color name="green">#4CD964</color>
<color name="tealBlue">#5AC8FA</color>
<color name="blue">#007AFF</color>
<color name="purple">#5855D6</color>
<color name="pink">#FF2D55</color>
</resources>

View File

@@ -1,22 +1,5 @@
<resources> <resources>
<!-- Default screen margins, per the Android Design guidelines. --> <!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="action_card_description_text_size">10sp</dimen> <dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="action_card_height">80dp</dimen> <dimen name="activity_vertical_margin">16dp</dimen>
<dimen name="action_card_name_text_size">14sp</dimen> </resources>
<dimen name="corner_radius">4dp</dimen>
<dimen name="fab_margin">16dp</dimen>
<dimen name="icon_size">40dp</dimen>
<dimen name="monster_card_meta_text_size">12sp</dimen>
<dimen name="monster_card_name_text_size">20sp</dimen>
<dimen name="monster_tile_meta_text_size">10sp</dimen>
<dimen name="monster_tile_name_text_size">16sp</dimen>
<dimen name="padding_huge">32dp</dimen>
<dimen name="padding_large">16dp</dimen>
<dimen name="padding_normal">8dp</dimen>
<dimen name="padding_small">4dp</dimen>
<dimen name="text_h4_size">20sp</dimen>
<dimen name="text_icon_border_padding">2dp</dimen>
<dimen name="text_icon_size">16sp</dimen>
<dimen name="text_icon_tiny">8sp</dimen>
<dimen name="text_margin">16dp</dimen>
</resources>

View File

@@ -1,140 +1,6 @@
<resources> <resources>
<string name="action_add_ability">Add Ability</string>
<string name="action_add_condition_immunity">Add Condition</string>
<string name="action_add_damage_type">Add Damage Type</string>
<string name="action_add_item">Add Item</string>
<string name="action_add_language">Add Language</string>
<string name="action_add_monster">Add monster</string>
<string name="action_add_sense">Add Sense</string>
<string name="action_add_skill">Add Skill</string>
<string name="action_add_trait">Add Trait</string>
<string name="action_edit">Edit</string>
<string name="action_import_monster">Import Monster</string>
<string name="app_name">MonsterCards</string> <string name="app_name">MonsterCards</string>
<string name="charisma_abbreviation">CHA</string> <string name="title_home">Home</string>
<string name="constitution_abbreviation">CON</string>
<string name="default_monster_name">Unnamed Monster</string>
<string name="dexterity_abbreviation">DEX</string>
<string name="format_distance_in_feet">%d ft.</string>
<string name="intelligence_abbreviation">INT</string>
<string name="label_ability_scores">Ability Scores</string>
<string name="label_abilities">Abilities</string>
<string name="label_actions">Actions</string>
<string name="label_advantage">Advantage</string>
<string name="label_advantage_advantage">Advantage</string>
<string name="label_advantage_disadvantage">Disadvantage</string>
<string name="label_advantage_none">None</string>
<string name="label_alignment">Alignment</string>
<string name="label_armor">Armor</string>
<string name="label_armor_class">Armor Class</string>
<string name="label_armorClass_icon">AC</string>
<string name="label_base_speed">Base Speed</string>
<string name="label_basic_info">Basic Info</string>
<string name="label_burrow_speed">Burrow Speed</string>
<string name="label_can_hover">Can Hover</string>
<string name="label_can_speak_language">Can Speak</string>
<string name="label_challenge_rating">Challenge Rating</string>
<string name="label_challenge_rating_with_value">CR %s</string>
<string name="label_challengeRating_icon">CR</string>
<string name="label_charisma">Charisma</string>
<string name="label_climb_speed">Climb Speed</string>
<string name="label_condition_immunities">Condition Immunities</string>
<string name="label_constitution">Constitution</string>
<string name="label_custom_armor">Custom Armor</string>
<string name="label_custom_challenge_rating_description">Custom CR</string>
<string name="label_custom_hp">Custom HP</string>
<string name="label_custom_proficiency_bonus">Custom Proficiency Bonus</string>
<string name="label_custom_speed">Custom Speed</string>
<string name="label_damage_immunities">Damage Immunities</string>
<string name="label_damage_resistances">Damage Resistances</string>
<string name="label_damage_type">Damage Type</string>
<string name="label_damage_vulnerabilities">Damage Vulnerabilities</string>
<string name="label_decrement_field">-</string>
<string name="label_description">Description</string>
<string name="label_dexterity">Dexterity</string>
<string name="label_fly_speed">Fly Speed</string>
<string name="label_has_custom_hp">Has Custom HP</string>
<string name="label_has_custom_speed">Has Custom Speed</string>
<string name="label_has_a_shield">Has a Shield</string>
<string name="label_hit_dice">Hit Dice</string>
<string name="label_hit_points">Hit Points</string>
<string name="label_hitPoints_icon">HP</string>
<string name="label_increment_field">+</string>
<string name="label_initiative_icon">INIT</string>
<string name="label_intelligence">Intelligence</string>
<string name="label_lair_actions">Lair Actions</string>
<string name="label_languages">Languages</string>
<string name="label_legendary_actions">Legendary Actions</string>
<string name="label_natural_armor_bonus">Natural Armor Bonus</string>
<string name="label_name">Name</string>
<string name="label_understands_but">Understands But</string>
<string name="label_proficiency">Proficiency</string>
<string name="label_proficiency_expertise">Expertise</string>
<string name="label_proficiency_none">None</string>
<string name="label_proficiency_proficient">Proficient</string>
<string name="label_reactions">Reactions</string>
<string name="label_regional_effects">Regional Effects</string>
<string name="label_saving_throws">Saving Throws</string>
<string name="label_search_query">Query</string>
<string name="label_senses">Senses</string>
<string name="label_shield_bonus">Shield Bonus</string>
<string name="label_size">Size</string>
<string name="label_skills">Skills</string>
<string name="label_speed">Speed</string>
<string name="label_strength">Strength</string>
<string name="label_subtype">Subtype</string>
<string name="label_swim_speed">Swim Speed</string>
<string name="label_telepathy">Telepathy</string>
<string name="label_type">Type</string>
<string name="label_wisdom">Wisdom</string>
<string name="section_divider">section divider</string>
<string name="snackbar_failed_to_create_monster">Failed to create monster</string>
<string name="snackbar_monster_created">%1$s created</string>
<string name="strength_abbreviation">STR</string>
<string name="title_collections">Collections</string>
<string name="title_dashboard">Dashboard</string> <string name="title_dashboard">Dashboard</string>
<string name="title_editAbilities">Ability</string> <string name="title_notifications">Notifications</string>
<string name="title_editAbility">Abilities</string> </resources>
<string name="title_editAbilityScores">Ability Scores</string>
<string name="title_editAction">Action</string>
<string name="title_editActions">Actions</string>
<string name="title_editArmor">Armor</string>
<string name="title_editBasicInfo">Basic Info</string>
<string name="title_editChallengeRating">Challenge Rating</string>
<string name="title_editConditionImmunities">Condition Immunities</string>
<string name="title_editConditionImmunity">Condition Immunity</string>
<string name="title_editDamageImmunities">Damage Immunities</string>
<string name="title_editDamageImmunity">Damage Immunity</string>
<string name="title_editDamageResistance">Damage Resistance</string>
<string name="title_editDamageResistances">Damage Resistances</string>
<string name="title_editDamageVulnerabilities">Damage Vulnerabilities</string>
<string name="title_editDamageVulnerability">Damage Vulnerability</string>
<string name="title_editLairAction">Lair Action</string>
<string name="title_editLairActions">Lair Actions</string>
<string name="title_editLanguage">Language</string>
<string name="title_editLanguages">Languages</string>
<string name="title_editLegendaryAction">Legendary Action</string>
<string name="title_editLegendaryActions">Legendary Actions</string>
<string name="title_editMonster">Edit Monster</string>
<string name="title_editMonster_fmt">Edit %1$s</string>
<string name="title_editReaction">Reaction</string>
<string name="title_editReactions">Reactions</string>
<string name="title_editRegionalAction">Regional Action</string>
<string name="title_editRegionalActions">Regional Actions</string>
<string name="title_editSpeed">Speed</string>
<string name="title_editSavingThrows">Saving Throws</string>
<string name="title_editSense">Senses</string>
<string name="title_editSenses">Senses</string>
<string name="title_editSkill">Skill</string>
<string name="title_editSkills">Skills</string>
<string name="title_editString">String</string>
<string name="title_editStrings">Strings</string>
<string name="title_editTrait">Trait</string>
<string name="title_editTraits">Traits</string>
<string name="title_importMonster">Import Monster</string>
<string name="title_library">Library</string>
<string name="title_monsterDetails">Monster Details</string>
<string name="title_monsterDetails_fmt">%1$s Details</string>
<string name="title_search">Search</string>
<string name="wisdom_abbreviation">WIS</string>
</resources>

View File

@@ -7,4 +7,4 @@
<item name="colorAccent">@color/colorAccent</item> <item name="colorAccent">@color/colorAccent</item>
</style> </style>
</resources> </resources>

View File

@@ -2,11 +2,10 @@
buildscript { buildscript {
repositories { repositories {
google() google()
mavenCentral() jcenter()
} }
dependencies { dependencies {
classpath "com.android.tools.build:gradle:7.0.1" classpath "com.android.tools.build:gradle:4.0.1"
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:2.3.5"
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files // in the individual module build.gradle files
@@ -16,18 +15,10 @@ buildscript {
allprojects { allprojects {
repositories { repositories {
google() google()
mavenCentral() jcenter()
// maven { url "https://oss.jfrog.org/libs-snapshot" }
// maven { url 'http://repo1.maven.org/maven2' }
}
// Temporary workaround until room 2.4.0 is released https://issuetracker.google.com/issues/174695268?pli=1#comment10
configurations.configureEach {
resolutionStrategy {
force 'org.xerial:sqlite-jdbc:3.34.0'
}
} }
} }
task clean(type: Delete) { task clean(type: Delete) {
delete rootProject.buildDir delete rootProject.buildDir
} }

View File

@@ -1,6 +1,6 @@
#Sat May 01 23:00:30 PDT 2021 #Mon Aug 31 21:50:22 PDT 2020
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip