diff --git a/app/build.gradle b/app/build.gradle index 915c415d..388ff068 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -5,9 +5,12 @@ plugins { id "kotlin-android" } -// Edit this line every release def releaseVersion = "1.0.5" +// Note: Please, don't edit it if you don't know what it does +def startVersionCode = 2808 +def startMillis = 1719658313080 + def gitCommitHash = providers.exec { commandLine("git", "rev-parse", "--short", "HEAD") }.standardOutput.asText.get().trim() @@ -20,19 +23,39 @@ android { applicationId "com.mrboomdev.awery" targetSdk 34 - /* We want to make sure that all build versions across the planet will be in sync */ - var timezone = TimeZone.getTimeZone("UTC") - var calendarCurrent = Calendar.getInstance(timezone) + /* Only one version can be published per second or else horrible things will happen. + * After 70 years we'll be required to make Awery 2 because of an integer limit, + * Date receiver from the test below: + * + * 3865053756028 : 2145398250 - Mon Jun 23 15:02:36 YEKT 2092 + * 3865747384956 : 2146091879 - Tue Jul 01 15:43:04 YEKT 2092 + * 3866441013884 : 2146785508 - Wed Jul 09 16:23:33 YEKT 2092 + * 3867134642812 : 2147479137 - Thu Jul 17 17:04:02 YEKT 2092 + * 3867828271740 : -2146794530 - Fri Jul 25 17:44:31 YEKT 2092 + * */ + versionName "$releaseVersion-$gitCommitHash" + versionCode ((startVersionCode + ((System.currentTimeMillis() - startMillis) / 1000)) as int) + + /*long i = System.currentTimeMillis() + var a = new Date(i) + while(true) { + i += (1000 * 60 * 60 * 24 * 356) + a.setTime(i) - /* Just a random date to begin with */ - var calendarBegin = Calendar.getInstance(timezone) - calendarBegin.set(2024, 2, 4) + versionCode ((startVersionCode + ((i - startMillis) / 1000)) as int) - /* Only one version can be published per hour or else horrible things will happen */ - var newVersionCodeTimeout = 60 * 60 * 1000 + System.out.println("$i : $versionCode - ${a}") - versionName "$releaseVersion-$gitCommitHash" - versionCode (((calendarCurrent.timeInMillis - calendarBegin.timeInMillis) / newVersionCodeTimeout) as int) + if(versionCode < 0 || versionCode >= Integer.MAX_VALUE) { + throw new IllegalStateException("We've reached the end. Now Awery 2 must be released!" + + " Input: $versionCode : ${a}") + } + }*/ + + if(versionCode < 0 || versionCode >= Integer.MAX_VALUE) { + throw new IllegalStateException("We've reached the end. " + + "Now Awery 2 must be released! Input int: $versionCode") + } javaCompileOptions { annotationProcessorOptions { @@ -167,19 +190,18 @@ dependencies { annotationProcessor "androidx.room:room-compiler:$room_version" // UI + implementation "androidx.core:core-splashscreen:1.0.1" implementation "androidx.recyclerview:recyclerview:1.3.2" implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0" implementation "com.google.android.material:material:1.12.0" - implementation "nl.joery.animatedbottombar:library:1.1.0" - implementation "com.davemorrissey.labs:subsampling-scale-image-view-androidx:3.10.0" implementation "com.github.VipulOG:ebook-reader:0.1.6" implementation "com.github.emilaleborn:PageIndicatorView:905cd4e2ab" - implementation "androidx.paging:paging-runtime-ktx:3.3.0" implementation "com.github.skydoves:colorpickerview:2.3.0" - implementation "androidx.core:core-splashscreen:1.0.1" implementation "com.github.skydoves:balloon:1.6.4" - implementation "nl.dionsegijn:konfetti-xml:2.0.4" + implementation "com.davemorrissey.labs:subsampling-scale-image-view-androidx:3.10.0" implementation "com.rubensousa.dpadrecyclerview:dpadrecyclerview:1.3.0-alpha04" + implementation "nl.dionsegijn:konfetti-xml:2.0.4" + implementation "nl.joery.animatedbottombar:library:1.1.0" // Markdown for(String module_name : List.of("core", "editor", "ext-strikethrough", "html", "image", "image-glide", "linkify")) { @@ -214,8 +236,6 @@ dependencies { implementation "com.github.inorichi.injekt:injekt-core:65b0440" implementation "org.jsoup:jsoup:1.15.4" implementation "com.github.gpanther:java-nat-sort:natural-comparator-1.1" - implementation "com.github.tachiyomiorg:unifile:17bec43" - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlin_serialization_verison" implementation "org.jetbrains.kotlinx:kotlinx-serialization-json-okio:$kotlin_serialization_verison" implementation "org.jetbrains.kotlinx:kotlinx-serialization-protobuf:$kotlin_serialization_verison" diff --git a/app/src/main/java/com/mrboomdev/awery/data/settings/NicePreferences.java b/app/src/main/java/com/mrboomdev/awery/data/settings/NicePreferences.java index f1d48987..35f22b7e 100644 --- a/app/src/main/java/com/mrboomdev/awery/data/settings/NicePreferences.java +++ b/app/src/main/java/com/mrboomdev/awery/data/settings/NicePreferences.java @@ -94,7 +94,7 @@ public Boolean getBoolean(String key, Boolean defaultValue) { return null; } - checkEditorExistence().putBoolean(key, defaultValue); + setValue(key, defaultValue); saveSync(); return defaultValue; } diff --git a/app/src/main/java/com/mrboomdev/awery/ui/ThemeManager.java b/app/src/main/java/com/mrboomdev/awery/ui/ThemeManager.java index a422e223..e3bed469 100644 --- a/app/src/main/java/com/mrboomdev/awery/ui/ThemeManager.java +++ b/app/src/main/java/com/mrboomdev/awery/ui/ThemeManager.java @@ -77,14 +77,7 @@ public static void apply( return; } - // In light mode there is no amoled theme so we need to check the current night mode - if(useOLED && (activity.getResources().getConfiguration().uiMode - & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_NO) { - activity.setTheme(getThemeRes(palette, false)); - return; - } - - activity.setTheme(getThemeRes(palette, useOLED)); + activity.setTheme(getThemeRes(palette, useOLED && isDarkModeEnabled())); } public static void apply(Activity activity) { @@ -107,6 +100,9 @@ private static void applyMaterialYou(Activity activity, Bitmap bitmap, boolean u @SuppressLint("PrivateResource") public static int getThemeRes(@NonNull AwerySettings.ThemeColorPalette_Values theme, boolean isAmoled) { + // Amoled theme breaks some colors in a light theme. + isAmoled = isAmoled && isDarkModeEnabled(); + return switch(theme) { case RED -> isAmoled ? R.style.Theme_Awery_RedOLED : R.style.Theme_Awery_Red; case PINK -> isAmoled ? R.style.Theme_Awery_PinkOLED : R.style.Theme_Awery_Pink; diff --git a/app/src/main/java/com/mrboomdev/awery/ui/activity/setup/SetupThemeAdapter.java b/app/src/main/java/com/mrboomdev/awery/ui/activity/setup/SetupThemeAdapter.java index 4f014b44..ff81846a 100644 --- a/app/src/main/java/com/mrboomdev/awery/ui/activity/setup/SetupThemeAdapter.java +++ b/app/src/main/java/com/mrboomdev/awery/ui/activity/setup/SetupThemeAdapter.java @@ -5,6 +5,7 @@ import static com.mrboomdev.awery.app.AweryLifecycle.getActivities; import static com.mrboomdev.awery.data.settings.NicePreferences.getPrefs; import static com.mrboomdev.awery.data.settings.NicePreferences.getSettingsMap; +import static com.mrboomdev.awery.ui.ThemeManager.isDarkModeEnabled; import static com.mrboomdev.awery.util.NiceUtils.find; import static com.mrboomdev.awery.util.NiceUtils.returnWith; import static com.mrboomdev.awery.util.ui.ViewUtil.dpPx; @@ -65,10 +66,15 @@ public static ConcatAdapter create(Context context) { setBottomPadding(recycler, dpPx(24)); return recycler; }), new SettingsAdapter(new SettingsItem() { - private final List items = List.of( - getSettingsMap().findItem(AwerySettings.USE_DARK_THEME.getKey()), - getSettingsMap().findItem(AwerySettings.USE_AMOLED_THEME.getKey()) - ); + private final List items = new ArrayList<>(); + + { + items.add(getSettingsMap().findItem(AwerySettings.USE_DARK_THEME.getKey())); + + if(AwerySettings.USE_DARK_THEME.getValue()) { + items.add(getSettingsMap().findItem(AwerySettings.USE_AMOLED_THEME.getKey())); + } + } @Override public List getItems() { @@ -89,6 +95,7 @@ public void saveValue(SettingsItem item, Object newValue) { if(AwerySettings.USE_DARK_THEME.getKey().equals(item.getKey())) { ThemeManager.applyApp(context); + return; } for(var activity : getActivities(AppCompatActivity.class)) { @@ -99,7 +106,7 @@ public void saveValue(SettingsItem item, Object newValue) { @Override public Object restoreValue(SettingsItem item) { if(AwerySettings.USE_DARK_THEME.getKey().equals(item.getKey())) { - return getPrefs().getBoolean(item.getKey(), ThemeManager.isDarkModeEnabled()); + return getPrefs().getBoolean(item.getKey(), isDarkModeEnabled()); } // NOTE: There are only boolean settings, so we don't expect other setting types. diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/storage/DiskUtil.kt b/app/src/main/java/eu/kanade/tachiyomi/util/storage/DiskUtil.kt deleted file mode 100644 index 8e3141a2..00000000 --- a/app/src/main/java/eu/kanade/tachiyomi/util/storage/DiskUtil.kt +++ /dev/null @@ -1,117 +0,0 @@ -package eu.kanade.tachiyomi.util.storage - -import android.content.Context -import android.media.MediaScannerConnection -import android.net.Uri -import android.os.Environment -import android.os.StatFs -import androidx.core.content.ContextCompat -import com.hippo.unifile.UniFile -import eu.kanade.tachiyomi.util.lang.Hash -import java.io.File - -object DiskUtil { - - fun hashKeyForDisk(key: String): String { - return Hash.md5(key) - } - - fun getDirectorySize(f: File): Long { - var size: Long = 0 - if (f.isDirectory) { - for (file in f.listFiles().orEmpty()) { - size += getDirectorySize(file) - } - } else { - size = f.length() - } - return size - } - - /** - * Gets the available space for the disk that a file path points to, in bytes. - */ - fun getAvailableStorageSpace(f: UniFile): Long { - return try { - val stat = StatFs(f.uri.path) - stat.availableBlocksLong * stat.blockSizeLong - } catch (_: Exception) { - -1L - } - } - - /** - * Returns the root folders of all the available external storages. - */ - fun getExternalStorages(context: Context): List { - return ContextCompat.getExternalFilesDirs(context, null) - .filterNotNull() - .mapNotNull { - val file = File(it.absolutePath.substringBefore("/Android/")) - val state = Environment.getExternalStorageState(file) - if (state == Environment.MEDIA_MOUNTED || state == Environment.MEDIA_MOUNTED_READ_ONLY) { - file - } else { - null - } - } - } - - /** - * Don't display downloaded chapters in gallery apps creating `.nomedia`. - */ - fun createNoMediaFile(dir: UniFile?, context: Context?) { - if (dir != null && dir.exists()) { - val nomedia = dir.findFile(NOMEDIA_FILE) - if (nomedia == null) { - dir.createFile(NOMEDIA_FILE) - context?.let { scanMedia(it, dir.uri) } - } - } - } - - /** - * Scans the given file so that it can be shown in gallery apps, for example. - */ - fun scanMedia(context: Context, uri: Uri) { - MediaScannerConnection.scanFile(context, arrayOf(uri.path), null, null) - } - - /** - * Mutate the given filename to make it valid for a FAT filesystem, - * replacing any invalid characters with "_". This method doesn't allow hidden files (starting - * with a dot), but you can manually add it later. - */ - fun buildValidFilename(origName: String): String { - val name = origName.trim('.', ' ') - if (name.isEmpty()) { - return "(invalid)" - } - val sb = StringBuilder(name.length) - name.forEach { c -> - if (isValidFatFilenameChar(c)) { - sb.append(c) - } else { - sb.append('_') - } - } - // Even though vfat allows 255 UCS-2 chars, we might eventually write to - // ext4 through a FUSE layer, so use that limit minus 15 reserved characters. - return sb.toString().take(240) - } - - /** - * Returns true if the given character is a valid filename character, false otherwise. - */ - private fun isValidFatFilenameChar(c: Char): Boolean { - if (0x00.toChar() <= c && c <= 0x1f.toChar()) { - return false - } - return when (c) { - '"', '*', '/', ':', '<', '>', '?', '\\', '|', 0x7f.toChar() -> false - else -> true - } - } - - const val NOMEDIA_FILE = ".nomedia" -}