From 1e0c76b1dc6fad59a3fab128143efa6a768787a1 Mon Sep 17 00:00:00 2001 From: Gregor Santner Date: Sat, 23 Sep 2017 19:56:49 +0200 Subject: [PATCH] Dont include assets at buildtime (fixes #30) * Download assets at runtime (github assets) * Allows updating assets * Remove builtin assets * Allow using without storage permission (share & edit only) * Migration for old data * Allow templates to be shown in normal tabs * Replace categories with tags. A meme can now be e.g. animals and cartoon --- app/build.gradle | 35 +- app/src/main/AndroidManifest.xml | 55 ++- .../assets/bundled/+0A_memetastic.conf.json | 1 + app/src/main/assets/bundled/00_Pressuru.otf | Bin 0 -> 48212 bytes .../main/assets/bundled/10_Bad_Luck_Brian.jpg | Bin 0 -> 174122 bytes app/src/main/assets/bundled/Derpina-300px.png | Bin 0 -> 23155 bytes .../assets/bundled/YaoMing-meme-300px.png | Bin 0 -> 9476 bytes .../io/github/gsantner/memetastic/App.java | 60 +-- .../memetastic/activity/AboutActivity.java | 5 +- .../activity/ImageViewActivity.java | 59 +-- .../memetastic/activity/MainActivity.java | 222 ++++++++--- .../activity/MemeCreateActivity.java | 70 +++- .../memetastic/activity/SettingsActivity.java | 16 +- .../memetastic/activity/SplashActivity.java | 87 ----- .../memetastic/data/MemeCategory.java | 79 ---- .../gsantner/memetastic/data/MemeConfig.java | 260 +++++++++++++ .../gsantner/memetastic/data/MemeData.java | 101 +++++ .../gsantner/memetastic/data/MemeFont.java | 42 -- .../memetastic/data/MemeLibConfig.java | 20 +- .../memetastic/data/MemeOriginAssets.java | 84 ---- .../memetastic/data/MemeOriginFavorite.java | 50 --- .../memetastic/data/MemeOriginInterface.java | 58 --- .../memetastic/data/MemeOriginStorage.java | 106 ----- .../gsantner/memetastic/data/MemeSetting.java | 20 +- .../memetastic/service/AssetUpdater.java | 361 ++++++++++++++++++ .../memetastic/service/ImageLoaderTask.java | 64 ++++ .../memetastic/service/MigrationThread.java | 68 ++++ .../service/ThumbnailCleanupTask.java | 22 ++ .../gsantner/memetastic/ui/FontAdapter.java | 30 +- .../memetastic/ui/GridRecycleAdapter.java | 144 ++++--- .../memetastic/ui/TouchImageView.java | 4 +- .../gsantner/memetastic/util/AppCast.java | 69 ++++ .../gsantner/memetastic/util/AppSettings.java | 110 ++++-- .../memetastic/util/ContextUtils.java | 36 +- .../memetastic/util/ImageLoaderTask.java | 97 ----- .../memetastic/util/PermissionChecker.java | 48 +++ .../memetastic/util/ThumbnailCleanupTask.java | 76 ---- .../net/gsantner/opoc/util/ActivityUtils.java | 12 +- .../net/gsantner/opoc/util/ContextUtils.java | 33 +- .../net/gsantner/opoc/util/FileUtils.java | 150 +++++++- .../java/net/gsantner/opoc/util/ZipUtils.java | 167 ++++++++ .../drawable/ic_file_download_black_24dp.xml | 9 + .../drawable/ic_file_download_white_32dp.xml | 4 + .../res/drawable/ic_mood_bad_black_256dp.xml | 4 + app/src/main/res/layout/splash__activity.xml | 59 --- app/src/main/res/values-de/strings.xml | 9 + app/src/main/res/values/arrays.xml | 12 +- .../res/values/strings-not_translatable.xml | 13 +- app/src/main/res/values/strings.xml | 9 + app/src/main/res/xml/preferences_master.xml | 21 +- 50 files changed, 1930 insertions(+), 1131 deletions(-) create mode 100644 app/src/main/assets/bundled/+0A_memetastic.conf.json create mode 100644 app/src/main/assets/bundled/00_Pressuru.otf create mode 100644 app/src/main/assets/bundled/10_Bad_Luck_Brian.jpg create mode 100755 app/src/main/assets/bundled/Derpina-300px.png create mode 100755 app/src/main/assets/bundled/YaoMing-meme-300px.png delete mode 100644 app/src/main/java/io/github/gsantner/memetastic/activity/SplashActivity.java delete mode 100644 app/src/main/java/io/github/gsantner/memetastic/data/MemeCategory.java create mode 100644 app/src/main/java/io/github/gsantner/memetastic/data/MemeConfig.java create mode 100644 app/src/main/java/io/github/gsantner/memetastic/data/MemeData.java delete mode 100644 app/src/main/java/io/github/gsantner/memetastic/data/MemeFont.java delete mode 100644 app/src/main/java/io/github/gsantner/memetastic/data/MemeOriginAssets.java delete mode 100644 app/src/main/java/io/github/gsantner/memetastic/data/MemeOriginFavorite.java delete mode 100644 app/src/main/java/io/github/gsantner/memetastic/data/MemeOriginInterface.java delete mode 100644 app/src/main/java/io/github/gsantner/memetastic/data/MemeOriginStorage.java create mode 100644 app/src/main/java/io/github/gsantner/memetastic/service/AssetUpdater.java create mode 100644 app/src/main/java/io/github/gsantner/memetastic/service/ImageLoaderTask.java create mode 100644 app/src/main/java/io/github/gsantner/memetastic/service/MigrationThread.java create mode 100644 app/src/main/java/io/github/gsantner/memetastic/service/ThumbnailCleanupTask.java create mode 100644 app/src/main/java/io/github/gsantner/memetastic/util/AppCast.java delete mode 100644 app/src/main/java/io/github/gsantner/memetastic/util/ImageLoaderTask.java create mode 100644 app/src/main/java/io/github/gsantner/memetastic/util/PermissionChecker.java delete mode 100644 app/src/main/java/io/github/gsantner/memetastic/util/ThumbnailCleanupTask.java create mode 100644 app/src/main/java/net/gsantner/opoc/util/ZipUtils.java create mode 100644 app/src/main/res/drawable/ic_file_download_black_24dp.xml create mode 100644 app/src/main/res/drawable/ic_file_download_white_32dp.xml create mode 100644 app/src/main/res/drawable/ic_mood_bad_black_256dp.xml delete mode 100644 app/src/main/res/layout/splash__activity.xml diff --git a/app/build.gradle b/app/build.gradle index 942345436..565aacc42 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -56,24 +56,7 @@ android { disable 'MissingTranslation' } - sourceSets { main { assets.srcDirs = ['src/main/assets', '../assets'] } } -} - -@SuppressWarnings(["UnnecessaryQualifiedReference", "SpellCheckingInspection"]) -static String[] getUsedAndroidLanguages() { - Set langs = new HashSet<>() - new File('.').eachFileRecurse(groovy.io.FileType.DIRECTORIES) { - final foldername = it.name - if (foldername.startsWith('values-') && !it.canonicalPath.contains("build" + File.separator + "intermediates")) { - new File(it.toString()).eachFileRecurse(groovy.io.FileType.FILES) { - if (it.name.toLowerCase().endsWith(".xml") && it.getCanonicalFile().getText('UTF-8').contains(" langs = new HashSet<>() + new File('.').eachFileRecurse(groovy.io.FileType.DIRECTORIES) { + final foldername = it.name + if (foldername.startsWith('values-') && !it.canonicalPath.contains("build" + File.separator + "intermediates")) { + new File(it.toString()).eachFileRecurse(groovy.io.FileType.FILES) { + if (it.name.toLowerCase().endsWith(".xml") && it.getCanonicalFile().getText('UTF-8').contains(" + xmlns:tools="http://schemas.android.com/tools" + package="io.github.gsantner.memetastic" + android:installLocation="auto" + tools:ignore="GoogleAppIndexingWarning"> - - + + + - + + android:resource="@xml/filepaths"/> + android:theme="@style/AppTheme.NoActionBar"> + - - + + - + + android:theme="@style/AppTheme.NoActionBar" + android:windowSoftInputMode="adjustResize"> + android:value="io.github.gsantner.memetastic.activity.MainActivity"/> - - - + + + + android:value="io.github.gsantner.memetastic.activity.MainActivity"/> + android:value=".activity.MainActivity"/> + android:value="io.github.gsantner.memetastic.activity.MainActivity"/> diff --git a/app/src/main/assets/bundled/+0A_memetastic.conf.json b/app/src/main/assets/bundled/+0A_memetastic.conf.json new file mode 100644 index 000000000..56b10b080 --- /dev/null +++ b/app/src/main/assets/bundled/+0A_memetastic.conf.json @@ -0,0 +1 @@ +{"images":[{"title":"10 Bad Luck Brian","filename":"10_Bad_Luck_Brian.jpg","tags":["humans"]},{"title":"Derpina","filename":"Derpina-300px.png","tags":["rage"]},{"title":"YaoMing","filename":"YaoMing-meme-300px.png","tags":["rage"]}],"fonts":[{"title":"Pressuru","filename":"00_Pressuru.otf"}]} diff --git a/app/src/main/assets/bundled/00_Pressuru.otf b/app/src/main/assets/bundled/00_Pressuru.otf new file mode 100644 index 0000000000000000000000000000000000000000..5e73bbd9621ffc6cd2a2efe8856afe6cd7a39df0 GIT binary patch literal 48212 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�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 literal 0 HcmV?d00001 diff --git a/app/src/main/assets/bundled/10_Bad_Luck_Brian.jpg b/app/src/main/assets/bundled/10_Bad_Luck_Brian.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e05f8188412b9d75d17608eccd5237b2bc1fa2d8 GIT binary patch literal 174122 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

(reU%gF)#Zf2q*BGYamFeJDi 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 literal 0 HcmV?d00001 diff --git a/app/src/main/assets/bundled/Derpina-300px.png b/app/src/main/assets/bundled/Derpina-300px.png new file mode 100755 index 0000000000000000000000000000000000000000..ed95fbb291e3fa46bcfd5690c6dfce029c1911a9 GIT binary patch literal 23155 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 literal 0 HcmV?d00001 diff --git a/app/src/main/assets/bundled/YaoMing-meme-300px.png b/app/src/main/assets/bundled/YaoMing-meme-300px.png new file mode 100755 index 0000000000000000000000000000000000000000..1e09ecf192e2e54b6083707e40320f86ac286c1a GIT binary patch literal 9476 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 memeCategories; - List fonts; public static App get() { return app; @@ -39,8 +30,6 @@ public void onCreate() { app = this; settings = AppSettings.get(); - loadFonts(); - loadMemeNames(); if (settings.isAppFirstStart(false)) { // Set default values (calculated in getters) @@ -49,54 +38,9 @@ public void onCreate() { } } - public void loadFonts() { - String FONT_FOLDER = MemeLibConfig.getPath(MemeLibConfig.Assets.FONTS, false); - try { - String[] fontFilenames = getAssets().list(FONT_FOLDER); - FONT_FOLDER = MemeLibConfig.getPath(FONT_FOLDER, true); - fonts = new ArrayList<>(); - - for (int i = 0; i < fontFilenames.length; i++) { - Typeface tf = Typeface.createFromAsset(getResources().getAssets(), FONT_FOLDER + fontFilenames[i]); - fonts.add(new MemeFont(FONT_FOLDER + fontFilenames[i], tf)); - } - } catch (IOException e) { - log("Could not load fonts"); - fonts = new ArrayList<>(); - } - } - - public void loadMemeNames() { - String IMAGE_FOLDER = MemeLibConfig.getPath(MemeLibConfig.Assets.MEMES, false); - try { - String[] memeCategories = getAssets().list(IMAGE_FOLDER); - IMAGE_FOLDER = MemeLibConfig.getPath(IMAGE_FOLDER, true); - this.memeCategories = new ArrayList(); - - for (String memeCat : memeCategories) { - this.memeCategories.add(new MemeCategory(memeCat, getAssets().list(IMAGE_FOLDER + memeCat)).orderByNameCaseInsensitive()); - } - } catch (IOException e) { - log("Could not load images"); - memeCategories = new ArrayList(); - } - } - - public List getFonts() { - return this.fonts; - } - - // Get meme category object (parameter = foldername in assets) - public MemeCategory getMemeCategory(String category) { - for (MemeCategory cat : memeCategories) { - if (cat.getCategoryName().equalsIgnoreCase(category)) - return cat; - } - return null; - } - public void shareBitmapToOtherApp(Bitmap bitmap, Activity activity) { - File imageFile = ContextUtils.get().writeImageToFileJpeg(getCacheDir().getAbsolutePath(), getString(R.string.cached_picture_filename), bitmap); + File file = new File(getCacheDir(), getString(R.string.cached_picture_filename)); + File imageFile = ContextUtils.get().writeImageToFileJpeg(file, bitmap); if (imageFile != null) { Uri imageUri = FileProvider.getUriForFile(this, getString(R.string.app_fileprovider), imageFile); if (imageUri != null) { diff --git a/app/src/main/java/io/github/gsantner/memetastic/activity/AboutActivity.java b/app/src/main/java/io/github/gsantner/memetastic/activity/AboutActivity.java index 1b7313c2a..49abed8a8 100644 --- a/app/src/main/java/io/github/gsantner/memetastic/activity/AboutActivity.java +++ b/app/src/main/java/io/github/gsantner/memetastic/activity/AboutActivity.java @@ -11,15 +11,16 @@ import android.view.View; import android.widget.TextView; +import net.gsantner.opoc.util.SimpleMarkdownParser; + import java.io.IOException; import butterknife.BindView; import butterknife.ButterKnife; import butterknife.OnClick; import io.github.gsantner.memetastic.R; -import io.github.gsantner.memetastic.util.ContextUtils; import io.github.gsantner.memetastic.util.ActivityUtils; -import net.gsantner.opoc.util.SimpleMarkdownParser; +import io.github.gsantner.memetastic.util.ContextUtils; @SuppressWarnings("unused") public class AboutActivity extends AppCompatActivity { diff --git a/app/src/main/java/io/github/gsantner/memetastic/activity/ImageViewActivity.java b/app/src/main/java/io/github/gsantner/memetastic/activity/ImageViewActivity.java index 87ee9638d..e9dbce6df 100644 --- a/app/src/main/java/io/github/gsantner/memetastic/activity/ImageViewActivity.java +++ b/app/src/main/java/io/github/gsantner/memetastic/activity/ImageViewActivity.java @@ -2,6 +2,7 @@ import android.graphics.Bitmap; import android.os.Bundle; +import android.support.v4.content.ContextCompat; import android.support.v7.app.ActionBar; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; @@ -17,25 +18,26 @@ import butterknife.OnClick; import io.github.gsantner.memetastic.App; import io.github.gsantner.memetastic.R; +import io.github.gsantner.memetastic.data.MemeData; import io.github.gsantner.memetastic.util.AppSettings; import io.github.gsantner.memetastic.util.ContextUtils; +import io.github.gsantner.memetastic.util.PermissionChecker; public class ImageViewActivity extends AppCompatActivity { //######################## //## UI Binding //######################## @BindView(R.id.imageview_activity__expanded_image) - ImageView expandedImageView; + ImageView _expandedImageView; @BindView(R.id.toolbar) - Toolbar toolbar; + Toolbar _toolbar; //##################### //## Members //##################### - private String imagePath; - private Bitmap mBitmap = null; - private App app; + private File _imagePath; + private Bitmap _bitmap = null; //##################### //## Methods @@ -48,56 +50,59 @@ protected void onCreate(Bundle savedInstanceState) { } setContentView(R.layout.imageview__activity); ButterKnife.bind(this); - app = (App) getApplication(); //ContextUtils.get().enableImmersiveMode(getWindow().getDecorView()); - setSupportActionBar(toolbar); + setSupportActionBar(_toolbar); if (getSupportActionBar() != null) { ActionBar ab = getSupportActionBar(); ab.setDisplayShowTitleEnabled(false); ab.setDisplayHomeAsUpEnabled(true); } - imagePath = getIntent().getStringExtra(MainActivity.IMAGE_PATH); - File imageFile = new File(imagePath); - if (!imageFile.exists()) { - // Thumbnail - imagePath = imagePath.replace(getString(R.string.app_name) + "_", - ".thumbnails" + File.separator + getString(R.string.app_name) + "_"); + _imagePath = new File(getIntent().getStringExtra(MainActivity.IMAGE_PATH)); + if (PermissionChecker.hasExtStoragePerm(this) && _imagePath.exists()) { + _bitmap = ContextUtils.get().loadImageFromFilesystem(_imagePath); } - - mBitmap = ContextUtils.get().loadImageFromFilesystem(imagePath); - expandedImageView.setImageBitmap(mBitmap); + if (_bitmap == null) { + _imagePath = null; + _bitmap = ContextUtils.get().drawableToBitmap( + ContextCompat.getDrawable(this, R.drawable.ic_mood_bad_black_256dp)); + } + _expandedImageView.setImageBitmap(_bitmap); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.imageview__menu, menu); + menu.findItem(R.id.action_delete).setVisible(_imagePath != null); return true; } @Override protected void onDestroy() { - expandedImageView.setImageBitmap(null); - if (mBitmap != null && !mBitmap.isRecycled()) - mBitmap.recycle(); + _expandedImageView.setImageBitmap(null); + if (_bitmap != null && !_bitmap.isRecycled()) + _bitmap.recycle(); super.onDestroy(); } @Override - @SuppressWarnings("ResultOfMethodCallIgnored") public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.action_share: { - app.shareBitmapToOtherApp(mBitmap, this); + ((App) getApplication()).shareBitmapToOtherApp(_bitmap, this); return true; } case R.id.action_delete: { finish(); - File file = new File(imagePath); - if (file.exists()) { - file.delete(); + if (_imagePath != null) { + deleteFile(_imagePath); + deleteFile(new File(getCacheDir(), _imagePath.getAbsolutePath().substring(1))); + MemeData.Image memeData = MemeData.findImage(_imagePath); + if (memeData != null) { + MemeData.getCreatedMemes().remove(memeData); + } } return true; } @@ -105,8 +110,12 @@ public boolean onOptionsItemSelected(MenuItem item) { return super.onOptionsItemSelected(item); } + private boolean deleteFile(File file) { + return file.exists() && file.delete(); + } + /** - * The image was clicked + * The conf was clicked */ @OnClick(R.id.imageview_activity__expanded_image) public void onImageClicked() { diff --git a/app/src/main/java/io/github/gsantner/memetastic/activity/MainActivity.java b/app/src/main/java/io/github/gsantner/memetastic/activity/MainActivity.java index e52780cb6..599df1c74 100644 --- a/app/src/main/java/io/github/gsantner/memetastic/activity/MainActivity.java +++ b/app/src/main/java/io/github/gsantner/memetastic/activity/MainActivity.java @@ -1,5 +1,8 @@ package io.github.gsantner.memetastic.activity; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.DialogInterface; import android.content.Intent; import android.database.Cursor; import android.graphics.PorterDuff; @@ -8,15 +11,20 @@ import android.os.Build; import android.os.Bundle; import android.os.Environment; +import android.os.Handler; import android.provider.MediaStore; +import android.support.annotation.DrawableRes; import android.support.annotation.NonNull; +import android.support.annotation.StringRes; import android.support.design.widget.NavigationView; import android.support.design.widget.TabLayout; import android.support.v4.content.ContextCompat; import android.support.v4.content.FileProvider; +import android.support.v4.content.LocalBroadcastManager; import android.support.v4.view.GravityCompat; import android.support.v4.widget.DrawerLayout; import android.support.v7.app.ActionBarDrawerToggle; +import android.support.v7.app.AlertDialog; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.RecyclerView; @@ -27,6 +35,7 @@ import android.view.MotionEvent; import android.view.View; import android.view.WindowManager; +import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ProgressBar; import android.widget.TextView; @@ -36,6 +45,9 @@ import java.io.File; import java.io.IOException; import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; import java.util.Random; import butterknife.BindView; @@ -43,23 +55,21 @@ import io.github.gsantner.memetastic.App; import io.github.gsantner.memetastic.BuildConfig; import io.github.gsantner.memetastic.R; -import io.github.gsantner.memetastic.data.MemeCategory; -import io.github.gsantner.memetastic.data.MemeLibConfig; -import io.github.gsantner.memetastic.data.MemeOriginAssets; -import io.github.gsantner.memetastic.data.MemeOriginFavorite; -import io.github.gsantner.memetastic.data.MemeOriginInterface; -import io.github.gsantner.memetastic.data.MemeOriginStorage; +import io.github.gsantner.memetastic.data.MemeData; +import io.github.gsantner.memetastic.service.AssetUpdater; import io.github.gsantner.memetastic.ui.GridDecoration; import io.github.gsantner.memetastic.ui.GridRecycleAdapter; import io.github.gsantner.memetastic.util.ActivityUtils; +import io.github.gsantner.memetastic.util.AppCast; import io.github.gsantner.memetastic.util.AppSettings; import io.github.gsantner.memetastic.util.ContextUtils; -import io.github.gsantner.memetastic.util.ThumbnailCleanupTask; +import io.github.gsantner.memetastic.util.PermissionChecker; public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener, TabLayout.OnTabSelectedListener { public static final int REQUEST_LOAD_GALLERY_IMAGE = 50; public static final int REQUEST_TAKE_CAMERA_PICTURE = 51; + public static final int REQUEST_SHOW_IMAGE = 52; public static final String IMAGE_PATH = "imagePath"; private static boolean _isShowingFullscreenImage = false; @@ -86,11 +96,22 @@ public class MainActivity extends AppCompatActivity @BindView(R.id.main__activity__list_empty__text) TextView _emptylistText; + @BindView(R.id.main__activity__infobar) + LinearLayout _infoBar; + @BindView(R.id.main__activity__infobar__progress) - ProgressBar _progressBar; + ProgressBar _infoBarProgressBar; + + @BindView(R.id.main__activity__infobar__image) + ImageView _infoBarImage; + + @BindView(R.id.main__activity__infobar__text) + TextView _infoBarText; App app; private String cameraPictureFilepath = ""; + String[] _tagKeys, _tagValues; + private int _currentMainMode = 0; @Override protected void onCreate(Bundle savedInstanceState) { @@ -113,6 +134,9 @@ protected void onCreate(Bundle savedInstanceState) { _navigationView.setNavigationItemSelectedListener(this); _tabLayout.setOnTabSelectedListener(this); + _tagKeys = getResources().getStringArray(R.array.meme_tags__keys); + _tagValues = getResources().getStringArray(R.array.meme_tags__titles); + // Setup Floating Action Button int gridColumns = ContextUtils.get().isInPortraitMode() ? app.settings.getGridColumnCountPortrait() @@ -126,7 +150,7 @@ protected void onCreate(Bundle savedInstanceState) { RecyclerView.LayoutManager recyclerGridLayout = new GridLayoutManager(this, gridColumns); _recyclerMemeList.setLayoutManager(recyclerGridLayout); - for (String cat : getResources().getStringArray(R.array.meme_categories)) { + for (String cat : _tagValues) { TabLayout.Tab tab = _tabLayout.newTab(); tab.setText(cat); _tabLayout.addTab(tab); @@ -134,7 +158,7 @@ protected void onCreate(Bundle savedInstanceState) { _areTabsReady = true; selectTab(app.settings.getLastSelectedTab(), app.settings.getDefaultMainMode()); - _progressBar.getProgressDrawable().setColorFilter(ContextCompat.getColor(this, R.color.accent), PorterDuff.Mode.SRC_IN); + _infoBarProgressBar.getProgressDrawable().setColorFilter(ContextCompat.getColor(this, R.color.accent), PorterDuff.Mode.SRC_IN); // // Actions based on build type or version @@ -160,6 +184,12 @@ protected void onCreate(Bundle savedInstanceState) { } catch (IOException e) { e.printStackTrace(); } + + new AssetUpdater.LoadAssetsThread(this).start(); + + if (PermissionChecker.doIfPermissionGranted(this)) { + ContextUtils.checkForAssetUpdates(this); + } } @SuppressWarnings("ConstantConditions") @@ -187,10 +217,12 @@ private void selectTab(int pos, int mainMode) { @Override protected void onResume() { + super.onResume(); if (_isShowingFullscreenImage) { _isShowingFullscreenImage = false; overridePendingTransition(R.anim.fadein, R.anim.fadeout); } + LocalBroadcastManager.getInstance(this).registerReceiver(_localBroadcastReceiver, AppCast.getLocalBroadcastFilter()); if (SettingsActivity.activityRetVal == SettingsActivity.RESULT.CHANGE_RESTART) { SettingsActivity.activityRetVal = SettingsActivity.RESULT.NOCHANGE; @@ -209,11 +241,21 @@ protected void onResume() { } } catch (Exception ignored) { } - new ThumbnailCleanupTask(this).start(); + } - super.onResume(); + @Override + protected void onPause() { + super.onPause(); + LocalBroadcastManager.getInstance(this).unregisterReceiver(_localBroadcastReceiver); } + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + if (PermissionChecker.checkPermissionResult(this, requestCode, permissions, grantResults)) { + ContextUtils.checkForAssetUpdates(this); + } + selectTab(_tabLayout.getSelectedTabPosition(), _currentMainMode); + } @Override public void onBackPressed() { @@ -226,7 +268,7 @@ public void onBackPressed() { @SuppressWarnings("ResultOfMethodCallIgnored") public boolean handleBarClick(MenuItem item) { - MemeOriginInterface memeOriginObject = null; + List imageList = null; switch (item.getItemId()) { case R.id.action_about: { @@ -258,8 +300,10 @@ public boolean handleBarClick(MenuItem item) { return true; } case R.id.action_picture_from_gallery: { - Intent i = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI); - ActivityUtils.get(this).animateToActivity(i, false, REQUEST_LOAD_GALLERY_IMAGE); + if (PermissionChecker.doIfPermissionGranted(this)) { + Intent i = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI); + ActivityUtils.get(this).animateToActivity(i, false, REQUEST_LOAD_GALLERY_IMAGE); + } return true; } case R.id.action_picture_from_camera: { @@ -268,32 +312,43 @@ public boolean handleBarClick(MenuItem item) { } case R.id.action_mode_create: { + _currentMainMode = 0; _emptylistText.setText(getString(R.string.main__nodata__custom_templates, getString(R.string.custom_templates_visual))); selectTab(app.settings.getLastSelectedTab(), app.settings.getDefaultMainMode()); _toolbar.setTitle(R.string.app_name); break; } case R.id.action_mode_favs: { + _currentMainMode = 1; + imageList = new ArrayList<>(); _emptylistText.setText(R.string.main__nodata__favourites); - memeOriginObject = new MemeOriginFavorite(app.settings.getFavoriteMemes(), getAssets()); + for (String fav : app.settings.getFavoriteMemeTemplates()) { + MemeData.Image img = MemeData.findImage(new File(fav)); + if (img != null) { + imageList.add(img); + } + } _toolbar.setTitle(R.string.main__mode__favs); break; } case R.id.action_mode_saved: { + _currentMainMode = 2; _emptylistText.setText(R.string.main__nodata__saved); - File filePath = ContextUtils.get().getPicturesMemetasticFolder(); - filePath.mkdirs(); - memeOriginObject = new MemeOriginStorage(filePath, getString(R.string.dot_thumbnails)); + if (PermissionChecker.hasExtStoragePerm(this)) { + File folder = AssetUpdater.getMemesDir(AppSettings.get()); + folder.mkdirs(); + imageList = MemeData.getCreatedMemes(); + } _toolbar.setTitle(R.string.main__mode__saved); break; } } // Change mode + _drawer.closeDrawers(); _tabLayout.setVisibility(item.getItemId() == R.id.action_mode_create ? View.VISIBLE : View.GONE); - if (memeOriginObject != null) { - _drawer.closeDrawers(); - GridRecycleAdapter recyclerMemeAdapter = new GridRecycleAdapter(memeOriginObject, this); + if (imageList != null) { + GridRecycleAdapter recyclerMemeAdapter = new GridRecycleAdapter(imageList, this); setRecyclerMemeListAdapter(recyclerMemeAdapter); return true; } @@ -341,6 +396,9 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) { ActivityUtils.get(this).showSnackBar(R.string.main__error_no_picture_selected, false); } } + if (requestCode == REQUEST_SHOW_IMAGE) { + selectTab(_tabLayout.getSelectedTabPosition(), _currentMainMode); + } } /** @@ -348,6 +406,9 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) { * Source: http://developer.android.com/training/camera/photobasics.html */ public void showCameraDialog() { + if (!PermissionChecker.doIfPermissionGranted(this)) { + return; + } Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); if (takePictureIntent.resolveActivity(getPackageManager()) != null) { File photoFile = null; @@ -391,38 +452,27 @@ public void openImageViewActivityWithImage(String imagePath) { Intent intent = new Intent(this, ImageViewActivity.class); intent.putExtra(IMAGE_PATH, imagePath); intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); - ActivityUtils.get(this).animateToActivity(intent, false, null); + ActivityUtils.get(this).animateToActivity(intent, false, REQUEST_SHOW_IMAGE); } @Override public void onTabSelected(TabLayout.Tab tab) { - MemeOriginInterface memeOriginObject = null; int tabPos = tab.getPosition(); + List imageList = new ArrayList<>(); - // Asset tabs - if (tabPos >= 0 && tabPos < MemeLibConfig.MEME_CATEGORIES.ALL.length) { - MemeCategory memeCategory = app.getMemeCategory(MemeLibConfig.MEME_CATEGORIES.ALL[tabPos]); - memeOriginObject = new MemeOriginAssets(memeCategory, getAssets()); + if (tabPos >= 0 && tabPos < _tagKeys.length) { + imageList = MemeData.getImagesWithTag(_tagKeys[tabPos]); } - // Custom tab - if (tabPos >= 0 && tabPos == MemeLibConfig.MEME_CATEGORIES.ALL.length) { - File customFolder = ContextUtils.get().getPicturesMemetasticTemplatesCustomFolder(); - _emptylistText.setText(getString(R.string.main__nodata__custom_templates, getString(R.string.custom_templates_visual))); - memeOriginObject = new MemeOriginStorage(customFolder, getString(R.string.dot_thumbnails)); - ((MemeOriginStorage) memeOriginObject).setIsTemplate(true); + if (_areTabsReady) { + app.settings.setLastSelectedTab(tabPos); } - if (memeOriginObject != null) { - if (_areTabsReady) { - app.settings.setLastSelectedTab(tabPos); - } - if (app.settings.isShuffleMemeCategories()) { - memeOriginObject.shuffleList(); - } - GridRecycleAdapter recyclerMemeAdapter = new GridRecycleAdapter(memeOriginObject, this); - setRecyclerMemeListAdapter(recyclerMemeAdapter); + if (app.settings.isShuffleTagLists()) { + Collections.shuffle(imageList); } + GridRecycleAdapter recyclerMemeAdapter = new GridRecycleAdapter(imageList, this); + setRecyclerMemeListAdapter(recyclerMemeAdapter); } private final RectF point = new RectF(0, 0, 0, 0); @@ -445,6 +495,92 @@ public boolean dispatchTouchEvent(MotionEvent event) { return super.dispatchTouchEvent(event); } + private BroadcastReceiver _localBroadcastReceiver = new BroadcastReceiver() { + @SuppressWarnings("unchecked") + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + switch (action) { + case AppCast.DOWNLOAD_REQUEST_RESULT.ACTION: { + switch (intent.getIntExtra(AppCast.DOWNLOAD_REQUEST_RESULT.EXTRA_RESULT, AssetUpdater.UpdateThread.DOWNLOAD_REQUEST_RESULT__FAILED)) { + case AssetUpdater.UpdateThread.DOWNLOAD_REQUEST_RESULT__FAILED: { + updateInfoBar(0, R.string.downloading_failed, R.drawable.ic_file_download_white_32dp, 1000); + break; + } + case AssetUpdater.UpdateThread.DOWNLOAD_REQUEST_RESULT__DO_DOWNLOAD_ASK: { + updateInfoBar(0, R.string.downloading, R.drawable.ic_file_download_white_32dp, 1); + showDownloadDialog(); + break; + } + } + return; + } + case AppCast.DOWNLOAD_STATUS.ACTION: { + int percent = intent.getIntExtra(AppCast.DOWNLOAD_STATUS.EXTRA_PERCENT, 100); + switch (intent.getIntExtra(AppCast.DOWNLOAD_STATUS.EXTRA_STATUS, AssetUpdater.UpdateThread.DOWNLOAD_STATUS__FAILED)) { + case AssetUpdater.UpdateThread.DOWNLOAD_STATUS__DOWNLOADING: { + updateInfoBar(percent, R.string.downloading, R.drawable.ic_file_download_white_32dp, -1); + break; + } + case AssetUpdater.UpdateThread.DOWNLOAD_STATUS__FAILED: { + updateInfoBar(percent, R.string.downloading_failed, R.drawable.ic_mood_bad_black_256dp, 2000); + break; + } + case AssetUpdater.UpdateThread.DOWNLOAD_STATUS__UNZIPPING: { + updateInfoBar(percent, R.string.unzipping, R.drawable.ic_file_download_white_32dp, -1); + break; + } + case AssetUpdater.UpdateThread.DOWNLOAD_STATUS__FINISHED: { + updateInfoBar(percent, R.string.downloading_success, R.drawable.ic_gavel_white_48px, 2000); + break; + } + } + return; + } + case AppCast.ASSETS_LOADED.ACTION: { + selectTab(_tabLayout.getSelectedTabPosition(), _currentMainMode); + return; + } + } + } + }; + + private void showDownloadDialog() { + AlertDialog.Builder dialog = new AlertDialog.Builder(this) + .setTitle(R.string.download_latest_assets_title) + .setMessage(R.string.download_latest_assets_message) + .setNegativeButton(android.R.string.cancel, null) + .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + new AssetUpdater.UpdateThread(MainActivity.this, true).start(); + } + }); + dialog.show(); + } + + public void updateInfoBar(Integer percent, @StringRes Integer textResId, @DrawableRes Integer image, int hideInMillis) { + _infoBar.setVisibility(View.VISIBLE); + if (hideInMillis >= 0) { + Handler handler = new Handler(); + handler.postDelayed(new Runnable() { + @Override + public void run() { + _infoBar.setVisibility(View.GONE); + } + }, hideInMillis); + } + if (percent != null) { + _infoBarProgressBar.setProgress(percent); + } + if (textResId != null) { + _infoBarText.setText(textResId); + } + if (image != null) { + _infoBarImage.setImageResource(image); + } + } + //######################## //## Single line overrides diff --git a/app/src/main/java/io/github/gsantner/memetastic/activity/MemeCreateActivity.java b/app/src/main/java/io/github/gsantner/memetastic/activity/MemeCreateActivity.java index 66a463785..a9150923d 100644 --- a/app/src/main/java/io/github/gsantner/memetastic/activity/MemeCreateActivity.java +++ b/app/src/main/java/io/github/gsantner/memetastic/activity/MemeCreateActivity.java @@ -13,9 +13,9 @@ import android.graphics.Rect; import android.net.Uri; import android.os.Bundle; -import android.os.Environment; import android.os.Handler; import android.provider.MediaStore; +import android.support.annotation.NonNull; import android.support.design.widget.FloatingActionButton; import android.support.design.widget.Snackbar; import android.support.v7.app.AppCompatActivity; @@ -53,15 +53,18 @@ import butterknife.OnTouch; import io.github.gsantner.memetastic.App; import io.github.gsantner.memetastic.R; -import io.github.gsantner.memetastic.data.MemeFont; +import io.github.gsantner.memetastic.data.MemeConfig; +import io.github.gsantner.memetastic.data.MemeData; import io.github.gsantner.memetastic.data.MemeLibConfig; import io.github.gsantner.memetastic.data.MemeSetting; import io.github.gsantner.memetastic.data.MemeSettingBase; +import io.github.gsantner.memetastic.service.AssetUpdater; import io.github.gsantner.memetastic.ui.FontAdapter; +import io.github.gsantner.memetastic.util.ActivityUtils; import io.github.gsantner.memetastic.util.AndroidBug5497Workaround; import io.github.gsantner.memetastic.util.AppSettings; import io.github.gsantner.memetastic.util.ContextUtils; -import io.github.gsantner.memetastic.util.ActivityUtils; +import io.github.gsantner.memetastic.util.PermissionChecker; import uz.shift.colorpicker.LineColorPicker; /** @@ -123,7 +126,7 @@ protected void onCreate(Bundle savedInstanceState) { AndroidBug5497Workaround.assistActivity(this); } - // Quit activity if no image was given + // Quit activity if no conf was given Intent intent = getIntent(); String action = intent.getAction(); String type = intent.getType(); @@ -147,16 +150,15 @@ protected void onCreate(Bundle savedInstanceState) { } public void initMemeSettings(Bundle savedInstanceState) { + MemeData.Font lastUsedFont = getFont(app.settings.getLastUsedFont()); Bitmap bitmap = extractBitmapFromIntent(getIntent()); if (savedInstanceState != null && savedInstanceState.containsKey("memeObj")) { memeSetting = (MemeSetting) savedInstanceState.getSerializable("memeObj"); memeSetting.getImageMain().setImage(bitmap); - memeSetting.getCaptionTop().setFont(app.getFonts().get(app.settings.getLastSelectedFont())); - memeSetting.getCaptionBottom().setFont(app.getFonts().get(app.settings.getLastSelectedFont())); + memeSetting.getCaptionTop().setFont(lastUsedFont); + memeSetting.getCaptionBottom().setFont(lastUsedFont); } else { - memeSetting = new MemeSetting(app.getFonts().get(app.settings.getLastSelectedFont()), bitmap); - memeSetting.getCaptionTop().setFontId(app.settings.getLastSelectedFont()); - memeSetting.getCaptionBottom().setFontId(app.settings.getLastSelectedFont()); + memeSetting = new MemeSetting(lastUsedFont, bitmap); } memeSetting.getImageMain().setDisplayImage(memeSetting.getImageMain().getImage().copy(Bitmap.Config.RGB_565, false)); @@ -166,6 +168,14 @@ public void initMemeSettings(Bundle savedInstanceState) { memeSetting.notifyChangedListener(); } + public MemeData.Font getFont(String filepath) { + MemeData.Font font = MemeData.findFont(new File(filepath)); + if (font == null) { + font = MemeData.getFonts().get(0); + } + return font; + } + @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); @@ -175,6 +185,9 @@ public void onSaveInstanceState(Bundle outState) { } private void prepareForSaving() { + if (memeSetting == null) { + return; + } memeSetting.setMemeSettingChangedListener(null); imageEditView.setImageBitmap(null); if (lastBitmap != null && !lastBitmap.isRecycled()) @@ -350,14 +363,18 @@ public boolean onOptionsItemSelected(MenuItem item) { } private boolean saveMemeToFilesystem(boolean showDialog) { - String filepath = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), getString(R.string.app_name)).getAbsolutePath(); - String thumbnailPath = new File(filepath, getString(R.string.dot_thumbnails)).getAbsolutePath(); + if (!PermissionChecker.doIfPermissionGranted(this)) { + return false; + } + + File folder = AssetUpdater.getMemesDir(AppSettings.get()); if (memeSavetime < 0) { memeSavetime = System.currentTimeMillis(); } String filename = String.format(Locale.getDefault(), "%s_%d.jpg", getString(R.string.app_name), memeSavetime); - boolean wasSaved = ContextUtils.get().writeImageToFileJpeg(filepath, filename, lastBitmap) != null && ContextUtils.get().writeImageToFileJpeg(thumbnailPath, filename, ContextUtils.get().scaleBitmap(lastBitmap)) != null; + File fullpath = new File(folder, filename); + boolean wasSaved = ContextUtils.get().writeImageToFileJpeg(fullpath, lastBitmap) != null; if (wasSaved && showDialog) { AlertDialog.Builder dialog = new AlertDialog.Builder(this); @@ -376,9 +393,22 @@ public void onClick(DialogInterface dialog, int which) { }); dialog.show(); } + if (wasSaved) { + MemeConfig.Image confImage = AssetUpdater.generateImageEntry(folder, filename, new String[0]); + MemeData.Image dataImage = new MemeData.Image(); + dataImage.conf = confImage; + dataImage.fullPath = fullpath; + dataImage.isTemplate = false; + MemeData.getCreatedMemes().add(dataImage); + } return wasSaved; } + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + PermissionChecker.checkPermissionResult(this, requestCode, permissions, grantResults); + } + public void toggleMoarControls(boolean forceVisibile, boolean visible) { moarControlsContainerVisible = !moarControlsContainerVisible; if (forceVisibile) { @@ -388,7 +418,7 @@ public void toggleMoarControls(boolean forceVisibile, boolean visible) { textEditTopCaption.setVisibility(moarControlsContainerVisible ? View.GONE : View.VISIBLE); toolbar.setVisibility(moarControlsContainerVisible ? View.GONE : View.VISIBLE); - // higher weightRatio means the image is more wide, so below view can be higher + // higher weightRatio means the conf is more wide, so below view can be higher // 100 is the max weight, 55 means the below view is a little more weighted Bitmap curImg = memeSetting.getImageMain().getDisplayImage(); int weight = (int) (55f * (1 + ((curImg.getWidth() / (float) curImg.getHeight()) / 10f))); @@ -434,7 +464,7 @@ private void initMoarControlsContainer() { colorPickerPadding.setColors(MemeLibConfig.MEME_COLORS.ALL); FontAdapter adapter = new FontAdapter(this, - android.R.layout.simple_list_item_1, app.getFonts(), + android.R.layout.simple_list_item_1, MemeData.getFonts(), true, getString(R.string.creator__font)); dropdownFont.setAdapter(adapter); @@ -443,7 +473,7 @@ private void initMoarControlsContainer() { colorPickerText.setSelectedColor(memeSetting.getCaptionTop().getTextColor()); colorPickerShade.setSelectedColor(memeSetting.getCaptionTop().getBorderColor()); colorPickerPadding.setSelectedColor(memeSetting.getImageMain().getPaddingColor()); - dropdownFont.setSelection(memeSetting.getCaptionTop().getFontId()); + adapter.setSelectedFont(dropdownFont, memeSetting.getCaptionTop().getFont()); toggleAllCaps.setChecked(memeSetting.getCaptionTop().isAllCaps()); seekFontSize.setProgress(memeSetting.getCaptionTop().getFontSize() - MemeLibConfig.FONT_SIZES.MIN); seekPaddingSize.setProgress(memeSetting.getImageMain().getPadding()); @@ -476,11 +506,9 @@ public void onNothingSelected(AdapterView parent) { } public void onItemSelected(AdapterView parent, View view, int position, long id) { - memeSetting.getCaptionTop().setFont((MemeFont) parent.getSelectedItem()); - memeSetting.getCaptionTop().setFontId(parent.getSelectedItemPosition()); - memeSetting.getCaptionBottom().setFont((MemeFont) parent.getSelectedItem()); - memeSetting.getCaptionBottom().setFontId(parent.getSelectedItemPosition()); - app.settings.setLastSelectedFont(parent.getSelectedItemPosition()); + memeSetting.getCaptionTop().setFont((MemeData.Font) parent.getSelectedItem()); + memeSetting.getCaptionBottom().setFont((MemeData.Font) parent.getSelectedItem()); + app.settings.setLastUsedFont(((MemeData.Font) parent.getSelectedItem()).fullPath.getAbsolutePath()); } }); SeekBar.OnSeekBarChangeListener seekBarChangeListener = new SeekBar.OnSeekBarChangeListener() { @@ -551,7 +579,7 @@ public Bitmap drawMultilineTextToBitmap(Context c, MemeSetting memeSetting) { // new antialiased Paint TextPaint paint = new TextPaint(Paint.ANTI_ALIAS_FLAG); paint.setTextSize((int) (memeSetting.getCaptionTop().getFontSize() * scale)); - paint.setTypeface(memeSetting.getCaptionTop().getFont().getFont()); + paint.setTypeface(memeSetting.getCaptionTop().getFont().typeFace); //paint.setStrokeWidth(memeSetting.getFontSize() / 4); paint.setStrokeWidth(borderScale); diff --git a/app/src/main/java/io/github/gsantner/memetastic/activity/SettingsActivity.java b/app/src/main/java/io/github/gsantner/memetastic/activity/SettingsActivity.java index 643f729ef..d86e90195 100644 --- a/app/src/main/java/io/github/gsantner/memetastic/activity/SettingsActivity.java +++ b/app/src/main/java/io/github/gsantner/memetastic/activity/SettingsActivity.java @@ -12,11 +12,15 @@ import android.support.v7.widget.Toolbar; import android.view.View; +import java.util.Date; + import butterknife.BindView; import butterknife.ButterKnife; import io.github.gsantner.memetastic.R; +import io.github.gsantner.memetastic.service.AssetUpdater; +import io.github.gsantner.memetastic.service.ThumbnailCleanupTask; import io.github.gsantner.memetastic.util.AppSettings; -import io.github.gsantner.memetastic.util.ThumbnailCleanupTask; +import io.github.gsantner.memetastic.util.PermissionChecker; public class SettingsActivity extends AppCompatActivity implements SharedPreferences.OnSharedPreferenceChangeListener { static final int ACTIVITY_ID = 10; @@ -121,6 +125,16 @@ public boolean onPreferenceTreeClick(PreferenceScreen screen, Preference prefere if (key.equals(getString(R.string.pref_key__language))) { activityRetVal = RESULT.CHANGE_RESTART; } + if (key.equals(getString(R.string.pref_key__download_assets_try))) { + if (PermissionChecker.doIfPermissionGranted(getActivity())) { + Date zero = new Date(0); + settings.setLastArchiveCheckDate(zero); + settings.setLastArchiveDate(zero); + settings.getDefaultPreferences().edit().commit(); + new AssetUpdater.UpdateThread(context, true).start(); + getActivity().finish(); + } + } } return super.onPreferenceTreeClick(screen, preference); } diff --git a/app/src/main/java/io/github/gsantner/memetastic/activity/SplashActivity.java b/app/src/main/java/io/github/gsantner/memetastic/activity/SplashActivity.java deleted file mode 100644 index 0f10fa21c..000000000 --- a/app/src/main/java/io/github/gsantner/memetastic/activity/SplashActivity.java +++ /dev/null @@ -1,87 +0,0 @@ -package io.github.gsantner.memetastic.activity; - -import android.Manifest; -import android.content.pm.PackageManager; -import android.os.Build; -import android.os.Bundle; -import android.os.Handler; -import android.support.design.widget.Snackbar; -import android.support.v4.app.ActivityCompat; -import android.support.v7.app.AppCompatActivity; -import android.widget.ImageView; -import android.widget.Toast; - -import java.io.File; - -import io.github.gsantner.memetastic.BuildConfig; -import io.github.gsantner.memetastic.R; -import io.github.gsantner.memetastic.util.ContextUtils; -import io.github.gsantner.memetastic.util.ActivityUtils; - -public class SplashActivity extends AppCompatActivity { - - private static final int REQUEST_STORAGE_PERM = 7; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.splash__activity); - - if (getSupportActionBar() != null) - getSupportActionBar().hide(); - - requestStoragePermission(); - } - - private void requestStoragePermission() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M - && checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { - if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_EXTERNAL_STORAGE)) { - Snackbar.make(findViewById(android.R.id.content), - "This app needs the Storage permission, because it will save memes to your Pictures folder.\n" + - "No need to worry, nothing gets sent to the web.", Snackbar.LENGTH_LONG).show(); - } - - // If we already learned why this is needed, request the perm from user - ActivityCompat.requestPermissions(this, new String[] - {Manifest.permission.READ_EXTERNAL_STORAGE}, REQUEST_STORAGE_PERM); - return; - } - - // Older device API, or already granted - startMemeCreator(false); - } - - @Override - public void onRequestPermissionsResult(int req, String[] perm, int[] grantResults) { - boolean somethingGranted = grantResults.length > 0; - switch (req) { - case REQUEST_STORAGE_PERM: - if (somethingGranted && grantResults[0] == PackageManager.PERMISSION_GRANTED) { - startMemeCreator(true); - return; - } - break; - } - Toast.makeText(this, "Cannot start Meme-Creator without Storage Permission.", Toast.LENGTH_LONG).show(); - } - - @SuppressWarnings("ResultOfMethodCallIgnored") - private void startMemeCreator(boolean skipDelay) { - // Create MemeCreator directories - int delay = (skipDelay || BuildConfig.DEBUG) ? 1000 : getResources().getInteger(R.integer.splash_delay); - new File(ContextUtils.get().getPicturesMemetasticFolder(), getString(R.string.dot_thumbnails)).mkdirs(); - new File(ContextUtils.get().getPicturesMemetasticTemplatesCustomFolder(), getString(R.string.dot_thumbnails)).mkdirs(); - - - // Start activity and exit splash - // Skip if possible - Handler handler = new Handler(); - handler.postDelayed(new Runnable() { - @Override - public void run() { - ActivityUtils.get(SplashActivity.this).animateToActivity(MainActivity.class, true, null); - } - }, delay); - } -} diff --git a/app/src/main/java/io/github/gsantner/memetastic/data/MemeCategory.java b/app/src/main/java/io/github/gsantner/memetastic/data/MemeCategory.java deleted file mode 100644 index 270eae30a..000000000 --- a/app/src/main/java/io/github/gsantner/memetastic/data/MemeCategory.java +++ /dev/null @@ -1,79 +0,0 @@ -package io.github.gsantner.memetastic.data; - -import java.io.File; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; - -/** - * Contains the category name of the memes and all the available meme names in this category - */ -public class MemeCategory { - private final String categoryName; - private String[] imageNames; - - /** - * Constructor that takes and saves the category name and the memes - * - * @param categoryName name of the category of the memes - * @param imageNames names of the memes as string array - */ - public MemeCategory(String categoryName, String[] imageNames) { - this.categoryName = categoryName; - this.imageNames = imageNames; - } - - /** - * gets and returns the name of the category - * - * @return the name of the category - */ - public String getCategoryName() { - return categoryName; - } - - /** - * creates a valid path to the memes of this category - * - * @param trailingSlash true if the path should end with a slash - * @return a valid path to the memes of this category - */ - public String getFolderPath(boolean trailingSlash) { - String ret = MemeLibConfig.getPath(MemeLibConfig.Assets.MEMES, true) + categoryName; - if (trailingSlash) - ret += File.separator; - return ret; - } - -// public String[] getImageNames() { -// return imageNames; -// } - - /** - * creates a path to a specific meme of this category - * - * @param position the position of the meme in the array of memes of this category - * @return the valid path to the meme at the position in the array of memes - */ - public String getImagePath(int position) { - return getFolderPath(true) + imageNames[position]; - } - - public void shuffleList() { - List l = new ArrayList(Arrays.asList(imageNames)); - Collections.shuffle(l); - imageNames = l.toArray(new String[l.size()]); - } - - public MemeCategory orderByNameCaseInsensitive() { - Arrays.sort(imageNames, new Comparator() { - @Override - public int compare(String f1, String f2) { - return f1.toLowerCase().compareTo(f2.toLowerCase()); - } - }); - return this; - } -} diff --git a/app/src/main/java/io/github/gsantner/memetastic/data/MemeConfig.java b/app/src/main/java/io/github/gsantner/memetastic/data/MemeConfig.java new file mode 100644 index 000000000..a6e2a14f1 --- /dev/null +++ b/app/src/main/java/io/github/gsantner/memetastic/data/MemeConfig.java @@ -0,0 +1,260 @@ +package io.github.gsantner.memetastic.data; + +import android.text.TextUtils; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + + +@SuppressWarnings({"WeakerAccess", "unused", "SameParameterValue", "SpellCheckingInspection", "UnusedReturnValue", "JavaDoc", "FieldCanBeLocal"}) +public class MemeConfig implements Serializable { + + public static class Config { + private List _fonts; + private List _images; + + public Config fromJson(JSONObject json) throws JSONException { + List imagesList = new ArrayList<>(); + JSONArray jsonArr = json.getJSONArray("images"); + for (int i = 0; i < jsonArr.length(); i++) { + try { + Image element = new Image().fromJson(jsonArr.getJSONObject(i)); + imagesList.add(element); + } catch (JSONException ignored) { + } + } + setImages(imagesList); + + List fontList = new ArrayList<>(); + jsonArr = json.getJSONArray("fonts"); + for (int i = 0; i < jsonArr.length(); i++) { + try { + Font element = new Font().fromJson(jsonArr.getJSONObject(i)); + fontList.add(element); + } catch (JSONException ignored) { + } + } + setFonts(fontList); + return this; + } + + public JSONObject toJson() throws JSONException { + JSONObject root = new JSONObject(); + JSONArray jsonArray = new JSONArray(); + for (Image element : getImages()) { + jsonArray.put(element.toJson()); + } + root.put("images", jsonArray); + + jsonArray = new JSONArray(); + for (Font element : getFonts()) { + jsonArray.put(element.toJson()); + } + root.put("fonts", jsonArray); + + return root; + } + + public List getFonts() { + if (_fonts.isEmpty()) { + setFonts(new ArrayList()); + } + return _fonts; + } + + public void setFonts(List fonts) { + _fonts = fonts; + } + + public List getImages() { + if (_images.isEmpty()) { + setImages(new ArrayList()); + } + return _images; + } + + public void setImages(List images) { + _images = images; + } + } + + public static class Image { + public final static String IMAGE_TAG_OTHER = "other"; + + private List _tags; + private List _imageTexts; + private String _title; + private String _filename; + + public Image fromJson(JSONObject json) throws JSONException { + setTitle(json.getString("title")); + setFilename(json.getString("filename")); + + JSONArray jsonArr; + List tagsList = new ArrayList<>(); + if (json.has("tags")) { + jsonArr = json.getJSONArray("tags"); + for (int i = 0; i < jsonArr.length(); i++) { + tagsList.add(jsonArr.getString(i)); + } + } + setTags(tagsList); + + List imageTexts = new ArrayList<>(); + if (json.has("image_texts")) { + jsonArr = json.getJSONArray("image_texts"); + for (int i = 0; i < jsonArr.length(); i++) { + try { + ImageText element = new ImageText().fromJson(jsonArr.getJSONObject(i)); + imageTexts.add(element); + } catch (JSONException ignored) { + } + } + } + setImageTexts(imageTexts); + + return this; + } + + public JSONObject toJson() throws JSONException { + JSONObject root = new JSONObject(); + root.put("title", getTitle()); + root.put("filename", getFilename()); + root.put("tags", new JSONArray(getTags())); + + return root; + } + + + public String getTitle() { + if (TextUtils.isEmpty(_title)) { + setTitle(getFilename()); + } + return _title; + } + + public void setTitle(String title) { + _title = title; + } + + public String getFilename() { + return _filename; + } + + public void setFilename(String filename) { + _filename = filename; + } + + public List getTags() { + if (_tags == null) { + setTags(new ArrayList()); + } + return _tags; + } + + public void setTags(List tags) { + _tags = tags; + } + + public List getImageTexts() { + return _imageTexts; + } + + public void setImageTexts(List imageTexts) { + _imageTexts = imageTexts; + } + } + + public static class ImageText { + private int _id; // -1 top, -2 bottom + private String _text; + + public ImageText fromJson(JSONObject json) throws JSONException { + setId(json.getInt("id")); + setText(json.getString("text")); + return this; + } + + public JSONObject toJson() throws JSONException { + JSONObject root = new JSONObject(); + root.put("id", getId()); + root.put("text", getText()); + + return root; + } + + public int getId() { + return _id; + } + + public void setId(int id) { + _id = id; + } + + public String getText() { + return _text; + } + + public void setText(String text) { + _text = text; + } + } + + public static class Font { + public static final int FONT_TYPE__DEFAULT = 0; + public static final int FONT_TYPE__COMIC = 1; + + private String _title; + private String _filename; + private int _fontType; + + public Font fromJson(JSONObject json) throws JSONException { + setTitle(json.getString("title")); + setFilename(json.getString("filename")); + setFontType(json.optInt("font_type", 0)); + return this; + } + + public JSONObject toJson() throws JSONException { + JSONObject root = new JSONObject(); + root.put("title", getTitle()); + root.put("filename", getFilename()); + if (getFontType() != 0) { + root.put("font_type", getFontType()); + } + return root; + } + + public String getTitle() { + if (TextUtils.isEmpty(_title)) { + setTitle(getFilename()); + } + return _title; + } + + public void setTitle(String title) { + _title = title; + } + + public String getFilename() { + return _filename; + } + + public void setFilename(String filename) { + _filename = filename; + } + + public int getFontType() { + return _fontType; + } + + public void setFontType(int fontType) { + _fontType = fontType; + } + } +} diff --git a/app/src/main/java/io/github/gsantner/memetastic/data/MemeData.java b/app/src/main/java/io/github/gsantner/memetastic/data/MemeData.java new file mode 100644 index 000000000..11cf0f73c --- /dev/null +++ b/app/src/main/java/io/github/gsantner/memetastic/data/MemeData.java @@ -0,0 +1,101 @@ +package io.github.gsantner.memetastic.data; + +import android.graphics.Typeface; + +import java.io.File; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; + + +@SuppressWarnings({"WeakerAccess", "unused", "SameParameterValue", "SpellCheckingInspection", "UnusedReturnValue", "JavaDoc", "FieldCanBeLocal"}) +public class MemeData implements Serializable { + private static final List _fonts = new ArrayList<>(); + private static final List _images = new ArrayList<>(); + private static final List _createdMemes = new ArrayList<>(); + private static final HashMap> _imagesWithTags = new HashMap<>(); + + public static List getFonts() { + return _fonts; + } + + public static List getImages() { + return _images; + } + + public static List getCreatedMemes() { + for (Image image : _createdMemes) { + image.isTemplate = false; + } + Collections.sort(_createdMemes, new Comparator() { + @Override + public int compare(Image mine, Image other) { + return other.fullPath.compareTo(mine.fullPath); + } + }); + return _createdMemes; + } + + public static void clearImagesWithTags() { + _imagesWithTags.clear(); + } + + public static Image findImage(File filePath) { + for (Image img : _images) { + if (img.fullPath.equals(filePath)) { + return img; + } + } + for (Image img : _createdMemes) { + if (img.fullPath.equals(filePath)) { + return img; + } + } + return null; + } + + public static Font findFont(File filePath) { + for (Font font : _fonts) { + if (font.fullPath.equals(filePath)) { + return font; + } + } + return null; + } + + public static synchronized List getImagesWithTag(String tag) { + if (_imagesWithTags.containsKey(tag)) { + return _imagesWithTags.get(tag); + } + boolean isOtherTag = tag.equals("other"); + List newlist = new ArrayList<>(); + for (Image image : getImages()) { + for (String imgTag : image.conf.getTags()) { + if (imgTag.equals(tag)) { + newlist.add(image); + break; + } + } + if (isOtherTag && image.conf.getTags().isEmpty()) { + newlist.add(image); + } + } + _imagesWithTags.put(tag, newlist); + return newlist; + } + + public static class Font { + public MemeConfig.Font conf; + public File fullPath; + public Typeface typeFace; + } + + public static class Image { + public MemeConfig.Image conf; + public File fullPath; + public boolean isTemplate; + } +} diff --git a/app/src/main/java/io/github/gsantner/memetastic/data/MemeFont.java b/app/src/main/java/io/github/gsantner/memetastic/data/MemeFont.java deleted file mode 100644 index 3313e13c1..000000000 --- a/app/src/main/java/io/github/gsantner/memetastic/data/MemeFont.java +++ /dev/null @@ -1,42 +0,0 @@ -package io.github.gsantner.memetastic.data; - -import android.graphics.Typeface; - -import java.io.File; - -/** - * Contains the path and the name of a font - */ -public class MemeFont { - private final String filePath; - private final String fontName; - private Typeface font; - - /** - * Constructor that takes and saves the filepath to the font and the font itself - * - * @param filePath path where the font is saved - * @param font the platform specific font type for the font at the path - */ - public MemeFont(String filePath, Typeface font) { - this.font = font; - this.filePath = filePath; - - // Extract fontName - String name = filePath; - int sep = name.lastIndexOf(File.separator); - name = name.substring(sep + 1); - sep = name.lastIndexOf("."); - fontName = name.substring(0, sep); - - } - - - public String getFontName() { - return fontName; - } - - public Typeface getFont() { - return font; - } -} \ No newline at end of file diff --git a/app/src/main/java/io/github/gsantner/memetastic/data/MemeLibConfig.java b/app/src/main/java/io/github/gsantner/memetastic/data/MemeLibConfig.java index 211dc962d..9a8a5a0b1 100644 --- a/app/src/main/java/io/github/gsantner/memetastic/data/MemeLibConfig.java +++ b/app/src/main/java/io/github/gsantner/memetastic/data/MemeLibConfig.java @@ -12,15 +12,6 @@ public static class Assets { public static final String MEMES = "memes"; } - public static class MEME_CATEGORIES { - public static final String RAGE = "rage"; - public static final String ANIMAL = "animals"; - public static final String HUMANS = "humans"; - public static final String CARTOON = "cartoon"; - - public static final String[] ALL = {HUMANS, ANIMAL, CARTOON, RAGE}; - } - public static class FONT_SIZES { public static final int DEFAULT = 14; public static final int MIN = 4; @@ -47,16 +38,7 @@ public static class MEME_COLORS { }; } - public static int getIndexOfCategory(String category) { - for (int i = 0; i < MEME_CATEGORIES.ALL.length; i++) { - if (MEME_CATEGORIES.ALL[i].equals(category)) { - return i; - } - } - return 0; - } - - public static final int MEME_FULLSCREEN_MAX_IMAGESIZE = 1200; + public static final int MEME_FULLSCREEN_MAX_IMAGESIZE = 2000; /** diff --git a/app/src/main/java/io/github/gsantner/memetastic/data/MemeOriginAssets.java b/app/src/main/java/io/github/gsantner/memetastic/data/MemeOriginAssets.java deleted file mode 100644 index 262294a15..000000000 --- a/app/src/main/java/io/github/gsantner/memetastic/data/MemeOriginAssets.java +++ /dev/null @@ -1,84 +0,0 @@ -package io.github.gsantner.memetastic.data; - -import android.content.res.AssetManager; - -import java.io.IOException; -import java.io.InputStream; - -/** - * Handles the memes (loading, count of memes, etc.) inside a category in the assets - */ -public class MemeOriginAssets implements MemeOriginInterface { - protected MemeCategory mMemeCategory; - protected AssetManager mAssetManager; - protected int length; - - /** - * Constructor that takes and saves the meme category, an instance of the asset manager - * and calculates the length of the available memes - * - * @param memeCategory the category of the memes - * @param assetManager the asset manager which will be used to load the memes of the category - */ - public MemeOriginAssets(MemeCategory memeCategory, AssetManager assetManager) { - mMemeCategory = memeCategory; - mAssetManager = assetManager; - if (mMemeCategory != null) { - try { - length = mAssetManager.list(mMemeCategory.getFolderPath(false)).length; - } catch (IOException e) { - length = 0; - } - } - } - - @Override - public String getPath(int position, boolean bThumbnail) { - return getFilepath(position); - } - - @Override - public int getLength() { - return length; - } - - @Override - public boolean isAsset() { - return true; - } - - @Override - public String getFilepath(int position) { - return mMemeCategory.getImagePath(position); - } - - @Override - public String getThumbnailPath(int position) { - return getFilepath(position); - } - - @Override - public boolean showFavButton() { - return true; - } - - public boolean fileExists(int position) { - try { - InputStream is = mAssetManager.open(getFilepath(position)); - is.close(); - return true; - } catch (IOException ex) { - return false; - } - } - - @Override - public void shuffleList() { - mMemeCategory.shuffleList(); - } - - @Override - public boolean isTemplate() { - return true; - } -} diff --git a/app/src/main/java/io/github/gsantner/memetastic/data/MemeOriginFavorite.java b/app/src/main/java/io/github/gsantner/memetastic/data/MemeOriginFavorite.java deleted file mode 100644 index 7017bbebb..000000000 --- a/app/src/main/java/io/github/gsantner/memetastic/data/MemeOriginFavorite.java +++ /dev/null @@ -1,50 +0,0 @@ -package io.github.gsantner.memetastic.data; - -import android.content.res.AssetManager; - -import java.util.ArrayList; -import java.util.Arrays; - -/** - * Handles the favorite memes (loading, count of favorites, etc.) - */ -public class MemeOriginFavorite extends MemeOriginAssets { - ArrayList mFiles; - - /** - * Constructor that takes the favorites as string array and an instance of the assetmanager - * to load the favorites later - * - * @param files the paths to the favorite memes - * @param assetManager the instance of the asset manager which will be used later to load the memes - */ - public MemeOriginFavorite(String[] files, AssetManager assetManager) { - super(null, assetManager); - setFiles(files); - } - - /** - * used to set the favorites to new data in case that something has changed (added/removed a favorite) - * - * @param files the new paths to the favorite memes - */ - public void setFiles(String[] files) { - if (files == null) { - length = 0; - mFiles = new ArrayList<>(); - return; - } - mFiles = new ArrayList(Arrays.asList(files)); - for (int x = mFiles.size() - 1; x >= 0; x--) { - if (!fileExists(x)) { - mFiles.remove(x); - } - } - length = mFiles.size(); - } - - @Override - public String getFilepath(int position) { - return mFiles.get(position); - } -} diff --git a/app/src/main/java/io/github/gsantner/memetastic/data/MemeOriginInterface.java b/app/src/main/java/io/github/gsantner/memetastic/data/MemeOriginInterface.java deleted file mode 100644 index f96f8c99c..000000000 --- a/app/src/main/java/io/github/gsantner/memetastic/data/MemeOriginInterface.java +++ /dev/null @@ -1,58 +0,0 @@ -package io.github.gsantner.memetastic.data; - -/** - * Interface that contains all necessary methods to access memes from different sources - */ -public interface MemeOriginInterface { - - public String getPath(int position, boolean bThumbnail); - - /** - * gets and returns the number of available images - * - * @return the number of available images - */ - public int getLength(); - - /** - * indicates if the image is saved in the assets or somewhere else - * - * @return true if the image is saved in the assets or somewhere else - */ - public boolean isAsset(); - - /** - * creates and returns a valid path to a specific image - * - * @param position the position in the array/list of available images - * @return the path to the image at the specified position - */ - public String getFilepath(int position); - - /** - * creates and returns a valid path to a specific thumbnail of an image - * - * @param position the position in the array/list of available images - * @return the path to the thumbnail of the image at the specified position - */ - public String getThumbnailPath(int position); - - /** - * indicates the image should be able to be set as a favorite or not - * - * @return true if the image is favoritable, else false - */ - public boolean showFavButton(); - - /** - * Shuffle the list of items - */ - public void shuffleList(); - - /** - * Tell if the image is to be used as template - * - * @return true if is template - */ - public boolean isTemplate(); -} diff --git a/app/src/main/java/io/github/gsantner/memetastic/data/MemeOriginStorage.java b/app/src/main/java/io/github/gsantner/memetastic/data/MemeOriginStorage.java deleted file mode 100644 index aec04bfb8..000000000 --- a/app/src/main/java/io/github/gsantner/memetastic/data/MemeOriginStorage.java +++ /dev/null @@ -1,106 +0,0 @@ -package io.github.gsantner.memetastic.data; - -import java.io.File; -import java.io.FilenameFilter; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Handles the already created memes (loading, count of memes, etc.) that are stored in the pictures folder - */ -public class MemeOriginStorage implements MemeOriginInterface { - private boolean mIsTemplate; - private File[] mFiles; - private String mFilePath; - private String mThumbnailPath; - private Map mMissingThumbnails = new HashMap<>(); - private int mLength; - - /** - * Constructor that takes the path to the created memes and path to the thumbnail folder of the created memes - * - * @param folderPathContainingPics path to the already created memes - * @param subfolderThumbnails path to the thumbnails of the created memes - */ - public MemeOriginStorage(File folderPathContainingPics, final String subfolderThumbnails) { - mFilePath = folderPathContainingPics.getAbsolutePath(); - mFiles = folderPathContainingPics.listFiles(new FilenameFilter() { - @Override - public boolean accept(File dir, String filename) { - File thumbnailFile = new File(new File(dir, subfolderThumbnails), filename); - File memeFile = new File(dir, filename); - boolean ok = thumbnailFile.isFile() && memeFile.isFile(); - if (memeFile.isFile() && !thumbnailFile.exists()) { - mMissingThumbnails.put(memeFile.getAbsolutePath(), thumbnailFile.getAbsolutePath()); - } - - return ok; - } - }); - Arrays.sort(mFiles, new Comparator() { - @Override - public int compare(File f1, File f2) { - return (int) (f2.lastModified() - f1.lastModified()); - } - }); - mThumbnailPath = subfolderThumbnails; - mLength = mFiles.length; - } - - @Override - public String getPath(int position, boolean bThumbnail) { - if (bThumbnail) - return getThumbnailPath(position); - return getFilepath(position); - } - - @Override - public int getLength() { - return mLength; - } - - @Override - public boolean isAsset() { - return false; - } - - @Override - public String getFilepath(int position) { - return mFilePath + File.separator + mFiles[position].getName(); - } - - @Override - public String getThumbnailPath(int position) { - return mFilePath + File.separator + mThumbnailPath + File.separator + mFiles[position].getName(); - } - - @Override - public boolean showFavButton() { - return false; - } - - @Override - public void shuffleList() { - List l = new ArrayList<>(Arrays.asList(mFiles)); - Collections.shuffle(l); - mFiles = l.toArray(new File[l.size()]); - } - - @Override - public boolean isTemplate() { - return mIsTemplate; - } - - public void setIsTemplate(boolean isTemplate) { - this.mIsTemplate = isTemplate; - } - - public Map getMissingThumbnails() { - return mMissingThumbnails; - } -} \ No newline at end of file diff --git a/app/src/main/java/io/github/gsantner/memetastic/data/MemeSetting.java b/app/src/main/java/io/github/gsantner/memetastic/data/MemeSetting.java index 606deb008..1e46c2a16 100644 --- a/app/src/main/java/io/github/gsantner/memetastic/data/MemeSetting.java +++ b/app/src/main/java/io/github/gsantner/memetastic/data/MemeSetting.java @@ -11,7 +11,7 @@ public class MemeSetting extends MemeSettingBase implements MemeSettingBase.OnMe private MemeElementText _captionBottom; private MemeElementImage _imageMain; - public MemeSetting(MemeFont font, Bitmap image) { + public MemeSetting(MemeData.Font font, Bitmap image) { _captionTop = new MemeElementText(font); _captionBottom = new MemeElementText(font); _imageMain = new MemeElementImage(image); @@ -64,19 +64,18 @@ public static class MemeElementText extends MemeSettingBase { private int _textColor = MemeLibConfig.MEME_COLORS.DEFAULT_TEXT; private int _borderColor = MemeLibConfig.MEME_COLORS.DEFAULT_BORDER; private boolean _allCaps = true; - private MemeFont _font = null; - private int _fontId; + private MemeData.Font _font = null; - public MemeElementText(MemeFont font) { + public MemeElementText(MemeData.Font font) { _font = font; notifyChangedListener(); } - public MemeFont getFont() { + public MemeData.Font getFont() { return _font; } - public void setFont(MemeFont font) { + public void setFont(MemeData.Font font) { _font = font; notifyChangedListener(); } @@ -117,15 +116,6 @@ public void setAllCaps(boolean allCaps) { notifyChangedListener(); } - public int getFontId() { - return _fontId; - } - - public void setFontId(int fontId) { - _fontId = fontId; - notifyChangedListener(); - } - public String getText() { return _text; } diff --git a/app/src/main/java/io/github/gsantner/memetastic/service/AssetUpdater.java b/app/src/main/java/io/github/gsantner/memetastic/service/AssetUpdater.java new file mode 100644 index 000000000..b755a74b1 --- /dev/null +++ b/app/src/main/java/io/github/gsantner/memetastic/service/AssetUpdater.java @@ -0,0 +1,361 @@ +package io.github.gsantner.memetastic.service; + + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.res.AssetManager; +import android.graphics.Typeface; + +import net.gsantner.opoc.util.Callback; +import net.gsantner.opoc.util.FileUtils; +import net.gsantner.opoc.util.NetworkUtils; +import net.gsantner.opoc.util.ZipUtils; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.File; +import java.io.FilenameFilter; +import java.io.IOException; +import java.io.InputStream; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.List; + +import io.github.gsantner.memetastic.R; +import io.github.gsantner.memetastic.data.MemeConfig; +import io.github.gsantner.memetastic.data.MemeData; +import io.github.gsantner.memetastic.util.AppCast; +import io.github.gsantner.memetastic.util.AppSettings; +import io.github.gsantner.memetastic.util.PermissionChecker; + +@SuppressLint("SimpleDateFormat") +public class AssetUpdater { + public static final SimpleDateFormat FORMAT_RFC3339 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX"); + + private static final String URL_ARCHIVE_ZIP = "https://github.com/gsantner/memetastic-assets/archive/master.zip"; + private static final String URL_API = "https://api.github.com/repos/gsantner/memetastic-assets"; + private final static String MEMETASTIC_CONFIG_FILE = "+0A_memetastic.conf.json"; + private final static String[] MEMETASTIC_IMAGES_EXTS = {"png", "jpg", "jpeg", "webp"}; + private final static String[] MEMETASTIC_FONT_EXTS = {"otf", "ttf"}; + + public static File getDownloadedAssetsDir(AppSettings appSettings) { + return new File(new File(appSettings.getSaveDirectory(), ".downloads"), "memetastic-assets"); + } + + public static File getCustomAssetsDir(AppSettings appSettings) { + return new File(appSettings.getSaveDirectory(), "templates"); + } + + public static File getBundledAssetsDir(AppSettings appSettings) { + return new File(appSettings.getContext().getCacheDir(), "bundled"); + } + + public static File getMemesDir(AppSettings appSettings) { + return new File(appSettings.getSaveDirectory(), "memes"); + } + + public static class UpdateThread extends Thread { + public static final int DOWNLOAD_REQUEST_RESULT__FAILED = -1; + public static final int DOWNLOAD_REQUEST_RESULT__DO_DOWNLOAD_ASK = 1; + public static final int DOWNLOAD_STATUS__DOWNLOADING = 1; + public static final int DOWNLOAD_STATUS__UNZIPPING = 2; + public static final int DOWNLOAD_STATUS__FINISHED = 3; + public static final int DOWNLOAD_STATUS__FAILED = -1; + + + private static boolean _isAlreadyDownloading = false; + + private boolean _doDownload; + private Context _context; + private AppSettings _appSettings; + private int _lastPercent = -1; + + public UpdateThread(Context context, boolean doDownload) { + _doDownload = doDownload; + _context = context; + _appSettings = AppSettings.get(); + } + + @Override + public void run() { + if (PermissionChecker.hasExtStoragePerm(_context)) { + String apiJsonS = NetworkUtils.performCall(URL_API, NetworkUtils.GET); + try { + JSONObject apiJson = new JSONObject(apiJsonS); + String lastUpdate = apiJson.getString("pushed_at"); + Date date = FORMAT_RFC3339.parse(lastUpdate); + if (date.after(_appSettings.getLastAssetArchiveDate())) { + _appSettings.setLastArchiveCheckDate(new Date(System.currentTimeMillis())); + if (!_doDownload) { + AppCast.DOWNLOAD_REQUEST_RESULT.send(_context, DOWNLOAD_REQUEST_RESULT__DO_DOWNLOAD_ASK); + return; + } else { + doDownload(date); + new LoadAssetsThread(_context).start(); + return; + } + } + } catch (JSONException | ParseException e) { + e.printStackTrace(); + } + } + AppCast.DOWNLOAD_REQUEST_RESULT.send(_context, DOWNLOAD_REQUEST_RESULT__FAILED); + } + + + private synchronized void doDownload(Date date) throws ParseException { + if (_isAlreadyDownloading || date.before(_appSettings.getLastAssetArchiveDate())) { + return; + } + _isAlreadyDownloading = true; + File templatesDir = getDownloadedAssetsDir(_appSettings); + File file = new File(_appSettings.getSaveDirectory(), ".downloads"); + MemeData.getFonts().clear(); + MemeData.getImages().clear(); + MemeData.clearImagesWithTags(); + FileUtils.deleteRecursive(file); + boolean ok; + if (file.mkdirs() && (templatesDir.exists() || templatesDir.mkdirs())) { + file = new File(file, FORMAT_RFC3339.format(date) + ".memetastic.zip"); + ok = NetworkUtils.downloadFile(URL_ARCHIVE_ZIP, file, new Callback() { + public void onCallback(Float aFloat) { + if (_lastPercent != (int) (aFloat * 100)) { + AppCast.DOWNLOAD_STATUS.send(_context, DOWNLOAD_STATUS__DOWNLOADING, _lastPercent * 3 / 4); + _lastPercent = (int) (aFloat * 100); + } + } + }); + if (ok) { + ok = ZipUtils.unzip(file, templatesDir, true, new Callback() { + public void onCallback(Float aFloat) { + if (_lastPercent != (int) (aFloat * 100)) { + AppCast.DOWNLOAD_STATUS.send(_context, DOWNLOAD_STATUS__UNZIPPING, 50 + _lastPercent / 4); + _lastPercent = (int) (aFloat * 100); + } + } + }); + } + AppCast.DOWNLOAD_STATUS.send(_context, ok ? DOWNLOAD_STATUS__FINISHED : DOWNLOAD_STATUS__FAILED, 100); + _appSettings.setLastArchiveDate(date); + _isAlreadyDownloading = false; + } + } + } + + public static class LoadAssetsThread extends Thread { + private static boolean _isAlreadyLoading = false; + + private Context _context; + private AppSettings _appSettings; + private String[] _tagKeys; + + public LoadAssetsThread(Context context) { + _context = context.getApplicationContext(); + _appSettings = AppSettings.get(); + _tagKeys = context.getResources().getStringArray(R.array.meme_tags__keys); + } + + @Override + public void run() { + if (_isAlreadyLoading) { + return; + } + _isAlreadyLoading = true; + List fonts = MemeData.getFonts(); + List images = MemeData.getImages(); + fonts.clear(); + images.clear(); + + boolean permGranted = PermissionChecker.hasExtStoragePerm(_context); + + if (permGranted) { + loadConfigFromFolder(getMemesDir(_appSettings), new ArrayList(), MemeData.getCreatedMemes()); + loadConfigFromFolder(getDownloadedAssetsDir(_appSettings), fonts, images); + loadConfigFromFolder(getCustomAssetsDir(_appSettings), fonts, images); + } + if (!permGranted || fonts.isEmpty() || images.isEmpty()) { + loadBundledAssets(fonts, images); + loadConfigFromFolder(getBundledAssetsDir(_appSettings), fonts, images); + } + MemeData.clearImagesWithTags(); + _isAlreadyLoading = false; + AppCast.ASSETS_LOADED.send(_context); + } + + private void loadConfigFromFolder(File folder, List dataFonts, List dataImages) { + if (!folder.exists() && !folder.mkdirs()) { + return; + } + if (folder.list().length == 0) { + return; + } + + MemeConfig.Config conf = null; + File configFile = new File(folder, MEMETASTIC_CONFIG_FILE); + FileUtils.touch(new File(folder, ".nomedia")); + if (configFile.exists()) { + try { + String contents = FileUtils.readTextFile(configFile); + JSONObject json = new JSONObject(contents); + conf = new MemeConfig.Config().fromJson(json); + } catch (Exception ignored) { + } + } + + // Create new if empty + if (conf == null) { + conf = new MemeConfig.Config(); + conf.setFonts(new ArrayList()); + conf.setImages(new ArrayList()); + } + + boolean assetsChanged = checkForNewAssets(folder, conf); + + for (MemeConfig.Font confFont : conf.getFonts()) { + MemeData.Font dataFont = new MemeData.Font(); + dataFont.conf = confFont; + dataFont.fullPath = new File(folder, confFont.getFilename()); + dataFont.typeFace = Typeface.createFromFile(dataFont.fullPath); + if (dataFont.fullPath.exists()) { + dataFonts.add(dataFont); + } else { + assetsChanged = true; + } + } + + for (MemeConfig.Image confImage : conf.getImages()) { + MemeData.Image dataImage = new MemeData.Image(); + dataImage.conf = confImage; + dataImage.fullPath = new File(folder, confImage.getFilename()); + dataImage.isTemplate = true; + if (dataImage.fullPath.exists()) { + dataImages.add(dataImage); + } else { + assetsChanged = true; + } + } + + if (assetsChanged) { + try { + FileUtils.writeFile(configFile, conf.toJson().toString()); + } catch (Exception ignored) { + } + } + } + + private boolean checkForNewAssets(File folder, MemeConfig.Config conf) { + boolean assetsChanged = false; + final ArrayList extensions = new ArrayList<>(); + extensions.addAll(Arrays.asList(MEMETASTIC_IMAGES_EXTS)); + extensions.addAll(Arrays.asList(MEMETASTIC_FONT_EXTS)); + + // Get all files that are maybe compatible + ArrayList files = new ArrayList<>(Arrays.asList( + folder.list(new FilenameFilter() { + @Override + public boolean accept(File file, String s) { + String flc = s.toLowerCase(); + for (String extension : extensions) { + if (flc.endsWith("." + extension.toLowerCase())) { + return true; + } + } + return false; + } + }) + )); + + // Check if all fonts and images are indexed + for (MemeConfig.Font data : conf.getFonts()) { + if (files.contains(data.getFilename())) { + files.remove(data.getFilename()); + } + } + for (MemeConfig.Image data : conf.getImages()) { + if (files.contains(data.getFilename())) { + files.remove(data.getFilename()); + } + } + + // Index everything not indexed yet + for (String filename : files) { + String flc = filename.toLowerCase(); + for (String ext : MEMETASTIC_IMAGES_EXTS) { + if (flc.endsWith("." + ext)) { + MemeConfig.Image image = generateImageEntry(folder, filename, _tagKeys); + if (image != null) { + conf.getImages().add(image); + assetsChanged = true; + } + } + } + for (String ext : MEMETASTIC_FONT_EXTS) { + if (flc.endsWith("." + ext)) { + MemeConfig.Font font = generateFontEntry(folder, filename); + if (font != null) { + conf.getFonts().add(font); + assetsChanged = true; + } + } + } + } + return assetsChanged; + } + + @SuppressWarnings("ResultOfMethodCallIgnored") + private void loadBundledAssets(List fonts, List images) { + AssetManager assetManager = _context.getAssets(); + File config = new File(getBundledAssetsDir(_appSettings), MEMETASTIC_CONFIG_FILE); + config.delete(); + try { + File cacheDir = getBundledAssetsDir(_appSettings); + if (cacheDir.exists() || cacheDir.mkdirs()) { + for (String assetFilename : assetManager.list("bundled")) { + InputStream is = assetManager.open("bundled/" + assetFilename); + byte[] data = FileUtils.readCloseBinaryStream(is); + FileUtils.writeFile(new File(cacheDir, assetFilename), data); + } + } + } catch (IOException ignored) { + } + } + } + + public static MemeConfig.Font generateFontEntry(File folder, String filename) { + MemeConfig.Font confFont = new MemeConfig.Font(); + confFont.setFilename(filename); + confFont.setTitle(filename.substring(0, filename.lastIndexOf(".")).replace("_", " ")); + + return confFont; + } + + public static MemeConfig.Image generateImageEntry(File folder, String filename, String[] tagKeys) { + ArrayList tags = new ArrayList<>(); + + // animals__advice_mallard.jpg --> tag animals recognized + String[] nameSplits = filename.split("__"); + for (String tagKey : tagKeys) { + for (String nameSplit : nameSplits) { + if (nameSplit.equals(tagKey)) { + tags.add(tagKey); + } + } + } + + if (tags.isEmpty()) { + tags.add(MemeConfig.Image.IMAGE_TAG_OTHER); + } + + MemeConfig.Image confImage = new MemeConfig.Image(); + confImage.setImageTexts(new ArrayList()); + confImage.setFilename(filename); + confImage.setTags(tags); + confImage.setTitle(filename.substring(0, filename.lastIndexOf(".")).replace("_", " ")); + + return confImage; + } +} diff --git a/app/src/main/java/io/github/gsantner/memetastic/service/ImageLoaderTask.java b/app/src/main/java/io/github/gsantner/memetastic/service/ImageLoaderTask.java new file mode 100644 index 000000000..0a8697292 --- /dev/null +++ b/app/src/main/java/io/github/gsantner/memetastic/service/ImageLoaderTask.java @@ -0,0 +1,64 @@ +package io.github.gsantner.memetastic.service; + +import android.content.Context; +import android.graphics.Bitmap; +import android.os.AsyncTask; + +import java.io.File; + +import io.github.gsantner.memetastic.data.MemeLibConfig; +import io.github.gsantner.memetastic.util.AppSettings; +import io.github.gsantner.memetastic.util.ContextUtils; + +public class ImageLoaderTask extends AsyncTask { + private final static int MAX_DIMENSION = 5000; + + public interface OnImageLoadedListener { + void onImageLoaded(Bitmap bitmap, T callbackParam); + } + + private final Context _context; + private final int _maxSize; + private final OnImageLoadedListener _listener; + private final T _callbackParam; + private final boolean _loadThumbnail; + + public ImageLoaderTask(OnImageLoadedListener listener, Context context, boolean loadThumbnail, T callbackParam) { + _listener = listener; + _context = context; + _callbackParam = callbackParam; + _loadThumbnail = loadThumbnail; + _maxSize = loadThumbnail ? AppSettings.get().getThumbnailQualityReal() + : MemeLibConfig.MEME_FULLSCREEN_MAX_IMAGESIZE; + } + + private Bitmap loadStorageImage(File pathToImage) { + File cacheFile = new File(_context.getCacheDir(), pathToImage.getAbsolutePath().substring(1)); + ContextUtils cu = ContextUtils.get(); + Bitmap bitmap; + if (_loadThumbnail) { + if (cacheFile.exists()) { + bitmap = cu.loadImageFromFilesystem(cacheFile, _maxSize); + } else { + bitmap = cu.loadImageFromFilesystem(pathToImage, _maxSize); + cu.writeImageToFileDetectFormat(cacheFile, bitmap, 80); + } + } else { + bitmap = cu.loadImageFromFilesystem(pathToImage, _maxSize); + } + + return bitmap; + } + + @Override + protected Bitmap doInBackground(File... params) { + return loadStorageImage(params[0]); + } + + @Override + protected void onPostExecute(Bitmap bitmap) { + super.onPostExecute(bitmap); + if (_listener != null) + _listener.onImageLoaded(bitmap, _callbackParam); + } +} diff --git a/app/src/main/java/io/github/gsantner/memetastic/service/MigrationThread.java b/app/src/main/java/io/github/gsantner/memetastic/service/MigrationThread.java new file mode 100644 index 000000000..b73624884 --- /dev/null +++ b/app/src/main/java/io/github/gsantner/memetastic/service/MigrationThread.java @@ -0,0 +1,68 @@ +package io.github.gsantner.memetastic.service; + +import android.content.Context; +import android.os.Environment; + +import net.gsantner.opoc.util.FileUtils; + +import java.io.File; + +import io.github.gsantner.memetastic.R; +import io.github.gsantner.memetastic.util.AppSettings; +import io.github.gsantner.memetastic.util.PermissionChecker; + +/** + * Created by gregor on 23.09.17. + */ + +public class MigrationThread extends Thread { + private final Context _context; + + public MigrationThread(Context context) { + _context = context; + } + + @Override + public void run() { + super.run(); + AppSettings appSettings = AppSettings.get(); + if (!PermissionChecker.hasExtStoragePerm(_context) || appSettings.isMigrated()) { + return; + } + + File newMemesDir = AssetUpdater.getMemesDir(AppSettings.get()); + File newTemplatesDir = AssetUpdater.getCustomAssetsDir(AppSettings.get()); + File oldMemesDir = new File(Environment.getExternalStoragePublicDirectory( + Environment.DIRECTORY_PICTURES), _context.getString(R.string.app_name)); + File oldTemplatesDir = new File(oldMemesDir, "templates"); + File oldTemplatesCustomDir = new File(oldMemesDir, "custom"); + String thumbnails = ".thumbnails"; + + if (!oldMemesDir.exists()) { + return; + } + + FileUtils.deleteRecursive(new File(oldMemesDir, thumbnails)); + + try { + FileUtils.deleteRecursive(new File(oldTemplatesCustomDir, thumbnails)); + for (File file : new File(oldTemplatesDir, "custom").listFiles()) { + if (file.isFile()) { + FileUtils.renameFile(file, new File(newTemplatesDir, file.getName())); + } + } + } catch (Exception ignored) { + } + + try { + for (File file : oldMemesDir.listFiles()) { + if (file.isFile()) { + FileUtils.renameFile(file, new File(newMemesDir, file.getName())); + } + } + } catch (Exception ignored) { + } + FileUtils.deleteRecursive(oldTemplatesCustomDir); + appSettings.setMigrated(true); + } +} diff --git a/app/src/main/java/io/github/gsantner/memetastic/service/ThumbnailCleanupTask.java b/app/src/main/java/io/github/gsantner/memetastic/service/ThumbnailCleanupTask.java new file mode 100644 index 000000000..246d2492a --- /dev/null +++ b/app/src/main/java/io/github/gsantner/memetastic/service/ThumbnailCleanupTask.java @@ -0,0 +1,22 @@ +package io.github.gsantner.memetastic.service; + +import android.content.Context; + +import net.gsantner.opoc.util.FileUtils; + +import java.io.File; + +import io.github.gsantner.memetastic.util.AppSettings; + +public class ThumbnailCleanupTask extends Thread { + private Context _context; + + public ThumbnailCleanupTask(Context context) { + _context = context; + } + + public void run() { + File cacheDirForFiles = new File(_context.getCacheDir(), AppSettings.get().getSaveDirectory().getAbsolutePath().substring(1)); + FileUtils.deleteRecursive(cacheDirForFiles); + } +} \ No newline at end of file diff --git a/app/src/main/java/io/github/gsantner/memetastic/ui/FontAdapter.java b/app/src/main/java/io/github/gsantner/memetastic/ui/FontAdapter.java index 75e6dab9a..05ca467be 100644 --- a/app/src/main/java/io/github/gsantner/memetastic/ui/FontAdapter.java +++ b/app/src/main/java/io/github/gsantner/memetastic/ui/FontAdapter.java @@ -5,25 +5,28 @@ import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; +import android.widget.Spinner; import android.widget.TextView; import java.util.List; -import io.github.gsantner.memetastic.data.MemeFont; +import io.github.gsantner.memetastic.data.MemeData; /** * Adapter to show the available fonts rendered in there own style as preview */ -public class FontAdapter extends ArrayAdapter { - boolean _showCustomSelectedText; - String _customSelectedText; +public class FontAdapter extends ArrayAdapter { + private boolean _showCustomSelectedText; + private String _customSelectedText; + private List _fontList; - public FontAdapter(Context context, int resource, List fontList) { + public FontAdapter(Context context, int resource, List fontList) { this(context, resource, fontList, false, ""); } - public FontAdapter(Context context, int resource, List fontList, boolean showCustomSelectedText, String customSelectedText) { + public FontAdapter(Context context, int resource, List fontList, boolean showCustomSelectedText, String customSelectedText) { super(context, resource, fontList); + _fontList = fontList; _showCustomSelectedText = showCustomSelectedText; _customSelectedText = customSelectedText; } @@ -42,16 +45,25 @@ public View getDropDownView(int position, View convertView, ViewGroup parent) { return getTheView(position, convertView, parent); } - // set how the item should look like (rendered in own font) + // set how the item should look like (rendered in own conf) private View getTheView(int position, View convertView, ViewGroup parent) { - String fontName = getItem(position).getFontName(); + String fontName = getItem(position).conf.getTitle(); if (fontName.contains("_") && !fontName.endsWith("_")) ; fontName = fontName.substring(fontName.indexOf('_') + 1); TextView view = (TextView) super.getDropDownView(position, convertView, parent); - view.setTypeface(getItem(position).getFont()); + view.setTypeface(getItem(position).typeFace); view.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16); view.setText(fontName); return view; } + + public void setSelectedFont(Spinner spinner, MemeData.Font font) { + for (int i = 0; i < _fontList.size(); i++) { + if (_fontList.get(i).equals(font)) { + spinner.setSelection(i); + return; + } + } + } } \ No newline at end of file diff --git a/app/src/main/java/io/github/gsantner/memetastic/ui/GridRecycleAdapter.java b/app/src/main/java/io/github/gsantner/memetastic/ui/GridRecycleAdapter.java index 6d9db68de..20979587c 100644 --- a/app/src/main/java/io/github/gsantner/memetastic/ui/GridRecycleAdapter.java +++ b/app/src/main/java/io/github/gsantner/memetastic/ui/GridRecycleAdapter.java @@ -1,10 +1,8 @@ package io.github.gsantner.memetastic.ui; import android.app.Activity; -import android.content.Context; import android.content.Intent; import android.graphics.Bitmap; -import android.support.design.widget.Snackbar; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; @@ -12,30 +10,33 @@ import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.widget.ImageView; +import android.widget.Toast; +import java.util.List; + +import butterknife.BindView; +import butterknife.ButterKnife; import io.github.gsantner.memetastic.App; import io.github.gsantner.memetastic.R; import io.github.gsantner.memetastic.activity.MainActivity; import io.github.gsantner.memetastic.activity.MemeCreateActivity; -import io.github.gsantner.memetastic.data.MemeOriginAssets; -import io.github.gsantner.memetastic.data.MemeOriginFavorite; -import io.github.gsantner.memetastic.data.MemeOriginInterface; +import io.github.gsantner.memetastic.data.MemeData; +import io.github.gsantner.memetastic.service.ImageLoaderTask; import io.github.gsantner.memetastic.util.ContextUtils; -import io.github.gsantner.memetastic.util.ImageLoaderTask; /** * Adapter to show images in a Grid */ -public class GridRecycleAdapter extends RecyclerView.Adapter implements ImageLoaderTask.OnImageLoadedListener { - private MemeOriginInterface _memeObject; +public class GridRecycleAdapter extends RecyclerView.Adapter implements ImageLoaderTask.OnImageLoadedListener { + private List _imageDataList; private int _shortAnimationDuration; private Activity _activity; private App _app; - public GridRecycleAdapter(MemeOriginInterface memeObject, Activity act) { - _memeObject = memeObject; + public GridRecycleAdapter(List imageDataList, Activity activity) { + _imageDataList = imageDataList; _shortAnimationDuration = -1; - _activity = act; + _activity = activity; _app = (App) (_activity.getApplication()); } @@ -46,108 +47,72 @@ public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { return vh; } - /** - * adds/removes a meme template to/from the favorites depending on if it's already a favorite or not - * - * @param positionInGrid the position of the meme in the grid that should be toggled - * @param imageButtonFav the ImageView of the clicked meme to toggle the favorite star - * @param memeObj the memes of the grid where the clicked meme is saved in - */ - private void toggleFavorite(int positionInGrid, ImageView imageButtonFav, MemeOriginInterface memeObj) { - if (_app.settings.toggleFavorite(memeObj.getFilepath(positionInGrid))) { - tintFavourite(imageButtonFav, true); - } else { - if (_memeObject instanceof MemeOriginFavorite) { - ((MemeOriginFavorite) _memeObject).setFiles(_app.settings.getFavoriteMemes()); - notifyDataSetChanged(); - } else { - tintFavourite(imageButtonFav, false); - } - } - } - // sets up the view of the item at the position in the grid @Override public void onBindViewHolder(final ViewHolder holder, int pos) { - final int position = pos; + final MemeData.Image imageData = _imageDataList.get(pos); + if (imageData == null || imageData.fullPath == null || !imageData.fullPath.exists()) { + holder.imageView.setImageResource(R.drawable.ic_mood_bad_black_256dp); + holder.imageButtonFav.setVisibility(View.INVISIBLE); + return; + } holder.imageButtonFav.setVisibility(View.INVISIBLE); holder.imageView.setVisibility(View.INVISIBLE); - ImageLoaderTask taskLoadImage; - if (_memeObject instanceof MemeOriginAssets) { - taskLoadImage = new ImageLoaderTask(this, holder, true, _activity.getAssets()); - } else { - taskLoadImage = new ImageLoaderTask(this, holder, true); - } - taskLoadImage.execute(_memeObject.getPath(position, true)); - holder.imageView.setTag(_memeObject.getFilepath(position)); + ImageLoaderTask taskLoadImage = new ImageLoaderTask<>(this, _activity, true, holder); + taskLoadImage.execute(imageData.fullPath); + holder.imageView.setTag(imageData); + holder.imageButtonFav.setTag(imageData); - tintFavourite(holder.imageButtonFav, _app.settings.isFavorite(_memeObject.getFilepath(position))); + tintFavouriteImage(holder.imageButtonFav, _app.settings.isFavorite(imageData.fullPath.toString())); holder.imageView.setOnLongClickListener(new View.OnLongClickListener() { public boolean onLongClick(View v) { - onImageLongClicked(position, holder.imageButtonFav, _memeObject); + MemeData.Image image = (MemeData.Image) v.getTag(); + Toast.makeText(v.getContext(), image.conf.getTitle(), Toast.LENGTH_SHORT).show(); return true; } }); holder.imageButtonFav.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - toggleFavorite(position, holder.imageButtonFav, _memeObject); + MemeData.Image image = (MemeData.Image) v.getTag(); + if (image.isTemplate) { + toggleFavorite(holder); + } } }); holder.imageView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - if (_memeObject.isTemplate()) { + MemeData.Image image = (MemeData.Image) v.getTag(); + + if (image.isTemplate) { Intent intent = new Intent(_activity, MemeCreateActivity.class); - intent.putExtra(MemeCreateActivity.EXTRA_IMAGE_PATH, _memeObject.getFilepath(position)); - intent.putExtra(MemeCreateActivity.ASSET_IMAGE, _memeObject.isAsset()); + intent.putExtra(MemeCreateActivity.EXTRA_IMAGE_PATH, image.fullPath.getAbsolutePath()); + intent.putExtra(MemeCreateActivity.ASSET_IMAGE, false); _activity.startActivityForResult(intent, MemeCreateActivity.RESULT_MEME_EDITING_FINISHED); } else { if (_activity instanceof MainActivity) { - ((MainActivity) _activity).openImageViewActivityWithImage(_memeObject.getFilepath(position)); + ((MainActivity) _activity).openImageViewActivityWithImage(image.fullPath.getAbsolutePath()); } } } }); } - private void tintFavourite(ImageView iv, boolean isFav) { - ContextUtils.get().setDrawableWithColorToImageView(iv, - isFav ? R.drawable.ic_star_black_32dp : R.drawable.ic_star_border_black_32dp, - isFav ? R.color.comic_yellow : R.color.comic_blue); - } - // gets and returns the count of available items in the grid @Override public int getItemCount() { - return _memeObject.getLength(); - } - - public void onImageLongClicked(final int position, final ImageView iv, final MemeOriginInterface memeObj) { - Context context = iv.getContext().getApplicationContext(); - String pic = _memeObject.getFilepath(position); - if (!pic.contains(context.getString(R.string.app_name))) { - pic = pic.substring(pic.lastIndexOf("_") + 1); - pic = pic.substring(0, pic.indexOf(".")); - } - Snackbar snackbar = Snackbar.make(_activity.findViewById(android.R.id.content), pic, Snackbar.LENGTH_SHORT); - if (memeObj instanceof MemeOriginAssets) { - snackbar.setAction(R.string.main__mode__favs, new View.OnClickListener() { - public void onClick(View v) { - toggleFavorite(position, iv, memeObj); - } - }); - } - snackbar.show(); + return _imageDataList.size(); } @Override public void onImageLoaded(Bitmap bitmap, ViewHolder holder) { + MemeData.Image dataImage = (MemeData.Image) holder.imageView.getTag(); Animation animation = AnimationUtils.loadAnimation(_activity, R.anim.fadeinfast); holder.imageView.startAnimation(animation); - if (_memeObject.showFavButton()) { + if (dataImage.isTemplate) { holder.imageButtonFav.startAnimation(animation); holder.imageButtonFav.setVisibility(View.VISIBLE); } @@ -155,16 +120,41 @@ public void onImageLoaded(Bitmap bitmap, ViewHolder holder) { holder.imageView.setVisibility(View.VISIBLE); } - // contains the image view for the meme and the favorite button to access them + private void toggleFavorite(ViewHolder holder) { + MemeData.Image dataImage = (MemeData.Image) holder.imageView.getTag(); + if (!dataImage.isTemplate) { + return; + } + if (_app.settings.toggleFavorite(dataImage.fullPath.getAbsolutePath())) { + tintFavouriteImage(holder.imageButtonFav, true); + } else { + tintFavouriteImage(holder.imageButtonFav, false); + } + int index = _imageDataList.indexOf(dataImage); + if (index >= 0) { + notifyItemChanged(index); + } + } + + private void tintFavouriteImage(ImageView iv, boolean isFav) { + ContextUtils.setDrawableWithColorToImageView(iv, + isFav ? R.drawable.ic_star_black_32dp : R.drawable.ic_star_border_black_32dp, + isFav ? R.color.comic_yellow : R.color.comic_blue); + } + + + // contains the conf view for the meme and the favorite button to access them public class ViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.item__square_image__image) public ImageView imageView; + + @BindView(R.id.item__square_image__image_bottom_end) public ImageView imageButtonFav; - // saves the instance of the image view of the meme and favorite button to access them later + // saves the instance of the conf view of the meme and favorite button to access them later public ViewHolder(View itemView) { super(itemView); - imageButtonFav = (ImageView) itemView.findViewById(R.id.item__square_image__image_bottom_end); - imageView = (ImageView) itemView.findViewById(R.id.item__square_image__image); + ButterKnife.bind(this, itemView); if (_shortAnimationDuration < 0) _shortAnimationDuration = imageView.getContext().getResources().getInteger( android.R.integer.config_shortAnimTime); diff --git a/app/src/main/java/io/github/gsantner/memetastic/ui/TouchImageView.java b/app/src/main/java/io/github/gsantner/memetastic/ui/TouchImageView.java index 7ef058585..b23448310 100644 --- a/app/src/main/java/io/github/gsantner/memetastic/ui/TouchImageView.java +++ b/app/src/main/java/io/github/gsantner/memetastic/ui/TouchImageView.java @@ -188,7 +188,7 @@ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { viewHeight = MeasureSpec.getSize(heightMeasureSpec); // - // Rescales image on rotation + // Rescales data on rotation // if (oldMeasuredHeight == viewWidth && oldMeasuredHeight == viewHeight || viewWidth == 0 || viewHeight == 0) @@ -212,7 +212,7 @@ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { scale = Math.min(scaleX, scaleY); matrix.setScale(scale, scale); - // Center the image + // Center the data float redundantYSpace = (float) viewHeight - (scale * (float) bmHeight); float redundantXSpace = (float) viewWidth diff --git a/app/src/main/java/io/github/gsantner/memetastic/util/AppCast.java b/app/src/main/java/io/github/gsantner/memetastic/util/AppCast.java new file mode 100644 index 000000000..1a9e55a3c --- /dev/null +++ b/app/src/main/java/io/github/gsantner/memetastic/util/AppCast.java @@ -0,0 +1,69 @@ +package io.github.gsantner.memetastic.util; + +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.support.v4.content.LocalBroadcastManager; + +public class AppCast { + //######################## + //## Send broadcast + //######################## + private static void sendBroadcast(Context c, Intent i) { + if (c != null) { + LocalBroadcastManager.getInstance(c).sendBroadcast(i); + } + } + + //######################## + //## Filter + //######################## + public static IntentFilter getLocalBroadcastFilter() { + IntentFilter intentFilter = new IntentFilter(); + String[] BROADCAST_ACTIONS = { + DOWNLOAD_REQUEST_RESULT.ACTION, + DOWNLOAD_STATUS.ACTION, + ASSETS_LOADED.ACTION + }; + for (String action : BROADCAST_ACTIONS) { + intentFilter.addAction(action); + } + return intentFilter; + } + + //######################## + //## Actions + //######################## + public static class DOWNLOAD_REQUEST_RESULT { + public static final String ACTION = "DOWNLOAD_REQUEST_RESULT"; + public static final String EXTRA_RESULT = "EXTRA_RESULT"; + + public static void send(Context c, int result) { + Intent intent = new Intent(ACTION); + intent.putExtra(EXTRA_RESULT, result); + sendBroadcast(c, intent); + } + } + + public static class ASSETS_LOADED { + public static final String ACTION = "ASSETS_LOADED"; + + public static void send(Context c) { + Intent intent = new Intent(ACTION); + sendBroadcast(c, intent); + } + } + + public static class DOWNLOAD_STATUS { + public static final String ACTION = "DOWNLOAD_STATUS"; + public static final String EXTRA_STATUS = "EXTRA_STATUS"; + public static final String EXTRA_PERCENT = "EXTRA_PERCENT"; + + public static void send(Context c, int status, int percent) { + Intent intent = new Intent(ACTION); + intent.putExtra(EXTRA_STATUS, status); + intent.putExtra(EXTRA_PERCENT, percent); + sendBroadcast(c, intent); + } + } +} diff --git a/app/src/main/java/io/github/gsantner/memetastic/util/AppSettings.java b/app/src/main/java/io/github/gsantner/memetastic/util/AppSettings.java index 184b37c9e..7d245c641 100644 --- a/app/src/main/java/io/github/gsantner/memetastic/util/AppSettings.java +++ b/app/src/main/java/io/github/gsantner/memetastic/util/AppSettings.java @@ -1,15 +1,21 @@ package io.github.gsantner.memetastic.util; import android.content.Context; +import android.os.Environment; +import net.gsantner.opoc.util.AppSettingsBase; + +import java.io.File; +import java.text.ParseException; import java.util.ArrayList; import java.util.Arrays; +import java.util.Date; import java.util.List; import io.github.gsantner.memetastic.App; import io.github.gsantner.memetastic.BuildConfig; import io.github.gsantner.memetastic.R; -import net.gsantner.opoc.util.AppSettingsBase; +import io.github.gsantner.memetastic.service.AssetUpdater; public class AppSettings extends AppSettingsBase { private static final int MAX_FAVS = 50; @@ -84,52 +90,52 @@ public int getThumbnailQualityReal() { return (int) (100 + (939 * (val / 100.0))); } - public void setLastSelectedFont(int value) { - setInt(R.string.pref_key__last_selected_font, value); + public void setLastUsedFont(String value) { + setString(R.string.pref_key__last_used_font, value); } - public int getLastSelectedFont() { - return getInt(R.string.pref_key__last_selected_font, 0); + public String getLastUsedFont() { + return getString(R.string.pref_key__last_used_font, ""); } public void setFavoriteMemes(String[] value) { - setStringArray(R.string.pref_key__meme_favourites, value); + setStringArray(R.string.pref_key__favourite_meme_templates, value); } - public String[] getFavoriteMemes() { - return getStringArray(R.string.pref_key__meme_favourites); + public String[] getFavoriteMemeTemplates() { + return getStringArray(R.string.pref_key__favourite_meme_templates); } - public void appendFavoriteMeme(String meme) { - String[] memes = insertAndMaximize(getFavoriteMemes(), meme, MAX_FAVS); + public void appendFavoriteMeme(String filepath) { + String[] memes = insertAndMaximize(getFavoriteMemeTemplates(), filepath, MAX_FAVS); setFavoriteMemes(memes); } - public boolean isFavorite(String name) { - if (getFavoriteMemes() == null) + public boolean isFavorite(String filepath) { + if (getFavoriteMemeTemplates() == null) return false; - for (String s : getFavoriteMemes()) { - if (s.equalsIgnoreCase(name)) + for (String s : getFavoriteMemeTemplates()) { + if (s.equals(filepath)) return true; } return false; } - public boolean toggleFavorite(String name) { - if (!isFavorite(name)) { - appendFavoriteMeme(name); + public boolean toggleFavorite(String filepath) { + if (!isFavorite(filepath)) { + appendFavoriteMeme(filepath); return true; } - removeFavorite(name); + removeFavorite(filepath); return false; } - public void removeFavorite(String name) { - String[] favs = getFavoriteMemes(); + public void removeFavorite(String filepath) { + String[] favs = getFavoriteMemeTemplates(); ArrayList newFavs = new ArrayList(); for (String fav : favs) { - if (!fav.equalsIgnoreCase(name)) + if (!fav.equals(filepath)) newFavs.add(fav); } setFavoriteMemes(newFavs.toArray(new String[newFavs.size()])); @@ -179,8 +185,12 @@ public boolean isAppFirstStart(boolean doSet) { public boolean isAppCurrentVersionFirstStart() { int value = getInt(R.string.pref_key__app_first_start_current_version, -1); + boolean isFirstStart = value != BuildConfig.VERSION_CODE && !BuildConfig.IS_TEST_BUILD; setInt(R.string.pref_key__app_first_start_current_version, BuildConfig.VERSION_CODE); - return value != BuildConfig.VERSION_CODE && !BuildConfig.IS_TEST_BUILD; + if (isFirstStart) { + setLastArchiveCheckDate(new Date(0)); + } + return isFirstStart; } public boolean isAutoSaveMeme() { @@ -191,8 +201,8 @@ public int getDefaultMainMode() { return getIntOfStringPref(R.string.pref_key__default_main_mode, 0); } - public boolean isShuffleMemeCategories() { - return getBool(R.string.pref_key__is_shuffle_meme_categories, false); + public boolean isShuffleTagLists() { + return getBool(R.string.pref_key__is_shuffle_meme_tags, false); } public boolean isEditorStatusBarHidden() { @@ -206,4 +216,56 @@ public boolean isOverviewStatusBarHidden() { public String getLanguage() { return getString(R.string.pref_key__language, ""); } + + public void setSaveDirectory(String value) { + setString(R.string.pref_key__save_directory, value); + } + + public File getSaveDirectory() { + String dir = getString(R.string.pref_key__save_directory, ""); + if (dir.isEmpty()) { + + dir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + , rstr(R.string.app_name).toLowerCase()) + .getAbsolutePath(); + setSaveDirectory(dir); + } + return new File(dir); + } + + public Date getLastAssetArchiveDate() throws ParseException { + String date = getString(R.string.pref_key__last_asset_archive_date, ""); + if (date.isEmpty()) { + return new Date(0); + } + return AssetUpdater.FORMAT_RFC3339.parse(date); + } + + public void setLastArchiveCheckDate(Date value) { + setString(R.string.pref_key__last_asset_archive_check_date, AssetUpdater.FORMAT_RFC3339.format(value)); + } + + public Date getLastAssetArchiveCheckDate() { + String date = getString(R.string.pref_key__last_asset_archive_check_date, ""); + if (date.isEmpty()) { + return new Date(0); + } + try { + return AssetUpdater.FORMAT_RFC3339.parse(date); + } catch (ParseException e) { + return new Date(0); + } + } + + public void setLastArchiveDate(Date value) { + setString(R.string.pref_key__last_asset_archive_date, AssetUpdater.FORMAT_RFC3339.format(value)); + } + + public boolean isMigrated() { + return getBool(R.string.pref_key__is_migrated, false); + } + + public void setMigrated(boolean value) { + setBool(R.string.pref_key__is_migrated, value); + } } diff --git a/app/src/main/java/io/github/gsantner/memetastic/util/ContextUtils.java b/app/src/main/java/io/github/gsantner/memetastic/util/ContextUtils.java index a6c370447..485fbf300 100644 --- a/app/src/main/java/io/github/gsantner/memetastic/util/ContextUtils.java +++ b/app/src/main/java/io/github/gsantner/memetastic/util/ContextUtils.java @@ -2,24 +2,16 @@ import android.content.Context; import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.graphics.Matrix; import android.os.Build; -import android.os.Environment; -import android.support.annotation.ColorRes; -import android.support.annotation.DrawableRes; -import android.support.v4.content.ContextCompat; import android.view.View; -import android.widget.ImageView; import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; +import java.util.Date; import io.github.gsantner.memetastic.App; -import io.github.gsantner.memetastic.R; import io.github.gsantner.memetastic.data.MemeLibConfig; +import io.github.gsantner.memetastic.service.AssetUpdater; +import io.github.gsantner.memetastic.service.MigrationThread; public class ContextUtils extends net.gsantner.opoc.util.ContextUtils { public ContextUtils(Context context) { @@ -31,12 +23,20 @@ public static ContextUtils get() { return new ContextUtils(App.get()); } + public static void checkForAssetUpdates(Context context) { + new MigrationThread(context).start(); + Date fiveDaysAgo = new Date(System.currentTimeMillis() - 5 * 1000 * 60 * 60 * 24); + if (AppSettings.get().getLastAssetArchiveCheckDate().before(fiveDaysAgo)) { + new AssetUpdater.UpdateThread(context, false).start(); + } + } + public Bitmap scaleBitmap(Bitmap bitmap) { return scaleBitmap(bitmap, 300); } - public Bitmap loadImageFromFilesystem(String imagePath) { + public Bitmap loadImageFromFilesystem(File imagePath) { return loadImageFromFilesystem(imagePath, MemeLibConfig.MEME_FULLSCREEN_MAX_IMAGESIZE); } @@ -69,11 +69,11 @@ public void onSystemUiVisibilityChange(int visibility) { } /** - * Calculates the scaling factor to convert font size to size in pixels + * Calculates the scaling factor to convert conf size to size in pixels * * @param w width of the bitmap where a text should be written on * @param h height of the bitmap where a text should be written on - * @return the size of the font in pixels + * @return the size of the conf in pixels */ public float getScalingFactorInPixelsForWritingOnPicture(int w, int h) { final float fontScaler = (float) 133; @@ -86,12 +86,4 @@ public float getScalingFactorInPixelsForWritingOnPicture(int w, int h) { return (size + addl) / (fontScaler); } - - public File getPicturesMemetasticFolder() { - return new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), _context.getString(R.string.app_name)); - } - - public File getPicturesMemetasticTemplatesCustomFolder() { - return new File(new File(getPicturesMemetasticFolder(), "templates"), "custom"); - } } diff --git a/app/src/main/java/io/github/gsantner/memetastic/util/ImageLoaderTask.java b/app/src/main/java/io/github/gsantner/memetastic/util/ImageLoaderTask.java deleted file mode 100644 index fef7e7857..000000000 --- a/app/src/main/java/io/github/gsantner/memetastic/util/ImageLoaderTask.java +++ /dev/null @@ -1,97 +0,0 @@ -package io.github.gsantner.memetastic.util; - -import android.content.res.AssetManager; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.graphics.Rect; -import android.os.AsyncTask; - -import java.io.IOException; -import java.io.InputStream; - -import io.github.gsantner.memetastic.data.MemeLibConfig; -import io.github.gsantner.memetastic.ui.GridRecycleAdapter; - -public class ImageLoaderTask extends AsyncTask { - public interface OnImageLoadedListener { - void onImageLoaded(Bitmap bitmap, GridRecycleAdapter.ViewHolder holder); - } - - private final int _sampleSizeThumbnails; - private final OnImageLoadedListener _listener; - private final GridRecycleAdapter.ViewHolder _holder; - private final AssetManager _assetManager; - private final boolean _isThumbnail; - - public ImageLoaderTask(OnImageLoadedListener listener, GridRecycleAdapter.ViewHolder holder, boolean isThumbnail) { - this(listener, holder, isThumbnail, null); - } - - public ImageLoaderTask(OnImageLoadedListener listener, GridRecycleAdapter.ViewHolder holder, boolean isThumbnail, AssetManager assetManager) { - _listener = listener; - _holder = holder; - _isThumbnail = isThumbnail; - _assetManager = assetManager; - _sampleSizeThumbnails = AppSettings.get().getThumbnailQualityReal(); - } - - private Bitmap loadStorageImage(String imagePath) { - final BitmapFactory.Options options = new BitmapFactory.Options(); - options.inJustDecodeBounds = true; - BitmapFactory.decodeFile(imagePath, options); - - if (_isThumbnail) - options.inSampleSize = ContextUtils.get().calculateInSampleSize(options, _sampleSizeThumbnails); - else - options.inSampleSize = ContextUtils.get().calculateInSampleSize(options, MemeLibConfig.MEME_FULLSCREEN_MAX_IMAGESIZE); - options.inJustDecodeBounds = false; - return BitmapFactory.decodeFile(imagePath, options); - } - - private Bitmap loadAssetImage(String imagePath) { - final BitmapFactory.Options options = new BitmapFactory.Options(); - options.inJustDecodeBounds = true; - InputStream inputStream = null; - try { - inputStream = _assetManager.open(imagePath); - BitmapFactory.decodeStream(inputStream, new Rect(0, 0, 0, 0), options); - if (_isThumbnail) { - options.inSampleSize = ContextUtils.get().calculateInSampleSize(options, _sampleSizeThumbnails); - } else { - options.inSampleSize = ContextUtils.get().calculateInSampleSize(options, MemeLibConfig.MEME_FULLSCREEN_MAX_IMAGESIZE); - } - if (inputStream != null) { - inputStream.close(); - } - inputStream = _assetManager.open(imagePath); - options.inJustDecodeBounds = false; - return BitmapFactory.decodeStream(inputStream, new Rect(0, 0, 0, 0), options); - } catch (IOException e) { - e.printStackTrace(); - } finally { - if (inputStream != null) { - try { - inputStream.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - return null; - } - - @Override - protected Bitmap doInBackground(String... params) { - if (_assetManager == null) { - return loadStorageImage(params[0]); - } - return loadAssetImage(params[0]); - } - - @Override - protected void onPostExecute(Bitmap bitmap) { - super.onPostExecute(bitmap); - if (_listener != null) - _listener.onImageLoaded(bitmap, _holder); - } -} diff --git a/app/src/main/java/io/github/gsantner/memetastic/util/PermissionChecker.java b/app/src/main/java/io/github/gsantner/memetastic/util/PermissionChecker.java new file mode 100644 index 000000000..c8b4b2804 --- /dev/null +++ b/app/src/main/java/io/github/gsantner/memetastic/util/PermissionChecker.java @@ -0,0 +1,48 @@ +package io.github.gsantner.memetastic.util; + +import android.Manifest; +import android.app.Activity; +import android.content.Context; +import android.content.pm.PackageManager; +import android.support.v4.app.ActivityCompat; +import android.support.v4.content.ContextCompat; + +import java.io.File; + +import io.github.gsantner.memetastic.R; + +public class PermissionChecker { + + public static boolean doIfPermissionGranted(final Activity activity) { + if (!hasExtStoragePerm(activity)) { + ActivityCompat.requestPermissions( + activity, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 123 + ); + return false; + } + return true; + } + + public static boolean hasExtStoragePerm(Context context) { + return ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED; + } + + public static boolean checkPermissionResult(final Activity activity, int requestCode, String[] permissions, int[] grantResults) { + if (requestCode == 123) { + if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { + return true; + } + } + ActivityUtils.get(activity).showSnackBar(R.string.error_storage_permission, true); + return false; + } + + public static boolean mkSaveDir(Activity activity) { + File saveDir = AppSettings.get().getSaveDirectory(); + if (!saveDir.exists() && !saveDir.mkdirs()) { + ActivityUtils.get(activity).showSnackBar(R.string.error_cannot_create_save_dir, false); + return false; + } + return true; + } +} diff --git a/app/src/main/java/io/github/gsantner/memetastic/util/ThumbnailCleanupTask.java b/app/src/main/java/io/github/gsantner/memetastic/util/ThumbnailCleanupTask.java deleted file mode 100644 index 6799c5cb3..000000000 --- a/app/src/main/java/io/github/gsantner/memetastic/util/ThumbnailCleanupTask.java +++ /dev/null @@ -1,76 +0,0 @@ -package io.github.gsantner.memetastic.util; - -import android.content.Context; -import android.graphics.Bitmap; - -import java.io.File; -import java.io.FilenameFilter; -import java.util.Arrays; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -import io.github.gsantner.memetastic.R; -import io.github.gsantner.memetastic.data.MemeOriginStorage; - -public class ThumbnailCleanupTask extends Thread implements FilenameFilter { - private String strres_dotThumbnails; - - public ThumbnailCleanupTask(Context context) { - strres_dotThumbnails = context.getString(R.string.dot_thumbnails); - } - - public void run() { - ContextUtils cu = ContextUtils.get(); - - File picPath = cu.getPicturesMemetasticFolder(); - File thumbPath = new File(picPath, strres_dotThumbnails); - cleanupThumbnails(picPath, thumbPath); - - - picPath = cu.getPicturesMemetasticTemplatesCustomFolder(); - thumbPath = new File(picPath, strres_dotThumbnails); - cleanupThumbnails(picPath, thumbPath); - } - - @SuppressWarnings("ResultOfMethodCallIgnored") - private void cleanupThumbnails(File picPath, File thumbPath) { - - // Scan for unused Thumbnails - File[] tmp = thumbPath.listFiles(this); - tmp = tmp != null ? tmp : new File[0]; - List thumbFiles = new LinkedList(Arrays.asList(tmp)); - tmp = picPath.listFiles(this); - for (File picFile : (tmp == null ? new File[0] : tmp)) { - String filename = picFile.getName(); - for (int i = 0; i < thumbFiles.size(); i++) { - if (thumbFiles.get(i).getName().equals(filename)) { - thumbFiles.remove(i); - break; - } - } - } - - // Delete unused thumbnails - for (File thumbFile : thumbFiles) { - thumbFile.delete(); - } - - // Create not existing thumbs - MemeOriginStorage memeOriginStorage = new MemeOriginStorage(picPath, strres_dotThumbnails); - Map missing = memeOriginStorage.getMissingThumbnails(); - for (Map.Entry entry : missing.entrySet()) { - Bitmap bitmap = ContextUtils.get().loadImageFromFilesystem(entry.getKey()); - if (bitmap != null) { - File thumbFp = new File(entry.getValue()); - bitmap = ContextUtils.get().scaleBitmap(bitmap); - ContextUtils.get().writeImageToFileJpeg(thumbFp.getParent(), thumbFp.getName(), bitmap); - } - } - } - - @Override - public boolean accept(File dir, String filename) { - return new File(dir, filename).isFile(); - } -} \ No newline at end of file diff --git a/app/src/main/java/net/gsantner/opoc/util/ActivityUtils.java b/app/src/main/java/net/gsantner/opoc/util/ActivityUtils.java index 9d5850d74..1d5fe8cc3 100644 --- a/app/src/main/java/net/gsantner/opoc/util/ActivityUtils.java +++ b/app/src/main/java/net/gsantner/opoc/util/ActivityUtils.java @@ -22,6 +22,7 @@ import android.text.SpannableString; import android.text.method.LinkMovementMethod; import android.util.TypedValue; +import android.view.View; import android.view.WindowManager; import android.view.inputmethod.InputMethodManager; @@ -76,11 +77,18 @@ public void animateToActivity(Intent intent, Boolean finishFromActivity, Integer } - public void showSnackBar(@StringRes int stringId, boolean showLong) { - Snackbar.make(_activity.findViewById(android.R.id.content), stringId, + public void showSnackBar(@StringRes int stringResId, boolean showLong) { + Snackbar.make(_activity.findViewById(android.R.id.content), stringResId, showLong ? Snackbar.LENGTH_LONG : Snackbar.LENGTH_SHORT).show(); } + public void showSnackBar(@StringRes int stringResId, boolean showLong, @StringRes int actionResId, View.OnClickListener listener) { + Snackbar.make(_activity.findViewById(android.R.id.content), stringResId, + showLong ? Snackbar.LENGTH_LONG : Snackbar.LENGTH_SHORT) + .setAction(actionResId, listener) + .show(); + } + public void hideSoftKeyboard() { InputMethodManager inputMethodManager = (InputMethodManager) _activity.getSystemService(Activity.INPUT_METHOD_SERVICE); if (_activity.getCurrentFocus() != null && _activity.getCurrentFocus().getWindowToken() != null) { diff --git a/app/src/main/java/net/gsantner/opoc/util/ContextUtils.java b/app/src/main/java/net/gsantner/opoc/util/ContextUtils.java index 01f4ef06c..8605ed208 100644 --- a/app/src/main/java/net/gsantner/opoc/util/ContextUtils.java +++ b/app/src/main/java/net/gsantner/opoc/util/ContextUtils.java @@ -371,13 +371,13 @@ public Bitmap drawableToBitmap(Drawable drawable) { return bitmap; } - public Bitmap loadImageFromFilesystem(String imagePath, int maxDimen) { + public Bitmap loadImageFromFilesystem(File imagePath, int maxDimen) { BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; - BitmapFactory.decodeFile(imagePath, options); + BitmapFactory.decodeFile(imagePath.getAbsolutePath(), options); options.inSampleSize = calculateInSampleSize(options, maxDimen); options.inJustDecodeBounds = false; - return BitmapFactory.decodeFile(imagePath, options); + return BitmapFactory.decodeFile(imagePath.getAbsolutePath(), options); } /** @@ -388,7 +388,7 @@ public Bitmap loadImageFromFilesystem(String imagePath, int maxDimen) { * @return the scaling factor that needs to be applied to the bitmap */ public int calculateInSampleSize(BitmapFactory.Options options, int maxDimen) { - // Raw height and width of image + // Raw height and width of conf int height = options.outHeight; int width = options.outWidth; int inSampleSize = 1; @@ -407,18 +407,29 @@ public Bitmap scaleBitmap(Bitmap bitmap, int maxDimen) { return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); } - public File writeImageToFileJpeg(String path, String filename, Bitmap image) { - return writeImageToFile(path, filename, image, Bitmap.CompressFormat.JPEG, 95); + public File writeImageToFileJpeg(File imageFile, Bitmap image) { + return writeImageToFile(imageFile, image, Bitmap.CompressFormat.JPEG, 95); } - public File writeImageToFile(String path, String filename, Bitmap image, CompressFormat format, int quality) { - File imageFile = new File(path); - if (imageFile.exists() || imageFile.mkdirs()) { - imageFile = new File(path, filename); + public File writeImageToFileDetectFormat(File imageFile, Bitmap image, int quality) { + CompressFormat format = CompressFormat.JPEG; + String lc = imageFile.getAbsolutePath().toLowerCase(); + if (lc.endsWith(".png")) { + format = CompressFormat.PNG; + } + if (lc.endsWith(".webp")) { + format = CompressFormat.WEBP; + } + return writeImageToFile(imageFile, image, format, quality); + } + + public File writeImageToFile(File imageFile, Bitmap image, CompressFormat format, int quality) { + File folder = new File(imageFile.getParent()); + if (folder.exists() || folder.mkdirs()) { FileOutputStream stream = null; try { - stream = new FileOutputStream(imageFile); // overwrites this image every time + stream = new FileOutputStream(imageFile); // overwrites this conf every time image.compress(format, quality, stream); return imageFile; } catch (FileNotFoundException ignored) { diff --git a/app/src/main/java/net/gsantner/opoc/util/FileUtils.java b/app/src/main/java/net/gsantner/opoc/util/FileUtils.java index ff5132dab..a1e031539 100644 --- a/app/src/main/java/net/gsantner/opoc/util/FileUtils.java +++ b/app/src/main/java/net/gsantner/opoc/util/FileUtils.java @@ -13,8 +13,13 @@ package net.gsantner.opoc.util; +import android.webkit.MimeTypeMap; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.BufferedWriter; +import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; @@ -23,8 +28,10 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.io.OutputStream; import java.util.ArrayList; import java.util.List; +import java.util.UUID; @SuppressWarnings({"WeakerAccess", "unused", "SameParameterValue", "SpellCheckingInspection", "deprecation"}) public class FileUtils { @@ -79,6 +86,84 @@ public static List readCloseTextStream(final InputStream stream, boolean return lines; } + public static byte[] readBinaryFile(final File file) { + try { + return readCloseBinaryStream(new FileInputStream(file), (int) file.length()); + } catch (FileNotFoundException e) { + System.err.println("readBinaryFile: File " + file + " not found."); + } + + return new byte[0]; + } + + public static byte[] readCloseBinaryStream(final InputStream stream, int byteCount) { + final ArrayList lines = new ArrayList<>(); + BufferedInputStream reader = null; + byte[] buf = new byte[byteCount]; + int totalBytesRead = 0; + try { + reader = new BufferedInputStream(stream); + while (totalBytesRead < byteCount) { + int bytesRead = reader.read(buf, totalBytesRead, byteCount - totalBytesRead); + if (bytesRead > 0) { + totalBytesRead = totalBytesRead + bytesRead; + } + } + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (reader != null) { + try { + reader.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return buf; + } + + // Read binary stream (of unknown conf size) + public static byte[] readCloseBinaryStream(final InputStream stream) { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try { + byte[] buffer = new byte[BUFFER_SIZE]; + int read; + while ((read = stream.read(buffer)) != -1) { + baos.write(buffer, 0, read); + } + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (stream != null) { + try { + stream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return baos.toByteArray(); + } + + public static boolean writeFile(final File file, byte[] data) { + try { + OutputStream output = null; + try { + output = new BufferedOutputStream(new FileOutputStream(file)); + output.write(data); + output.flush(); + return true; + } finally { + if (output != null) { + output.close(); + } + } + } catch (Exception ex) { + return false; + } + } + public static boolean writeFile(final File file, final String content) { BufferedWriter writer = null; try { @@ -104,6 +189,11 @@ public static boolean writeFile(final File file, final String content) { } public static boolean copyFile(final File src, final File dst) { + // Just touch file if src is empty + if (src.length() == 0) { + return touch(dst); + } + InputStream is = null; FileOutputStream os = null; try { @@ -115,6 +205,7 @@ public static boolean copyFile(final File src, final File dst) { while ((len = is.read(buf)) > 0) { os.write(buf, 0, len); } + return true; } finally { if (is != null) { is.close(); @@ -126,7 +217,6 @@ public static boolean copyFile(final File src, final File dst) { } catch (IOException ex) { return false; } - return true; } // Returns -1 if the file did not contain any of the needles, otherwise, @@ -166,4 +256,62 @@ public static boolean deleteRecursive(final File file) { } return ok; } + + public static String getMimeType(String url) { + String mime = null; + String ext = MimeTypeMap.getFileExtensionFromUrl(url); + return ext != null ? MimeTypeMap.getSingleton().getMimeTypeFromExtension(ext) : null; + } + + // Example: Check if this is maybe a conf: (str, "jpg", "png", "jpeg") + public static boolean hasExtension(String str, String... extensions) { + String lc = str.toLowerCase(); + for (String extension : extensions) { + if (lc.endsWith("." + extension.toLowerCase())) { + return true; + } + } + return false; + } + + public static boolean renameFile(File srcFile, File destFile) { + if (srcFile.getAbsolutePath().equals(destFile.getAbsolutePath())) { + return false; + } + + // renameTo will fail in case of case-changed filename in same dir.Even on case-sensitive FS!!! + if (srcFile.getParent().equals(destFile.getParent()) && srcFile.getName().toLowerCase().equals(destFile.getName().toLowerCase())) { + File tmpFile = new File(destFile.getParent(), UUID.randomUUID().getLeastSignificantBits() + ".tmp"); + if (!tmpFile.exists()) { + renameFile(srcFile, tmpFile); + srcFile = tmpFile; + } + } + + if (!srcFile.renameTo(destFile)) { + if (copyFile(srcFile, destFile) && !srcFile.delete()) { + if (!destFile.delete()) { + return false; + } + return false; + } + } + return true; + } + + @SuppressWarnings("ResultOfMethodCallIgnored") + public static boolean renameFileInSameFolder(File srcFile, String destFilename) { + return renameFile(srcFile, new File(srcFile.getParent(), destFilename)); + } + + public static boolean touch(File file) { + try { + if (!file.exists()) { + new FileOutputStream(file).close(); + } + return file.setLastModified(System.currentTimeMillis()); + } catch (IOException e) { + return false; + } + } } diff --git a/app/src/main/java/net/gsantner/opoc/util/ZipUtils.java b/app/src/main/java/net/gsantner/opoc/util/ZipUtils.java new file mode 100644 index 000000000..2dc8ee22d --- /dev/null +++ b/app/src/main/java/net/gsantner/opoc/util/ZipUtils.java @@ -0,0 +1,167 @@ +/* + * ------------------------------------------------------------------------------ + * Lonami Exo wrote this. You can do whatever you want + * with it. If we meet some day, and you think it is worth it, you can buy me + * a coke in return. Provided as is without any kind of warranty. Do not blame + * or sue me if something goes wrong. No attribution required. + * - Lonami Exo + * + * License: Creative Commons Zero (CC0 1.0) + * http://creativecommons.org/publicdomain/zero/1.0/ + * ---------------------------------------------------------------------------- + */ +package net.gsantner.opoc.util; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; +import java.util.zip.ZipOutputStream; + +@SuppressWarnings({"WeakerAccess", "unused", "SameParameterValue", "SpellCheckingInspection", "deprecation"}) +public class ZipUtils { + private static final int BUFFER_SIZE = 4096; + + public static boolean unzip(final File zipFile, final File destRootFolder, boolean flatten) { + return unzip(zipFile, destRootFolder, flatten, null); + } + + public static boolean unzip(final File zipFile, final File destRootFolder, + final boolean flatten, final Callback progressCallback) { + try { + final float knownLength = progressCallback == null ? -1f : getZipLength(zipFile); + return unzip(new FileInputStream(zipFile), destRootFolder, flatten, progressCallback, knownLength); + } catch (IOException ignored) { + return false; + } + } + + public static boolean unzip(final InputStream input, final File destRootFolder, + final boolean flatten, final Callback progressCallback, + final float knownLength) throws IOException { + String filename; + final ZipInputStream in = new ZipInputStream(new BufferedInputStream(input)); + + int count; + int written = 0; + final byte[] buffer = new byte[BUFFER_SIZE]; + float invLength = 1f / knownLength; + + ZipEntry ze; + while ((ze = in.getNextEntry()) != null) { + filename = ze.getName(); + if (ze.isDirectory()) { + if (!flatten && !new File(destRootFolder, filename).mkdirs()) + return false; + } else { + if (flatten) { + final int idx = filename.lastIndexOf("/"); + if (idx != -1) + filename = filename.substring(idx + 1); + } + + final FileOutputStream out = new FileOutputStream(new File(destRootFolder, filename)); + while ((count = in.read(buffer)) != -1) { + out.write(buffer, 0, count); + if (invLength != -1f) { + written += count; + progressCallback.onCallback(written * invLength); + } + } + + out.close(); + in.closeEntry(); + } + } + in.close(); + return true; + } + + // TODO Maybe there's a way to avoid reading the zip twice, + // but ZipEntry.getSize() may return -1 so we can't just cace the ZipEntries + private static long getZipLength(final File zipFile) { + int count; + long totalSize = 0; + byte[] buffer = new byte[BUFFER_SIZE]; + try { + final ZipInputStream in = new ZipInputStream(new BufferedInputStream(new FileInputStream(zipFile))); + + ZipEntry ze; + while ((ze = in.getNextEntry()) != null) { + if (!ze.isDirectory()) { + if (ze.getSize() == -1) { + while ((count = in.read(buffer)) != -1) + totalSize += count; + } else { + totalSize += ze.getSize(); + } + } + } + + in.close(); + return totalSize; + } catch (IOException ignored) { + return -1; + } + } + + public static void zipFolder(final File srcFolder, final OutputStream out) throws IOException { + ZipOutputStream outZip = null; + try { + outZip = new ZipOutputStream(out); + addFolderToZip("", srcFolder, outZip); + } finally { + if (outZip != null) { + try { + outZip.close(); + } catch (IOException ignored) { + } + } + } + } + + private static void addFileToZip(final String pathInsideZip, final File fileToZip, + final ZipOutputStream outZip) throws IOException { + if (fileToZip.isDirectory()) { + addFolderToZip(pathInsideZip, fileToZip, outZip); + } else { + FileInputStream in = null; + try { + in = new FileInputStream(fileToZip); + outZip.putNextEntry(new ZipEntry(pathInsideZip + "/" + fileToZip.getName())); + + int count; + byte[] buffer = new byte[BUFFER_SIZE]; + while ((count = in.read(buffer)) > 0) + outZip.write(buffer, 0, count); + + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException ignored) { + } + } + } + } + } + + + private static void addFolderToZip(String pathInsideZip, final File folderToZip, + final ZipOutputStream outZip) throws IOException { + pathInsideZip = pathInsideZip.isEmpty() ? + folderToZip.getName() : + pathInsideZip + "/" + folderToZip.getName(); + + File[] files = folderToZip.listFiles(); + if (files != null) { + for (File file : files) + addFileToZip(pathInsideZip, file, outZip); + } + } +} diff --git a/app/src/main/res/drawable/ic_file_download_black_24dp.xml b/app/src/main/res/drawable/ic_file_download_black_24dp.xml new file mode 100644 index 000000000..492b41d34 --- /dev/null +++ b/app/src/main/res/drawable/ic_file_download_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_file_download_white_32dp.xml b/app/src/main/res/drawable/ic_file_download_white_32dp.xml new file mode 100644 index 000000000..7f35357ab --- /dev/null +++ b/app/src/main/res/drawable/ic_file_download_white_32dp.xml @@ -0,0 +1,4 @@ + + + diff --git a/app/src/main/res/drawable/ic_mood_bad_black_256dp.xml b/app/src/main/res/drawable/ic_mood_bad_black_256dp.xml new file mode 100644 index 000000000..993357e6a --- /dev/null +++ b/app/src/main/res/drawable/ic_mood_bad_black_256dp.xml @@ -0,0 +1,4 @@ + + + diff --git a/app/src/main/res/layout/splash__activity.xml b/app/src/main/res/layout/splash__activity.xml deleted file mode 100644 index 3bfa58c5f..000000000 --- a/app/src/main/res/layout/splash__activity.xml +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - - - - - diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 093a319f9..37da0d32a 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -79,4 +79,13 @@ Qualität und Größe von Bildern. Höhere Werte bedeuten eine erhöhte Ladezeit. Abhängig von Geräte-Hardware und Bildgröße kann die App über einen Wert von 25% nicht wie erwartet funktionieren. Sprache der App ändern. Ein Neustart der App ist erforderlich um die Einstellung zu übernehmen Sprache + Dies wird Schriftarten und Meme Vorlagen (ca. 20 MB) herunterladen + Aktuellste Zusatzinhalte herunteladen + Lade herunter + Herunterladen fehlgeschlagen + Herunterladen erfolgreich + Fehler: Konnte Speicher Ordner nicht erstellen + "Benötige Datei-Berichtigung um Memes zu speichern " + Anderes + Entpacken \ No newline at end of file diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index 3bf0fa849..e6966ac43 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -1,11 +1,19 @@ - + @string/main__memecat__humans @string/main__memecat__animals @string/main__memecat__cartoon @string/main__memecat__rage - @string/main__memecat__custom + @string/main__memecat__other + + + + humans + animals + cartoon + rage + other diff --git a/app/src/main/res/values/strings-not_translatable.xml b/app/src/main/res/values/strings-not_translatable.xml index 0bfd3378c..2577408f6 100644 --- a/app/src/main/res/values/strings-not_translatable.xml +++ b/app/src/main/res/values/strings-not_translatable.xml @@ -14,7 +14,6 @@ MemeTastic_meme.jpg - .thumbnails \n» Pictures » MemeTastic » templates » custom App Version v%1$s @@ -54,8 +53,8 @@ pref_key__render_quality__percent pref_key__cleanup_thumbnails - pref_key__last_selected_font - pref_key__meme_favourites + pref_key__last_used_font + pref_key__favourite_meme_templates pref_key__last_selected_tab pref_key__grid_column_count_portrait pref_key__grid_column_count_landscape @@ -63,10 +62,14 @@ pref_key__app_current_versionfirst_run pref_key__default_main_mode pref_key__auto_save_meme - pref_key__is_shuffle_meme_categories + pref_key__is_shuffle_meme_tags pref_key__is_editor_statusbar_hidden pref_key__is_overview_statusbar_hidden pref_key__thumbnail_quality__percent pref_key__language - + pref_key__save_directory + pref_key__last_asset_archive_date + pref_key__last_asset_archive_check_date + pref_key__is_migrated + pref_key__download_assets_try diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f71ca184b..e14c5e147 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -92,4 +92,13 @@ Language Change language of this app. Restart app for changes to take effect + Error: Cannot create save directory + Need permission for storage to save memes and templates + Other + Downloading + Downloading failed + Unzipping + Sucessfully downloaded + This will download fonts and meme templates (about 20 MB data) + Download latest assets diff --git a/app/src/main/res/xml/preferences_master.xml b/app/src/main/res/xml/preferences_master.xml index 53ae02d08..9cac222b7 100644 --- a/app/src/main/res/xml/preferences_master.xml +++ b/app/src/main/res/xml/preferences_master.xml @@ -20,24 +20,24 @@ app:minValue="2"/> @@ -57,15 +57,15 @@ @@ -85,12 +85,17 @@ +