Adds icon/logo images and a splash screen.
@@ -12,17 +12,22 @@
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppTheme">
|
||||
<activity
|
||||
android:name=".SplashActivity"
|
||||
android:theme="@style/Theme.App.Starting"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:label="@string/app_name"
|
||||
android:launchMode="singleTask"
|
||||
android:windowSoftInputMode="adjustResize"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
|
||||
<!-- Intent filter for viewing/opening content:// URIs with binary/octet-stream MIME type (.monster) -->
|
||||
<intent-filter>
|
||||
|
||||
@@ -58,12 +58,33 @@ public class MainActivity extends AppCompatActivity {
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
setTheme(R.style.AppTheme);
|
||||
WindowCompat.setDecorFitsSystemWindows(getWindow(), false);
|
||||
super.onCreate(savedInstanceState);
|
||||
AppCenterInitializer.init(getApplication());
|
||||
setContentView(R.layout.activity_main);
|
||||
|
||||
com.google.android.material.appbar.MaterialToolbar toolbar = findViewById(R.id.toolbar);
|
||||
if (toolbar != null) {
|
||||
setSupportActionBar(toolbar);
|
||||
}
|
||||
|
||||
View appBarLayout = findViewById(R.id.app_bar_layout);
|
||||
BottomNavigationView navView = findViewById(R.id.nav_view);
|
||||
|
||||
View container = findViewById(R.id.container);
|
||||
if (container != null) {
|
||||
ViewCompat.setOnApplyWindowInsetsListener(container, (v, windowInsets) -> {
|
||||
Insets systemBars = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars());
|
||||
if (appBarLayout != null) {
|
||||
appBarLayout.setPadding(0, systemBars.top, 0, 0);
|
||||
}
|
||||
if (navView != null) {
|
||||
navView.setPadding(0, 0, 0, systemBars.bottom);
|
||||
}
|
||||
return windowInsets;
|
||||
});
|
||||
}
|
||||
// Passing each menu ID as a set of Ids because each
|
||||
// menu should be considered as top level destinations.
|
||||
AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder(
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.majinnaibu.monstercards;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
public class SplashActivity extends AppCompatActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
setTheme(R.style.AppTheme);
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_splash);
|
||||
|
||||
new Handler(Looper.getMainLooper()).postDelayed(() -> {
|
||||
Intent intent = new Intent(SplashActivity.this, MainActivity.class);
|
||||
if (getIntent() != null) {
|
||||
if (getIntent().getExtras() != null) {
|
||||
intent.putExtras(getIntent().getExtras());
|
||||
}
|
||||
if (getIntent().getAction() != null) {
|
||||
intent.setAction(getIntent().getAction());
|
||||
}
|
||||
if (getIntent().getData() != null) {
|
||||
intent.setData(getIntent().getData());
|
||||
}
|
||||
}
|
||||
startActivity(intent);
|
||||
finish();
|
||||
overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
|
||||
}, 1200);
|
||||
}
|
||||
}
|
||||
@@ -31,10 +31,12 @@ import com.majinnaibu.monstercards.utils.Logger;
|
||||
import java.util.UUID;
|
||||
|
||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.rxjava3.disposables.CompositeDisposable;
|
||||
import io.reactivex.rxjava3.observers.DisposableCompletableObserver;
|
||||
import io.reactivex.rxjava3.schedulers.Schedulers;
|
||||
|
||||
public class CollectionsFragment extends MCFragment {
|
||||
private final CompositeDisposable mDisposables = new CompositeDisposable();
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
@@ -48,18 +50,35 @@ public class CollectionsFragment extends MCFragment {
|
||||
fab.setOnClickListener(v -> showCreateCollectionDialog());
|
||||
}
|
||||
|
||||
View emptyState = root.findViewById(R.id.empty_state);
|
||||
View emptyStateButton = root.findViewById(R.id.empty_state_button);
|
||||
if (emptyStateButton != null) {
|
||||
emptyStateButton.setOnClickListener(v -> showCreateCollectionDialog());
|
||||
}
|
||||
|
||||
RecyclerView recyclerView = root.findViewById(R.id.collection_list);
|
||||
if (recyclerView != null) {
|
||||
setupRecyclerView(recyclerView);
|
||||
setupRecyclerView(recyclerView, emptyState);
|
||||
}
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
private void setupRecyclerView(@NonNull RecyclerView recyclerView) {
|
||||
private void setupRecyclerView(@NonNull RecyclerView recyclerView, @Nullable View emptyState) {
|
||||
Context context = requireContext();
|
||||
MonsterRepository repository = getMonsterRepository();
|
||||
|
||||
mDisposables.add(repository.getCollectionsWithCount()
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(collections -> {
|
||||
boolean isEmpty = (collections == null || collections.isEmpty());
|
||||
if (emptyState != null) {
|
||||
emptyState.setVisibility(isEmpty ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
recyclerView.setVisibility(isEmpty ? View.GONE : View.VISIBLE);
|
||||
}, Logger::logError));
|
||||
|
||||
CollectionsRecyclerViewAdapter adapter = new CollectionsRecyclerViewAdapter(
|
||||
context,
|
||||
repository.getCollectionsWithCount(),
|
||||
@@ -155,4 +174,10 @@ public class CollectionsFragment extends MCFragment {
|
||||
NavDirections action = CollectionsFragmentDirections.actionNavigationCollectionsToCollectionDetailFragment(collectionId.toString());
|
||||
Navigation.findNavController(requireView()).navigate(action);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
mDisposables.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,6 +57,9 @@ public class DashboardFragment extends MCFragment {
|
||||
if (fab != null) {
|
||||
fab.setOnClickListener(v -> showAddToDashboardOptionsDialog());
|
||||
}
|
||||
if (mHolder.emptyStateButton != null) {
|
||||
mHolder.emptyStateButton.setOnClickListener(v -> showAddToDashboardOptionsDialog());
|
||||
}
|
||||
|
||||
setupRecyclerView(mHolder.list);
|
||||
loadDashboardMonsters();
|
||||
@@ -88,7 +91,16 @@ public class DashboardFragment extends MCFragment {
|
||||
}
|
||||
});
|
||||
if (monsterData != null) {
|
||||
monsterData.observe(getViewLifecycleOwner(), monsters -> mAdapter.submitList(monsters));
|
||||
monsterData.observe(getViewLifecycleOwner(), monsters -> {
|
||||
mAdapter.submitList(monsters);
|
||||
boolean isEmpty = (monsters == null || monsters.isEmpty());
|
||||
if (mHolder.emptyState != null) {
|
||||
mHolder.emptyState.setVisibility(isEmpty ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
if (mHolder.list != null) {
|
||||
mHolder.list.setVisibility(isEmpty ? View.GONE : View.VISIBLE);
|
||||
}
|
||||
});
|
||||
}
|
||||
recyclerView.setAdapter(mAdapter);
|
||||
|
||||
@@ -301,9 +313,13 @@ public class DashboardFragment extends MCFragment {
|
||||
|
||||
private static class ViewHolder {
|
||||
final RecyclerView list;
|
||||
final View emptyState;
|
||||
final View emptyStateButton;
|
||||
|
||||
ViewHolder(View root) {
|
||||
list = root.findViewById(R.id.list);
|
||||
emptyState = root.findViewById(R.id.empty_state);
|
||||
emptyStateButton = root.findViewById(R.id.empty_state_button);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import android.view.ViewGroup;
|
||||
import android.widget.EditText;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.navigation.NavController;
|
||||
import androidx.navigation.NavDirections;
|
||||
@@ -38,10 +39,12 @@ import com.majinnaibu.monstercards.utils.Logger;
|
||||
import java.util.UUID;
|
||||
|
||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.rxjava3.disposables.CompositeDisposable;
|
||||
import io.reactivex.rxjava3.observers.DisposableCompletableObserver;
|
||||
import io.reactivex.rxjava3.schedulers.Schedulers;
|
||||
|
||||
public class LibraryFragment extends MCFragment {
|
||||
private final CompositeDisposable mDisposables = new CompositeDisposable();
|
||||
|
||||
public View onCreateView(@NonNull LayoutInflater inflater,
|
||||
ViewGroup container, Bundle savedInstanceState) {
|
||||
@@ -52,9 +55,15 @@ public class LibraryFragment extends MCFragment {
|
||||
assert fab != null;
|
||||
setupAddMonsterButton(fab);
|
||||
|
||||
View emptyState = root.findViewById(R.id.empty_state);
|
||||
View emptyStateButton = root.findViewById(R.id.empty_state_button);
|
||||
if (emptyStateButton != null) {
|
||||
emptyStateButton.setOnClickListener(v -> createNewMonster());
|
||||
}
|
||||
|
||||
final RecyclerView recyclerView = root.findViewById(R.id.monster_list);
|
||||
assert recyclerView != null;
|
||||
setupRecyclerView(recyclerView);
|
||||
setupRecyclerView(recyclerView, emptyState);
|
||||
|
||||
return root;
|
||||
}
|
||||
@@ -130,10 +139,21 @@ public class LibraryFragment extends MCFragment {
|
||||
builder.show();
|
||||
}
|
||||
|
||||
private void setupRecyclerView(@NonNull RecyclerView recyclerView) {
|
||||
private void setupRecyclerView(@NonNull RecyclerView recyclerView, @Nullable View emptyState) {
|
||||
Context context = requireContext();
|
||||
MonsterRepository repository = this.getMonsterRepository();
|
||||
|
||||
mDisposables.add(repository.getMonsters()
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(monsters -> {
|
||||
boolean isEmpty = (monsters == null || monsters.isEmpty());
|
||||
if (emptyState != null) {
|
||||
emptyState.setVisibility(isEmpty ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
recyclerView.setVisibility(isEmpty ? View.GONE : View.VISIBLE);
|
||||
}, Logger::logError));
|
||||
|
||||
LibraryRecyclerViewAdapter adapter = new LibraryRecyclerViewAdapter(
|
||||
context,
|
||||
repository.getMonsters(),
|
||||
@@ -165,30 +185,31 @@ public class LibraryFragment extends MCFragment {
|
||||
}
|
||||
|
||||
private void setupAddMonsterButton(@NonNull FloatingActionButton fab) {
|
||||
fab.setOnClickListener(view -> {
|
||||
Monster monster = new Monster();
|
||||
monster.name = getString(R.string.default_monster_name);
|
||||
MonsterRepository repository = this.getMonsterRepository();
|
||||
repository.addMonster(monster)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
new DisposableCompletableObserver() {
|
||||
@Override
|
||||
public void onComplete() {
|
||||
navigateToEditMonster(monster.id);
|
||||
}
|
||||
fab.setOnClickListener(view -> createNewMonster());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(@io.reactivex.rxjava3.annotations.NonNull Throwable e) {
|
||||
Logger.logError("Error creating monster", e);
|
||||
View view = getView();
|
||||
if (view != null) {
|
||||
Snackbar.make(view, getString(R.string.snackbar_failed_to_create_monster), Snackbar.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
private void createNewMonster() {
|
||||
Monster monster = new Monster();
|
||||
monster.name = getString(R.string.default_monster_name);
|
||||
MonsterRepository repository = this.getMonsterRepository();
|
||||
mDisposables.add(repository.addMonster(monster)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribeWith(new DisposableCompletableObserver() {
|
||||
@Override
|
||||
public void onComplete() {
|
||||
navigateToEditMonster(monster.id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(@io.reactivex.rxjava3.annotations.NonNull Throwable e) {
|
||||
Logger.logError("Error creating monster", e);
|
||||
View view = getView();
|
||||
if (view != null) {
|
||||
Snackbar.make(view, getString(R.string.snackbar_failed_to_create_monster), Snackbar.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
protected void navigateToMonsterDetail(@NonNull UUID monsterId) {
|
||||
@@ -203,4 +224,10 @@ public class LibraryFragment extends MCFragment {
|
||||
action = MonsterDetailFragmentDirections.actionNavigationMonsterToEditMonsterFragment(monsterId.toString());
|
||||
navController.navigate(action);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
mDisposables.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,166 +5,6 @@
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
<path
|
||||
android:fillColor="#3DDC84"
|
||||
android:fillColor="@color/colorPrimaryDark"
|
||||
android:pathData="M0,0h108v108h-108z" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M9,0L9,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,0L19,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M29,0L29,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M39,0L39,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M49,0L49,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M59,0L59,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M69,0L69,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M79,0L79,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M89,0L89,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M99,0L99,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,9L108,9"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,19L108,19"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,29L108,29"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,39L108,39"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,49L108,49"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,59L108,59"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,69L108,69"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,79L108,79"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,89L108,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,99L108,99"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,29L89,29"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,39L89,39"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,49L89,49"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,59L89,59"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,69L89,69"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,79L89,79"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M29,19L29,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M39,19L39,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M49,19L49,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M59,19L59,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M69,19L69,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M79,19L79,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
</vector>
|
||||
|
||||
BIN
Android/app/src/main/res/drawable/ic_launcher_foreground.png
Normal file
|
After Width: | Height: | Size: 84 KiB |
BIN
Android/app/src/main/res/drawable/ic_logo.png
Normal file
|
After Width: | Height: | Size: 485 KiB |
BIN
Android/app/src/main/res/drawable/ic_splash_combined.png
Normal file
|
After Width: | Height: | Size: 98 KiB |
BIN
Android/app/src/main/res/drawable/ic_splash_logo.png
Normal file
|
After Width: | Height: | Size: 100 KiB |
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<!-- Solid dark red background -->
|
||||
<item android:drawable="@color/colorPrimaryDark" />
|
||||
|
||||
<!-- Centered logo + Spindle's End font text -->
|
||||
<item
|
||||
android:width="280dp"
|
||||
android:height="280dp"
|
||||
android:drawable="@drawable/ic_splash_combined"
|
||||
android:gravity="center" />
|
||||
</layer-list>
|
||||
BIN
Android/app/src/main/res/font/spindles_end.ttf
Normal file
@@ -6,6 +6,25 @@
|
||||
android:layout_height="match_parent"
|
||||
android:background="?attr/colorSurface">
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/app_bar_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<com.google.android.material.appbar.MaterialToolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:background="?attr/colorPrimary"
|
||||
android:theme="@style/ThemeOverlay.MaterialComponents.Dark.ActionBar"
|
||||
app:popupTheme="@style/ThemeOverlay.MaterialComponents.Light"
|
||||
app:navigationIconTint="@android:color/white"
|
||||
app:titleTextColor="@android:color/white" />
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<com.google.android.material.bottomnavigation.BottomNavigationView
|
||||
android:id="@+id/nav_view"
|
||||
android:layout_width="0dp"
|
||||
@@ -20,7 +39,6 @@
|
||||
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/nav_host_fragment"
|
||||
|
||||
android:name="androidx.navigation.fragment.NavHostFragment"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
@@ -29,8 +47,8 @@
|
||||
app:layout_constraintHorizontal_bias="0.0"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/app_bar_layout"
|
||||
app:layout_constraintVertical_bias="0.0"
|
||||
app:navGraph="@navigation/mobile_navigation" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
34
Android/app/src/main/res/layout/activity_splash.xml
Normal file
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/colorPrimaryDark">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/splash_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="24dp"
|
||||
android:fontFamily="@font/spindles_end"
|
||||
android:text="@string/app_title_splash"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="36sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toTopOf="@id/splash_logo"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/splash_logo"
|
||||
android:layout_width="220dp"
|
||||
android:layout_height="220dp"
|
||||
android:contentDescription="@string/app_name"
|
||||
android:scaleType="fitCenter"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:srcCompat="@drawable/ic_logo" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -17,6 +17,56 @@
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:listitem="@layout/collection_list_item" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/empty_state"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:padding="32dp"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:visibility="visible">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/empty_state_logo"
|
||||
android:layout_width="140dp"
|
||||
android:layout_height="140dp"
|
||||
android:contentDescription="@string/app_name"
|
||||
app:srcCompat="@drawable/ic_logo" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/empty_state_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:text="@string/empty_collections_title"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/empty_state_subtitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:gravity="center"
|
||||
android:text="@string/empty_collections_subtitle"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/empty_state_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:text="@string/action_add_collection"
|
||||
app:cornerRadius="20dp" />
|
||||
</LinearLayout>
|
||||
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/fab_add_collection"
|
||||
android:layout_width="wrap_content"
|
||||
|
||||
@@ -21,6 +21,56 @@
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:listitem="@layout/card_monster" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/empty_state"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:padding="32dp"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:visibility="visible">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/empty_state_logo"
|
||||
android:layout_width="140dp"
|
||||
android:layout_height="140dp"
|
||||
android:contentDescription="@string/app_name"
|
||||
app:srcCompat="@drawable/ic_logo" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/empty_state_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:text="@string/empty_dashboard_title"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/empty_state_subtitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:gravity="center"
|
||||
android:text="@string/empty_dashboard_subtitle"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/empty_state_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:text="@string/action_add_to_dashboard"
|
||||
app:cornerRadius="20dp" />
|
||||
</LinearLayout>
|
||||
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/fab_add_to_dashboard"
|
||||
android:layout_width="wrap_content"
|
||||
|
||||
@@ -19,6 +19,56 @@
|
||||
tools:context=".MonsterListFragment"
|
||||
tools:listitem="@layout/monster_list_content" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/empty_state"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:padding="32dp"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:visibility="visible">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/empty_state_logo"
|
||||
android:layout_width="140dp"
|
||||
android:layout_height="140dp"
|
||||
android:contentDescription="@string/app_name"
|
||||
app:srcCompat="@drawable/ic_logo" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/empty_state_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:text="@string/empty_library_title"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/empty_state_subtitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:gravity="center"
|
||||
android:text="@string/empty_library_subtitle"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/empty_state_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:text="@string/action_add_monster"
|
||||
app:cornerRadius="20dp" />
|
||||
</LinearLayout>
|
||||
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/fab"
|
||||
android:layout_width="wrap_content"
|
||||
|
||||
|
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 7.7 KiB |
|
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 7.7 KiB |
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 7.7 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 42 KiB |
25
Android/app/src/main/res/values-v31/styles.xml
Normal file
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- Base application theme for Android 12+ (API 31+). -->
|
||||
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">
|
||||
<!-- Customize your theme here. -->
|
||||
<item name="colorPrimary">@color/colorPrimary</item>
|
||||
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||
<item name="colorSecondary">@color/colorSecondary</item>
|
||||
<item name="colorSecondaryVariant">@color/colorSecondaryDark</item>
|
||||
<item name="colorAccent">@color/colorAccent</item>
|
||||
<item name="colorOnPrimary">#ffffff</item>
|
||||
<item name="colorOnSecondary">#000000</item>
|
||||
|
||||
<item name="android:windowBackground">@color/colorPrimaryDark</item>
|
||||
|
||||
<!-- Android 12+ Splash Screen API -->
|
||||
<item name="android:windowSplashScreenAnimatedIcon">@drawable/ic_splash_logo</item>
|
||||
<item name="android:windowSplashScreenBackground">@color/colorPrimaryDark</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.App.Starting" parent="AppTheme">
|
||||
<item name="android:windowSplashScreenAnimatedIcon">@drawable/ic_splash_logo</item>
|
||||
<item name="android:windowSplashScreenBackground">@color/colorPrimaryDark</item>
|
||||
</style>
|
||||
</resources>
|
||||
@@ -180,4 +180,12 @@
|
||||
<string name="snackbar_import_binder_success">Imported binder successfully</string>
|
||||
<string name="default_filename_library">MonsterCards Library</string>
|
||||
<string name="default_filename_dashboard">MonsterCards Dashboard</string>
|
||||
|
||||
<string name="empty_dashboard_title">Dashboard is Empty</string>
|
||||
<string name="empty_dashboard_subtitle">Pin monster cards or collections here for quick reference during your tabletop sessions.</string>
|
||||
<string name="empty_collections_title">No Collections Yet</string>
|
||||
<string name="empty_collections_subtitle">Organize your monsters into custom campaign or encounter collections.</string>
|
||||
<string name="empty_library_title">Your Library is Empty</string>
|
||||
<string name="empty_library_subtitle">Create new monster cards or import them from D&D Beyond or Open5e.</string>
|
||||
<string name="app_title_splash">Monster Cards</string>
|
||||
</resources>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<resources>
|
||||
<!-- Base application theme. -->
|
||||
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
|
||||
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">
|
||||
<!-- Customize your theme here. -->
|
||||
<item name="colorPrimary">@color/colorPrimary</item>
|
||||
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||
@@ -13,4 +13,9 @@
|
||||
<item name="android:windowBackground">@color/colorPrimaryDark</item>
|
||||
</style>
|
||||
|
||||
<!-- Instant starting theme displaying logo on launch -->
|
||||
<style name="Theme.App.Starting" parent="AppTheme">
|
||||
<item name="android:windowBackground">@color/colorPrimaryDark</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
|
||||
BIN
shared/fonts/mountain-king-font.zip
Normal file
BIN
shared/fonts/mountain-king/MountainKingRegular-woBYn.ttf
Normal file
2
shared/fonts/mountain-king/info.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
license: Creative Commons (by) Attribution
|
||||
link: https://www.fontspace.com/mountain-king-font-f119642
|
||||
@@ -0,0 +1,12 @@
|
||||
Mountain King Regular
|
||||
Version 1.0
|
||||
|
||||
Designed by Michael W. Moss
|
||||
|
||||
https://michaelwmoss.com
|
||||
Contact me at mechanismatic@gmail.com for questions or feedback.
|
||||
|
||||
7/24/2024
|
||||
|
||||
Copyright and Licensing:
|
||||
This work is licensed under a Creative Commons Attribution 4.0 International License. http://creativecommons.org/licenses/by/4.0/
|
||||
BIN
shared/fonts/spindles-end-font.zip
Normal file
BIN
shared/fonts/spindles-end/SpindlesEnd-YqV8.ttf
Normal file
2
shared/fonts/spindles-end/info.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
license: Freeware
|
||||
link: https://www.fontspace.com/spindles-end-font-f2715
|
||||
39
shared/fonts/spindles-end/misc/readme.txt
Normal file
@@ -0,0 +1,39 @@
|
||||
__
|
||||
_________ __ /\_\
|
||||
/\ _______\ /\ \ \/_/
|
||||
\ \ \______/ _\_\ \____ _____ __ _____ __ ___ ___ __ __ _____
|
||||
\ \ \_______ X X /\____ ___\ /'____'\ /\ V_____\/\ V V \ /\ \ /\ V __ \
|
||||
\ \ _______\ X X \/___/\ \__/ /\ \__L\ \\ \ \____/\ \ /\ /\ \\ \ \\ \ /_/\ \
|
||||
\ \ \______/ X \ \ \ \ \ ____/ \ \ \ \ \ \ \ \ \ \\ \ \\ \ \ \ \ \
|
||||
\ \ \_______ X X \ \ \___\ \ \___L__\ \ \ \ \ \ \ \ \ \\ \ \\ \ \ \ \ \
|
||||
\ \_________\ X X \ \____\\ \_______\\ \_\ \ \_\ \_\ \_\\ \_\\ \_\ \ \_\
|
||||
\/_________/ \/____/ \/_______/ \/_/ \/_/\/_/\/_/ \/_/ \/_/ \/_/
|
||||
|
||||
|
||||
_____ __
|
||||
/ ___ \ /\ \
|
||||
/\ \ \ \ _\_\ \____ ______ __ _____
|
||||
\ \ \__\ \ /\____ ___\ / ____ \ /\ V_____\
|
||||
\ > ___< \/___/\ \__/ /\ \__/\ \\ \ \____/
|
||||
> \ \ \ \ \ \ \ \ \ \ \ \ \\ \ \
|
||||
\ \ \__\ \ \ \ \___\ \ \_\_\ \\ \ \
|
||||
\ \_____/ \ \____\\ \______/ \ \_\
|
||||
\/____/ \/____/ \/_____/ \/_/
|
||||
|
||||
|
||||
|
||||
|
||||
+-----------------------------------------------------------+
|
||||
¦ Spindle's End Font version 1 -2005 ¦
|
||||
¦ created by extermin8tor ¦
|
||||
+-----------------------------------------------------------+
|
||||
:::::::::::::!Thanks for downloading this font!:::::::::::::
|
||||
|
||||
I hope you enjoy using this font, please distribute it anywhere, and you may bundle it with anything eg. templates, etc. You do not have to leave any credit to me, but if you host this font on your site i would like you to leave it in the original package. This font may be modified. Thanks.
|
||||
|
||||
Have fun using the font!!!!!!!!!!!!!!!
|
||||
;)
|
||||
|
||||
For more fonts, templates, webmaster resources and much more visit www.bestfreetemplates.net.
|
||||
I make custom fonts as well as sites and HTML templates. Please visit my site, if you like this font. And if you dont, then go there and find something you Do like! :)
|
||||
If you have any questions or comments please mail me at extermin8tor(at)gmail.coma
|
||||
BIN
shared/icon.png
Normal file
|
After Width: | Height: | Size: 726 KiB |
BIN
shared/logo.png
Normal file
|
After Width: | Height: | Size: 1.9 MiB |
BIN
shared/screenshots.png
Normal file
|
After Width: | Height: | Size: 778 KiB |
|
Before Width: | Height: | Size: 179 KiB After Width: | Height: | Size: 179 KiB |
|
Before Width: | Height: | Size: 291 KiB After Width: | Height: | Size: 291 KiB |
|
Before Width: | Height: | Size: 180 KiB After Width: | Height: | Size: 180 KiB |