diff --git a/app/build.gradle b/app/build.gradle index bd3ca3f8..5922739c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -18,6 +18,8 @@ android { versionCode 23_05_23_003 versionName "2023.05.23.3" + setProperty("archivesBaseName", versionName) + resValue "string", "app_name", "QuranApp" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/app/src/main/java/com/quranapp/android/activities/ActivityAbout.kt b/app/src/main/java/com/quranapp/android/activities/ActivityAbout.kt index e736da6a..b53702b4 100644 --- a/app/src/main/java/com/quranapp/android/activities/ActivityAbout.kt +++ b/app/src/main/java/com/quranapp/android/activities/ActivityAbout.kt @@ -40,7 +40,7 @@ class ActivityAbout : BaseActivity() { private fun initHeader(header: BoldHeader) { header.let { - it.setCallback { onBackPressed() } + it.setCallback { onBackPressedDispatcher.onBackPressed() } it.setTitleText(R.string.strTitleAboutUs) it.setShowRightIcon(false) it.setShowSearchIcon(false) diff --git a/app/src/main/java/com/quranapp/android/activities/ActivityBookmark.java b/app/src/main/java/com/quranapp/android/activities/ActivityBookmark.java index 5b9a4aaa..51c4d52b 100644 --- a/app/src/main/java/com/quranapp/android/activities/ActivityBookmark.java +++ b/app/src/main/java/com/quranapp/android/activities/ActivityBookmark.java @@ -4,6 +4,7 @@ import android.content.Intent; import android.os.Bundle; import android.view.View; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.recyclerview.widget.GridLayoutManager; @@ -117,7 +118,7 @@ private void initHeader(BoldHeader header) { header.setCallback(new BoldHeader.BoldHeaderCallback() { @Override public void onBackIconClick() { - onBackPressed(); + getOnBackPressedDispatcher().onBackPressed(); } @Override @@ -137,8 +138,8 @@ public void onRightIconClick() { private void deleteAllWithCheckpoint() { boolean isSelecting = mAdapter != null && mAdapter.mIsSelecting && !mAdapter.mSelectedModels.isEmpty(); String title = isSelecting ? getString(R.string.strTitleBookmarkDeleteCount, - mAdapter.mSelectedModels.size()) : getString( - R.string.strTitleBookmarkDeleteAll); + mAdapter.mSelectedModels.size()) : getString( + R.string.strTitleBookmarkDeleteAll); int dec = isSelecting ? R.string.strMsgBookmarkDeleteSelected : R.string.strMsgBookmarkDeleteAll; int labelNeg = isSelecting ? R.string.strLabelRemove : R.string.strLabelRemoveAll; @@ -230,7 +231,7 @@ public void onView(BookmarkModel model, int position) { public void onOpen(BookmarkModel model) { Intent intent = ReaderFactory.prepareVerseRangeIntent(model.getChapterNo(), model.getFromVerseNo(), - model.getToVerseNo()); + model.getToVerseNo()); intent.setClass(this, ActivityReader.class); startActivity(intent); } diff --git a/app/src/main/java/com/quranapp/android/adapters/reference/ADPReferenceVerses.java b/app/src/main/java/com/quranapp/android/adapters/reference/ADPReferenceVerses.java index daacd8aa..4eb1f8f2 100644 --- a/app/src/main/java/com/quranapp/android/adapters/reference/ADPReferenceVerses.java +++ b/app/src/main/java/com/quranapp/android/adapters/reference/ADPReferenceVerses.java @@ -218,14 +218,14 @@ private void bindTitle(LytReferenceVerseTitleBinding binding, ReferenceVerseItem @Override public void onBookmarkRemoved(BookmarkModel model) { - int adapterPosition = getAdapterPosition(); + int adapterPosition = getBindingAdapterPosition(); mVerseModels.get(adapterPosition).setBookmarked(false); notifyItemChanged(adapterPosition); } @Override public void onBookmarkAdded(BookmarkModel model) { - int adapterPosition = getAdapterPosition(); + int adapterPosition = getBindingAdapterPosition(); mVerseModels.get(adapterPosition).setBookmarked(true); notifyItemChanged(adapterPosition); } diff --git a/app/src/main/java/com/quranapp/android/adapters/storageCleanup/ADPScriptCleanup.kt b/app/src/main/java/com/quranapp/android/adapters/storageCleanup/ADPScriptCleanup.kt index 4a9d6ce5..ec175be7 100644 --- a/app/src/main/java/com/quranapp/android/adapters/storageCleanup/ADPScriptCleanup.kt +++ b/app/src/main/java/com/quranapp/android/adapters/storageCleanup/ADPScriptCleanup.kt @@ -90,7 +90,7 @@ class ADPScriptCleanup( fileUtils.getKFQPCScriptFontDir(model.scriptKey).deleteRecursively() model.isCleared = true - notifyItemChanged(adapterPosition) + notifyItemChanged(bindingAdapterPosition) } setFocusOnNegative(true) }.show() diff --git a/app/src/main/java/com/quranapp/android/adapters/storageCleanup/ADPTafsirCleanup.kt b/app/src/main/java/com/quranapp/android/adapters/storageCleanup/ADPTafsirCleanup.kt index e4e393d6..595f612f 100644 --- a/app/src/main/java/com/quranapp/android/adapters/storageCleanup/ADPTafsirCleanup.kt +++ b/app/src/main/java/com/quranapp/android/adapters/storageCleanup/ADPTafsirCleanup.kt @@ -77,7 +77,7 @@ class ADPTafsirCleanup( setNegativeButton(R.string.strLabelDelete, ColorUtils.DANGER) { _, _ -> File(fileUtils.tafsirDir, model.tafsirModel.key).deleteRecursively() model.isCleared = true - notifyItemChanged(adapterPosition) + notifyItemChanged(bindingAdapterPosition) } setFocusOnNegative(true) }.show() diff --git a/app/src/main/java/com/quranapp/android/adapters/storageCleanup/ADPTranslationCleanup.kt b/app/src/main/java/com/quranapp/android/adapters/storageCleanup/ADPTranslationCleanup.kt index 5c9b1793..9193d11a 100644 --- a/app/src/main/java/com/quranapp/android/adapters/storageCleanup/ADPTranslationCleanup.kt +++ b/app/src/main/java/com/quranapp/android/adapters/storageCleanup/ADPTranslationCleanup.kt @@ -128,7 +128,7 @@ class ADPTranslationCleanup(ctx: Context, private val items: List) : it.setOnClickListener { group.isExpanded = !group.isExpanded - notifyItemChanged(adapterPosition) + notifyItemChanged(bindingAdapterPosition) } } @@ -56,7 +56,7 @@ class ADPTafsirGroup(private val models: List) : } } - models[adapterPosition].tafsirs[changedIndex].isChecked = true + models[bindingAdapterPosition].tafsirs[changedIndex].isChecked = true notifyDataSetChanged() } } diff --git a/app/src/main/java/com/quranapp/android/adapters/transl/ADPDownloadTranslationsGroup.kt b/app/src/main/java/com/quranapp/android/adapters/transl/ADPDownloadTranslationsGroup.kt index 13a2218e..9176528f 100644 --- a/app/src/main/java/com/quranapp/android/adapters/transl/ADPDownloadTranslationsGroup.kt +++ b/app/src/main/java/com/quranapp/android/adapters/transl/ADPDownloadTranslationsGroup.kt @@ -102,7 +102,7 @@ class ADPDownloadTranslationsGroup( it.setOnClickListener { group.isExpanded = !group.isExpanded - notifyItemChanged(adapterPosition) + notifyItemChanged(bindingAdapterPosition) } } diff --git a/app/src/main/java/com/quranapp/android/frags/settings/FragSettingsScripts.kt b/app/src/main/java/com/quranapp/android/frags/settings/FragSettingsScripts.kt index 024c48f9..666313b3 100644 --- a/app/src/main/java/com/quranapp/android/frags/settings/FragSettingsScripts.kt +++ b/app/src/main/java/com/quranapp/android/frags/settings/FragSettingsScripts.kt @@ -74,7 +74,7 @@ class FragSettingsScripts : FragSettingsBase(), ServiceConnection { override fun setupHeader(activity: ActivitySettings, header: BoldHeader) { super.setupHeader(activity, header) header.apply { - setCallback { activity.onBackPressed() } + setCallback { activity.onBackPressedDispatcher.onBackPressed() } disableRightBtn(true) setShowSearchIcon(false) setShowRightIcon(false) diff --git a/app/src/main/java/com/quranapp/android/frags/settings/FragSettingsTransl.java b/app/src/main/java/com/quranapp/android/frags/settings/FragSettingsTransl.java index 29833bf1..7e8ef6f2 100644 --- a/app/src/main/java/com/quranapp/android/frags/settings/FragSettingsTransl.java +++ b/app/src/main/java/com/quranapp/android/frags/settings/FragSettingsTransl.java @@ -95,7 +95,7 @@ public void setupHeader(ActivitySettings activity, BoldHeader header) { header.setCallback(new BoldHeader.BoldHeaderCallback() { @Override public void onBackIconClick() { - activity.onBackPressed(); + activity.getOnBackPressedDispatcher().onBackPressed(); } @Override diff --git a/app/src/main/java/com/quranapp/android/frags/settings/FragSettingsTranslationsDownload.kt b/app/src/main/java/com/quranapp/android/frags/settings/FragSettingsTranslationsDownload.kt index 11e05784..55b5686b 100644 --- a/app/src/main/java/com/quranapp/android/frags/settings/FragSettingsTranslationsDownload.kt +++ b/app/src/main/java/com/quranapp/android/frags/settings/FragSettingsTranslationsDownload.kt @@ -317,7 +317,7 @@ class FragSettingsTranslationsDownload : if (isTranslationDownloading(bookInfo.slug)) { model.isDownloading = true - adapter.notifyItemChanged(vhTransl.adapterPosition) + adapter.notifyItemChanged(vhTransl.bindingAdapterPosition) return } diff --git a/app/src/main/java/com/quranapp/android/frags/settings/appLogs/FragAppLogsCrash.kt b/app/src/main/java/com/quranapp/android/frags/settings/appLogs/FragAppLogsCrash.kt index d3a690d9..ac54c4a7 100644 --- a/app/src/main/java/com/quranapp/android/frags/settings/appLogs/FragAppLogsCrash.kt +++ b/app/src/main/java/com/quranapp/android/frags/settings/appLogs/FragAppLogsCrash.kt @@ -54,19 +54,18 @@ class FragAppLogsCrash : BaseFragment() { files.sortedByDescending { it.lastModified() }.forEach { logFile -> val log = logFile.readText() val logShort = if (log.length > 200) log.substring(0, 200) + "... ${log.length - 200} more chars" else log - val formattedDateTime = DateUtils.format( - DateUtils.toDate(logFile.name, Log.FILE_NAME_DATE_FORMAT), - DateUtils.DATETIME_FORMAT_USER - ) + + val parsedDate = DateUtils.toDate(logFile.name, Log.FILE_NAME_DATE_FORMAT) + val formattedDateTime = if (parsedDate != null) DateUtils.format(parsedDate, DateUtils.DATETIME_FORMAT_USER) else logFile.name logs.add( - AppLogModel( - formattedDateTime, - "Fatal Crash", - logFile, - log, - logShort, - ) + AppLogModel( + formattedDateTime, + "Fatal Crash", + logFile, + log, + logShort, + ) ) } diff --git a/app/src/main/java/com/quranapp/android/frags/settings/appLogs/FragAppLogsSuppressed.kt b/app/src/main/java/com/quranapp/android/frags/settings/appLogs/FragAppLogsSuppressed.kt index 09db59bd..4b0eb390 100644 --- a/app/src/main/java/com/quranapp/android/frags/settings/appLogs/FragAppLogsSuppressed.kt +++ b/app/src/main/java/com/quranapp/android/frags/settings/appLogs/FragAppLogsSuppressed.kt @@ -55,19 +55,17 @@ class FragAppLogsSuppressed : BaseFragment() { val (datetimeStr, place) = logFile.nameWithoutExtension.split("@") val log = logFile.readText() val logShort = if (log.length > 200) log.substring(0, 200) + "... ${log.length - 200} more chars" else log - val formattedDateTime = DateUtils.format( - DateUtils.toDate(datetimeStr, Log.FILE_NAME_DATE_FORMAT), - DateUtils.DATETIME_FORMAT_USER - ) + val parsedDate = DateUtils.toDate(datetimeStr, Log.FILE_NAME_DATE_FORMAT) + val formattedDateTime = if (parsedDate != null) DateUtils.format(parsedDate, DateUtils.DATETIME_FORMAT_USER) else datetimeStr logs.add( - AppLogModel( - formattedDateTime, - place, - logFile, - log, - logShort, - ) + AppLogModel( + formattedDateTime, + place, + logFile, + log, + logShort, + ) ) } diff --git a/app/src/main/java/com/quranapp/android/utils/RVLazyLoadListener.java b/app/src/main/java/com/quranapp/android/utils/RVLazyLoadListener.java deleted file mode 100644 index 2667d778..00000000 --- a/app/src/main/java/com/quranapp/android/utils/RVLazyLoadListener.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.quranapp.android.utils; - -import androidx.annotation.NonNull; -import androidx.recyclerview.widget.GridLayoutManager; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; -import androidx.recyclerview.widget.StaggeredGridLayoutManager; -import static androidx.recyclerview.widget.RecyclerView.LayoutManager; -import static androidx.recyclerview.widget.RecyclerView.OnScrollListener; - -/** - * Custom Scroll Listener for recycler view to listen to up and down scroll - */ -@SuppressWarnings("FieldCanBeLocal") -public abstract class RVLazyLoadListener extends OnScrollListener { - private final int mTHRESHOLD; - private final boolean isStaggeredGLM; - private final boolean isNormalGLM; - private final boolean isLLM; - private StaggeredGridLayoutManager staggeredGLM; - private GridLayoutManager GLM; - private LinearLayoutManager LLM; - - public RVLazyLoadListener(@NonNull LayoutManager layoutManager, int threshold) { - mTHRESHOLD = threshold; - if (layoutManager instanceof StaggeredGridLayoutManager) { - isStaggeredGLM = true; - isNormalGLM = false; - isLLM = false; - staggeredGLM = (StaggeredGridLayoutManager) layoutManager; - } else if (layoutManager instanceof GridLayoutManager) { - isStaggeredGLM = false; - isNormalGLM = true; - isLLM = false; - GLM = (GridLayoutManager) layoutManager; - } else if (layoutManager instanceof LinearLayoutManager) { - isStaggeredGLM = false; - isNormalGLM = false; - isLLM = true; - LLM = (LinearLayoutManager) layoutManager; - } else { - isStaggeredGLM = false; - isNormalGLM = false; - isLLM = false; - } - } - - @Override - public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { - super.onScrolled(recyclerView, dx, dy); - if (dy <= 0) return; - onCheckLazyLoad(); - } - - public void onCheckLazyLoad() { - if (isStaggeredGLM) { - onStaggeredGLMScroll(); - } else if (isLLM) { - onLLMScroll(); - } - } - - private void onStaggeredGLMScroll() { - int[] items = new int[staggeredGLM.getSpanCount()]; - staggeredGLM.findFirstVisibleItemPositions(items); - if (items.length == 0) return; - - int totalItems = staggeredGLM.getItemCount(); - int totalVisibleItems = staggeredGLM.getChildCount(); - int pastVisibleItems = items[0]; - if ((totalVisibleItems + pastVisibleItems) >= totalItems - mTHRESHOLD) onLoadMore(); - } - - private void onLLMScroll() { - int position = LLM.findFirstVisibleItemPosition(); - int totalItems = LLM.getItemCount(); - int totalVisibleItems = LLM.getChildCount(); - if ((totalVisibleItems + position) >= totalItems - mTHRESHOLD) onLoadMore(); - } - - public abstract void onLoadMore(); -} \ No newline at end of file diff --git a/app/src/main/java/com/quranapp/android/utils/app/InfoUtils.kt b/app/src/main/java/com/quranapp/android/utils/app/InfoUtils.kt index d8f8d21a..dacaf4fa 100644 --- a/app/src/main/java/com/quranapp/android/utils/app/InfoUtils.kt +++ b/app/src/main/java/com/quranapp/android/utils/app/InfoUtils.kt @@ -6,6 +6,7 @@ package com.quranapp.android.utils.app import android.content.Context import android.content.DialogInterface import android.net.Uri +import androidx.browser.customtabs.CustomTabColorSchemeParams import androidx.browser.customtabs.CustomTabsIntent import androidx.core.content.ContextCompat import com.quranapp.android.R @@ -53,15 +54,15 @@ object InfoUtils { if (e !is CancellationException) { Logger.reportError(e) MessageUtils.popMessage( - context, - context.getString(R.string.strMsgSomethingWrong), - "${context.getString(R.string.strMsgCouldNotOpenPage)} ${ - context.getString( - R.string.strMsgTryLater - ) - }", - context.getString(R.string.strLabelClose), - null + context, + context.getString(R.string.strMsgSomethingWrong), + "${context.getString(R.string.strMsgCouldNotOpenPage)} ${ + context.getString( + R.string.strMsgTryLater + ) + }", + context.getString(R.string.strLabelClose), + null ) } } @@ -85,10 +86,15 @@ object InfoUtils { } private fun prepareCustomTab(context: Context): CustomTabsIntent { + val colorSchemeParams = CustomTabColorSchemeParams.Builder() + .setToolbarColor(ContextCompat.getColor(context, R.color.colorBGPage)) + .setNavigationBarColor(ContextCompat.getColor(context, R.color.colorBGPage)) + .build() + return CustomTabsIntent.Builder() - .setToolbarColor(ContextCompat.getColor(context, R.color.colorBGPage)) - .setShowTitle(true) - .setUrlBarHidingEnabled(true) - .build() + .setDefaultColorSchemeParams(colorSchemeParams) + .setShowTitle(true) + .setUrlBarHidingEnabled(true) + .build() } } diff --git a/app/src/main/java/com/quranapp/android/utils/chapterInfo/ChapterInfoJSInterface.java b/app/src/main/java/com/quranapp/android/utils/chapterInfo/ChapterInfoJSInterface.java index bd88490e..45296e12 100644 --- a/app/src/main/java/com/quranapp/android/utils/chapterInfo/ChapterInfoJSInterface.java +++ b/app/src/main/java/com/quranapp/android/utils/chapterInfo/ChapterInfoJSInterface.java @@ -23,15 +23,15 @@ public void openReference(int chapterNo, int fromVerse, int toVerse) { QuranMeta quranMeta = mActivity.mQuranMeta; if (!QuranMeta.isChapterValid(chapterNo) || !quranMeta.isVerseRangeValid4Chapter(chapterNo, fromVerse, - toVerse)) { + toVerse)) { Log.d(chapterNo, fromVerse, toVerse); - MessageUtils.showRemovableToast(mActivity, "Could not open references", Toast.LENGTH_LONG); + MessageUtils.INSTANCE.showRemovableToast(mActivity, "Could not open references", Toast.LENGTH_LONG); return; } mActivity.showReferenceSingleVerseOrRange( - TranslUtils.defaultTranslationSlugs(), - chapterNo, new Pair<>(fromVerse, toVerse) + TranslUtils.defaultTranslationSlugs(), + chapterNo, new Pair<>(fromVerse, toVerse) ); } } diff --git a/app/src/main/java/com/quranapp/android/utils/exceptions/HttpNotFoundException.java b/app/src/main/java/com/quranapp/android/utils/exceptions/HttpNotFoundException.java deleted file mode 100644 index a0f921cd..00000000 --- a/app/src/main/java/com/quranapp/android/utils/exceptions/HttpNotFoundException.java +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (c) Faisal Khan (https://github.com/faisalcodes) - * Created on 1/4/2022. - * All rights reserved. - */ - -package com.quranapp.android.utils.exceptions; - -public class HttpNotFoundException extends RuntimeException { - public HttpNotFoundException() { - this("Not found"); - } - - public HttpNotFoundException(String msg) { - super(msg); - } -} diff --git a/app/src/main/java/com/quranapp/android/utils/exceptions/HttpNotFoundException.kt b/app/src/main/java/com/quranapp/android/utils/exceptions/HttpNotFoundException.kt new file mode 100644 index 00000000..e4050ab6 --- /dev/null +++ b/app/src/main/java/com/quranapp/android/utils/exceptions/HttpNotFoundException.kt @@ -0,0 +1,8 @@ +/* + * Copyright (c) Faisal Khan (https://github.com/faisalcodes) + * Created on 1/4/2022. + * All rights reserved. + */ +package com.quranapp.android.utils.exceptions + +class HttpNotFoundException @JvmOverloads constructor(msg: String? = "Not found") : RuntimeException(msg) \ No newline at end of file diff --git a/app/src/main/java/com/quranapp/android/utils/exceptions/NoInternetException.java b/app/src/main/java/com/quranapp/android/utils/exceptions/NoInternetException.java deleted file mode 100644 index 9710a117..00000000 --- a/app/src/main/java/com/quranapp/android/utils/exceptions/NoInternetException.java +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (c) Faisal Khan (https://github.com/faisalcodes) - * Created on 1/4/2022. - * All rights reserved. - */ - -package com.quranapp.android.utils.exceptions; - -public class NoInternetException extends RuntimeException { - public NoInternetException() { - this("No internet"); - } - - public NoInternetException(String msg) { - super(msg); - } -} diff --git a/app/src/main/java/com/quranapp/android/utils/exceptions/NoInternetException.kt b/app/src/main/java/com/quranapp/android/utils/exceptions/NoInternetException.kt new file mode 100644 index 00000000..80a6d537 --- /dev/null +++ b/app/src/main/java/com/quranapp/android/utils/exceptions/NoInternetException.kt @@ -0,0 +1,8 @@ +/* + * Copyright (c) Faisal Khan (https://github.com/faisalcodes) + * Created on 1/4/2022. + * All rights reserved. + */ +package com.quranapp.android.utils.exceptions + +class NoInternetException @JvmOverloads constructor(msg: String? = "No internet") : RuntimeException(msg) \ No newline at end of file diff --git a/app/src/main/java/com/quranapp/android/utils/extended/GapedItemDecoration.java b/app/src/main/java/com/quranapp/android/utils/extended/GapedItemDecoration.java deleted file mode 100644 index b6d62229..00000000 --- a/app/src/main/java/com/quranapp/android/utils/extended/GapedItemDecoration.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.quranapp.android.utils.extended; - -import android.graphics.Rect; -import android.view.View; -import androidx.annotation.NonNull; -import androidx.recyclerview.widget.RecyclerView; - -public class GapedItemDecoration extends RecyclerView.ItemDecoration { - private final int gap; - - public GapedItemDecoration(int gap) { - this.gap = gap; - } - - @Override - public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) { - super.getItemOffsets(outRect, view, parent, state); - outRect.set(gap, gap, gap, gap); - } -} \ No newline at end of file diff --git a/app/src/main/java/com/quranapp/android/utils/extended/GapedItemDecoration.kt b/app/src/main/java/com/quranapp/android/utils/extended/GapedItemDecoration.kt new file mode 100644 index 00000000..49733191 --- /dev/null +++ b/app/src/main/java/com/quranapp/android/utils/extended/GapedItemDecoration.kt @@ -0,0 +1,12 @@ +package com.quranapp.android.utils.extended + +import android.graphics.Rect +import android.view.View +import androidx.recyclerview.widget.RecyclerView + +class GapedItemDecoration(private val gap: Int) : RecyclerView.ItemDecoration() { + override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) { + super.getItemOffsets(outRect, view, parent, state) + outRect.set(gap, gap, gap, gap) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/quranapp/android/utils/univ/DateUtils.java b/app/src/main/java/com/quranapp/android/utils/univ/DateUtils.java deleted file mode 100644 index cb2c4f57..00000000 --- a/app/src/main/java/com/quranapp/android/utils/univ/DateUtils.java +++ /dev/null @@ -1,97 +0,0 @@ -package com.quranapp.android.utils.univ; - -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.time.Duration; -import java.time.format.DateTimeFormatter; -import java.util.Calendar; -import java.util.Date; -import java.util.Locale; - -public abstract class DateUtils { - public static final String DATETIME_FORMAT_SYSTEM = "yyyy-MM-dd HH:mm:ss"; - public static final String DATETIME_FORMAT_USER = "dd-MM-yyyy hh:mm a"; - public static final String DATETIME_FORMAT_FILENAME = "yyyyMMddhhmmss"; - - public static String reformat(String dateStr, String oldPattern, String newPattern) { - DateTimeFormatter oFormatter = DateTimeFormatter.ofPattern(oldPattern); - DateTimeFormatter nFormatter = DateTimeFormatter.ofPattern(newPattern); - - try { - return nFormatter.format(oFormatter.parse(dateStr)); - } catch (Exception e) { - e.printStackTrace(); - } - - return null; - } - - public static Date toDate(String dateStr, String format) { - SimpleDateFormat formatter = new SimpleDateFormat(format, Locale.ENGLISH); - try { - return formatter.parse(dateStr); - } catch (ParseException e) { - return null; - } - } - - public static String format(Date date, String format) { - SimpleDateFormat formatter = new SimpleDateFormat(format, Locale.ENGLISH); - return formatter.format(date); - } - - public static String getDateTimeNow(String format) { - SimpleDateFormat formatter = new SimpleDateFormat(format, Locale.ENGLISH); - return formatter.format(Calendar.getInstance().getTime()); - } - - public static String getDateTimeNow() { - return getDateTimeNow(DATETIME_FORMAT_SYSTEM); - } - - public static String getDateTimeNow4Filename() { - return getDateTimeNow(DATETIME_FORMAT_FILENAME); - } - - public static boolean isNewer(long oldDate, long newDate) { - return new Date(oldDate).before(new Date(newDate)); - } - - public static long daysSince(String timeStr) { - long time = Long.parseLong(timeStr); - Calendar calThen = Calendar.getInstance(); - calThen.setTimeInMillis(time); - - Calendar calNow = Calendar.getInstance(); - return Duration.between(calThen.toInstant(), calNow.toInstant()).toDays(); - } - - public static long hoursSince(String timeMillisStr) { - long timeMillis = Long.parseLong(timeMillisStr); - Calendar calThen = Calendar.getInstance(); - calThen.setTimeInMillis(timeMillis); - - Calendar calNow = Calendar.getInstance(); - return Duration.between(calThen.toInstant(), calNow.toInstant()).toHours(); - } - - public static long hoursSince(Long timeMillis) { - Calendar calThen = Calendar.getInstance(); - calThen.setTimeInMillis(timeMillis); - - Calendar calNow = Calendar.getInstance(); - return Duration.between(calThen.toInstant(), calNow.toInstant()).toHours(); - } - - public static long minutesSince(String timeMillisStr) { - return minutesSince(Long.parseLong(timeMillisStr)); - } - - public static long minutesSince(Long time) { - Calendar calThen = Calendar.getInstance(); - calThen.setTimeInMillis(time); - - Calendar calNow = Calendar.getInstance(); - return Duration.between(calThen.toInstant(), calNow.toInstant()).toMinutes(); - } -} diff --git a/app/src/main/java/com/quranapp/android/utils/univ/DateUtils.kt b/app/src/main/java/com/quranapp/android/utils/univ/DateUtils.kt new file mode 100644 index 00000000..2e2a13b7 --- /dev/null +++ b/app/src/main/java/com/quranapp/android/utils/univ/DateUtils.kt @@ -0,0 +1,32 @@ +package com.quranapp.android.utils.univ + +import java.text.ParseException +import java.text.SimpleDateFormat +import java.util.Calendar +import java.util.Date +import java.util.Locale + +object DateUtils { + const val DATETIME_FORMAT_SYSTEM = "yyyy-MM-dd HH:mm:ss" + const val DATETIME_FORMAT_USER = "dd-MM-yyyy hh:mm a" + fun toDate(dateStr: String, format: String): Date? { + val formatter = SimpleDateFormat(format, Locale.ENGLISH) + + return try { + formatter.parse(dateStr) + } catch (e: ParseException) { + null + } + } + + fun format(date: Date, format: String): String { + return SimpleDateFormat(format, Locale.ENGLISH).format(date) + } + + fun getDateTimeNow(format: String?): String { + return SimpleDateFormat(format, Locale.ENGLISH).format(Calendar.getInstance().time) + } + + @JvmStatic + val dateTimeNow get() = getDateTimeNow(DATETIME_FORMAT_SYSTEM) +} \ No newline at end of file diff --git a/app/src/main/java/com/quranapp/android/utils/univ/MessageUtils.java b/app/src/main/java/com/quranapp/android/utils/univ/MessageUtils.java deleted file mode 100644 index 4461e7a8..00000000 --- a/app/src/main/java/com/quranapp/android/utils/univ/MessageUtils.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.quranapp.android.utils.univ; - -import android.content.Context; -import android.widget.Toast; - -import com.peacedesign.android.widget.dialog.base.PeaceDialog; -import com.quranapp.android.R; - -import java.lang.ref.WeakReference; - -public class MessageUtils { - private static WeakReference mToast; - - public static void showRemovableToast(Context context, int msgRes, int duration) { - showRemovableToast(context, context.getString(msgRes), duration); - } - - public static void showRemovableToast(Context context, CharSequence msg, int duration) { - try { - mToast.get().cancel(); - } catch (Exception ignored) {} - - mToast = new WeakReference<>(Toast.makeText(context, msg, duration)); - mToast.get().show(); - } - - public static void popNoInternetMessage(Context ctx, boolean cancelable, Runnable runOnDismiss) { - PeaceDialog.Builder builder = PeaceDialog.newBuilder(ctx); - builder.setTitle(R.string.strTitleNoInternet); - builder.setMessage(R.string.strMsgNoInternetLong); - builder.setNeutralButton(R.string.strLabelClose, null); - if (runOnDismiss != null) { - builder.setOnDismissListener(dialog -> runOnDismiss.run()); - } - builder.setCancelable(cancelable); - builder.setFocusOnNeutral(true); - builder.show(); - } - - public static void popMessage(Context context, String title, String msg, String btn, Runnable action) { - PeaceDialog.Builder builder = PeaceDialog.newBuilder(context); - builder.setTitle(title); - builder.setMessage(msg); - builder.setNeutralButton(btn, (dialog, which) -> { - if (action != null) { - action.run(); - } - }); - builder.setFocusOnNeutral(true); - builder.show(); - } -} diff --git a/app/src/main/java/com/quranapp/android/utils/univ/MessageUtils.kt b/app/src/main/java/com/quranapp/android/utils/univ/MessageUtils.kt new file mode 100644 index 00000000..9a013136 --- /dev/null +++ b/app/src/main/java/com/quranapp/android/utils/univ/MessageUtils.kt @@ -0,0 +1,47 @@ +package com.quranapp.android.utils.univ + +import android.content.Context +import android.widget.Toast +import com.peacedesign.android.widget.dialog.base.PeaceDialog +import com.quranapp.android.R +import java.lang.ref.WeakReference + +object MessageUtils { + private var toast: WeakReference? = null + fun showRemovableToast(context: Context, msgRes: Int, duration: Int) { + showRemovableToast(context, context.getString(msgRes), duration) + } + + fun showRemovableToast(context: Context?, msg: CharSequence?, duration: Int) { + try { + toast?.get()?.cancel() + } catch (ignored: Exception) { + } + toast = WeakReference(Toast.makeText(context, msg, duration)) + toast!!.get()!!.show() + } + + fun popNoInternetMessage(ctx: Context, cancelable: Boolean, runOnDismiss: Runnable?) { + PeaceDialog.newBuilder(ctx).apply { + setTitle(R.string.strTitleNoInternet) + setMessage(R.string.strMsgNoInternetLong) + setNeutralButton(R.string.strLabelClose, null) + if (runOnDismiss != null) { + setOnDismissListener { runOnDismiss.run() } + } + setCancelable(cancelable) + setFocusOnNeutral(true) + show() + } + } + + @JvmStatic + fun popMessage(context: Context, title: String, msg: String?, btn: String, action: Runnable?) { + val builder = PeaceDialog.newBuilder(context) + builder.setTitle(title) + if (msg != null) builder.setMessage(msg) + builder.setNeutralButton(btn) { _, _ -> action?.run() } + builder.setFocusOnNeutral(true) + builder.show() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/quranapp/android/utils/univ/StringUtils.java b/app/src/main/java/com/quranapp/android/utils/univ/StringUtils.java index 0cdafd06..e35a22eb 100644 --- a/app/src/main/java/com/quranapp/android/utils/univ/StringUtils.java +++ b/app/src/main/java/com/quranapp/android/utils/univ/StringUtils.java @@ -1,15 +1,9 @@ package com.quranapp.android.utils.univ; import android.os.Bundle; -import android.text.TextUtils; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import static com.quranapp.android.utils.univ.StringUtils.RandomPattern.ALPHABETIC; -import static com.quranapp.android.utils.univ.StringUtils.RandomPattern.ALPHABETIC_LOWER; -import static com.quranapp.android.utils.univ.StringUtils.RandomPattern.ALPHABETIC_UPPER; -import static com.quranapp.android.utils.univ.StringUtils.RandomPattern.ALPHANUMERIC_LOWER; -import static com.quranapp.android.utils.univ.StringUtils.RandomPattern.ALPHANUMERIC_UPPER; -import static com.quranapp.android.utils.univ.StringUtils.RandomPattern.NUMERIC; import java.io.BufferedReader; import java.io.IOException; @@ -18,8 +12,6 @@ import java.nio.charset.StandardCharsets; import java.text.Normalizer; import java.util.Arrays; -import java.util.List; -import java.util.Random; import java.util.regex.Pattern; @SuppressWarnings({"unused", "SpellCheckingInspection"}) @@ -140,117 +132,6 @@ public static String stripDiacritics(String str) { return str; } - /** - *

Delete one character from last from a text.

- * Examples: - *
-     * "hello".backspace() returns "hell"
-     * "together".backspace() returns "togethe"
-     * 
- * - * @param text Text to be backspaced - * @return Return backspaced text. - */ - @NonNull - public static String backspace(@NonNull String text) { - if (TextUtils.isEmpty(text)) return ""; - return text.trim().substring(0, text.length() - 1); - } - - /** - * Find common substring in two strings. - * - * @param str1 First string - * @param str2 Second string - * @param delimiter The delimiter each string can be separated with, into substrings. - * @return Returns the common string if found any, null otherwise. - */ - @Nullable - public static String commonString(@NonNull String str1, @NonNull String str2, @NonNull String delimiter) { - if (str1.equals(str2)) return str1; - String[] a1 = str1.split(delimiter); - String[] b1 = str2.split(delimiter); - - String[] cRay = b1.length > a1.length ? a1 : b1; - String[] dRay = b1.length > a1.length ? b1 : a1; - List cList = Arrays.asList(cRay); - for (String val : dRay) if (cList.contains(val)) return val; - return null; - } - - /** - *

Append first character of every word in a string.

- *
- * Examples: If arguments passed are - "Hello Word", "[SPACE]", "_". - *
-     *     Then it returns "H_W"
-     * 
- *
- * - * @param string The string from which characters are to be appended - * @param sepDelimiter What delimiter is separating words. eg - [UNDERSCORE] or [SPACE]. - * @param apdDelimiter The delimiter which will be used to append the characters. - * @param count How many characters should be taken from each word. - * @return Returns first character of every word appended. - */ - @NonNull - public static String appendFirstChars( - @NonNull String string, - @NonNull String sepDelimiter, - @NonNull String apdDelimiter, int count - ) { - String[] substringArr = string.split(sepDelimiter); - StringBuilder res = new StringBuilder(); - int len = substringArr.length; - for (int i = 0; i < len; i++) { - for (int j = 0; j < count; j++) res.append(substringArr[i].charAt(j)); - if (i < len - 1) res.append(apdDelimiter); - } - return res.toString(); - } - - /** - * Generate a random string based of given parameters. - * - * @param length The length of which the string should be. - * @param randomPattern Pattern of the resulting string. - * One of - - * {@link RandomPattern#ALPHANUMERIC}, - * {@link RandomPattern#ALPHANUMERIC_LOWER}, - * {@link RandomPattern#ALPHANUMERIC_UPPER}, - * {@link RandomPattern#ALPHABETIC}, - * {@link RandomPattern#ALPHABETIC_LOWER}, - * {@link RandomPattern#ALPHABETIC_UPPER}, - * {@link RandomPattern#NUMERIC}, - * @return Returns a random string based of the given parameters. - */ - @NonNull - public static String random(int length, int randomPattern) { - final String chars; - switch (randomPattern) { - case ALPHABETIC: chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; - break; - case ALPHABETIC_LOWER: chars = "abcdefghijklmnopqrstuvwxyz"; - break; - case ALPHABETIC_UPPER: chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - break; - case ALPHANUMERIC_LOWER: chars = "abcdefghijklmnopqrstuvwxyz1234567890"; - break; - case ALPHANUMERIC_UPPER: chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"; - break; - case NUMERIC: chars = "1234567890"; - break; - default: chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"; - break; - } - - StringBuilder string = new StringBuilder(); - Random rnd = new Random(); - int charLen = chars.length(); - while (string.length() < length) string.append(chars.charAt((int) (rnd.nextFloat() * charLen))); - return string.toString(); - } - public static String escapeRegex(String string) { return Pattern.quote(string); } @@ -272,21 +153,8 @@ public static String readInputStream(InputStream inputStream) throws IOException public static boolean isRTL(char c) { byte d = Character.getDirectionality(c); return d == Character.DIRECTIONALITY_RIGHT_TO_LEFT || - d == Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC || - d == Character.DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING || - d == Character.DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE; - } - - /** - * Pattern for {@link #random(int, int)} - */ - public static class RandomPattern { - public static final int ALPHANUMERIC = 0x1; - public static final int ALPHANUMERIC_LOWER = 0x2; - public static final int ALPHANUMERIC_UPPER = 0x3; - public static final int ALPHABETIC = 0x4; - public static final int ALPHABETIC_LOWER = 0x5; - public static final int ALPHABETIC_UPPER = 0x6; - public static final int NUMERIC = 0x7; + d == Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC || + d == Character.DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING || + d == Character.DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE; } } \ No newline at end of file diff --git a/app/src/main/java/com/quranapp/android/vh/search/VHChapterJump.java b/app/src/main/java/com/quranapp/android/vh/search/VHChapterJump.java deleted file mode 100644 index 97d4aa00..00000000 --- a/app/src/main/java/com/quranapp/android/vh/search/VHChapterJump.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.quranapp.android.vh.search; - -import com.quranapp.android.components.search.ChapterJumpModel; -import com.quranapp.android.components.search.SearchResultModelBase; -import com.quranapp.android.utils.reader.factory.ReaderFactory; -import com.quranapp.android.widgets.chapterCard.ChapterCard; - -public class VHChapterJump extends VHSearchResultBase { - private final ChapterCard mChapterCard; - - public VHChapterJump(ChapterCard chapterCard, boolean applyMargins) { - super(chapterCard); - mChapterCard = chapterCard; - - setupJumperView(chapterCard, applyMargins); - } - - - @Override - public void bind(SearchResultModelBase parentModel, int pos) { - ChapterJumpModel model = (ChapterJumpModel) parentModel; - - mChapterCard.setChapterNumber(model.getChapterNo()); - mChapterCard.setName(model.getName(), model.getNameTranslation()); - mChapterCard.setOnClickListener(v -> ReaderFactory.startChapter(v.getContext(), model.getChapterNo())); - } -} diff --git a/app/src/main/java/com/quranapp/android/vh/search/VHChapterJump.kt b/app/src/main/java/com/quranapp/android/vh/search/VHChapterJump.kt new file mode 100644 index 00000000..e4fac2a8 --- /dev/null +++ b/app/src/main/java/com/quranapp/android/vh/search/VHChapterJump.kt @@ -0,0 +1,22 @@ +package com.quranapp.android.vh.search + +import com.quranapp.android.components.search.ChapterJumpModel +import com.quranapp.android.components.search.SearchResultModelBase +import com.quranapp.android.utils.reader.factory.ReaderFactory.startChapter +import com.quranapp.android.widgets.chapterCard.ChapterCard + +class VHChapterJump(private val chapterCard: ChapterCard, applyMargins: Boolean) : VHSearchResultBase(chapterCard) { + init { + setupJumperView(chapterCard, applyMargins) + } + + override fun bind(model: SearchResultModelBase, pos: Int) { + if (model is ChapterJumpModel) { + chapterCard.apply { + chapterNumber = model.chapterNo + setName(model.name, model.nameTranslation) + setOnClickListener { startChapter(it.context, model.chapterNo) } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/quranapp/android/views/reader/dialogs/VerseShareDialog.java b/app/src/main/java/com/quranapp/android/views/reader/dialogs/VerseShareDialog.java index e01bba91..1d32d74d 100644 --- a/app/src/main/java/com/quranapp/android/views/reader/dialogs/VerseShareDialog.java +++ b/app/src/main/java/com/quranapp/android/views/reader/dialogs/VerseShareDialog.java @@ -241,7 +241,7 @@ private void share(LytVerseShareBinding binding, QuranMeta quranMeta) { boolean incFootnotes = binding.includeFootnotes.isChecked(); if (!quranMeta.isVerseRangeValid4Chapter(mChapterNo, fromVerse, toVerse)) { - MessageUtils.showRemovableToast(mActivity, getContext().getString(R.string.strMsgEnterValidRange), + MessageUtils.INSTANCE.showRemovableToast(mActivity, getContext().getString(R.string.strMsgEnterValidRange), Toast.LENGTH_LONG); return; }