diff --git a/commons/detekt-baseline.xml b/commons/detekt-baseline.xml
index ea5a6eddb..e6561c733 100644
--- a/commons/detekt-baseline.xml
+++ b/commons/detekt-baseline.xml
@@ -6,8 +6,8 @@
ComplexCondition:Activity.kt$!isRPlus() || (isRPlus() && (hasProperStoredDocumentUriSdk30(path) || Environment.isExternalStorageManager()))
ComplexCondition:Activity.kt$(!isRPlus() && isPathOnSD(path) && !isSDCardSetAsDefaultStorage() && (baseConfig.sdTreeUri.isEmpty() || !hasProperStoredTreeUri(false)))
ComplexCondition:Activity.kt$startIntentForUriAction( uri, "android.intent.action.VIEW", ComponentName("com.google.android.documentsui", "com.android.documentsui.files.FilesActivity") ) || startIntentForUriAction( uri, "android.intent.action.VIEW", ComponentName("com.android.documentsui", "com.android.documentsui.files.FilesActivity") ) || startIntentForUriAction( uri, "android.intent.action.VIEW", ComponentName("com.android.documentsui", "com.android.documentsui.FilesActivity") ) || startIntentForUriAction(uri, "android.intent.action.VIEW", null) || startIntentForUriAction(uri, "android.provider.action.BROWSE", null) || startIntentForUriAction(uri, "android.provider.action.BROWSE_DOCUMENT_ROOT", null)
- ComplexCondition:BaseSimpleActivity.kt$BaseSimpleActivity$isPathOnOTG(source) || isPathOnOTG(destination) || isPathOnSD(source) || isPathOnSD(destination) || isRestrictedSAFOnlyRoot(source) || isRestrictedSAFOnlyRoot(destination) || isAccessibleWithSAFSdk30(source) || isAccessibleWithSAFSdk30(destination) || fileDirItems.first().isDirectory
- ComplexCondition:BaseSimpleActivity.kt$BaseSimpleActivity$requestCode == SELECT_EXPORT_SETTINGS_FILE_INTENT && resultCode == Activity.RESULT_OK && resultData != null && resultData.data != null
+ ComplexCondition:BaseSimpleActivity.kt$BaseSimpleActivity$isPathOnOTG(source) || isPathOnOTG(destination) || isPathOnSD(source) || isPathOnSD( destination ) || isRestrictedSAFOnlyRoot(source) || isRestrictedSAFOnlyRoot(destination) || isAccessibleWithSAFSdk30(source) || isAccessibleWithSAFSdk30(destination) || fileDirItems.first().isDirectory
+ ComplexCondition:BaseSimpleActivity.kt$BaseSimpleActivity$requestCode == SELECT_EXPORT_SETTINGS_FILE_INTENT && resultCode == RESULT_OK && resultData != null && resultData.data != null
ComplexCondition:Contact.kt$Contact$firstValue.isEmpty() && firstName.isEmpty() && middleName.isEmpty() && surname.isEmpty()
ComplexCondition:Contact.kt$Contact$secondValue.isEmpty() && other.firstName.isEmpty() && other.middleName.isEmpty() && other.surname.isEmpty()
ComplexCondition:CustomizationActivity.kt$CustomizationActivity$curTextColor == getColor(value.textColorId) && curBackgroundColor == getColor(value.backgroundColorId) && curPrimaryColor == getColor(value.primaryColorId) && curAppIconColor == getColor(value.appIconColorId)
@@ -124,11 +124,12 @@
LambdaParameterEventTrailing:ManageBlockedNumbersScreen.kt$onCopy
LambdaParameterEventTrailing:ManageBlockedNumbersScreen.kt$onSelectAll
LambdaParameterEventTrailing:SimpleDropDownMenuItem.kt$onClick
- LargeClass:BaseSimpleActivity.kt$BaseSimpleActivity : AppCompatActivity
+ LargeClass:BaseSimpleActivity.kt$BaseSimpleActivity : EdgeToEdgeActivity
LargeClass:ContactsHelper.kt$ContactsHelper
LargeClass:CustomizationActivity.kt$CustomizationActivity : BaseSimpleActivity
LongMethod:Activity-themes.kt$fun Activity.getThemeId(color: Int = baseConfig.primaryColor, showTransparentTop: Boolean = false)
LongMethod:Activity.kt$private fun BaseSimpleActivity.renameCasually( oldPath: String, newPath: String, isRenamingMultipleFiles: Boolean, callback: ((success: Boolean, android30RenameFormat: Android30RenameFormat) -> Unit)? )
+ LongMethod:BaseSimpleActivity.kt$BaseSimpleActivity$fun copyMoveFilesTo( fileDirItems: ArrayList<FileDirItem>, source: String, destination: String, isCopyOperation: Boolean, copyPhotoVideoOnly: Boolean, copyHidden: Boolean, callback: (destinationPath: String) -> Unit, )
LongMethod:BaseSimpleActivity.kt$BaseSimpleActivity$override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?)
LongMethod:ContactsHelper.kt$ContactsHelper$fun insertContact(contact: Contact): Boolean
LongMethod:ContactsHelper.kt$ContactsHelper$fun updateContact(contact: Contact, photoUpdateStatus: Int): Boolean
@@ -327,11 +328,6 @@
MagicNumber:BaseSimpleActivity.kt$BaseSimpleActivity$10
MagicNumber:BaseSimpleActivity.kt$BaseSimpleActivity$100
MagicNumber:BaseSimpleActivity.kt$BaseSimpleActivity$18
- MagicNumber:BaseSimpleActivity.kt$BaseSimpleActivity$300
- MagicNumber:BaseSimpleActivity.kt$BaseSimpleActivity$301
- MagicNumber:BaseSimpleActivity.kt$BaseSimpleActivity$302
- MagicNumber:BaseSimpleActivity.kt$BaseSimpleActivity$303
- MagicNumber:BaseSimpleActivity.kt$BaseSimpleActivity$304
MagicNumber:BaseSimpleActivity.kt$BaseSimpleActivity$50
MagicNumber:BaseSimpleActivity.kt$BaseSimpleActivity$9
MagicNumber:Bitmap.kt$80
@@ -938,7 +934,6 @@
MagicNumber:LineColorPickerDialog.kt$LineColorPickerDialog$16
MagicNumber:LineColorPickerDialog.kt$LineColorPickerDialog$17
MagicNumber:LineColorPickerDialog.kt$LineColorPickerDialog$18
- MagicNumber:LineColorPickerDialog.kt$LineColorPickerDialog$19
MagicNumber:LineColorPickerDialog.kt$LineColorPickerDialog$3
MagicNumber:LineColorPickerDialog.kt$LineColorPickerDialog$4
MagicNumber:LineColorPickerDialog.kt$LineColorPickerDialog$5
@@ -1034,30 +1029,9 @@
MaxLineLength:BaseSecurityTab.kt$BaseSecurityTab$updateTitle(context.getString(R.string.too_many_incorrect_attempts, count), context.getColor(R.color.md_red))
MaxLineLength:BaseSimpleActivity.kt$BaseSimpleActivity$// synchronous return value determines only if we are showing the SAF dialog, callback result tells if the SD or OTG permission has been granted
MaxLineLength:BaseSimpleActivity.kt$BaseSimpleActivity$// this file is guaranteed to be on the internal storage, so just delete it this way
- MaxLineLength:BaseSimpleActivity.kt$BaseSimpleActivity$ActivityCompat.requestPermissions(this, permissionIds.map { getPermissionString(it) }.toTypedArray(), GENERIC_PERM_HANDLER)
- MaxLineLength:BaseSimpleActivity.kt$BaseSimpleActivity$Intent(TelecomManager.ACTION_CHANGE_DEFAULT_DIALER).putExtra(TelecomManager.EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME, packageName)
- MaxLineLength:BaseSimpleActivity.kt$BaseSimpleActivity$baseConfig.OTGPartition = baseConfig.OTGTreeUri.removeSuffix("%3A").substringAfterLast('/').trimEnd('/')
- MaxLineLength:BaseSimpleActivity.kt$BaseSimpleActivity$copyMoveListener.copySucceeded(false, fileCountToCopy <= updatedPaths.size, destination, updatedPaths.size == 1)
- MaxLineLength:BaseSimpleActivity.kt$BaseSimpleActivity$copyMoveListener.copySucceeded(false, fileCountToCopy == 0, destination, false)
- MaxLineLength:BaseSimpleActivity.kt$BaseSimpleActivity$fun
MaxLineLength:BaseSimpleActivity.kt$BaseSimpleActivity$getConflictResolution(it, newFile.absolutePath) == CONFLICT_KEEP_BOTH -> newFile = getAlternativeFile(newFile)
MaxLineLength:BaseSimpleActivity.kt$BaseSimpleActivity$getConflictResolution(it, newFile.absolutePath) == CONFLICT_SKIP -> fileCountToCopy--
MaxLineLength:BaseSimpleActivity.kt$BaseSimpleActivity$if
- MaxLineLength:BaseSimpleActivity.kt$BaseSimpleActivity$private fun isAndroidDir(uri: Uri)
- MaxLineLength:BaseSimpleActivity.kt$BaseSimpleActivity$private fun isInternalStorage(uri: Uri)
- MaxLineLength:BaseSimpleActivity.kt$BaseSimpleActivity$private fun isProperOTGRootFolder(uri: Uri)
- MaxLineLength:BaseSimpleActivity.kt$BaseSimpleActivity$private fun isProperSDRootFolder(uri: Uri)
- MaxLineLength:BaseSimpleActivity.kt$BaseSimpleActivity$putExtra(DocumentsContract.EXTRA_INITIAL_URI, createAndroidDataOrObbUri(checkedDocumentPath))
- MaxLineLength:BaseSimpleActivity.kt$BaseSimpleActivity$return
- MaxLineLength:BaseSimpleActivity.kt$BaseSimpleActivity$startCopyMove(fileDirItems, destination, isCopyOperation, copyPhotoVideoOnly, copyHidden)
- MaxLineLength:BaseSimpleActivity.kt$BaseSimpleActivity$val
- MaxLineLength:BaseSimpleActivity.kt$BaseSimpleActivity$val drawableId = if (toolbarNavigationIcon == NavigationIcon.Cross) R.drawable.ic_cross_vector else R.drawable.ic_arrow_left_vector
- MaxLineLength:BaseSimpleActivity.kt$BaseSimpleActivity$val label = "You are using a fake version of the app. For your own safety download the original one from www.fossify.org. Thanks"
- MaxLineLength:BaseSimpleActivity.kt$BaseSimpleActivity$val recoverableSecurityException = securityException as? RecoverableSecurityException ?: throw securityException
- MaxLineLength:BaseSimpleActivity.kt$BaseSimpleActivity$var isMaterialActivity = false // by material activity we mean translucent navigation bar and opaque status and action bars
- MaxLineLength:BaseSimpleActivity.kt$BaseSimpleActivity$window.decorView.systemUiVisibility = window.decorView.systemUiVisibility.addBit(View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION)
- MaxLineLength:BaseSimpleActivity.kt$BaseSimpleActivity$window.decorView.systemUiVisibility = window.decorView.systemUiVisibility.removeBit(View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION)
- MaxLineLength:BaseSimpleActivity.kt$BaseSimpleActivity$window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION)
MaxLineLength:BaseSimpleActivity.kt$BaseSimpleActivity$}
MaxLineLength:BaseSplashActivity.kt$BaseSplashActivity$resources.getColor(if (isUsingSystemDarkTheme) R.color.theme_dark_background_color else R.color.theme_light_background_color)
MaxLineLength:BaseSplashActivity.kt$BaseSplashActivity$textColor = resources.getColor(if (isUsingSystemDarkTheme) R.color.theme_dark_text_color else R.color.theme_light_text_color)
@@ -1229,8 +1203,6 @@
MaxLineLength:LicenseScreen.kt$License(LICENSE_RTL, R.string.rtl_viewpager_title, R.string.rtl_viewpager_text, R.string.rtl_viewpager_url)
MaxLineLength:LicenseScreen.kt$License(LICENSE_SUBSAMPLING, R.string.subsampling_title, R.string.subsampling_text, R.string.subsampling_url)
MaxLineLength:LicenseScreen.kt$}
- MaxLineLength:LineColorPickerDialog.kt$LineColorPickerDialog$val activity: BaseSimpleActivity
- MaxLineLength:LineColorPickerDialog.kt$LineColorPickerDialog$val appIconIDs: ArrayList<Int>? = null
MaxLineLength:LineColorPickerDialog.kt$if (isPrimaryColorPicker) dialogLineColorPickerBinding!!.secondaryLineColorPicker else dialogLineColorPickerBinding!!.primaryLineColorPicker
MaxLineLength:LocalContactsHelper.kt$LocalContactsHelper$fun
MaxLineLength:LocalContactsHelper.kt$LocalContactsHelper$return (contacts.map { convertLocalContactToContact(it, storedGroups) }.toMutableList() as? ArrayList<Contact>) ?: arrayListOf()
@@ -1285,7 +1257,6 @@
MaxLineLength:MyRecyclerViewListAdapter.kt$MyRecyclerViewListAdapter.<no name provided>$override
MaxLineLength:MyRecyclerViewListAdapter.kt$MyRecyclerViewListAdapter.<no name provided>$val backArrow = activity.findViewById<ImageView>(androidx.appcompat.R.id.action_mode_close_button)
MaxLineLength:MyRecyclerViewListAdapter.kt$MyRecyclerViewListAdapter.ViewHolder$fun
- MaxLineLength:MySearchMenu.kt$MySearchMenu$params.scrollFlags = params.scrollFlags.removeBit(LayoutParams.SCROLL_FLAG_SCROLL or LayoutParams.SCROLL_FLAG_ENTER_ALWAYS)
MaxLineLength:PasswordTypesAdapter.kt$PasswordTypesAdapter$(view as SecurityTab).initTab(requiredHash, hashListener, scrollView, biometricPromptHost, showBiometricAuthentication)
MaxLineLength:PreviewExtensions.kt$MyDevicesDarkOnly$@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES, device = Devices.PIXEL_2, name = "5.0 inches dark", group = DARK)
MaxLineLength:PreviewExtensions.kt$MyDevicesDarkOnly$@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES, device = Devices.PIXEL_2_XL, name = "6.0 inches dark", group = DARK)
@@ -1347,7 +1318,6 @@
MaxLineLength:VcfExporter.kt$VcfExporter$val
MaxLineLength:VcfExporter.kt$VcfExporter$val photoByteArray = MediaStore.Images.Media.getBitmap(activity.contentResolver, Uri.parse(contact.thumbnailUri)).getByteArray()
MaxLineLength:View.kt$fun View.performHapticFeedback()
- MaxLineLength:Window.kt$decorView.systemUiVisibility = decorView.systemUiVisibility.removeBit(View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR)
MaxLineLength:WritePermissionDialog.kt$.
MaxLineLength:WritePermissionDialog.kt$WritePermissionDialog$Html.fromHtml(activity.getString(R.string.confirm_storage_access_android_text_specific, humanizedPath))
MaxLineLength:WritePermissionDialog.kt$WritePermissionDialog$class
@@ -1507,7 +1477,7 @@
TooManyFunctions:Activity.kt$org.fossify.commons.extensions.Activity.kt
TooManyFunctions:BaseConfig.kt$BaseConfig
TooManyFunctions:BaseSecurityTab.kt$BaseSecurityTab : ConstraintLayoutSecurityTab
- TooManyFunctions:BaseSimpleActivity.kt$BaseSimpleActivity : AppCompatActivity
+ TooManyFunctions:BaseSimpleActivity.kt$BaseSimpleActivity : EdgeToEdgeActivity
TooManyFunctions:BottomActionMenuView.kt$BottomActionMenuView : LinearLayout
TooManyFunctions:Breadcrumbs.kt$Breadcrumbs : HorizontalScrollView
TooManyFunctions:ComposeExtensions.kt$org.fossify.commons.compose.extensions.ComposeExtensions.kt
@@ -1609,12 +1579,6 @@
VariableNaming:BaseConfig.kt$BaseConfig$var OTGPartition: String get() = prefs.getString(OTG_PARTITION, "")!! set(OTGPartition) = prefs.edit().putString(OTG_PARTITION, OTGPartition).apply()
VariableNaming:BaseConfig.kt$BaseConfig$var OTGPath: String get() = prefs.getString(OTG_REAL_PATH, "")!! set(OTGPath) = prefs.edit().putString(OTG_REAL_PATH, OTGPath).apply()
VariableNaming:BaseConfig.kt$BaseConfig$var OTGTreeUri: String get() = prefs.getString(OTG_TREE_URI, "")!! set(OTGTreeUri) = prefs.edit().putString(OTG_TREE_URI, OTGTreeUri).apply()
- VariableNaming:BaseSimpleActivity.kt$BaseSimpleActivity$private val DELETE_FILE_SDK_30_HANDLER = 300
- VariableNaming:BaseSimpleActivity.kt$BaseSimpleActivity$private val GENERIC_PERM_HANDLER = 100
- VariableNaming:BaseSimpleActivity.kt$BaseSimpleActivity$private val MANAGE_MEDIA_RC = 303
- VariableNaming:BaseSimpleActivity.kt$BaseSimpleActivity$private val RECOVERABLE_SECURITY_HANDLER = 301
- VariableNaming:BaseSimpleActivity.kt$BaseSimpleActivity$private val TRASH_FILE_SDK_30_HANDLER = 304
- VariableNaming:BaseSimpleActivity.kt$BaseSimpleActivity$private val UPDATE_FILE_SDK_30_HANDLER = 302
VariableNaming:ContactsHelper.kt$ContactsHelper$private val BATCH_SIZE = 50
VariableNaming:ContactsHelper.kt$ContactsHelper$val IDsString = TextUtils.join(",", relevantGroupIDs)
VariableNaming:ContactsHelper.kt$ContactsHelper$val IM = cursor.getStringValue(CommonDataKinds.Im.DATA) ?: return@queryCursor
@@ -1628,10 +1592,6 @@
VariableNaming:FingerprintTab.kt$FingerprintTab$private val RECHECK_PERIOD = 3000L
VariableNaming:Int.kt$val DARK_FACTOR = factor
VariableNaming:Int.kt$val LIGHT_FACTOR = factor
- VariableNaming:LineColorPickerDialog.kt$LineColorPickerDialog$private val DEFAULT_COLOR_VALUE = activity.resources.getColor(R.color.color_primary)
- VariableNaming:LineColorPickerDialog.kt$LineColorPickerDialog$private val DEFAULT_PRIMARY_COLOR_INDEX = 9
- VariableNaming:LineColorPickerDialog.kt$LineColorPickerDialog$private val DEFAULT_SECONDARY_COLOR_INDEX = 8
- VariableNaming:LineColorPickerDialog.kt$LineColorPickerDialog$private val PRIMARY_COLORS_COUNT = 19
VariableNaming:MyRecyclerView.kt$MyRecyclerView$private val AUTO_SCROLL_DELAY = 25L
VariableNaming:MyRecyclerView.kt$MyRecyclerView.GestureListener$private val ZOOM_IN_THRESHOLD = -0.4f
VariableNaming:MyRecyclerView.kt$MyRecyclerView.GestureListener$private val ZOOM_OUT_THRESHOLD = 0.15f
@@ -1646,7 +1606,6 @@
WildcardImport:AddBlockedNumberDialog.kt$import androidx.compose.runtime.*
WildcardImport:AddBlockedNumberDialog.kt$import org.fossify.commons.compose.alert_dialog.*
WildcardImport:AlertDialogState.kt$import androidx.compose.runtime.*
- WildcardImport:AppLockActivity.kt$import org.fossify.commons.extensions.*
WildcardImport:AppSideloadedDialog.kt$import org.fossify.commons.compose.alert_dialog.*
WildcardImport:AppSideloadedDialog.kt$import org.fossify.commons.extensions.*
WildcardImport:AppTheme.kt$import androidx.compose.runtime.*
@@ -1730,7 +1689,6 @@
WildcardImport:MyRecyclerViewAdapter.kt$import org.fossify.commons.extensions.*
WildcardImport:MyRecyclerViewListAdapter.kt$import android.view.*
WildcardImport:MyRecyclerViewListAdapter.kt$import org.fossify.commons.extensions.*
- WildcardImport:MySearchMenu.kt$import org.fossify.commons.extensions.*
WildcardImport:OpenDeviceSettingsDialog.kt$import org.fossify.commons.compose.alert_dialog.*
WildcardImport:PermissionRequiredDialog.kt$import org.fossify.commons.compose.alert_dialog.*
WildcardImport:PinTab.kt$import org.fossify.commons.extensions.*
diff --git a/commons/lint-baseline.xml b/commons/lint-baseline.xml
index 518d9790f..29e819b34 100644
--- a/commons/lint-baseline.xml
+++ b/commons/lint-baseline.xml
@@ -18,17 +18,6 @@
message="Reference from @style/PinNumberStyle.Base to style/PinNumberStyle here"/>
-
-
-
-
@@ -69,7 +58,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
@@ -80,7 +69,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
@@ -91,7 +80,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
@@ -102,7 +91,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
@@ -113,7 +102,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
@@ -124,7 +113,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
@@ -216,17 +205,6 @@
column="15"/>
-
-
-
-
@@ -300,7 +278,7 @@
errorLine2=" ~~~~">
@@ -354,7 +332,7 @@
errorLine1="distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
@@ -365,7 +343,7 @@
errorLine1="gradlePlugins-agp = "8.11.1""
errorLine2=" ~~~~~~~~">
@@ -376,7 +354,7 @@
errorLine1="gradlePlugins-agp = "8.11.1""
errorLine2=" ~~~~~~~~">
@@ -427,79 +405,13 @@
+ message="A newer version of com.google.devtools.ksp than 2.2.20-2.0.3 is available: 2.2.20-2.0.4"
+ errorLine1="ksp = "2.2.20-2.0.3""
+ errorLine2=" ~~~~~~~~~~~~~~">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ file="$HOME/Projects/Fossify/FossifyOrg/libs/Commons/gradle/libs.versions.toml"
+ line="7"
+ column="7"/>
-
-
-
-
@@ -552,62 +453,62 @@
errorLine1="compose = "1.7.6""
errorLine2=" ~~~~~~~">
@@ -618,7 +519,7 @@
errorLine1="compose = "1.7.6""
errorLine2=" ~~~~~~~">
@@ -629,20 +530,86 @@
errorLine1="composeMaterial3 = "1.3.2""
errorLine2=" ~~~~~~~">
+ message="A newer version of androidx.room:room-compiler than 2.8.1 is available: 2.8.3"
+ errorLine1="room = "2.8.1""
+ errorLine2=" ~~~~~~~">
+ file="$HOME/Projects/Fossify/FossifyOrg/libs/Commons/gradle/libs.versions.toml"
+ line="40"
+ column="8"/>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -662,22 +629,11 @@
errorLine1="reprint = "2cb206415d""
errorLine2=" ~~~~~~~~~~~~">
-
-
-
-
+
+
+
+
@@ -817,7 +784,7 @@
errorLine2=" ~~~~~~~~~~~~~">
@@ -828,7 +795,7 @@
errorLine2=" ~~~~~~~~~~~~~">
@@ -894,7 +861,7 @@
errorLine2="~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
@@ -905,7 +872,7 @@
errorLine2="~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
@@ -916,7 +883,7 @@
errorLine2="~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
@@ -927,7 +894,7 @@
errorLine2="~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
@@ -971,7 +938,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
@@ -982,7 +949,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
@@ -993,7 +960,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
@@ -1004,7 +971,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
@@ -1026,7 +993,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
@@ -1037,7 +1004,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
@@ -2900,6 +2867,17 @@
column="5"/>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -16156,7 +16200,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
@@ -16167,7 +16211,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
@@ -16178,7 +16222,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
@@ -16222,7 +16266,7 @@
errorLine2="~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
@@ -16233,7 +16277,7 @@
errorLine2="~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
@@ -16244,7 +16288,7 @@
errorLine2="~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
@@ -16255,7 +16299,7 @@
errorLine2="~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
@@ -16266,7 +16310,7 @@
errorLine2="~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
@@ -16303,17 +16347,6 @@
column="5"/>
-
-
-
-
+ errorLine1=" <EditText"
+ errorLine2=" ~~~~~~~~">
+ line="35"
+ column="14"/>
+ errorLine1=" <EditText"
+ errorLine2=" ~~~~~~~~">
-
-
-
-
+ line="35"
+ column="14"/>
@@ -18530,7 +18552,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
@@ -18541,7 +18563,7 @@
errorLine2=" ~~~~~~~~~~~~~~~">
@@ -18552,7 +18574,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~">
@@ -18563,7 +18585,7 @@
errorLine2=" ~~~~~~~~~~~~~~~">
@@ -19047,7 +19069,7 @@
errorLine2=" ~~~~~~~~~">
@@ -19058,7 +19080,7 @@
errorLine2=" ~~~~~~~~~">
@@ -19069,7 +19091,7 @@
errorLine2=" ~~~~~~~~~">
@@ -19080,7 +19102,7 @@
errorLine2=" ~~~~~~~~~">
@@ -19245,7 +19267,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
@@ -19256,7 +19278,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
@@ -19267,7 +19289,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
@@ -19278,7 +19300,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
@@ -19289,7 +19311,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
@@ -19337,26 +19359,4 @@
column="5"/>
-
-
-
-
-
-
-
-
diff --git a/commons/src/main/kotlin/org/fossify/commons/activities/AppLockActivity.kt b/commons/src/main/kotlin/org/fossify/commons/activities/AppLockActivity.kt
index 6dc18661b..4b226fd6e 100644
--- a/commons/src/main/kotlin/org/fossify/commons/activities/AppLockActivity.kt
+++ b/commons/src/main/kotlin/org/fossify/commons/activities/AppLockActivity.kt
@@ -4,17 +4,23 @@ import android.app.Activity
import android.content.Intent
import android.os.Bundle
import androidx.activity.addCallback
-import androidx.appcompat.app.AppCompatActivity
import androidx.biometric.auth.AuthPromptHost
import org.fossify.commons.R
import org.fossify.commons.adapters.AppLockAdapter
import org.fossify.commons.databinding.ActivityAppLockBinding
-import org.fossify.commons.extensions.*
+import org.fossify.commons.extensions.appLockManager
+import org.fossify.commons.extensions.baseConfig
+import org.fossify.commons.extensions.getProperBackgroundColor
+import org.fossify.commons.extensions.getThemeId
+import org.fossify.commons.extensions.isBiometricAuthSupported
+import org.fossify.commons.extensions.onGlobalLayout
+import org.fossify.commons.extensions.overrideActivityTransition
+import org.fossify.commons.extensions.viewBinding
import org.fossify.commons.helpers.PROTECTION_FINGERPRINT
import org.fossify.commons.helpers.isRPlus
import org.fossify.commons.interfaces.HashListener
-class AppLockActivity : AppCompatActivity(), HashListener {
+class AppLockActivity : EdgeToEdgeActivity(), HashListener {
private val binding by viewBinding(ActivityAppLockBinding::inflate)
@@ -24,6 +30,7 @@ class AppLockActivity : AppCompatActivity(), HashListener {
super.onCreate(savedInstanceState)
setContentView(binding.root)
+ setupEdgeToEdge(padBottomSystem = listOf(binding.viewPager))
onBackPressedDispatcher.addCallback(owner = this) {
appLockManager.lock()
finishAffinity()
@@ -77,8 +84,6 @@ class AppLockActivity : AppCompatActivity(), HashListener {
private fun setupTheme() {
setTheme(getThemeId(showTransparentTop = true))
with(getProperBackgroundColor()) {
- window.updateStatusBarColors(this)
- window.updateNavigationBarColors(this)
window.decorView.setBackgroundColor(this)
}
}
diff --git a/commons/src/main/kotlin/org/fossify/commons/activities/BaseSimpleActivity.kt b/commons/src/main/kotlin/org/fossify/commons/activities/BaseSimpleActivity.kt
index 9a7086ced..34eb2722b 100644
--- a/commons/src/main/kotlin/org/fossify/commons/activities/BaseSimpleActivity.kt
+++ b/commons/src/main/kotlin/org/fossify/commons/activities/BaseSimpleActivity.kt
@@ -1,10 +1,6 @@
package org.fossify.commons.activities
-import android.animation.ArgbEvaluator
-import android.animation.ObjectAnimator
-import android.animation.ValueAnimator
import android.annotation.SuppressLint
-import android.app.Activity
import android.app.ActivityManager
import android.app.RecoverableSecurityException
import android.app.role.RoleManager
@@ -25,35 +21,27 @@ import android.telecom.TelecomManager
import android.view.Menu
import android.view.MenuItem
import android.view.View
-import android.view.WindowManager
import android.widget.EditText
-import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.Toast
+import androidx.activity.OnBackPressedCallback
+import androidx.activity.addCallback
import androidx.annotation.RequiresApi
-import androidx.appcompat.app.AppCompatActivity
-import androidx.appcompat.widget.Toolbar
-import androidx.coordinatorlayout.widget.CoordinatorLayout
-import androidx.core.animation.doOnEnd
import androidx.core.app.ActivityCompat
import androidx.core.net.toUri
import androidx.core.util.Pair
-import androidx.core.view.ScrollingView
-import androidx.core.view.WindowInsetsCompat
+import androidx.core.view.ViewCompat
+import androidx.core.view.WindowCompat
import androidx.core.view.get
import androidx.core.view.size
-import androidx.core.widget.NestedScrollView
-import androidx.recyclerview.widget.RecyclerView
import org.fossify.commons.R
import org.fossify.commons.asynctasks.CopyMoveTask
-import org.fossify.commons.compose.extensions.DEVELOPER_PLAY_STORE_URL
import org.fossify.commons.dialogs.ConfirmationDialog
import org.fossify.commons.dialogs.ExportSettingsDialog
import org.fossify.commons.dialogs.FileConflictDialog
import org.fossify.commons.dialogs.PermissionRequiredDialog
import org.fossify.commons.dialogs.WritePermissionDialog
import org.fossify.commons.dialogs.WritePermissionDialog.WritePermissionDialogMode
-import org.fossify.commons.extensions.addBit
import org.fossify.commons.extensions.adjustAlpha
import org.fossify.commons.extensions.applyColorFilter
import org.fossify.commons.extensions.baseConfig
@@ -67,7 +55,6 @@ import org.fossify.commons.extensions.formatSize
import org.fossify.commons.extensions.getAppIconColors
import org.fossify.commons.extensions.getAvailableStorageB
import org.fossify.commons.extensions.getColoredDrawableWithColor
-import org.fossify.commons.extensions.getColoredMaterialStatusBarColor
import org.fossify.commons.extensions.getContrastColor
import org.fossify.commons.extensions.getCurrentFormattedDateTime
import org.fossify.commons.extensions.getDoesFilePathExist
@@ -93,22 +80,14 @@ import org.fossify.commons.extensions.isShowingOTGDialog
import org.fossify.commons.extensions.isShowingSAFCreateDocumentDialogSdk30
import org.fossify.commons.extensions.isShowingSAFDialog
import org.fossify.commons.extensions.isShowingSAFDialogSdk30
-import org.fossify.commons.extensions.isUsingGestureNavigation
-import org.fossify.commons.extensions.launchViewIntent
-import org.fossify.commons.extensions.navigationBarHeight
-import org.fossify.commons.extensions.onApplyWindowInsets
import org.fossify.commons.extensions.openDeviceSettings
import org.fossify.commons.extensions.openNotificationSettings
import org.fossify.commons.extensions.random
-import org.fossify.commons.extensions.removeBit
import org.fossify.commons.extensions.showErrorToast
-import org.fossify.commons.extensions.statusBarHeight
+import org.fossify.commons.extensions.showModdedAppWarning
import org.fossify.commons.extensions.storeAndroidTreeUri
-import org.fossify.commons.extensions.toInt
import org.fossify.commons.extensions.toast
-import org.fossify.commons.extensions.updateNavigationBarColors
import org.fossify.commons.extensions.updateOTGPathFromPartition
-import org.fossify.commons.extensions.updateStatusBarColors
import org.fossify.commons.extensions.writeLn
import org.fossify.commons.helpers.APP_FAQ
import org.fossify.commons.helpers.APP_ICON_IDS
@@ -122,7 +101,6 @@ import org.fossify.commons.helpers.CONFLICT_KEEP_BOTH
import org.fossify.commons.helpers.CONFLICT_SKIP
import org.fossify.commons.helpers.CREATE_DOCUMENT_SDK_30
import org.fossify.commons.helpers.EXTERNAL_STORAGE_PROVIDER_AUTHORITY
-import org.fossify.commons.helpers.HIGHER_ALPHA
import org.fossify.commons.helpers.MEDIUM_ALPHA
import org.fossify.commons.helpers.MyContextWrapper
import org.fossify.commons.helpers.NavigationIcon
@@ -148,36 +126,29 @@ import org.fossify.commons.helpers.sumByLong
import org.fossify.commons.interfaces.CopyMoveListener
import org.fossify.commons.models.FAQItem
import org.fossify.commons.models.FileDirItem
+import org.fossify.commons.views.MyAppBarLayout
import java.io.File
import java.io.OutputStream
import java.util.regex.Pattern
-abstract class BaseSimpleActivity : AppCompatActivity() {
- var materialScrollColorAnimation: ValueAnimator? = null
+abstract class BaseSimpleActivity : EdgeToEdgeActivity() {
var copyMoveCallback: ((destinationPath: String) -> Unit)? = null
var actionOnPermission: ((granted: Boolean) -> Unit)? = null
var isAskingPermissions = false
var useDynamicTheme = true
- var showTransparentTop = false
- var isMaterialActivity = false // by material activity we mean translucent navigation bar and opaque status and action bars
var checkedDocumentPath = ""
- var currentScrollY = 0
var configItemsToExport = LinkedHashMap()
- private var mainCoordinatorLayout: CoordinatorLayout? = null
- private var nestedView: View? = null
- private var scrollingView: ScrollingView? = null
- private var toolbar: Toolbar? = null
- private var useTransparentNavigation = false
- private var useTopSearchMenu = false
- private val GENERIC_PERM_HANDLER = 100
- private val DELETE_FILE_SDK_30_HANDLER = 300
- private val RECOVERABLE_SECURITY_HANDLER = 301
- private val UPDATE_FILE_SDK_30_HANDLER = 302
- private val MANAGE_MEDIA_RC = 303
- private val TRASH_FILE_SDK_30_HANDLER = 304
+ private lateinit var backCallback: OnBackPressedCallback
companion object {
+ private const val GENERIC_PERM_HANDLER = 100
+ private const val DELETE_FILE_SDK_30_HANDLER = 300
+ private const val RECOVERABLE_SECURITY_HANDLER = 301
+ private const val UPDATE_FILE_SDK_30_HANDLER = 302
+ private const val MANAGE_MEDIA_RC = 303
+ private const val TRASH_FILE_SDK_30_HANDLER = 304
+
var funAfterSAFPermission: ((success: Boolean) -> Unit)? = null
var funAfterSdk30Action: ((success: Boolean) -> Unit)? = null
var funAfterUpdate30File: ((success: Boolean) -> Unit)? = null
@@ -192,49 +163,45 @@ abstract class BaseSimpleActivity : AppCompatActivity() {
abstract fun getRepositoryName(): String?
+ /** Return true if the back press was consumed. */
+ protected open fun onBackPressedCompat(): Boolean = false
+
+ /** Use when a screen needs to temporarily ignore back (e.g., during animations). */
+ protected fun setBackHandlingEnabled(enabled: Boolean) {
+ backCallback.isEnabled = enabled
+ }
+
+ /** If a subclass wants to explicitly trigger the default behaviour. */
+ protected fun performDefaultBack() {
+ backCallback.isEnabled = false
+ onBackPressedDispatcher.onBackPressed()
+ backCallback.isEnabled = true
+ }
+
override fun onCreate(savedInstanceState: Bundle?) {
if (useDynamicTheme) {
- setTheme(getThemeId(showTransparentTop = showTransparentTop))
+ setTheme(getThemeId(showTransparentTop = true))
}
super.onCreate(savedInstanceState)
+ WindowCompat.enableEdgeToEdge(window)
+ registerBackPressedCallback()
+
if (!packageName.startsWith("org.fossify.", true)) {
if ((0..50).random() == 10 || baseConfig.appRunCount % 100 == 0) {
- val label = "You are using a fake version of the app. For your own safety download the original one from www.fossify.org. Thanks"
- ConfirmationDialog(
- activity = this,
- message = label,
- positive = R.string.ok,
- negative = 0
- ) {
- launchViewIntent(DEVELOPER_PLAY_STORE_URL)
- }
+ showModdedAppWarning()
}
}
}
- @SuppressLint("NewApi")
override fun onResume() {
super.onResume()
if (useDynamicTheme) {
- setTheme(getThemeId(showTransparentTop = showTransparentTop))
+ setTheme(getThemeId(showTransparentTop = true))
updateBackgroundColor(getProperBackgroundColor())
}
- if (showTransparentTop) {
- window.statusBarColor = Color.TRANSPARENT
- } else if (!isMaterialActivity) {
- updateActionbarColor(getProperStatusBarColor())
- }
-
updateRecentsAppIcon()
-
- var navBarColor = getProperBackgroundColor()
- if (isMaterialActivity) {
- navBarColor = navBarColor.adjustAlpha(HIGHER_ALPHA)
- }
-
- updateNavigationBarColor(navBarColor)
maybeLaunchAppUnlockActivity(requestCode = REQUEST_APP_UNLOCK)
}
@@ -246,7 +213,7 @@ abstract class BaseSimpleActivity : AppCompatActivity() {
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
- handleNavigationAndScrolling()
+ ViewCompat.requestApplyInsets(findViewById(android.R.id.content))
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
@@ -269,211 +236,71 @@ abstract class BaseSimpleActivity : AppCompatActivity() {
}
}
- fun updateBackgroundColor(color: Int = baseConfig.backgroundColor) {
- window.decorView.setBackgroundColor(color)
- }
-
- fun updateStatusbarColor(color: Int) {
- window.updateStatusBarColors(color)
- }
-
- fun animateStatusBarColor(colorTo: Int, colorFrom: Int = window.statusBarColor, duration: Long = 300L) {
- with(ObjectAnimator.ofInt(colorFrom, colorTo)) {
- setEvaluator(ArgbEvaluator())
- setDuration(duration)
- addUpdateListener {
- window.statusBarColor = it.animatedValue.toInt()
- }
-
- doOnEnd { updateStatusbarColor(window.statusBarColor) }
- start()
+ fun registerBackPressedCallback() {
+ backCallback = onBackPressedDispatcher.addCallback(this) {
+ if (onBackPressedCompat()) return@addCallback
+ // fallback to system
+ isEnabled = false
+ onBackPressedDispatcher.onBackPressed()
+ isEnabled = true
}
}
- fun updateActionbarColor(color: Int = getProperStatusBarColor()) {
- updateStatusbarColor(color)
- setTaskDescription(ActivityManager.TaskDescription(null, null, color))
- }
-
- fun updateNavigationBarColor(color: Int) {
- window.updateNavigationBarColors(color)
+ fun updateBackgroundColor(color: Int = baseConfig.backgroundColor) {
+ window.decorView.setBackgroundColor(color)
}
- // use translucent navigation bar, set the background color to action and status bars
- fun updateMaterialActivityViews(
- mainCoordinatorLayout: CoordinatorLayout?,
- nestedView: View?,
- useTransparentNavigation: Boolean,
- useTopSearchMenu: Boolean,
+ fun setupTopAppBar(
+ topAppBar: MyAppBarLayout,
+ navigationIcon: NavigationIcon = NavigationIcon.None,
+ topBarColor: Int = getRequiredTopBarColor(),
+ searchMenuItem: MenuItem? = null,
) {
- this.mainCoordinatorLayout = mainCoordinatorLayout
- this.nestedView = nestedView
- this.useTransparentNavigation = useTransparentNavigation
- this.useTopSearchMenu = useTopSearchMenu
- handleNavigationAndScrolling()
-
- val backgroundColor = getProperBackgroundColor()
- updateStatusbarColor(backgroundColor)
- updateActionbarColor(backgroundColor)
- }
-
- private fun handleNavigationAndScrolling() {
- if (useTransparentNavigation) {
- if (navigationBarHeight > 0 || isUsingGestureNavigation()) {
- window.decorView.systemUiVisibility = window.decorView.systemUiVisibility.addBit(View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION)
- updateTopBottomInsets(statusBarHeight, navigationBarHeight)
- // Don't touch this. Window Inset API often has a domino effect and things will most likely break.
- onApplyWindowInsets {
- val insets = it.getInsets(WindowInsetsCompat.Type.systemBars() or WindowInsetsCompat.Type.ime())
- updateTopBottomInsets(insets.top, insets.bottom)
- }
+ val contrastColor = topBarColor.getContrastColor()
+ if (navigationIcon != NavigationIcon.None) {
+ val drawableId = if (navigationIcon == NavigationIcon.Cross) {
+ R.drawable.ic_cross_vector
} else {
- window.decorView.systemUiVisibility = window.decorView.systemUiVisibility.removeBit(View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION)
- updateTopBottomInsets(0, 0)
- }
- }
- }
-
- private fun updateTopBottomInsets(top: Int, bottom: Int) {
- nestedView?.run {
- setPadding(paddingLeft, paddingTop, paddingRight, bottom)
- }
- (mainCoordinatorLayout?.layoutParams as? FrameLayout.LayoutParams)?.topMargin = top
- }
-
- // colorize the top toolbar and statusbar at scrolling down a bit
- fun setupMaterialScrollListener(scrollingView: ScrollingView?, toolbar: Toolbar) {
- this.scrollingView = scrollingView
- this.toolbar = toolbar
- if (scrollingView is RecyclerView) {
- scrollingView.setOnScrollChangeListener { v, scrollX, scrollY, oldScrollX, oldScrollY ->
- val newScrollY = scrollingView.computeVerticalScrollOffset()
- scrollingChanged(newScrollY, currentScrollY)
- currentScrollY = newScrollY
+ R.drawable.ic_arrow_left_vector
}
- } else if (scrollingView is NestedScrollView) {
- scrollingView.setOnScrollChangeListener { v, scrollX, scrollY, oldScrollX, oldScrollY ->
- scrollingChanged(scrollY, oldScrollY)
- }
- }
- }
-
- private fun scrollingChanged(newScrollY: Int, oldScrollY: Int) {
- if (newScrollY > 0 && oldScrollY == 0) {
- val colorFrom = window.statusBarColor
- val colorTo = getColoredMaterialStatusBarColor()
- animateTopBarColors(colorFrom, colorTo)
- } else if (newScrollY == 0 && oldScrollY > 0) {
- val colorFrom = window.statusBarColor
- val colorTo = getRequiredStatusBarColor()
- animateTopBarColors(colorFrom, colorTo)
- }
- }
- fun animateTopBarColors(colorFrom: Int, colorTo: Int) {
- if (toolbar == null) {
- return
- }
-
- materialScrollColorAnimation?.end()
- materialScrollColorAnimation = ValueAnimator.ofObject(ArgbEvaluator(), colorFrom, colorTo)
- materialScrollColorAnimation!!.addUpdateListener { animator ->
- val color = animator.animatedValue as Int
- if (toolbar != null) {
- updateTopBarColors(toolbar!!, color)
- }
+ topAppBar.toolbar?.navigationIcon =
+ resources.getColoredDrawableWithColor(drawableId, contrastColor)
+ topAppBar.toolbar?.setNavigationContentDescription(navigationIcon.accessibilityResId)
}
- materialScrollColorAnimation!!.start()
- }
-
- fun getRequiredStatusBarColor(): Int {
- return if ((scrollingView is RecyclerView || scrollingView is NestedScrollView) && scrollingView?.computeVerticalScrollOffset() == 0) {
- getProperBackgroundColor()
- } else {
- getColoredMaterialStatusBarColor()
- }
- }
-
- fun updateTopBarColors(toolbar: Toolbar, color: Int) {
- val contrastColor = if (useTopSearchMenu) {
- getProperBackgroundColor().getContrastColor()
- } else {
- color.getContrastColor()
- }
-
- if (!useTopSearchMenu) {
- updateStatusbarColor(color)
- toolbar.setBackgroundColor(color)
- toolbar.setTitleTextColor(contrastColor)
- toolbar.navigationIcon?.applyColorFilter(contrastColor)
- toolbar.collapseIcon = resources.getColoredDrawableWithColor(R.drawable.ic_arrow_left_vector, contrastColor)
- }
-
- toolbar.overflowIcon = resources.getColoredDrawableWithColor(R.drawable.ic_three_dots_vector, contrastColor)
-
- val menu = toolbar.menu
- for (i in 0 until menu.size) {
- try {
- menu[i].icon?.setTint(contrastColor)
- } catch (ignored: Exception) {
- }
- }
- }
-
- fun updateStatusBarOnPageChange() {
- if (scrollingView is RecyclerView || scrollingView is NestedScrollView) {
- val scrollY = scrollingView!!.computeVerticalScrollOffset()
- val colorFrom = window.statusBarColor
- val colorTo = if (scrollY > 0) {
- getColoredMaterialStatusBarColor()
- } else {
- getRequiredStatusBarColor()
- }
- animateTopBarColors(colorFrom, colorTo)
- currentScrollY = scrollY
- }
- }
-
- fun setupToolbar(
- toolbar: Toolbar,
- toolbarNavigationIcon: NavigationIcon = NavigationIcon.None,
- statusBarColor: Int = getRequiredStatusBarColor(),
- searchMenuItem: MenuItem? = null,
- ) {
- val contrastColor = statusBarColor.getContrastColor()
- if (toolbarNavigationIcon != NavigationIcon.None) {
- val drawableId = if (toolbarNavigationIcon == NavigationIcon.Cross) R.drawable.ic_cross_vector else R.drawable.ic_arrow_left_vector
- toolbar.navigationIcon = resources.getColoredDrawableWithColor(drawableId, contrastColor)
- toolbar.setNavigationContentDescription(toolbarNavigationIcon.accessibilityResId)
- }
-
- toolbar.setNavigationOnClickListener {
+ topAppBar.toolbar?.setNavigationOnClickListener {
hideKeyboard()
finish()
}
- updateTopBarColors(toolbar, statusBarColor)
+ updateTopBarColors(topAppBar, topBarColor)
- if (!useTopSearchMenu) {
- searchMenuItem?.actionView?.findViewById(androidx.appcompat.R.id.search_close_btn)?.apply {
- applyColorFilter(contrastColor)
- }
+ if (!isSearchBarEnabled) {
+ searchMenuItem?.actionView
+ ?.findViewById(androidx.appcompat.R.id.search_close_btn)
+ ?.apply {
+ applyColorFilter(contrastColor)
+ }
- searchMenuItem?.actionView?.findViewById(androidx.appcompat.R.id.search_src_text)?.apply {
- setTextColor(contrastColor)
- setHintTextColor(contrastColor.adjustAlpha(MEDIUM_ALPHA))
- hint = "${getString(R.string.search)}…"
+ searchMenuItem?.actionView
+ ?.findViewById(androidx.appcompat.R.id.search_src_text)
+ ?.apply {
+ setTextColor(contrastColor)
+ setHintTextColor(contrastColor.adjustAlpha(MEDIUM_ALPHA))
+ hint = "${getString(R.string.search)}…"
- if (isQPlus()) {
- textCursorDrawable = null
+ if (isQPlus()) {
+ textCursorDrawable = null
+ }
}
- }
// search underline
- searchMenuItem?.actionView?.findViewById(androidx.appcompat.R.id.search_plate)?.apply {
- background.setColorFilter(contrastColor, PorterDuff.Mode.MULTIPLY)
- }
+ searchMenuItem?.actionView
+ ?.findViewById(androidx.appcompat.R.id.search_plate)
+ ?.apply {
+ background.setColorFilter(contrastColor, PorterDuff.Mode.MULTIPLY)
+ }
}
}
@@ -485,7 +312,8 @@ abstract class BaseSimpleActivity : AppCompatActivity() {
return
}
- val recentsIcon = BitmapFactory.decodeResource(resources, appIconIDs[currentAppIconColorIndex])
+ val recentsIcon =
+ BitmapFactory.decodeResource(resources, appIconIDs[currentAppIconColorIndex])
val title = getAppLauncherName()
val color = baseConfig.primaryColor
@@ -526,10 +354,6 @@ abstract class BaseSimpleActivity : AppCompatActivity() {
return 0
}
- fun setTranslucentNavigation() {
- window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION)
- }
-
override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) {
super.onActivityResult(requestCode, resultCode, resultData)
val partition = try {
@@ -540,7 +364,7 @@ abstract class BaseSimpleActivity : AppCompatActivity() {
val sdOtgPattern = Pattern.compile(SD_OTG_SHORT)
if (requestCode == CREATE_DOCUMENT_SDK_30) {
- if (resultCode == Activity.RESULT_OK && resultData != null && resultData.data != null) {
+ if (resultCode == RESULT_OK && resultData != null && resultData.data != null) {
val treeUri = resultData.data
val checkedUri = buildDocumentUriSdk30(checkedDocumentPath)
@@ -550,7 +374,8 @@ abstract class BaseSimpleActivity : AppCompatActivity() {
return
}
- val takeFlags = Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
+ val takeFlags =
+ Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
applicationContext.contentResolver.takePersistableUriPermission(treeUri, takeFlags)
val funAfter = funAfterSdk30Action
funAfterSdk30Action = null
@@ -560,7 +385,7 @@ abstract class BaseSimpleActivity : AppCompatActivity() {
}
} else if (requestCode == OPEN_DOCUMENT_TREE_FOR_SDK_30) {
- if (resultCode == Activity.RESULT_OK && resultData != null && resultData.data != null) {
+ if (resultCode == RESULT_OK && resultData != null && resultData.data != null) {
val treeUri = resultData.data
val checkedUri = createFirstParentTreeUri(checkedDocumentPath)
@@ -571,7 +396,8 @@ abstract class BaseSimpleActivity : AppCompatActivity() {
return
}
- val takeFlags = Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
+ val takeFlags =
+ Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
applicationContext.contentResolver.takePersistableUriPermission(treeUri, takeFlags)
val funAfter = funAfterSdk30Action
funAfterSdk30Action = null
@@ -581,7 +407,7 @@ abstract class BaseSimpleActivity : AppCompatActivity() {
}
} else if (requestCode == OPEN_DOCUMENT_TREE_FOR_ANDROID_DATA_OR_OBB) {
- if (resultCode == Activity.RESULT_OK && resultData != null && resultData.data != null) {
+ if (resultCode == RESULT_OK && resultData != null && resultData.data != null) {
if (isProperAndroidRoot(checkedDocumentPath, resultData.data!!)) {
if (resultData.dataString == baseConfig.OTGTreeUri || resultData.dataString == baseConfig.sdTreeUri) {
val pathToSelect = createAndroidDataOrObbPath(checkedDocumentPath)
@@ -592,15 +418,27 @@ abstract class BaseSimpleActivity : AppCompatActivity() {
val treeUri = resultData.data
storeAndroidTreeUri(checkedDocumentPath, treeUri.toString())
- val takeFlags = Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
- applicationContext.contentResolver.takePersistableUriPermission(treeUri!!, takeFlags)
+ val takeFlags =
+ Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
+ applicationContext.contentResolver.takePersistableUriPermission(
+ treeUri!!,
+ takeFlags
+ )
funAfterSAFPermission?.invoke(true)
funAfterSAFPermission = null
} else {
- toast(getString(R.string.wrong_folder_selected, createAndroidDataOrObbPath(checkedDocumentPath)))
+ toast(
+ getString(
+ R.string.wrong_folder_selected,
+ createAndroidDataOrObbPath(checkedDocumentPath)
+ )
+ )
Intent(Intent.ACTION_OPEN_DOCUMENT_TREE).apply {
if (isRPlus()) {
- putExtra(DocumentsContract.EXTRA_INITIAL_URI, createAndroidDataOrObbUri(checkedDocumentPath))
+ putExtra(
+ DocumentsContract.EXTRA_INITIAL_URI,
+ createAndroidDataOrObbUri(checkedDocumentPath)
+ )
}
try {
@@ -614,8 +452,9 @@ abstract class BaseSimpleActivity : AppCompatActivity() {
funAfterSAFPermission?.invoke(false)
}
} else if (requestCode == OPEN_DOCUMENT_TREE_SD) {
- if (resultCode == Activity.RESULT_OK && resultData != null && resultData.data != null) {
- val isProperPartition = partition.isEmpty() || !sdOtgPattern.matcher(partition).matches() || (sdOtgPattern.matcher(partition)
+ if (resultCode == RESULT_OK && resultData != null && resultData.data != null) {
+ val isProperPartition = partition.isEmpty() || !sdOtgPattern.matcher(partition)
+ .matches() || (sdOtgPattern.matcher(partition)
.matches() && resultData.dataString!!.contains(partition))
if (isProperSDRootFolder(resultData.data!!) && isProperPartition) {
if (resultData.dataString == baseConfig.OTGTreeUri) {
@@ -640,8 +479,9 @@ abstract class BaseSimpleActivity : AppCompatActivity() {
funAfterSAFPermission?.invoke(false)
}
} else if (requestCode == OPEN_DOCUMENT_TREE_OTG) {
- if (resultCode == Activity.RESULT_OK && resultData != null && resultData.data != null) {
- val isProperPartition = partition.isEmpty() || !sdOtgPattern.matcher(partition).matches() || (sdOtgPattern.matcher(partition)
+ if (resultCode == RESULT_OK && resultData != null && resultData.data != null) {
+ val isProperPartition = partition.isEmpty() || !sdOtgPattern.matcher(partition)
+ .matches() || (sdOtgPattern.matcher(partition)
.matches() && resultData.dataString!!.contains(partition))
if (isProperOTGRootFolder(resultData.data!!) && isProperPartition) {
if (resultData.dataString == baseConfig.sdTreeUri) {
@@ -650,11 +490,17 @@ abstract class BaseSimpleActivity : AppCompatActivity() {
return
}
baseConfig.OTGTreeUri = resultData.dataString!!
- baseConfig.OTGPartition = baseConfig.OTGTreeUri.removeSuffix("%3A").substringAfterLast('/').trimEnd('/')
+ baseConfig.OTGPartition =
+ baseConfig.OTGTreeUri.removeSuffix("%3A").substringAfterLast('/')
+ .trimEnd('/')
updateOTGPathFromPartition()
- val takeFlags = Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
- applicationContext.contentResolver.takePersistableUriPermission(resultData.data!!, takeFlags)
+ val takeFlags =
+ Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
+ applicationContext.contentResolver.takePersistableUriPermission(
+ resultData.data!!,
+ takeFlags
+ )
funAfterSAFPermission?.invoke(true)
funAfterSAFPermission = null
@@ -671,20 +517,20 @@ abstract class BaseSimpleActivity : AppCompatActivity() {
} else {
funAfterSAFPermission?.invoke(false)
}
- } else if (requestCode == SELECT_EXPORT_SETTINGS_FILE_INTENT && resultCode == Activity.RESULT_OK && resultData != null && resultData.data != null) {
+ } else if (requestCode == SELECT_EXPORT_SETTINGS_FILE_INTENT && resultCode == RESULT_OK && resultData != null && resultData.data != null) {
val outputStream = contentResolver.openOutputStream(resultData.data!!)
exportSettingsTo(outputStream, configItemsToExport)
} else if (requestCode == DELETE_FILE_SDK_30_HANDLER) {
- funAfterSdk30Action?.invoke(resultCode == Activity.RESULT_OK)
+ funAfterSdk30Action?.invoke(resultCode == RESULT_OK)
} else if (requestCode == RECOVERABLE_SECURITY_HANDLER) {
- funRecoverableSecurity?.invoke(resultCode == Activity.RESULT_OK)
+ funRecoverableSecurity?.invoke(resultCode == RESULT_OK)
funRecoverableSecurity = null
} else if (requestCode == UPDATE_FILE_SDK_30_HANDLER) {
- funAfterUpdate30File?.invoke(resultCode == Activity.RESULT_OK)
+ funAfterUpdate30File?.invoke(resultCode == RESULT_OK)
} else if (requestCode == MANAGE_MEDIA_RC) {
funAfterManageMediaPermission?.invoke()
} else if (requestCode == TRASH_FILE_SDK_30_HANDLER) {
- funAfterTrash30File?.invoke(resultCode == Activity.RESULT_OK)
+ funAfterTrash30File?.invoke(resultCode == RESULT_OK)
}
}
@@ -692,24 +538,54 @@ abstract class BaseSimpleActivity : AppCompatActivity() {
val treeUri = resultData.data
baseConfig.sdTreeUri = treeUri.toString()
- val takeFlags = Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
+ val takeFlags =
+ Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
applicationContext.contentResolver.takePersistableUriPermission(treeUri!!, takeFlags)
}
- private fun isProperSDRootFolder(uri: Uri) = isExternalStorageDocument(uri) && isRootUri(uri) && !isInternalStorage(uri)
- private fun isProperSDFolder(uri: Uri) = isExternalStorageDocument(uri) && !isInternalStorage(uri)
+ private fun isProperSDRootFolder(uri: Uri): Boolean {
+ return isExternalStorageDocument(uri) && isRootUri(uri) && !isInternalStorage(uri)
+ }
+
+ private fun isProperSDFolder(uri: Uri): Boolean {
+ return isExternalStorageDocument(uri) && !isInternalStorage(uri)
+ }
- private fun isProperOTGRootFolder(uri: Uri) = isExternalStorageDocument(uri) && isRootUri(uri) && !isInternalStorage(uri)
- private fun isProperOTGFolder(uri: Uri) = isExternalStorageDocument(uri) && !isInternalStorage(uri)
+ private fun isProperOTGRootFolder(uri: Uri): Boolean {
+ return isExternalStorageDocument(uri) && isRootUri(uri) && !isInternalStorage(uri)
+ }
+
+ private fun isProperOTGFolder(uri: Uri): Boolean {
+ return isExternalStorageDocument(uri) && !isInternalStorage(uri)
+ }
private fun isRootUri(uri: Uri) = uri.lastPathSegment?.endsWith(":") ?: false
- private fun isInternalStorage(uri: Uri) = isExternalStorageDocument(uri) && DocumentsContract.getTreeDocumentId(uri).contains("primary")
- private fun isAndroidDir(uri: Uri) = isExternalStorageDocument(uri) && DocumentsContract.getTreeDocumentId(uri).contains(":Android")
- private fun isInternalStorageAndroidDir(uri: Uri) = isInternalStorage(uri) && isAndroidDir(uri)
- private fun isOTGAndroidDir(uri: Uri) = isProperOTGFolder(uri) && isAndroidDir(uri)
- private fun isSDAndroidDir(uri: Uri) = isProperSDFolder(uri) && isAndroidDir(uri)
- private fun isExternalStorageDocument(uri: Uri) = EXTERNAL_STORAGE_PROVIDER_AUTHORITY == uri.authority
+ private fun isInternalStorage(uri: Uri): Boolean {
+ return isExternalStorageDocument(uri) && DocumentsContract.getTreeDocumentId(uri)
+ .contains("primary")
+ }
+
+ private fun isAndroidDir(uri: Uri): Boolean {
+ return isExternalStorageDocument(uri) && DocumentsContract.getTreeDocumentId(uri)
+ .contains(":Android")
+ }
+
+ private fun isInternalStorageAndroidDir(uri: Uri): Boolean {
+ return isInternalStorage(uri) && isAndroidDir(uri)
+ }
+
+ private fun isOTGAndroidDir(uri: Uri): Boolean {
+ return isProperOTGFolder(uri) && isAndroidDir(uri)
+ }
+
+ private fun isSDAndroidDir(uri: Uri): Boolean {
+ return isProperSDFolder(uri) && isAndroidDir(uri)
+ }
+
+ private fun isExternalStorageDocument(uri: Uri): Boolean {
+ return EXTERNAL_STORAGE_PROVIDER_AUTHORITY == uri.authority
+ }
private fun isProperAndroidRoot(path: String, uri: Uri): Boolean {
return when {
@@ -744,15 +620,7 @@ abstract class BaseSimpleActivity : AppCompatActivity() {
fun startCustomizationActivity() {
if (!packageName.contains("yfissof".reversed(), true)) {
if (baseConfig.appRunCount > 100) {
- val label = "You are using a fake version of the app. For your own safety download the original one from www.fossify.org. Thanks"
- ConfirmationDialog(
- activity = this,
- message = label,
- positive = R.string.ok,
- negative = 0
- ) {
- launchViewIntent(DEVELOPER_PLAY_STORE_URL)
- }
+ showModdedAppWarning()
return
}
}
@@ -798,7 +666,11 @@ abstract class BaseSimpleActivity : AppCompatActivity() {
}
}
- fun handleSAFDialogSdk30(path: String, showRationale: Boolean = true, callback: (success: Boolean) -> Unit): Boolean {
+ fun handleSAFDialogSdk30(
+ path: String,
+ showRationale: Boolean = true,
+ callback: (success: Boolean) -> Unit
+ ): Boolean {
hideKeyboard()
return if (!packageName.startsWith("org.fossify")) {
callback(true)
@@ -812,7 +684,10 @@ abstract class BaseSimpleActivity : AppCompatActivity() {
}
}
- fun checkManageMediaOrHandleSAFDialogSdk30(path: String, callback: (success: Boolean) -> Unit): Boolean {
+ fun checkManageMediaOrHandleSAFDialogSdk30(
+ path: String,
+ callback: (success: Boolean) -> Unit
+ ): Boolean {
hideKeyboard()
return if (canManageMedia()) {
callback(true)
@@ -822,7 +697,10 @@ abstract class BaseSimpleActivity : AppCompatActivity() {
}
}
- fun handleSAFCreateDocumentDialogSdk30(path: String, callback: (success: Boolean) -> Unit): Boolean {
+ fun handleSAFCreateDocumentDialogSdk30(
+ path: String,
+ callback: (success: Boolean) -> Unit
+ ): Boolean {
hideKeyboard()
return if (!packageName.startsWith("org.fossify")) {
callback(true)
@@ -836,7 +714,11 @@ abstract class BaseSimpleActivity : AppCompatActivity() {
}
}
- fun handleAndroidSAFDialog(path: String, openInSystemAppAllowed: Boolean = false, callback: (success: Boolean) -> Unit): Boolean {
+ fun handleAndroidSAFDialog(
+ path: String,
+ openInSystemAppAllowed: Boolean = false,
+ callback: (success: Boolean) -> Unit
+ ): Boolean {
hideKeyboard()
return if (!packageName.startsWith("org.fossify")) {
callback(true)
@@ -884,7 +766,8 @@ abstract class BaseSimpleActivity : AppCompatActivity() {
if (isRPlus()) {
funAfterSdk30Action = callback
try {
- val deleteRequest = MediaStore.createDeleteRequest(contentResolver, uris).intentSender
+ val deleteRequest =
+ MediaStore.createDeleteRequest(contentResolver, uris).intentSender
startIntentSenderForResult(deleteRequest, DELETE_FILE_SDK_30_HANDLER, null, 0, 0, 0)
} catch (e: Exception) {
showErrorToast(e)
@@ -904,7 +787,8 @@ abstract class BaseSimpleActivity : AppCompatActivity() {
if (isRPlus()) {
funAfterTrash30File = callback
try {
- val trashRequest = MediaStore.createTrashRequest(contentResolver, uris, toTrash).intentSender
+ val trashRequest =
+ MediaStore.createTrashRequest(contentResolver, uris, toTrash).intentSender
startIntentSenderForResult(trashRequest, TRASH_FILE_SDK_30_HANDLER, null, 0, 0, 0)
} catch (e: Exception) {
showErrorToast(e)
@@ -940,9 +824,17 @@ abstract class BaseSimpleActivity : AppCompatActivity() {
} catch (securityException: SecurityException) {
if (isQPlus()) {
funRecoverableSecurity = callback
- val recoverableSecurityException = securityException as? RecoverableSecurityException ?: throw securityException
+ val recoverableSecurityException =
+ securityException as? RecoverableSecurityException ?: throw securityException
val intentSender = recoverableSecurityException.userAction.actionIntent.intentSender
- startIntentSenderForResult(intentSender, RECOVERABLE_SECURITY_HANDLER, null, 0, 0, 0)
+ startIntentSenderForResult(
+ intent = intentSender,
+ requestCode = RECOVERABLE_SECURITY_HANDLER,
+ fillInIntent = null,
+ flagsMask = 0,
+ flagsValues = 0,
+ extraFlags = 0
+ )
} else {
callback(false)
}
@@ -1001,14 +893,28 @@ abstract class BaseSimpleActivity : AppCompatActivity() {
val fileUris = getFileUrisFromFileDirItems(fileDirItems)
updateSDK30Uris(fileUris) { sdk30UriSuccess ->
if (sdk30UriSuccess) {
- startCopyMove(fileDirItems, destination, isCopyOperation, copyPhotoVideoOnly, copyHidden)
+ startCopyMove(
+ files = fileDirItems,
+ destinationPath = destination,
+ isCopyOperation = isCopyOperation,
+ copyPhotoVideoOnly = copyPhotoVideoOnly,
+ copyHidden = copyHidden
+ )
}
}
} else {
- startCopyMove(fileDirItems, destination, isCopyOperation, copyPhotoVideoOnly, copyHidden)
+ startCopyMove(
+ files = fileDirItems,
+ destinationPath = destination,
+ isCopyOperation = isCopyOperation,
+ copyPhotoVideoOnly = copyPhotoVideoOnly,
+ copyHidden = copyHidden
+ )
}
} else {
- if (isPathOnOTG(source) || isPathOnOTG(destination) || isPathOnSD(source) || isPathOnSD(destination) ||
+ if (isPathOnOTG(source) || isPathOnOTG(destination) || isPathOnSD(source) || isPathOnSD(
+ destination
+ ) ||
isRestrictedSAFOnlyRoot(source) || isRestrictedSAFOnlyRoot(destination) ||
isAccessibleWithSAFSdk30(source) || isAccessibleWithSAFSdk30(destination) ||
fileDirItems.first().isDirectory
@@ -1020,11 +926,23 @@ abstract class BaseSimpleActivity : AppCompatActivity() {
val fileUris = getFileUrisFromFileDirItems(fileDirItems)
updateSDK30Uris(fileUris) { sdk30UriSuccess ->
if (sdk30UriSuccess) {
- startCopyMove(fileDirItems, destination, isCopyOperation, copyPhotoVideoOnly, copyHidden)
+ startCopyMove(
+ files = fileDirItems,
+ destinationPath = destination,
+ isCopyOperation = isCopyOperation,
+ copyPhotoVideoOnly = copyPhotoVideoOnly,
+ copyHidden = copyHidden
+ )
}
}
} else {
- startCopyMove(fileDirItems, destination, isCopyOperation, copyPhotoVideoOnly, copyHidden)
+ startCopyMove(
+ files = fileDirItems,
+ destinationPath = destination,
+ isCopyOperation = isCopyOperation,
+ copyPhotoVideoOnly = copyPhotoVideoOnly,
+ copyHidden = copyHidden
+ )
}
}
}
@@ -1058,9 +976,19 @@ abstract class BaseSimpleActivity : AppCompatActivity() {
runOnUiThread {
if (updatedPaths.isEmpty()) {
- copyMoveListener.copySucceeded(false, fileCountToCopy == 0, destination, false)
+ copyMoveListener.copySucceeded(
+ copyOnly = false,
+ copiedAll = fileCountToCopy == 0,
+ destinationPath = destination,
+ wasCopyingOneFileOnly = false
+ )
} else {
- copyMoveListener.copySucceeded(false, fileCountToCopy <= updatedPaths.size, destination, updatedPaths.size == 1)
+ copyMoveListener.copySucceeded(
+ copyOnly = false,
+ copiedAll = fileCountToCopy <= updatedPaths.size,
+ destinationPath = destination,
+ wasCopyingOneFileOnly = updatedPaths.size == 1
+ )
}
}
}
@@ -1079,7 +1007,8 @@ abstract class BaseSimpleActivity : AppCompatActivity() {
var fileIndex = 1
var newFile: File?
do {
- val newName = String.format("%s(%d).%s", file.nameWithoutExtension, fileIndex, file.extension)
+ val newName =
+ String.format("%s(%d).%s", file.nameWithoutExtension, fileIndex, file.extension)
newFile = File(file.parent, newName)
fileIndex++
} while (getDoesFilePathExist(newFile!!.absolutePath))
@@ -1118,7 +1047,11 @@ abstract class BaseSimpleActivity : AppCompatActivity() {
}
}
} else {
- val text = String.format(getString(R.string.no_space), sumToCopy.formatSize(), availableSpace.formatSize())
+ val text = String.format(
+ getString(R.string.no_space),
+ sumToCopy.formatSize(),
+ availableSpace.formatSize()
+ )
toast(text, Toast.LENGTH_LONG)
}
}
@@ -1136,7 +1069,11 @@ abstract class BaseSimpleActivity : AppCompatActivity() {
}
val file = files[index]
- val newFileDirItem = FileDirItem("$destinationPath/${file.name}", file.name, file.isDirectory)
+ val newFileDirItem = FileDirItem(
+ path = "$destinationPath/${file.name}",
+ name = file.name,
+ isDirectory = file.isDirectory
+ )
ensureBackgroundThread {
if (getDoesFilePathExist(newFileDirItem.path)) {
runOnUiThread {
@@ -1191,7 +1128,11 @@ abstract class BaseSimpleActivity : AppCompatActivity() {
} else {
isAskingPermissions = true
actionOnPermission = callback
- ActivityCompat.requestPermissions(this, arrayOf(getPermissionString(permissionId)), GENERIC_PERM_HANDLER)
+ ActivityCompat.requestPermissions(
+ this,
+ arrayOf(getPermissionString(permissionId)),
+ GENERIC_PERM_HANDLER
+ )
}
}
@@ -1207,7 +1148,11 @@ abstract class BaseSimpleActivity : AppCompatActivity() {
} else {
isAskingPermissions = true
actionOnPermission = callback
- ActivityCompat.requestPermissions(this, permissionIds.map { getPermissionString(it) }.toTypedArray(), GENERIC_PERM_HANDLER)
+ ActivityCompat.requestPermissions(
+ this,
+ permissionIds.map { getPermissionString(it) }.toTypedArray(),
+ GENERIC_PERM_HANDLER
+ )
}
} else {
if (hasAllPermissions(permissionIds)) {
@@ -1215,7 +1160,11 @@ abstract class BaseSimpleActivity : AppCompatActivity() {
} else {
isAskingPermissions = true
actionOnPermission = callback
- ActivityCompat.requestPermissions(this, permissionIds.map { getPermissionString(it) }.toTypedArray(), GENERIC_PERM_HANDLER)
+ ActivityCompat.requestPermissions(
+ this,
+ permissionIds.map { getPermissionString(it) }.toTypedArray(),
+ GENERIC_PERM_HANDLER
+ )
}
}
}
@@ -1342,7 +1291,8 @@ abstract class BaseSimpleActivity : AppCompatActivity() {
}
private fun getExportSettingsFilename(): String {
- val appName = baseConfig.appId.removeSuffix(".debug").removeSuffix(".pro").removePrefix("org.fossify.")
+ val appName = baseConfig.appId.removeSuffix(".debug").removeSuffix(".pro")
+ .removePrefix("org.fossify.")
return "$appName-settings_${getCurrentFormattedDateTime()}"
}
@@ -1350,27 +1300,35 @@ abstract class BaseSimpleActivity : AppCompatActivity() {
protected fun launchSetDefaultDialerIntent() {
if (isQPlus()) {
val roleManager = getSystemService(RoleManager::class.java)
- if (roleManager!!.isRoleAvailable(RoleManager.ROLE_DIALER) && !roleManager.isRoleHeld(RoleManager.ROLE_DIALER)) {
+ if (
+ roleManager!!.isRoleAvailable(RoleManager.ROLE_DIALER)
+ && !roleManager.isRoleHeld(RoleManager.ROLE_DIALER)
+ ) {
val intent = roleManager.createRequestRoleIntent(RoleManager.ROLE_DIALER)
startActivityForResult(intent, REQUEST_CODE_SET_DEFAULT_DIALER)
}
} else {
- Intent(TelecomManager.ACTION_CHANGE_DEFAULT_DIALER).putExtra(TelecomManager.EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME, packageName).apply {
- try {
- startActivityForResult(this, REQUEST_CODE_SET_DEFAULT_DIALER)
- } catch (e: ActivityNotFoundException) {
- toast(R.string.no_app_found)
- } catch (e: Exception) {
- showErrorToast(e)
+ Intent(TelecomManager.ACTION_CHANGE_DEFAULT_DIALER)
+ .putExtra(TelecomManager.EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME, packageName)
+ .apply {
+ try {
+ startActivityForResult(this, REQUEST_CODE_SET_DEFAULT_DIALER)
+ } catch (e: ActivityNotFoundException) {
+ toast(R.string.no_app_found)
+ } catch (e: Exception) {
+ showErrorToast(e)
+ }
}
- }
}
}
@RequiresApi(Build.VERSION_CODES.Q)
fun setDefaultCallerIdApp() {
val roleManager = getSystemService(RoleManager::class.java)
- if (roleManager.isRoleAvailable(RoleManager.ROLE_CALL_SCREENING) && !roleManager.isRoleHeld(RoleManager.ROLE_CALL_SCREENING)) {
+ if (
+ roleManager.isRoleAvailable(RoleManager.ROLE_CALL_SCREENING)
+ && !roleManager.isRoleHeld(RoleManager.ROLE_CALL_SCREENING)
+ ) {
val intent = roleManager.createRequestRoleIntent(RoleManager.ROLE_CALL_SCREENING)
startActivityForResult(intent, REQUEST_CODE_SET_DEFAULT_CALLER_ID)
}
diff --git a/commons/src/main/kotlin/org/fossify/commons/activities/CustomizationActivity.kt b/commons/src/main/kotlin/org/fossify/commons/activities/CustomizationActivity.kt
index fda74bc0b..cfffccba9 100644
--- a/commons/src/main/kotlin/org/fossify/commons/activities/CustomizationActivity.kt
+++ b/commons/src/main/kotlin/org/fossify/commons/activities/CustomizationActivity.kt
@@ -84,18 +84,12 @@ class CustomizationActivity : BaseSimpleActivity() {
private val binding by viewBinding(ActivityCustomizationBinding::inflate)
override fun onCreate(savedInstanceState: Bundle?) {
- isMaterialActivity = true
super.onCreate(savedInstanceState)
setContentView(binding.root)
setupOptionsMenu()
refreshMenuItems()
- updateMaterialActivityViews(
- mainCoordinatorLayout = binding.customizationCoordinator,
- nestedView = binding.customizationHolder,
- useTransparentNavigation = true,
- useTopSearchMenu = false
- )
+ setupEdgeToEdge(padBottomSystem = listOf(binding.customizationHolder))
initColorVariables()
if (canAccessGlobalConfig()) {
@@ -124,18 +118,16 @@ class CustomizationActivity : BaseSimpleActivity() {
if (!isDynamicTheme()) {
updateBackgroundColor(getCurrentBackgroundColor())
- updateActionbarColor(getCurrentTopBarColor())
}
curPrimaryLineColorPicker?.getSpecificColor()?.apply {
- updateActionbarColor(this)
setTheme(getThemeId(this))
}
- setupToolbar(
- toolbar = binding.customizationToolbar,
- toolbarNavigationIcon = NavigationIcon.Cross,
- statusBarColor = getColoredMaterialStatusBarColor()
+ setupTopAppBar(
+ topAppBar = binding.appBar,
+ navigationIcon = NavigationIcon.Arrow,
+ topBarColor = getColoredMaterialStatusBarColor()
)
showOrHideThankYouFeatures()
updateApplyToAllColors()
@@ -158,11 +150,12 @@ class CustomizationActivity : BaseSimpleActivity() {
}
}
- override fun onBackPressed() {
- if (hasUnsavedChanges && System.currentTimeMillis() - lastSavePromptTS > SAVE_DISCARD_PROMPT_INTERVAL) {
+ override fun onBackPressedCompat(): Boolean {
+ return if (hasUnsavedChanges && System.currentTimeMillis() - lastSavePromptTS > SAVE_DISCARD_PROMPT_INTERVAL) {
promptSaveDiscard()
+ true
} else {
- super.onBackPressed()
+ false
}
}
@@ -274,10 +267,10 @@ class CustomizationActivity : BaseSimpleActivity() {
}
updateMenuItemColors(binding.customizationToolbar.menu, getCurrentTopBarColor())
- setupToolbar(
- toolbar = binding.customizationToolbar,
- toolbarNavigationIcon = NavigationIcon.Cross,
- statusBarColor = getCurrentTopBarColor()
+ setupTopAppBar(
+ topAppBar = binding.appBar,
+ navigationIcon = NavigationIcon.Arrow,
+ topBarColor = getCurrentTopBarColor()
)
}
}
@@ -295,7 +288,7 @@ class CustomizationActivity : BaseSimpleActivity() {
curAppIconColor = baseConfig.customAppIconColor
setTheme(getThemeId(curPrimaryColor))
updateMenuItemColors(binding.customizationToolbar.menu, curPrimaryColor)
- setupToolbar(binding.customizationToolbar, NavigationIcon.Cross, curPrimaryColor)
+ setupTopAppBar(binding.appBar, NavigationIcon.Arrow, curPrimaryColor)
setupColorsPickers()
} else {
baseConfig.customPrimaryColor = curPrimaryColor
@@ -320,10 +313,10 @@ class CustomizationActivity : BaseSimpleActivity() {
setTheme(getThemeId(getCurrentPrimaryColor()))
colorChanged()
updateMenuItemColors(binding.customizationToolbar.menu, getCurrentTopBarColor())
- setupToolbar(
- toolbar = binding.customizationToolbar,
- toolbarNavigationIcon = NavigationIcon.Cross,
- statusBarColor = getCurrentTopBarColor()
+ setupTopAppBar(
+ topAppBar = binding.appBar,
+ navigationIcon = NavigationIcon.Arrow,
+ topBarColor = getCurrentTopBarColor()
)
}
@@ -332,7 +325,6 @@ class CustomizationActivity : BaseSimpleActivity() {
updateLabelColors(getCurrentTextColor())
updateHeaderColors(getCurrentAccentOrPrimaryColor())
updateBackgroundColor(getCurrentBackgroundColor())
- updateActionbarColor(getCurrentTopBarColor())
updateAutoThemeFields()
updateApplyToAllColors()
handleAccentColorLayout()
@@ -486,7 +478,6 @@ class CustomizationActivity : BaseSimpleActivity() {
initColorVariables()
setupColorsPickers()
updateBackgroundColor()
- updateActionbarColor()
refreshMenuItems()
updateLabelColors(getCurrentTextColor())
updateHeaderColors(getCurrentAccentOrPrimaryColor())
@@ -559,7 +550,6 @@ class CustomizationActivity : BaseSimpleActivity() {
private fun setCurrentPrimaryColor(color: Int) {
curPrimaryColor = color
- updateActionbarColor(color)
updateApplyToAllColors()
updateHeaderColors(color)
}
@@ -626,7 +616,7 @@ class CustomizationActivity : BaseSimpleActivity() {
activity = this,
color = curPrimaryColor,
isPrimaryColorPicker = true,
- toolbar = binding.customizationToolbar
+ appBar = binding.appBar
) { wasPositivePressed, color ->
curPrimaryLineColorPicker = null
if (wasPositivePressed) {
@@ -637,13 +627,12 @@ class CustomizationActivity : BaseSimpleActivity() {
setTheme(getThemeId(color))
}
updateMenuItemColors(binding.customizationToolbar.menu, color)
- setupToolbar(binding.customizationToolbar, NavigationIcon.Cross, color)
+ setupTopAppBar(binding.appBar, NavigationIcon.Arrow, color)
} else {
- updateActionbarColor(curPrimaryColor)
setTheme(getThemeId(curPrimaryColor))
updateMenuItemColors(binding.customizationToolbar.menu, curPrimaryColor)
- setupToolbar(binding.customizationToolbar, NavigationIcon.Cross, curPrimaryColor)
- updateTopBarColors(binding.customizationToolbar, curPrimaryColor)
+ setupTopAppBar(binding.appBar, NavigationIcon.Arrow, curPrimaryColor)
+ updateTopBarColors(binding.appBar, curPrimaryColor)
}
}
}
@@ -656,8 +645,7 @@ class CustomizationActivity : BaseSimpleActivity() {
colorChanged()
updateApplyToAllColors()
updateHeaderColors(curAccentColor)
- updateActionbarColor(getCurrentTopBarColor())
- updateTopBarColors(binding.customizationToolbar, getCurrentTopBarColor())
+ updateTopBarColors(binding.appBar, getCurrentTopBarColor())
}
}
}
diff --git a/commons/src/main/kotlin/org/fossify/commons/activities/EdgeToEdgeActivity.kt b/commons/src/main/kotlin/org/fossify/commons/activities/EdgeToEdgeActivity.kt
new file mode 100644
index 000000000..3b5eb1b55
--- /dev/null
+++ b/commons/src/main/kotlin/org/fossify/commons/activities/EdgeToEdgeActivity.kt
@@ -0,0 +1,156 @@
+package org.fossify.commons.activities
+
+import android.animation.ArgbEvaluator
+import android.animation.ValueAnimator
+import android.os.Bundle
+import android.view.View
+import androidx.appcompat.app.AppCompatActivity
+import androidx.core.view.ScrollingView
+import androidx.core.view.WindowCompat
+import androidx.core.view.WindowInsetsCompat.Type
+import androidx.core.view.get
+import androidx.core.view.size
+import androidx.core.widget.NestedScrollView
+import androidx.recyclerview.widget.RecyclerView
+import org.fossify.commons.R
+import org.fossify.commons.extensions.applyColorFilter
+import org.fossify.commons.extensions.getColoredDrawableWithColor
+import org.fossify.commons.extensions.getColoredMaterialStatusBarColor
+import org.fossify.commons.extensions.getContrastColor
+import org.fossify.commons.extensions.getProperBackgroundColor
+import org.fossify.commons.extensions.onApplyWindowInsets
+import org.fossify.commons.extensions.setSystemBarsAppearance
+import org.fossify.commons.extensions.updatePaddingWithBase
+import org.fossify.commons.views.MyAppBarLayout
+
+abstract class EdgeToEdgeActivity : AppCompatActivity() {
+ open var isSearchBarEnabled = false
+ open val padCutout: Boolean
+ get() = true
+
+ private var topAppBar: MyAppBarLayout? = null
+ private var scrollingView: ScrollingView? = null
+ private var materialScrollColorAnimation: ValueAnimator? = null
+ private var currentScrollY = 0
+
+ private val contentRoot by lazy { findViewById(android.R.id.content) }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ WindowCompat.enableEdgeToEdge(window)
+ }
+
+ /**
+ * Helper for views that need to be edge to edge compatible.
+ */
+ fun setupEdgeToEdge(
+ padTopSystem: List = emptyList(),
+ padBottomSystem: List = emptyList(),
+ padBottomImeAndSystem: List = emptyList(),
+ ) {
+ onApplyWindowInsets { insets ->
+ val system = insets.getInsetsIgnoringVisibility(Type.systemBars())
+ val imeAndSystem = insets.getInsets(Type.ime() or Type.systemBars())
+
+ padTopSystem.forEach { it.updatePaddingWithBase(top = system.top) }
+ padBottomSystem.forEach { it.updatePaddingWithBase(bottom = system.bottom) }
+ padBottomImeAndSystem.forEach { it.updatePaddingWithBase(bottom = imeAndSystem.bottom) }
+
+ if (padCutout) {
+ val cutout = insets.getInsets(Type.displayCutout())
+ val sideLeft = maxOf(system.left, cutout.left)
+ val sideRight = maxOf(system.right, cutout.right)
+ contentRoot.updatePaddingWithBase(left = sideLeft, right = sideRight)
+ }
+ }
+ }
+
+ fun setupMaterialScrollListener(scrollingView: ScrollingView?, topAppBar: MyAppBarLayout) {
+ this.scrollingView = scrollingView
+ this.topAppBar = topAppBar
+ if (scrollingView is RecyclerView) {
+ scrollingView.setOnScrollChangeListener { v, scrollX, scrollY, oldScrollX, oldScrollY ->
+ val newScrollY = scrollingView.computeVerticalScrollOffset()
+ scrollingChanged(newScrollY, currentScrollY)
+ currentScrollY = newScrollY
+ }
+ } else if (scrollingView is NestedScrollView) {
+ scrollingView.setOnScrollChangeListener { v, scrollX, scrollY, oldScrollX, oldScrollY ->
+ scrollingChanged(scrollY, oldScrollY)
+ }
+ }
+ }
+
+ private fun scrollingChanged(newScrollY: Int, oldScrollY: Int) {
+ if (newScrollY > 0 && oldScrollY == 0) {
+ animateTopBarColors(getProperBackgroundColor(), getColoredMaterialStatusBarColor())
+ } else if (newScrollY == 0 && oldScrollY > 0) {
+ animateTopBarColors(getColoredMaterialStatusBarColor(), getRequiredTopBarColor())
+ }
+ }
+
+ fun animateTopBarColors(colorFrom: Int, colorTo: Int) {
+ if (topAppBar == null) {
+ return
+ }
+
+ materialScrollColorAnimation?.end()
+ materialScrollColorAnimation = ValueAnimator.ofObject(ArgbEvaluator(), colorFrom, colorTo)
+ materialScrollColorAnimation!!.addUpdateListener { animator ->
+ val color = animator.animatedValue as Int
+ if (topAppBar != null) {
+ updateTopBarColors(topAppBar!!, color)
+ }
+ }
+
+ materialScrollColorAnimation!!.start()
+ }
+
+ fun getRequiredTopBarColor(): Int {
+ return if (
+ (scrollingView is RecyclerView || scrollingView is NestedScrollView)
+ && scrollingView?.computeVerticalScrollOffset() == 0
+ ) {
+ getProperBackgroundColor()
+ } else {
+ getColoredMaterialStatusBarColor()
+ }
+ }
+
+ fun updateTopBarColors(topAppBar: MyAppBarLayout, color: Int) {
+ val contrastColor = if (isSearchBarEnabled) {
+ getProperBackgroundColor().getContrastColor()
+ } else {
+ color.getContrastColor()
+ }
+
+ window.setSystemBarsAppearance(color)
+ if (!isSearchBarEnabled) {
+ topAppBar.setBackgroundColor(color)
+ topAppBar.toolbar?.setBackgroundColor(color)
+ topAppBar.toolbar?.setTitleTextColor(contrastColor)
+ topAppBar.toolbar?.navigationIcon?.applyColorFilter(contrastColor)
+ topAppBar.toolbar?.collapseIcon = resources.getColoredDrawableWithColor(
+ drawableId = R.drawable.ic_arrow_left_vector,
+ color = contrastColor
+ )
+ }
+
+ topAppBar.toolbar?.overflowIcon =
+ resources.getColoredDrawableWithColor(R.drawable.ic_three_dots_vector, contrastColor)
+
+ val menu = topAppBar.toolbar?.menu ?: return
+ for (i in 0 until menu.size) {
+ try {
+ menu[i].icon?.setTint(contrastColor)
+ } catch (ignored: Exception) {
+ }
+ }
+ }
+
+ override fun onDestroy() {
+ materialScrollColorAnimation?.cancel()
+ materialScrollColorAnimation = null
+ super.onDestroy()
+ }
+}
diff --git a/commons/src/main/kotlin/org/fossify/commons/adapters/FilepickerItemsAdapter.kt b/commons/src/main/kotlin/org/fossify/commons/adapters/FilepickerItemsAdapter.kt
index 5a0a9dd3d..f6de3c9bd 100644
--- a/commons/src/main/kotlin/org/fossify/commons/adapters/FilepickerItemsAdapter.kt
+++ b/commons/src/main/kotlin/org/fossify/commons/adapters/FilepickerItemsAdapter.kt
@@ -101,8 +101,8 @@ class FilepickerItemsAdapter(
var itemToLoad = if (fileDirItem.name.endsWith(".apk", true)) {
val packageInfo = root.context.packageManager.getPackageArchiveInfo(path, PackageManager.GET_ACTIVITIES)
- if (packageInfo != null) {
- val appInfo = packageInfo.applicationInfo
+ val appInfo = packageInfo?.applicationInfo
+ if (appInfo != null) {
appInfo.sourceDir = path
appInfo.publicSourceDir = path
appInfo.loadIcon(root.context.packageManager)
diff --git a/commons/src/main/kotlin/org/fossify/commons/adapters/MyRecyclerViewAdapter.kt b/commons/src/main/kotlin/org/fossify/commons/adapters/MyRecyclerViewAdapter.kt
index a2566c76d..ded508f5b 100644
--- a/commons/src/main/kotlin/org/fossify/commons/adapters/MyRecyclerViewAdapter.kt
+++ b/commons/src/main/kotlin/org/fossify/commons/adapters/MyRecyclerViewAdapter.kt
@@ -53,8 +53,6 @@ abstract class MyRecyclerViewAdapter(val activity: BaseSimpleActivity, val recyc
init {
actModeCallback = object : MyActionModeCallback() {
- private var savedStatusBarColor = activity.getProperStatusBarColor()
-
override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean {
actionItemPressed(item.itemId)
return true
@@ -86,13 +84,6 @@ abstract class MyRecyclerViewAdapter(val activity: BaseSimpleActivity, val recyc
resources.getColor(R.color.dark_grey, activity.theme)
}
- savedStatusBarColor = activity.window.statusBarColor
- activity.animateStatusBarColor(
- colorTo = bgColor,
- colorFrom = savedStatusBarColor,
- duration = 300L
- )
-
actBarTextView!!.setTextColor(bgColor.getContrastColor())
activity.updateMenuItemColors(menu, baseColor = bgColor)
onActionModeCreated()
@@ -120,12 +111,6 @@ abstract class MyRecyclerViewAdapter(val activity: BaseSimpleActivity, val recyc
}
}
- activity.animateStatusBarColor(
- colorTo = savedStatusBarColor,
- colorFrom = activity.window.statusBarColor,
- duration = 400L
- )
-
updateTitle()
selectedKeys.clear()
actBarTextView?.text = ""
diff --git a/commons/src/main/kotlin/org/fossify/commons/adapters/MyRecyclerViewListAdapter.kt b/commons/src/main/kotlin/org/fossify/commons/adapters/MyRecyclerViewListAdapter.kt
index 241c01bd3..0679f67f6 100644
--- a/commons/src/main/kotlin/org/fossify/commons/adapters/MyRecyclerViewListAdapter.kt
+++ b/commons/src/main/kotlin/org/fossify/commons/adapters/MyRecyclerViewListAdapter.kt
@@ -62,8 +62,6 @@ abstract class MyRecyclerViewListAdapter(
init {
actModeCallback = object : MyActionModeCallback() {
- private var savedStatusBarColor = activity.getProperStatusBarColor()
-
override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean {
actionItemPressed(item.itemId)
return true
@@ -94,13 +92,6 @@ abstract class MyRecyclerViewListAdapter(
resources.getColor(R.color.dark_grey, activity.theme)
}
- savedStatusBarColor = activity.window.statusBarColor
- activity.animateStatusBarColor(
- colorTo = bgColor,
- colorFrom = savedStatusBarColor,
- duration = 300L
- )
-
actBarTextView!!.setTextColor(bgColor.getContrastColor())
activity.updateMenuItemColors(menu, baseColor = bgColor)
onActionModeCreated()
@@ -128,12 +119,6 @@ abstract class MyRecyclerViewListAdapter(
}
}
- activity.animateStatusBarColor(
- colorTo = savedStatusBarColor,
- colorFrom = activity.window.statusBarColor,
- duration = 400L
- )
-
updateTitle()
selectedKeys.clear()
actBarTextView?.text = ""
diff --git a/commons/src/main/kotlin/org/fossify/commons/compose/alert_dialog/AlertDialogsExtensions.kt b/commons/src/main/kotlin/org/fossify/commons/compose/alert_dialog/AlertDialogsExtensions.kt
index 937f52e7e..099f532b2 100644
--- a/commons/src/main/kotlin/org/fossify/commons/compose/alert_dialog/AlertDialogsExtensions.kt
+++ b/commons/src/main/kotlin/org/fossify/commons/compose/alert_dialog/AlertDialogsExtensions.kt
@@ -36,12 +36,12 @@ val dialogContainerColor
}
}
-val Modifier.dialogBackgroundShapeAndBorder: Modifier
- @ReadOnlyComposable
- @Composable get() = this
- .fillMaxWidth()
- .background(dialogContainerColor, dialogShape)
- .dialogBorder
+@Composable
+@ReadOnlyComposable
+fun Modifier.dialogBackgroundShapeAndBorder(): Modifier = this
+ .fillMaxWidth()
+ .background(dialogContainerColor, dialogShape)
+ .dialogBorder()
val dialogShape = Shapes.extraLarge
@@ -49,13 +49,13 @@ val dialogElevation = 0.dp
val dialogTextColor @Composable @ReadOnlyComposable get() = SimpleTheme.colorScheme.onSurface
-val Modifier.dialogBorder: Modifier
- @ReadOnlyComposable
- @Composable get() =
- when (LocalTheme.current) {
- is Theme.BlackAndWhite -> this.border(1.dp, light_grey_stroke, dialogShape)
- else -> this
- }
+@Composable
+@ReadOnlyComposable
+fun Modifier.dialogBorder(): Modifier =
+ when (LocalTheme.current) {
+ is Theme.BlackAndWhite -> this.border(1.dp, light_grey_stroke, dialogShape)
+ else -> this
+ }
@Composable
fun DialogSurface(
@@ -64,7 +64,7 @@ fun DialogSurface(
) {
Surface(
modifier = modifier
- .dialogBorder,
+ .dialogBorder(),
shape = dialogShape,
color = dialogContainerColor,
tonalElevation = dialogElevation,
diff --git a/commons/src/main/kotlin/org/fossify/commons/compose/bottom_sheet/BottomSheetDialogsExtensions.kt b/commons/src/main/kotlin/org/fossify/commons/compose/bottom_sheet/BottomSheetDialogsExtensions.kt
index e59b1a109..073abc280 100644
--- a/commons/src/main/kotlin/org/fossify/commons/compose/bottom_sheet/BottomSheetDialogsExtensions.kt
+++ b/commons/src/main/kotlin/org/fossify/commons/compose/bottom_sheet/BottomSheetDialogsExtensions.kt
@@ -22,13 +22,13 @@ val bottomSheetDialogShape = Shapes.extraLarge.copy(
bottomStart = CornerSize(0f)
)
-val Modifier.bottomSheetDialogBorder: Modifier
- @ReadOnlyComposable
- @Composable get() =
- when (LocalTheme.current) {
- is Theme.BlackAndWhite -> this.border(2.dp, light_grey_stroke, bottomSheetDialogShape)
- else -> this
- }
+@Composable
+@ReadOnlyComposable
+fun Modifier.bottomSheetDialogBorder(): Modifier =
+ when (LocalTheme.current) {
+ is Theme.BlackAndWhite -> this.border(2.dp, light_grey_stroke, bottomSheetDialogShape)
+ else -> this
+ }
@Composable
fun BottomSheetSpacerEdgeToEdge() {
@@ -43,7 +43,7 @@ fun BottomSheetColumnDialogSurface(
Surface(
modifier = modifier
.fillMaxSize()
- .bottomSheetDialogBorder,
+ .bottomSheetDialogBorder(),
shape = bottomSheetDialogShape,
color = dialogContainerColor,
tonalElevation = dialogElevation,
@@ -62,7 +62,7 @@ fun BottomSheetBoxDialogSurface(
Surface(
modifier = modifier
.fillMaxSize()
- .bottomSheetDialogBorder,
+ .bottomSheetDialogBorder(),
shape = bottomSheetDialogShape,
color = dialogContainerColor,
tonalElevation = dialogElevation,
@@ -81,7 +81,7 @@ fun BottomSheetDialogSurface(
Surface(
modifier = modifier
.fillMaxSize()
- .bottomSheetDialogBorder,
+ .bottomSheetDialogBorder(),
shape = bottomSheetDialogShape,
color = dialogContainerColor,
tonalElevation = dialogElevation,
diff --git a/commons/src/main/kotlin/org/fossify/commons/compose/menus/ActionMenu.kt b/commons/src/main/kotlin/org/fossify/commons/compose/menus/ActionMenu.kt
index 184155522..758abcdbf 100644
--- a/commons/src/main/kotlin/org/fossify/commons/compose/menus/ActionMenu.kt
+++ b/commons/src/main/kotlin/org/fossify/commons/compose/menus/ActionMenu.kt
@@ -144,7 +144,7 @@ fun ActionMenu(
DropdownMenu(
modifier = Modifier
.background(dialogContainerColor)
- .dialogBorder,
+ .dialogBorder(),
expanded = isMenuVisible,
onDismissRequest = { onMenuToggle(false) },
) {
diff --git a/commons/src/main/kotlin/org/fossify/commons/dialogs/AddBlockedNumberDialog.kt b/commons/src/main/kotlin/org/fossify/commons/dialogs/AddBlockedNumberDialog.kt
index 8d25b05cc..731e8893a 100644
--- a/commons/src/main/kotlin/org/fossify/commons/dialogs/AddBlockedNumberDialog.kt
+++ b/commons/src/main/kotlin/org/fossify/commons/dialogs/AddBlockedNumberDialog.kt
@@ -42,7 +42,7 @@ fun AddOrEditBlockedNumberAlertDialog(
AlertDialog(
containerColor = dialogContainerColor,
modifier = modifier
- .dialogBorder,
+ .dialogBorder(),
onDismissRequest = alertDialogState::hide,
confirmButton = {
TextButton(onClick = {
diff --git a/commons/src/main/kotlin/org/fossify/commons/dialogs/AppSideloadedDialog.kt b/commons/src/main/kotlin/org/fossify/commons/dialogs/AppSideloadedDialog.kt
index 050160cd7..39665c38e 100644
--- a/commons/src/main/kotlin/org/fossify/commons/dialogs/AppSideloadedDialog.kt
+++ b/commons/src/main/kotlin/org/fossify/commons/dialogs/AppSideloadedDialog.kt
@@ -70,7 +70,7 @@ fun AppSideLoadedAlertDialog(
AlertDialog(
containerColor = dialogContainerColor,
modifier = modifier
- .dialogBorder,
+ .dialogBorder(),
onDismissRequest = alertDialogState::hide,
confirmButton = {
TextButton(onClick = {
diff --git a/commons/src/main/kotlin/org/fossify/commons/dialogs/CallConfirmationDialog.kt b/commons/src/main/kotlin/org/fossify/commons/dialogs/CallConfirmationDialog.kt
index bfa3ffa33..3f670dd1c 100644
--- a/commons/src/main/kotlin/org/fossify/commons/dialogs/CallConfirmationDialog.kt
+++ b/commons/src/main/kotlin/org/fossify/commons/dialogs/CallConfirmationDialog.kt
@@ -68,7 +68,7 @@ fun CallConfirmationAlertDialog(
androidx.compose.material3.AlertDialog(
containerColor = dialogContainerColor,
modifier = modifier
- .dialogBorder,
+ .dialogBorder(),
onDismissRequest = {
alertDialogState.hide()
callback()
diff --git a/commons/src/main/kotlin/org/fossify/commons/dialogs/ColorPickerDialog.kt b/commons/src/main/kotlin/org/fossify/commons/dialogs/ColorPickerDialog.kt
index cb1133316..5af6cc391 100644
--- a/commons/src/main/kotlin/org/fossify/commons/dialogs/ColorPickerDialog.kt
+++ b/commons/src/main/kotlin/org/fossify/commons/dialogs/ColorPickerDialog.kt
@@ -159,7 +159,7 @@ fun ColorPickerAlertDialog(
AlertDialog(
modifier = modifier
- .dialogBorder,
+ .dialogBorder(),
onDismissRequest = alertDialogState::hide,
properties = DialogProperties(usePlatformDefaultWidth = false)
) {
diff --git a/commons/src/main/kotlin/org/fossify/commons/dialogs/ConfirmationAdvancedDialog.kt b/commons/src/main/kotlin/org/fossify/commons/dialogs/ConfirmationAdvancedDialog.kt
index 80942b722..f46e6f71b 100644
--- a/commons/src/main/kotlin/org/fossify/commons/dialogs/ConfirmationAdvancedDialog.kt
+++ b/commons/src/main/kotlin/org/fossify/commons/dialogs/ConfirmationAdvancedDialog.kt
@@ -73,7 +73,7 @@ fun ConfirmationAdvancedAlertDialog(
androidx.compose.material3.AlertDialog(
containerColor = dialogContainerColor,
modifier = modifier
- .dialogBorder,
+ .dialogBorder(),
properties = DialogProperties(dismissOnClickOutside = cancelOnTouchOutside),
onDismissRequest = {
alertDialogState.hide()
diff --git a/commons/src/main/kotlin/org/fossify/commons/dialogs/ConfirmationDialog.kt b/commons/src/main/kotlin/org/fossify/commons/dialogs/ConfirmationDialog.kt
index 2c35c37c5..6e9265b1d 100644
--- a/commons/src/main/kotlin/org/fossify/commons/dialogs/ConfirmationDialog.kt
+++ b/commons/src/main/kotlin/org/fossify/commons/dialogs/ConfirmationDialog.kt
@@ -80,7 +80,7 @@ fun ConfirmationAlertDialog(
androidx.compose.material3.AlertDialog(
containerColor = dialogContainerColor,
modifier = modifier
- .dialogBorder,
+ .dialogBorder(),
properties = DialogProperties(dismissOnClickOutside = cancelOnTouchOutside),
onDismissRequest = {
alertDialogState.hide()
diff --git a/commons/src/main/kotlin/org/fossify/commons/dialogs/CreateNewFolderDialog.kt b/commons/src/main/kotlin/org/fossify/commons/dialogs/CreateNewFolderDialog.kt
index 170ef3633..3d4de0a47 100644
--- a/commons/src/main/kotlin/org/fossify/commons/dialogs/CreateNewFolderDialog.kt
+++ b/commons/src/main/kotlin/org/fossify/commons/dialogs/CreateNewFolderDialog.kt
@@ -118,7 +118,7 @@ fun CreateNewFolderAlertDialog(
var title by remember { mutableStateOf("") }
AlertDialog(
- modifier = modifier.dialogBorder,
+ modifier = modifier.dialogBorder(),
shape = dialogShape,
containerColor = dialogContainerColor,
tonalElevation = dialogElevation,
diff --git a/commons/src/main/kotlin/org/fossify/commons/dialogs/DonateDialog.kt b/commons/src/main/kotlin/org/fossify/commons/dialogs/DonateDialog.kt
index 439fb6773..f63090aa9 100644
--- a/commons/src/main/kotlin/org/fossify/commons/dialogs/DonateDialog.kt
+++ b/commons/src/main/kotlin/org/fossify/commons/dialogs/DonateDialog.kt
@@ -64,7 +64,7 @@ fun DonateAlertDialog(
androidx.compose.material3.AlertDialog(
containerColor = dialogContainerColor,
modifier = modifier
- .dialogBorder,
+ .dialogBorder(),
properties = DialogProperties(dismissOnClickOutside = false, dismissOnBackPress = false),
onDismissRequest = {},
shape = dialogShape,
diff --git a/commons/src/main/kotlin/org/fossify/commons/dialogs/EnterPasswordDialog.kt b/commons/src/main/kotlin/org/fossify/commons/dialogs/EnterPasswordDialog.kt
index afc8c7f8b..657994cb7 100644
--- a/commons/src/main/kotlin/org/fossify/commons/dialogs/EnterPasswordDialog.kt
+++ b/commons/src/main/kotlin/org/fossify/commons/dialogs/EnterPasswordDialog.kt
@@ -91,7 +91,7 @@ fun EnterPasswordAlertDialog(
}
}
AlertDialog(
- modifier = modifier.dialogBorder,
+ modifier = modifier.dialogBorder(),
shape = dialogShape,
containerColor = dialogContainerColor,
tonalElevation = dialogElevation,
diff --git a/commons/src/main/kotlin/org/fossify/commons/dialogs/FeatureLockedDialog.kt b/commons/src/main/kotlin/org/fossify/commons/dialogs/FeatureLockedDialog.kt
index fd71cf000..f9aa1907b 100644
--- a/commons/src/main/kotlin/org/fossify/commons/dialogs/FeatureLockedDialog.kt
+++ b/commons/src/main/kotlin/org/fossify/commons/dialogs/FeatureLockedDialog.kt
@@ -72,7 +72,7 @@ fun FeatureLockedAlertDialog(
androidx.compose.material3.AlertDialog(
containerColor = dialogContainerColor,
modifier = modifier
- .dialogBorder,
+ .dialogBorder(),
properties = DialogProperties(dismissOnClickOutside = false, dismissOnBackPress = false),
onDismissRequest = cancelCallback,
shape = dialogShape,
diff --git a/commons/src/main/kotlin/org/fossify/commons/dialogs/FilePickerDialog.kt b/commons/src/main/kotlin/org/fossify/commons/dialogs/FilePickerDialog.kt
index 10aeb896a..2fae35f98 100644
--- a/commons/src/main/kotlin/org/fossify/commons/dialogs/FilePickerDialog.kt
+++ b/commons/src/main/kotlin/org/fossify/commons/dialogs/FilePickerDialog.kt
@@ -2,8 +2,8 @@ package org.fossify.commons.dialogs
import android.os.Environment
import android.os.Parcelable
-import android.view.KeyEvent
import android.widget.Toast
+import androidx.activity.addCallback
import androidx.appcompat.app.AlertDialog
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.documentfile.provider.DocumentFile
@@ -13,7 +13,39 @@ import org.fossify.commons.activities.BaseSimpleActivity
import org.fossify.commons.adapters.FilepickerFavoritesAdapter
import org.fossify.commons.adapters.FilepickerItemsAdapter
import org.fossify.commons.databinding.DialogFilepickerBinding
-import org.fossify.commons.extensions.*
+import org.fossify.commons.extensions.areSystemAnimationsEnabled
+import org.fossify.commons.extensions.baseConfig
+import org.fossify.commons.extensions.beGone
+import org.fossify.commons.extensions.beVisible
+import org.fossify.commons.extensions.beVisibleIf
+import org.fossify.commons.extensions.getAlertDialogBuilder
+import org.fossify.commons.extensions.getAndroidSAFFileItems
+import org.fossify.commons.extensions.getColoredDrawableWithColor
+import org.fossify.commons.extensions.getContrastColor
+import org.fossify.commons.extensions.getDirectChildrenCount
+import org.fossify.commons.extensions.getDoesFilePathExist
+import org.fossify.commons.extensions.getFilenameFromPath
+import org.fossify.commons.extensions.getFolderLastModifieds
+import org.fossify.commons.extensions.getIsPathDirectory
+import org.fossify.commons.extensions.getOTGItems
+import org.fossify.commons.extensions.getParentPath
+import org.fossify.commons.extensions.getProperPrimaryColor
+import org.fossify.commons.extensions.getProperTextColor
+import org.fossify.commons.extensions.getSomeAndroidSAFDocument
+import org.fossify.commons.extensions.getSomeDocumentFile
+import org.fossify.commons.extensions.getSomeDocumentSdk30
+import org.fossify.commons.extensions.getTextSize
+import org.fossify.commons.extensions.handleHiddenFolderPasswordProtection
+import org.fossify.commons.extensions.handleLockedFolderOpening
+import org.fossify.commons.extensions.internalStoragePath
+import org.fossify.commons.extensions.isAccessibleWithSAFSdk30
+import org.fossify.commons.extensions.isInDownloadDir
+import org.fossify.commons.extensions.isPathOnOTG
+import org.fossify.commons.extensions.isRestrictedSAFOnlyRoot
+import org.fossify.commons.extensions.isRestrictedWithSAFSdk30
+import org.fossify.commons.extensions.isVisible
+import org.fossify.commons.extensions.setupDialogStuff
+import org.fossify.commons.extensions.toast
import org.fossify.commons.helpers.ensureBackgroundThread
import org.fossify.commons.models.FileDirItem
import org.fossify.commons.views.Breadcrumbs
@@ -75,19 +107,6 @@ class FilePickerDialog(
val builder = activity.getAlertDialogBuilder()
.setNegativeButton(R.string.cancel, null)
- .setOnKeyListener { dialogInterface, i, keyEvent ->
- if (keyEvent.action == KeyEvent.ACTION_UP && i == KeyEvent.KEYCODE_BACK) {
- val breadcrumbs = mDialogView.filepickerBreadcrumbs
- if (breadcrumbs.getItemCount() > 1) {
- breadcrumbs.removeBreadcrumb()
- currPath = breadcrumbs.getLastItem().path.trimEnd('/')
- tryUpdateItems()
- } else {
- mDialog?.dismiss()
- }
- }
- true
- }
if (!pickFile) {
builder.setPositiveButton(R.string.ok, null)
@@ -133,6 +152,17 @@ class FilePickerDialog(
builder.apply {
activity.setupDialogStuff(mDialogView.root, this, getTitle()) { alertDialog ->
mDialog = alertDialog
+ alertDialog.onBackPressedDispatcher.addCallback(alertDialog) {
+ val breadcrumbs = mDialogView.filepickerBreadcrumbs
+ if (breadcrumbs.getItemCount() > 1) {
+ breadcrumbs.removeBreadcrumb()
+ currPath = breadcrumbs.getLastItem().path.trimEnd('/')
+ tryUpdateItems()
+ } else {
+ isEnabled = false
+ alertDialog.onBackPressedDispatcher.onBackPressed()
+ }
+ }
}
}
diff --git a/commons/src/main/kotlin/org/fossify/commons/dialogs/FolderLockingNoticeDialog.kt b/commons/src/main/kotlin/org/fossify/commons/dialogs/FolderLockingNoticeDialog.kt
index 3eae3a004..b9d6016a3 100644
--- a/commons/src/main/kotlin/org/fossify/commons/dialogs/FolderLockingNoticeDialog.kt
+++ b/commons/src/main/kotlin/org/fossify/commons/dialogs/FolderLockingNoticeDialog.kt
@@ -46,7 +46,7 @@ fun FolderLockingNoticeAlertDialog(
callback: () -> Unit
) {
AlertDialog(
- modifier = modifier.dialogBorder,
+ modifier = modifier.dialogBorder(),
shape = dialogShape,
containerColor = dialogContainerColor,
tonalElevation = dialogElevation,
diff --git a/commons/src/main/kotlin/org/fossify/commons/dialogs/LineColorPickerDialog.kt b/commons/src/main/kotlin/org/fossify/commons/dialogs/LineColorPickerDialog.kt
index 7610ce3f3..5f94c1396 100644
--- a/commons/src/main/kotlin/org/fossify/commons/dialogs/LineColorPickerDialog.kt
+++ b/commons/src/main/kotlin/org/fossify/commons/dialogs/LineColorPickerDialog.kt
@@ -1,6 +1,7 @@
package org.fossify.commons.dialogs
import android.content.Context
+import android.graphics.Color
import android.view.WindowManager
import android.widget.FrameLayout
import androidx.annotation.ColorInt
@@ -21,7 +22,6 @@ import androidx.compose.ui.window.DialogProperties
import androidx.compose.ui.window.DialogWindowProvider
import androidx.core.content.ContextCompat
import androidx.core.view.updateLayoutParams
-import com.google.android.material.appbar.MaterialToolbar
import org.fossify.commons.R
import org.fossify.commons.activities.BaseSimpleActivity
import org.fossify.commons.compose.alert_dialog.AlertDialogState
@@ -34,19 +34,27 @@ import org.fossify.commons.compose.theme.SimpleTheme
import org.fossify.commons.databinding.DialogLineColorPickerBinding
import org.fossify.commons.extensions.*
import org.fossify.commons.interfaces.LineColorPickerListener
+import org.fossify.commons.views.MyAppBarLayout
class LineColorPickerDialog(
- val activity: BaseSimpleActivity, val color: Int, val isPrimaryColorPicker: Boolean, val primaryColors: Int = R.array.md_primary_colors,
- val appIconIDs: ArrayList? = null, val toolbar: MaterialToolbar? = null, val callback: (wasPositivePressed: Boolean, color: Int) -> Unit
+ val activity: BaseSimpleActivity,
+ val color: Int,
+ val isPrimaryColorPicker: Boolean,
+ val primaryColors: Int = R.array.md_primary_colors,
+ val appIconIDs: ArrayList? = null,
+ val appBar: MyAppBarLayout? = null,
+ val callback: (wasPositivePressed: Boolean, color: Int) -> Unit
) {
- private val PRIMARY_COLORS_COUNT = 19
- private val DEFAULT_PRIMARY_COLOR_INDEX = 9
- private val DEFAULT_SECONDARY_COLOR_INDEX = 8
- private val DEFAULT_COLOR_VALUE = activity.resources.getColor(R.color.color_primary)
+ companion object {
+ private const val PRIMARY_COLORS_COUNT = 19
+ private const val DEFAULT_PRIMARY_COLOR_INDEX = 9
+ private const val DEFAULT_SECONDARY_COLOR_INDEX = 8
+ }
private var wasDimmedBackgroundRemoved = false
private var dialog: AlertDialog? = null
private var view = DialogLineColorPickerBinding.inflate(activity.layoutInflater, null, false)
+ private val defaultColorValue = activity.resources.getColor(R.color.color_primary)
init {
view.apply {
@@ -96,8 +104,8 @@ class LineColorPickerDialog(
view.hexCode.text = color.toHex()
if (isPrimaryColorPicker) {
- if (toolbar != null) {
- activity.updateTopBarColors(toolbar, color)
+ if (appBar != null) {
+ activity.updateTopBarColors(appBar, color)
}
if (!wasDimmedBackgroundRemoved) {
@@ -108,7 +116,7 @@ class LineColorPickerDialog(
}
private fun getColorIndexes(color: Int): Pair {
- if (color == DEFAULT_COLOR_VALUE) {
+ if (color == defaultColorValue) {
return getDefaultColorPair()
}
@@ -328,7 +336,7 @@ private fun Context.getColors(id: Int) = resources.getIntArray(id).toCollection(
private fun LineColorPickerAlertDialogPreview() {
AppThemeSurface {
LineColorPickerAlertDialog(alertDialogState = rememberAlertDialogState(),
- color = R.color.color_primary,
+ color = Color.GREEN,
isPrimaryColorPicker = true,
onActiveColorChange = {}
) { _, _ -> }
diff --git a/commons/src/main/kotlin/org/fossify/commons/dialogs/OpenDeviceSettingsDialog.kt b/commons/src/main/kotlin/org/fossify/commons/dialogs/OpenDeviceSettingsDialog.kt
index 127114d78..6cde77286 100644
--- a/commons/src/main/kotlin/org/fossify/commons/dialogs/OpenDeviceSettingsDialog.kt
+++ b/commons/src/main/kotlin/org/fossify/commons/dialogs/OpenDeviceSettingsDialog.kt
@@ -46,7 +46,7 @@ fun OpenDeviceSettingsAlertDialog(
AlertDialog(
containerColor = dialogContainerColor,
modifier = modifier
- .dialogBorder,
+ .dialogBorder(),
onDismissRequest = alertDialogState::hide,
shape = dialogShape,
tonalElevation = dialogElevation,
diff --git a/commons/src/main/kotlin/org/fossify/commons/dialogs/PermissionRequiredDialog.kt b/commons/src/main/kotlin/org/fossify/commons/dialogs/PermissionRequiredDialog.kt
index dda7d92f7..b0fcf257c 100644
--- a/commons/src/main/kotlin/org/fossify/commons/dialogs/PermissionRequiredDialog.kt
+++ b/commons/src/main/kotlin/org/fossify/commons/dialogs/PermissionRequiredDialog.kt
@@ -52,7 +52,7 @@ fun PermissionRequiredAlertDialog(
AlertDialog(
containerColor = dialogContainerColor,
modifier = modifier
- .dialogBorder,
+ .dialogBorder(),
onDismissRequest = alertDialogState::hide,
shape = dialogShape,
tonalElevation = dialogElevation,
diff --git a/commons/src/main/kotlin/org/fossify/commons/dialogs/PurchaseThankYouDialog.kt b/commons/src/main/kotlin/org/fossify/commons/dialogs/PurchaseThankYouDialog.kt
index 1c6a7c5bc..1f6f00cff 100644
--- a/commons/src/main/kotlin/org/fossify/commons/dialogs/PurchaseThankYouDialog.kt
+++ b/commons/src/main/kotlin/org/fossify/commons/dialogs/PurchaseThankYouDialog.kt
@@ -58,7 +58,7 @@ fun PurchaseThankYouAlertDialog(
androidx.compose.material3.AlertDialog(
containerColor = dialogContainerColor,
modifier = modifier
- .dialogBorder,
+ .dialogBorder(),
properties = DialogProperties(dismissOnClickOutside = false, dismissOnBackPress = false),
onDismissRequest = {},
shape = dialogShape,
diff --git a/commons/src/main/kotlin/org/fossify/commons/dialogs/UpgradeToProDialog.kt b/commons/src/main/kotlin/org/fossify/commons/dialogs/UpgradeToProDialog.kt
index 6fe63e04d..31efa88f3 100644
--- a/commons/src/main/kotlin/org/fossify/commons/dialogs/UpgradeToProDialog.kt
+++ b/commons/src/main/kotlin/org/fossify/commons/dialogs/UpgradeToProDialog.kt
@@ -109,7 +109,7 @@ fun UpgradeToProAlertDialog(
}
}
},
- modifier = modifier.dialogBorder,
+ modifier = modifier.dialogBorder(),
properties = DialogProperties(dismissOnBackPress = false, dismissOnClickOutside = false)
)
}
diff --git a/commons/src/main/kotlin/org/fossify/commons/dialogs/WhatsNewDialog.kt b/commons/src/main/kotlin/org/fossify/commons/dialogs/WhatsNewDialog.kt
index 64b58e02c..1516a96d2 100644
--- a/commons/src/main/kotlin/org/fossify/commons/dialogs/WhatsNewDialog.kt
+++ b/commons/src/main/kotlin/org/fossify/commons/dialogs/WhatsNewDialog.kt
@@ -72,7 +72,7 @@ fun WhatsNewAlertDialog(
containerColor = dialogContainerColor,
shape = dialogShape,
tonalElevation = dialogElevation,
- modifier = modifier.dialogBorder,
+ modifier = modifier.dialogBorder(),
title = {
Text(
text = stringResource(id = R.string.whats_new),
diff --git a/commons/src/main/kotlin/org/fossify/commons/extensions/Activity-themes.kt b/commons/src/main/kotlin/org/fossify/commons/extensions/Activity-themes.kt
index 4fd6d6f5c..4684886c1 100644
--- a/commons/src/main/kotlin/org/fossify/commons/extensions/Activity-themes.kt
+++ b/commons/src/main/kotlin/org/fossify/commons/extensions/Activity-themes.kt
@@ -19,7 +19,7 @@ fun Activity.getThemeId(color: Int = baseConfig.primaryColor, showTransparentTop
else -> R.style.AppTheme_White
}
- showTransparentTop -> {
+ else -> {
when (color) {
-12846 -> R.style.AppTheme_Red_100_core
-1074534 -> R.style.AppTheme_Red_200_core
@@ -214,200 +214,4 @@ fun Activity.getThemeId(color: Int = baseConfig.primaryColor, showTransparentTop
else -> R.style.AppTheme_Green_900_core
}
}
-
- else -> {
- when (color) {
- -12846 -> R.style.AppTheme_Red_100
- -1074534 -> R.style.AppTheme_Red_200
- -1739917 -> R.style.AppTheme_Red_300
- -1092784 -> R.style.AppTheme_Red_400
- -769226 -> R.style.AppTheme_Red_500
- -1754827 -> R.style.AppTheme_Red_600
- -2937041 -> R.style.AppTheme_Red_700
- -3790808 -> R.style.AppTheme_Red_800
- -4776932 -> R.style.AppTheme_Red_900
-
- -476208 -> R.style.AppTheme_Pink_100
- -749647 -> R.style.AppTheme_Pink_200
- -1023342 -> R.style.AppTheme_Pink_300
- -1294214 -> R.style.AppTheme_Pink_400
- -1499549 -> R.style.AppTheme_Pink_500
- -2614432 -> R.style.AppTheme_Pink_600
- -4056997 -> R.style.AppTheme_Pink_700
- -5434281 -> R.style.AppTheme_Pink_800
- -7860657 -> R.style.AppTheme_Pink_900
-
- -1982745 -> R.style.AppTheme_Purple_100
- -3238952 -> R.style.AppTheme_Purple_200
- -4560696 -> R.style.AppTheme_Purple_300
- -5552196 -> R.style.AppTheme_Purple_400
- -6543440 -> R.style.AppTheme_Purple_500
- -7461718 -> R.style.AppTheme_Purple_600
- -8708190 -> R.style.AppTheme_Purple_700
- -9823334 -> R.style.AppTheme_Purple_800
- -11922292 -> R.style.AppTheme_Purple_900
-
- -3029783 -> R.style.AppTheme_Deep_Purple_100
- -5005861 -> R.style.AppTheme_Deep_Purple_200
- -6982195 -> R.style.AppTheme_Deep_Purple_300
- -8497214 -> R.style.AppTheme_Deep_Purple_400
- -10011977 -> R.style.AppTheme_Deep_Purple_500
- -10603087 -> R.style.AppTheme_Deep_Purple_600
- -11457112 -> R.style.AppTheme_Deep_Purple_700
- -12245088 -> R.style.AppTheme_Deep_Purple_800
- -13558894 -> R.style.AppTheme_Deep_Purple_900
-
- -3814679 -> R.style.AppTheme_Indigo_100
- -6313766 -> R.style.AppTheme_Indigo_200
- -8812853 -> R.style.AppTheme_Indigo_300
- -10720320 -> R.style.AppTheme_Indigo_400
- -12627531 -> R.style.AppTheme_Indigo_500
- -13022805 -> R.style.AppTheme_Indigo_600
- -13615201 -> R.style.AppTheme_Indigo_700
- -14142061 -> R.style.AppTheme_Indigo_800
- -15064194 -> R.style.AppTheme_Indigo_900
-
- -4464901 -> R.style.AppTheme_Blue_100
- -7288071 -> R.style.AppTheme_Blue_200
- -10177034 -> R.style.AppTheme_Blue_300
- -12409355 -> R.style.AppTheme_Blue_400
- -14575885 -> R.style.AppTheme_Blue_500
- -14776091 -> R.style.AppTheme_Blue_600
- -15108398 -> R.style.AppTheme_Blue_700
- -15374912 -> R.style.AppTheme_Blue_800
- -15906911 -> R.style.AppTheme_Blue_900
-
- -4987396 -> R.style.AppTheme_Light_Blue_100
- -8268550 -> R.style.AppTheme_Light_Blue_200
- -11549705 -> R.style.AppTheme_Light_Blue_300
- -14043396 -> R.style.AppTheme_Light_Blue_400
- -16537100 -> R.style.AppTheme_Light_Blue_500
- -16540699 -> R.style.AppTheme_Light_Blue_600
- -16611119 -> R.style.AppTheme_Light_Blue_700
- -16615491 -> R.style.AppTheme_Light_Blue_800
- -16689253 -> R.style.AppTheme_Light_Blue_900
-
- -5051406 -> R.style.AppTheme_Cyan_100
- -8331542 -> R.style.AppTheme_Cyan_200
- -11677471 -> R.style.AppTheme_Cyan_300
- -14235942 -> R.style.AppTheme_Cyan_400
- -16728876 -> R.style.AppTheme_Cyan_500
- -16732991 -> R.style.AppTheme_Cyan_600
- -16738393 -> R.style.AppTheme_Cyan_700
- -16743537 -> R.style.AppTheme_Cyan_800
- -16752540 -> R.style.AppTheme_Cyan_900
-
- -5054501 -> R.style.AppTheme_Teal_100
- -8336444 -> R.style.AppTheme_Teal_200
- -11684180 -> R.style.AppTheme_Teal_300
- -14244198 -> R.style.AppTheme_Teal_400
- -16738680 -> R.style.AppTheme_Teal_500
- -16742021 -> R.style.AppTheme_Teal_600
- -16746133 -> R.style.AppTheme_Teal_700
- -16750244 -> R.style.AppTheme_Teal_800
- -16757440 -> R.style.AppTheme_Teal_900
-
- -2691126 -> R.style.AppTheme_Green_100
- -4528984 -> R.style.AppTheme_Green_200
- -6366844 -> R.style.AppTheme_Green_300
- -7810712 -> R.style.AppTheme_Green_400
- -9254834 -> R.style.AppTheme_Green_500
- -10176442 -> R.style.AppTheme_Green_600
- -11492293 -> R.style.AppTheme_Green_700
- -12808398 -> R.style.AppTheme_Green_800
- -15700705 -> R.style.AppTheme_Green_900
-
- -2298424 -> R.style.AppTheme_Light_Green_100
- -3808859 -> R.style.AppTheme_Light_Green_200
- -5319295 -> R.style.AppTheme_Light_Green_300
- -6501275 -> R.style.AppTheme_Light_Green_400
- -7617718 -> R.style.AppTheme_Light_Green_500
- -8604862 -> R.style.AppTheme_Light_Green_600
- -9920712 -> R.style.AppTheme_Light_Green_700
- -11171025 -> R.style.AppTheme_Light_Green_800
- -13407970 -> R.style.AppTheme_Light_Green_900
-
- -985917 -> R.style.AppTheme_Lime_100
- -1642852 -> R.style.AppTheme_Lime_200
- -2300043 -> R.style.AppTheme_Lime_300
- -2825897 -> R.style.AppTheme_Lime_400
- -3285959 -> R.style.AppTheme_Lime_500
- -4142541 -> R.style.AppTheme_Lime_600
- -5983189 -> R.style.AppTheme_Lime_700
- -6382300 -> R.style.AppTheme_Lime_800
- -8227049 -> R.style.AppTheme_Lime_900
-
- -1596 -> R.style.AppTheme_Yellow_100
- -2672 -> R.style.AppTheme_Yellow_200
- -3722 -> R.style.AppTheme_Yellow_300
- -4520 -> R.style.AppTheme_Yellow_400
- -5317 -> R.style.AppTheme_Yellow_500
- -141259 -> R.style.AppTheme_Yellow_600
- -278483 -> R.style.AppTheme_Yellow_700
- -415707 -> R.style.AppTheme_Yellow_800
- -688361 -> R.style.AppTheme_Yellow_900
-
- -4941 -> R.style.AppTheme_Amber_100
- -8062 -> R.style.AppTheme_Amber_200
- -10929 -> R.style.AppTheme_Amber_300
- -13784 -> R.style.AppTheme_Amber_400
- -16121 -> R.style.AppTheme_Amber_500
- -19712 -> R.style.AppTheme_Amber_600
- -24576 -> R.style.AppTheme_Amber_700
- -28928 -> R.style.AppTheme_Amber_800
- -37120 -> R.style.AppTheme_Amber_900
-
- -8014 -> R.style.AppTheme_Orange_100
- -13184 -> R.style.AppTheme_Orange_200
- -18611 -> R.style.AppTheme_Orange_300
- -22746 -> R.style.AppTheme_Orange_400
- -26624 -> R.style.AppTheme_Orange_500
- -291840 -> R.style.AppTheme_Orange_600
- -689152 -> R.style.AppTheme_Orange_700
- -1086464 -> R.style.AppTheme_Orange_800
- -1683200 -> R.style.AppTheme_Orange_900
-
- -13124 -> R.style.AppTheme_Deep_Orange_100
- -21615 -> R.style.AppTheme_Deep_Orange_200
- -30107 -> R.style.AppTheme_Deep_Orange_300
- -36797 -> R.style.AppTheme_Deep_Orange_400
- -43230 -> R.style.AppTheme_Deep_Orange_500
- -765666 -> R.style.AppTheme_Deep_Orange_600
- -1684967 -> R.style.AppTheme_Deep_Orange_700
- -2604267 -> R.style.AppTheme_Deep_Orange_800
- -4246004 -> R.style.AppTheme_Deep_Orange_900
-
- -2634552 -> R.style.AppTheme_Brown_100
- -4412764 -> R.style.AppTheme_Brown_200
- -6190977 -> R.style.AppTheme_Brown_300
- -7508381 -> R.style.AppTheme_Brown_400
- -8825528 -> R.style.AppTheme_Brown_500
- -9614271 -> R.style.AppTheme_Brown_600
- -10665929 -> R.style.AppTheme_Brown_700
- -11652050 -> R.style.AppTheme_Brown_800
- -12703965 -> R.style.AppTheme_Brown_900
-
- -3155748 -> R.style.AppTheme_Blue_Grey_100
- -5194811 -> R.style.AppTheme_Blue_Grey_200
- -7297874 -> R.style.AppTheme_Blue_Grey_300
- -8875876 -> R.style.AppTheme_Blue_Grey_400
- -10453621 -> R.style.AppTheme_Blue_Grey_500
- -11243910 -> R.style.AppTheme_Blue_Grey_600
- -12232092 -> R.style.AppTheme_Blue_Grey_700
- -13154481 -> R.style.AppTheme_Blue_Grey_800
- -14273992 -> R.style.AppTheme_Blue_Grey_900
-
- -1 -> R.style.AppTheme_Grey_100
- -1118482 -> R.style.AppTheme_Grey_200
- -2039584 -> R.style.AppTheme_Grey_300
- -4342339 -> R.style.AppTheme_Grey_400
- -6381922 -> R.style.AppTheme_Grey_500
- -9079435 -> R.style.AppTheme_Grey_600
- -10395295 -> R.style.AppTheme_Grey_700
- -12434878 -> R.style.AppTheme_Grey_800
- -16777216 -> R.style.AppTheme_Grey_900
-
- else -> R.style.AppTheme_Green_900
- }
- }
}
diff --git a/commons/src/main/kotlin/org/fossify/commons/extensions/Activity.kt b/commons/src/main/kotlin/org/fossify/commons/extensions/Activity.kt
index bd198911c..e195fb626 100644
--- a/commons/src/main/kotlin/org/fossify/commons/extensions/Activity.kt
+++ b/commons/src/main/kotlin/org/fossify/commons/extensions/Activity.kt
@@ -143,8 +143,12 @@ fun Activity.showDonateOrUpgradeDialog() {
}
fun Activity.isAppInstalledOnSDCard(): Boolean = try {
- val applicationInfo = packageManager.getPackageInfo(packageName, 0).applicationInfo
- (applicationInfo.flags and ApplicationInfo.FLAG_EXTERNAL_STORAGE) == ApplicationInfo.FLAG_EXTERNAL_STORAGE
+ val appInfo = packageManager.getPackageInfo(packageName, 0).applicationInfo
+ if (appInfo != null) {
+ (appInfo.flags and ApplicationInfo.FLAG_EXTERNAL_STORAGE) == ApplicationInfo.FLAG_EXTERNAL_STORAGE
+ } else {
+ false
+ }
} catch (e: Exception) {
false
}
@@ -1720,6 +1724,20 @@ fun BaseSimpleActivity.getAlarmSounds(type: Int, callback: (ArrayList true
diff --git a/commons/src/main/kotlin/org/fossify/commons/extensions/Context.kt b/commons/src/main/kotlin/org/fossify/commons/extensions/Context.kt
index 2621334da..9f3033dc1 100644
--- a/commons/src/main/kotlin/org/fossify/commons/extensions/Context.kt
+++ b/commons/src/main/kotlin/org/fossify/commons/extensions/Context.kt
@@ -1,7 +1,6 @@
package org.fossify.commons.extensions
import android.Manifest
-import android.annotation.TargetApi
import android.app.Activity
import android.app.Application
import android.app.NotificationManager
@@ -116,7 +115,6 @@ import org.fossify.commons.helpers.YOUR_ALARM_SOUNDS_MIN_ID
import org.fossify.commons.helpers.ensureBackgroundThread
import org.fossify.commons.helpers.isNougatPlus
import org.fossify.commons.helpers.isOnMainThread
-import org.fossify.commons.helpers.isOreoPlus
import org.fossify.commons.helpers.isQPlus
import org.fossify.commons.helpers.isRPlus
import org.fossify.commons.helpers.isSPlus
@@ -129,6 +127,8 @@ import java.io.File
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
+import androidx.core.net.toUri
+import kotlin.math.roundToInt
fun Context.getSharedPrefs() = getSharedPreferences(PREFS_KEY, Context.MODE_PRIVATE)
@@ -480,7 +480,7 @@ fun Context.ensurePublicUri(path: String, applicationId: String): Uri? {
}
else -> {
- val uri = Uri.parse(path)
+ val uri = path.toUri()
if (uri.scheme == "content") {
uri
} else {
@@ -758,7 +758,11 @@ fun Context.getDefaultAlarmSound(type: Int) = AlarmSound(0, getDefaultAlarmTitle
fun Context.grantReadUriPermission(uriString: String) {
try {
// ensure custom reminder sounds play well
- grantUriPermission("com.android.systemui", Uri.parse(uriString), Intent.FLAG_GRANT_READ_URI_PERMISSION)
+ grantUriPermission(
+ "com.android.systemui",
+ uriString.toUri(),
+ Intent.FLAG_GRANT_READ_URI_PERMISSION
+ )
} catch (ignored: Exception) {
}
}
@@ -874,7 +878,7 @@ fun Context.getVideoResolution(path: String): Point? {
if (point == null && path.startsWith("content://", true)) {
try {
- val fd = contentResolver.openFileDescriptor(Uri.parse(path), "r")?.fileDescriptor
+ val fd = contentResolver.openFileDescriptor(path.toUri(), "r")?.fileDescriptor
val retriever = MediaMetadataRetriever()
retriever.setDataSource(fd)
val width = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH)!!.toInt()
@@ -900,7 +904,7 @@ fun Context.getDuration(path: String): Int? {
val cursor = contentResolver.query(uri, projection, selection, selectionArgs, null)
cursor?.use {
if (cursor.moveToFirst()) {
- return Math.round(cursor.getIntValue(MediaColumns.DURATION) / 1000.toDouble()).toInt()
+ return (cursor.getIntValue(MediaColumns.DURATION) / 1000.toDouble()).roundToInt()
}
}
} catch (ignored: Exception) {
@@ -909,7 +913,8 @@ fun Context.getDuration(path: String): Int? {
return try {
val retriever = MediaMetadataRetriever()
retriever.setDataSource(path)
- Math.round(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)!!.toInt() / 1000f)
+ (retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)!!
+ .toInt() / 1000f).roundToInt()
} catch (ignored: Exception) {
null
}
@@ -1044,45 +1049,6 @@ val Context.notificationManager: NotificationManager get() = getSystemService(Co
val Context.shortcutManager: ShortcutManager get() = getSystemService(ShortcutManager::class.java) as ShortcutManager
val Context.portrait get() = resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT
-val Context.navigationBarOnSide: Boolean get() = usableScreenSize.x < realScreenSize.x && usableScreenSize.x > usableScreenSize.y
-val Context.navigationBarOnBottom: Boolean get() = usableScreenSize.y < realScreenSize.y
-val Context.navigationBarHeight: Int get() = if (navigationBarOnBottom && navigationBarSize.y != usableScreenSize.y) navigationBarSize.y else 0
-val Context.navigationBarWidth: Int get() = if (navigationBarOnSide) navigationBarSize.x else 0
-
-val Context.navigationBarSize: Point
- get() = when {
- navigationBarOnSide -> Point(newNavigationBarHeight, usableScreenSize.y)
- navigationBarOnBottom -> Point(usableScreenSize.x, newNavigationBarHeight)
- else -> Point()
- }
-
-val Context.newNavigationBarHeight: Int
- get() {
- var navigationBarHeight = 0
- val resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android")
- if (resourceId > 0) {
- navigationBarHeight = resources.getDimensionPixelSize(resourceId)
- }
- return navigationBarHeight
- }
-
-val Context.statusBarHeight: Int
- get() {
- var statusBarHeight = 0
- val resourceId = resources.getIdentifier("status_bar_height", "dimen", "android")
- if (resourceId > 0) {
- statusBarHeight = resources.getDimensionPixelSize(resourceId)
- }
- return statusBarHeight
- }
-
-val Context.actionBarHeight: Int
- get() {
- val styledAttributes = theme.obtainStyledAttributes(intArrayOf(android.R.attr.actionBarSize))
- val actionBarHeight = styledAttributes.getDimension(0, 0f)
- styledAttributes.recycle()
- return actionBarHeight.toInt()
- }
val Context.usableScreenSize: Point
get() {
@@ -1098,19 +1064,6 @@ val Context.realScreenSize: Point
return size
}
-fun Context.isUsingGestureNavigation(): Boolean {
- return try {
- val resourceId = resources.getIdentifier("config_navBarInteractionMode", "integer", "android")
- if (resourceId > 0) {
- resources.getInteger(resourceId) == 2
- } else {
- false
- }
- } catch (e: Exception) {
- false
- }
-}
-
fun Context.getCornerRadius() = resources.getDimension(R.dimen.rounded_corner_radius_small)
// we need the Default Dialer functionality only in Simple Dialer and in Simple Contacts for now
@@ -1142,7 +1095,6 @@ fun Context.getContactsHasMap(withComparableNumbers: Boolean = false, callback:
}
}
-@TargetApi(Build.VERSION_CODES.N)
fun Context.getBlockedNumbersWithContact(callback: (ArrayList) -> Unit) {
getContactsHasMap(true) { contacts ->
val blockedNumbers = ArrayList()
@@ -1176,7 +1128,6 @@ fun Context.getBlockedNumbersWithContact(callback: (ArrayList) ->
}
}
-@TargetApi(Build.VERSION_CODES.N)
fun Context.getBlockedNumbers(): ArrayList {
val blockedNumbers = ArrayList()
if (!isNougatPlus() || !isDefaultDialer()) {
@@ -1202,7 +1153,6 @@ fun Context.getBlockedNumbers(): ArrayList {
return blockedNumbers
}
-@TargetApi(Build.VERSION_CODES.N)
fun Context.addBlockedNumber(number: String): Boolean {
ContentValues().apply {
put(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, number)
@@ -1219,7 +1169,6 @@ fun Context.addBlockedNumber(number: String): Boolean {
return true
}
-@TargetApi(Build.VERSION_CODES.N)
fun Context.deleteBlockedNumber(number: String): Boolean {
val selection = "${BlockedNumbers.COLUMN_ORIGINAL_NUMBER} = ?"
val selectionArgs = arrayOf(number)
diff --git a/commons/src/main/kotlin/org/fossify/commons/extensions/Fossify.kt b/commons/src/main/kotlin/org/fossify/commons/extensions/Fossify.kt
index 36e9480e9..f3a00da38 100644
--- a/commons/src/main/kotlin/org/fossify/commons/extensions/Fossify.kt
+++ b/commons/src/main/kotlin/org/fossify/commons/extensions/Fossify.kt
@@ -36,7 +36,7 @@ fun PackageManager.checkSignature(packageName: String?): Boolean {
fun PackageManager.getSignatures(packageName: String): Array? {
@Suppress("DEPRECATION")
return if (isPiePlus()) {
- getPackageInfo(packageName, GET_SIGNING_CERTIFICATES).signingInfo.apkContentsSigners
+ getPackageInfo(packageName, GET_SIGNING_CERTIFICATES).signingInfo?.apkContentsSigners
} else {
getPackageInfo(packageName, GET_SIGNATURES).signatures
}
diff --git a/commons/src/main/kotlin/org/fossify/commons/extensions/View.kt b/commons/src/main/kotlin/org/fossify/commons/extensions/View.kt
index 938429186..16464671d 100644
--- a/commons/src/main/kotlin/org/fossify/commons/extensions/View.kt
+++ b/commons/src/main/kotlin/org/fossify/commons/extensions/View.kt
@@ -4,6 +4,9 @@ import android.content.Context
import android.view.HapticFeedbackConstants
import android.view.View
import android.view.ViewTreeObserver
+import androidx.annotation.Px
+import androidx.core.view.updatePadding
+import androidx.core.view.updatePaddingRelative
import org.fossify.commons.R
import org.fossify.commons.helpers.SHORT_ANIMATION_DURATION
@@ -76,3 +79,27 @@ fun View.setDebouncedClickListener(
}
}
}
+
+fun View.ensureBasePadding(): IntArray {
+ val key = R.id.tag_base_padding
+ val base = getTag(key) as? IntArray
+ if (base != null) return base
+ val arr = intArrayOf(paddingLeft, paddingTop, paddingRight, paddingBottom)
+ setTag(key, arr)
+ return arr
+}
+
+fun View.updatePaddingWithBase(
+ @Px left: Int = 0,
+ @Px top: Int = 0,
+ @Px right: Int = 0,
+ @Px bottom: Int = 0,
+) {
+ val base = ensureBasePadding()
+ updatePadding(
+ left = base[0] + left,
+ top = base[1] + top,
+ right = base[2] + right,
+ bottom = base[3] + bottom
+ )
+}
diff --git a/commons/src/main/kotlin/org/fossify/commons/extensions/Window.kt b/commons/src/main/kotlin/org/fossify/commons/extensions/Window.kt
index 1d2b55d8e..4b91bd758 100644
--- a/commons/src/main/kotlin/org/fossify/commons/extensions/Window.kt
+++ b/commons/src/main/kotlin/org/fossify/commons/extensions/Window.kt
@@ -2,33 +2,33 @@ package org.fossify.commons.extensions
import android.view.View
import android.view.Window
+import androidx.core.view.WindowInsetsCompat
+import androidx.core.view.WindowInsetsControllerCompat
import org.fossify.commons.helpers.DARK_GREY
-import org.fossify.commons.helpers.isOreoPlus
-fun Window.updateStatusBarColors(backgroundColor: Int) {
- statusBarColor = backgroundColor
- updateStatusBarForegroundColor(backgroundColor)
+fun Window.insetsController(view: View? = null): WindowInsetsControllerCompat {
+ return WindowInsetsControllerCompat(this, view ?: decorView)
}
-fun Window.updateStatusBarForegroundColor(backgroundColor: Int) {
- if (backgroundColor.getContrastColor() == DARK_GREY) {
- decorView.systemUiVisibility = decorView.systemUiVisibility.addBit(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR)
- } else {
- decorView.systemUiVisibility = decorView.systemUiVisibility.removeBit(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR)
+fun Window.setSystemBarsAppearance(backgroundColor: Int) {
+ val isLightBackground = backgroundColor.getContrastColor() == DARK_GREY
+ insetsController().apply {
+ isAppearanceLightStatusBars = isLightBackground
+ isAppearanceLightNavigationBars = isLightBackground
}
}
-fun Window.updateNavigationBarColors(backgroundColor: Int) {
- navigationBarColor = backgroundColor
- updateNavigationBarForegroundColor(backgroundColor)
+fun Window.showBars() = insetsController().apply {
+ systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_DEFAULT
+ show(WindowInsetsCompat.Type.systemBars())
}
-fun Window.updateNavigationBarForegroundColor(backgroundColor: Int) {
- if (isOreoPlus()) {
- if (backgroundColor.getContrastColor() == DARK_GREY) {
- decorView.systemUiVisibility = decorView.systemUiVisibility.addBit(View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR)
- } else {
- decorView.systemUiVisibility = decorView.systemUiVisibility.removeBit(View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR)
- }
+fun Window.hideBars(transient: Boolean = true) = insetsController().apply {
+ systemBarsBehavior = if (transient) {
+ WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
+ } else {
+ WindowInsetsControllerCompat.BEHAVIOR_DEFAULT
}
+
+ hide(WindowInsetsCompat.Type.systemBars())
}
diff --git a/commons/src/main/kotlin/org/fossify/commons/helpers/Constants.kt b/commons/src/main/kotlin/org/fossify/commons/helpers/Constants.kt
index 21587fccf..e2816b4cb 100644
--- a/commons/src/main/kotlin/org/fossify/commons/helpers/Constants.kt
+++ b/commons/src/main/kotlin/org/fossify/commons/helpers/Constants.kt
@@ -50,6 +50,7 @@ const val MD5 = "MD5"
const val SHA1 = "SHA-1"
const val SHA256 = "SHA-256"
const val SHORT_ANIMATION_DURATION = 150L
+const val DEFAULT_ANIMATION_DURATION = 300L
val DARK_GREY = 0xFF333333.toInt()
const val LOWER_ALPHA = 0.25f
@@ -552,6 +553,12 @@ fun isTiramisuPlus() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU
@ChecksSdkIntAtLeast(api = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
fun isUpsideDownCakePlus() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE
+@ChecksSdkIntAtLeast(api = Build.VERSION_CODES.VANILLA_ICE_CREAM)
+fun isVanillaIceCreamPlus() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM
+
+@ChecksSdkIntAtLeast(api = Build.VERSION_CODES.BAKLAVA)
+fun isBaklavaPlus() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.BAKLAVA
+
fun getDateFormats() = arrayListOf(
"--MM-dd",
"yyyy-MM-dd",
diff --git a/commons/src/main/kotlin/org/fossify/commons/views/MyAppBarLayout.kt b/commons/src/main/kotlin/org/fossify/commons/views/MyAppBarLayout.kt
new file mode 100644
index 000000000..40af25985
--- /dev/null
+++ b/commons/src/main/kotlin/org/fossify/commons/views/MyAppBarLayout.kt
@@ -0,0 +1,62 @@
+package org.fossify.commons.views
+
+import android.content.Context
+import android.util.AttributeSet
+import android.view.View
+import androidx.core.view.ViewCompat
+import androidx.core.view.WindowInsetsCompat.Type
+import androidx.core.view.updatePadding
+import com.google.android.material.appbar.AppBarLayout
+import com.google.android.material.appbar.MaterialToolbar
+
+open class MyAppBarLayout @JvmOverloads constructor(
+ context: Context,
+ attrs: AttributeSet? = null,
+ defStyleAttr: Int = 0
+) : AppBarLayout(context, attrs, defStyleAttr) {
+ private var cachedToolbar: MaterialToolbar? = null
+
+ init {
+ elevation = 0f
+ ViewCompat.setElevation(this, 0f)
+ stateListAnimator = null
+ isLiftOnScroll = false
+ isLifted = false
+
+ ViewCompat.setOnApplyWindowInsetsListener(this) { view, insets ->
+ val system = insets.getInsetsIgnoringVisibility(Type.systemBars())
+ view.updatePadding(top = system.top, left = system.left, right = system.right)
+ insets
+ }
+ }
+
+ open val toolbar: MaterialToolbar?
+ get() {
+ for (i in 0 until childCount) {
+ val child = getChildAt(i)
+ if (child is MaterialToolbar) {
+ return child.also { cachedToolbar = it }
+ }
+ }
+
+ return null
+ }
+
+ override fun onAttachedToWindow() {
+ super.onAttachedToWindow()
+ ViewCompat.requestApplyInsets(this)
+ }
+
+ override fun onViewAdded(child: View) {
+ super.onViewAdded(child)
+ cachedToolbar = null
+ }
+
+ override fun onViewRemoved(child: View) {
+ super.onViewRemoved(child)
+ cachedToolbar = null
+ }
+
+ fun requireToolbar(): MaterialToolbar =
+ toolbar ?: error("MyAppBarLayout requires a Toolbar/MaterialToolbar child")
+}
diff --git a/commons/src/main/kotlin/org/fossify/commons/views/MyFloatingActionButton.kt b/commons/src/main/kotlin/org/fossify/commons/views/MyFloatingActionButton.kt
index c9ffc24aa..9a7a2d475 100644
--- a/commons/src/main/kotlin/org/fossify/commons/views/MyFloatingActionButton.kt
+++ b/commons/src/main/kotlin/org/fossify/commons/views/MyFloatingActionButton.kt
@@ -3,6 +3,8 @@ package org.fossify.commons.views
import android.content.Context
import android.content.res.ColorStateList
import android.util.AttributeSet
+import androidx.core.view.ViewCompat
+import androidx.core.view.WindowInsetsCompat
import com.google.android.material.floatingactionbutton.FloatingActionButton
import org.fossify.commons.extensions.applyColorFilter
import org.fossify.commons.extensions.getContrastColor
@@ -12,7 +14,19 @@ open class MyFloatingActionButton : FloatingActionButton {
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
- constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle)
+ constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(
+ context,
+ attrs,
+ defStyle
+ )
+
+ init {
+ ViewCompat.setOnApplyWindowInsetsListener(this) { _, insets ->
+ val system = insets.getInsetsIgnoringVisibility(WindowInsetsCompat.Type.systemBars())
+ translationY = -system.bottom.toFloat()
+ insets
+ }
+ }
fun setColors(textColor: Int, accentColor: Int, backgroundColor: Int) {
backgroundTintList = ColorStateList.valueOf(accentColor)
diff --git a/commons/src/main/kotlin/org/fossify/commons/views/MySearchMenu.kt b/commons/src/main/kotlin/org/fossify/commons/views/MySearchMenu.kt
index cd7cdd45f..1e1da6e3d 100644
--- a/commons/src/main/kotlin/org/fossify/commons/views/MySearchMenu.kt
+++ b/commons/src/main/kotlin/org/fossify/commons/views/MySearchMenu.kt
@@ -4,15 +4,23 @@ import android.app.Activity
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
-import com.google.android.material.appbar.AppBarLayout
+import com.google.android.material.appbar.MaterialToolbar
import org.fossify.commons.R
import org.fossify.commons.activities.BaseSimpleActivity
import org.fossify.commons.databinding.MenuSearchBinding
-import org.fossify.commons.extensions.*
+import org.fossify.commons.extensions.adjustAlpha
+import org.fossify.commons.extensions.applyColorFilter
+import org.fossify.commons.extensions.getContrastColor
+import org.fossify.commons.extensions.getProperBackgroundColor
+import org.fossify.commons.extensions.getProperPrimaryColor
+import org.fossify.commons.extensions.hideKeyboard
+import org.fossify.commons.extensions.onTextChangeListener
+import org.fossify.commons.extensions.removeBit
+import org.fossify.commons.extensions.showKeyboard
import org.fossify.commons.helpers.LOWER_ALPHA
import org.fossify.commons.helpers.MEDIUM_ALPHA
-open class MySearchMenu(context: Context, attrs: AttributeSet) : AppBarLayout(context, attrs) {
+open class MySearchMenu(context: Context, attrs: AttributeSet) : MyAppBarLayout(context, attrs) {
var isSearchOpen = false
var useArrowIcon = false
var onSearchOpenListener: (() -> Unit)? = null
@@ -20,9 +28,10 @@ open class MySearchMenu(context: Context, attrs: AttributeSet) : AppBarLayout(co
var onSearchTextChangedListener: ((text: String) -> Unit)? = null
var onNavigateBackClickListener: (() -> Unit)? = null
- val binding = MenuSearchBinding.inflate(LayoutInflater.from(context), this, true)
+ val binding = MenuSearchBinding.inflate(LayoutInflater.from(context), this)
- fun getToolbar() = binding.topToolbar
+ override val toolbar: MaterialToolbar?
+ get() = binding.topToolbar
fun setupMenu() {
binding.topToolbarSearchIcon.setOnClickListener {
@@ -77,14 +86,9 @@ open class MySearchMenu(context: Context, attrs: AttributeSet) : AppBarLayout(co
binding.topToolbarSearch.hint = text
}
- fun toggleHideOnScroll(hideOnScroll: Boolean) {
- val params = binding.topAppBarLayout.layoutParams as LayoutParams
- if (hideOnScroll) {
- params.scrollFlags = LayoutParams.SCROLL_FLAG_SCROLL or LayoutParams.SCROLL_FLAG_ENTER_ALWAYS
- } else {
- params.scrollFlags = params.scrollFlags.removeBit(LayoutParams.SCROLL_FLAG_SCROLL or LayoutParams.SCROLL_FLAG_ENTER_ALWAYS)
- }
- }
+ @Suppress("unused", "EmptyFunctionBlock")
+ @Deprecated("This feature is broken for now.")
+ fun toggleHideOnScroll(hideOnScroll: Boolean) {}
fun toggleForceArrowBackIcon(useArrowBack: Boolean) {
this.useArrowIcon = useArrowBack
@@ -103,11 +107,12 @@ open class MySearchMenu(context: Context, attrs: AttributeSet) : AppBarLayout(co
val contrastColor = backgroundColor.getContrastColor()
setBackgroundColor(backgroundColor)
- binding.topAppBarLayout.setBackgroundColor(backgroundColor)
binding.topToolbarSearchIcon.applyColorFilter(contrastColor)
- binding.topToolbarHolder.background?.applyColorFilter(context.getProperPrimaryColor().adjustAlpha(LOWER_ALPHA))
+ binding.toolbarContainer.background?.applyColorFilter(
+ color = context.getProperPrimaryColor().adjustAlpha(LOWER_ALPHA)
+ )
binding.topToolbarSearch.setTextColor(contrastColor)
binding.topToolbarSearch.setHintTextColor(contrastColor.adjustAlpha(MEDIUM_ALPHA))
- (context as? BaseSimpleActivity)?.updateTopBarColors(binding.topToolbar, backgroundColor)
+ (context as? BaseSimpleActivity)?.updateTopBarColors(this, backgroundColor)
}
}
diff --git a/commons/src/main/res/layout/activity_customization.xml b/commons/src/main/res/layout/activity_customization.xml
index 1a478aec2..db495e7e6 100644
--- a/commons/src/main/res/layout/activity_customization.xml
+++ b/commons/src/main/res/layout/activity_customization.xml
@@ -6,22 +6,29 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
-
+ android:layout_height="wrap_content">
+
+
+
+
+ android:scrollbars="none"
+ app:layout_behavior="@string/appbar_scrolling_view_behavior">
-
+ android:layout_height="wrap_content">
-
+ android:layout_height="?attr/actionBarSize"
+ android:paddingStart="@dimen/activity_margin"
+ android:paddingTop="@dimen/medium_margin"
+ android:paddingEnd="@dimen/activity_margin"
+ android:paddingBottom="@dimen/medium_margin">
-
-
-
+ android:layout_height="wrap_content"
+ android:background="@drawable/search_menu_background"
+ android:focusableInTouchMode="true"
+ tools:ignore="UselessParent">
+
+
+
+
+
+
-
+
-
-
+
+
diff --git a/commons/src/main/res/values/ids.xml b/commons/src/main/res/values/ids.xml
index a581e879d..3fdb40bfa 100644
--- a/commons/src/main/res/values/ids.xml
+++ b/commons/src/main/res/values/ids.xml
@@ -1,10 +1,11 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
diff --git a/commons/src/main/res/values/styles.xml b/commons/src/main/res/values/styles.xml
index c852d6987..dc1beefc3 100644
--- a/commons/src/main/res/values/styles.xml
+++ b/commons/src/main/res/values/styles.xml
@@ -563,1545 +563,6 @@
- @style/ActionMenuOverflowIcon
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-