diff --git a/README.md b/README.md index b654c4822..247cf2bb8 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@
Banner - # v6.8.0 is out! + # v6.9.0 is out!

Downloads diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 92623826b..6b802cd55 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -16,8 +16,8 @@ android { applicationId = "com.drdisagree.iconify" minSdk = 31 targetSdk = 34 - versionCode = 20 - versionName = "6.8.0" + versionCode = 21 + versionName = "6.9.0" setProperty("archivesBaseName", "Iconify v$versionName") buildConfigField("int", "MIN_SDK_VERSION", "$minSdk") } @@ -65,6 +65,7 @@ android { viewBinding = true dataBinding = true buildConfig = true + aidl = true } compileOptions { @@ -112,6 +113,7 @@ dependencies { // Data Binding implementation(libs.library) + implementation(libs.androidx.palette.ktx) // Xposed API compileOnly(files("libs/api-82.jar")) @@ -128,7 +130,7 @@ dependencies { implementation(libs.kotlinx.coroutines.android) // Color Picker - implementation(libs.colorpicker) + implementation(libs.jaredrummler.colorpicker) // Splash Screen implementation(libs.androidx.core.splashscreen) @@ -142,6 +144,9 @@ dependencies { // Zip Util implementation(libs.zip4j) + // Preference + implementation(libs.androidx.preference.ktx) + // Remote Preference implementation(libs.remotepreferences) @@ -190,12 +195,20 @@ dependencies { // Fading Edge Layout implementation(libs.fadingedgelayout) + // Google Subject Segmentation - MLKit + implementation(libs.com.google.android.gms.play.services.mlkit.subject.segmentation) + implementation(libs.play.services.base) + + // Blur View + implementation(libs.blurview) + // Misc implementation(libs.androidx.appcompat) implementation(libs.androidx.constraintlayout) implementation(libs.androidx.work.runtime) implementation(libs.androidx.work.runtime.ktx) implementation(libs.slf4j.api) + implementation(libs.commons.text) } tasks.register("printVersionName") { diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index bd62f20fe..474870070 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -21,15 +21,23 @@ public static int d(...); } +# Activity and Fragment names +-keep class com.drdisagree.iconify.ui.activities.** +-keep class com.drdisagree.iconify.ui.fragments.** + # Xposed -keep class de.robv.android.xposed.** -keep class com.drdisagree.iconify.xposed.InitHook -keepnames class com.drdisagree.iconify.xposed.** --keepnames class com.drdisagree.iconify.config.XPrefs +-keepnames class com.drdisagree.iconify.xposed.utils.XPrefs -keep class com.drdisagree.iconify.xposed.** { (android.content.Context); } +# Weather +-keepnames class com.drdisagree.iconify.utils.weather.** +-keep class com.drdisagree.iconify.utils.weather.** { *; } + # EventBus -keepattributes *Annotation* -keepclassmembers,allowoptimization,allowobfuscation class * { @@ -59,4 +67,13 @@ # Obfuscation -repackageclasses --allowaccessmodification \ No newline at end of file +-allowaccessmodification + +# Root Service +-keep class com.drdisagree.iconify.services.RootProviderProxy { *; } +-keep class com.drdisagree.iconify.IRootProviderProxy { *; } + +# AIDL Classes +-keep interface **.I* { *; } +-keep class **.I*$Stub { *; } +-keep class **.I*$Stub$Proxy { *; } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a7b81b747..676021d76 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -22,6 +22,17 @@ + + + + + + + + + + --> + + @@ -170,12 +191,192 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/aidl/com/drdisagree/iconify/IExtractSubjectCallback.aidl b/app/src/main/aidl/com/drdisagree/iconify/IExtractSubjectCallback.aidl new file mode 100644 index 000000000..d66b84c6e --- /dev/null +++ b/app/src/main/aidl/com/drdisagree/iconify/IExtractSubjectCallback.aidl @@ -0,0 +1,6 @@ +package com.drdisagree.iconify; + +interface IExtractSubjectCallback { + void onStart(String message); + void onResult(boolean success, String message); +} \ No newline at end of file diff --git a/app/src/main/aidl/com/drdisagree/iconify/IRootProviderProxy.aidl b/app/src/main/aidl/com/drdisagree/iconify/IRootProviderProxy.aidl new file mode 100644 index 000000000..e874a37be --- /dev/null +++ b/app/src/main/aidl/com/drdisagree/iconify/IRootProviderProxy.aidl @@ -0,0 +1,10 @@ +package com.drdisagree.iconify; + +import com.drdisagree.iconify.IExtractSubjectCallback; + +interface IRootProviderProxy { + String[] runCommand(String command); + void extractSubject(in Bitmap input, String resultPath, IExtractSubjectCallback callback); + void enableOverlay(in String packageName); + void disableOverlay(in String packageName); +} \ No newline at end of file diff --git a/app/src/main/assets/CompileOnDemand/android/TSTFRM12/res/drawable/toast_frame.xml b/app/src/main/assets/CompileOnDemand/android/TSTFRM12/res/drawable/toast_frame.xml new file mode 100644 index 000000000..e15325f98 --- /dev/null +++ b/app/src/main/assets/CompileOnDemand/android/TSTFRM12/res/drawable/toast_frame.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/assets/CompileOnDemand/android/TSTFRM12/res/drawable/toast_frame_material.xml b/app/src/main/assets/CompileOnDemand/android/TSTFRM12/res/drawable/toast_frame_material.xml new file mode 100644 index 000000000..e15325f98 --- /dev/null +++ b/app/src/main/assets/CompileOnDemand/android/TSTFRM12/res/drawable/toast_frame_material.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/assets/CompileOnDemand/android/TSTFRM12/res/values-night/colors.xml b/app/src/main/assets/CompileOnDemand/android/TSTFRM12/res/values-night/colors.xml new file mode 100644 index 000000000..e05ab934e --- /dev/null +++ b/app/src/main/assets/CompileOnDemand/android/TSTFRM12/res/values-night/colors.xml @@ -0,0 +1,6 @@ + + + + @android:color/system_neutral2_800 + + \ No newline at end of file diff --git a/app/src/main/assets/CompileOnDemand/android/TSTFRM12/res/values/colors.xml b/app/src/main/assets/CompileOnDemand/android/TSTFRM12/res/values/colors.xml new file mode 100644 index 000000000..b3ee65f40 --- /dev/null +++ b/app/src/main/assets/CompileOnDemand/android/TSTFRM12/res/values/colors.xml @@ -0,0 +1,6 @@ + + + + @android:color/system_neutral1_50 + + \ No newline at end of file diff --git a/app/src/main/assets/Module/IconifyCompanion/META-INF/com/google/android/update-binary b/app/src/main/assets/Module/IconifyCompanion/META-INF/com/google/android/update-binary index b91ebe4d6..88816b3ad 100644 --- a/app/src/main/assets/Module/IconifyCompanion/META-INF/com/google/android/update-binary +++ b/app/src/main/assets/Module/IconifyCompanion/META-INF/com/google/android/update-binary @@ -83,7 +83,8 @@ file_paths="/system/system_ext/priv-app/SystemUI/SystemUI.apk /system/system_ext/priv-app/sysuia/sysuia.apk /system/system_ext/priv-app/TranSystemUI/TranSystemUI.apk /system/system_ext/priv-app/MiuiSystemUI/MiuiSystemUI.apk -/system/product/priv-app/MiuiSystemUI/MiuiSystemUI.apk" +/system/product/priv-app/MiuiSystemUI/MiuiSystemUI.apk +/system/system_ext/priv-app/LMOSystemUI/LMOSystemUI.apk" found=0 diff --git a/app/src/main/assets/Overlays/android/QSPBA/res/values-night/iconify.xml b/app/src/main/assets/Overlays/android/QSPBA/res/values-night/iconify.xml index 3b3e92095..2d42498a7 100644 --- a/app/src/main/assets/Overlays/android/QSPBA/res/values-night/iconify.xml +++ b/app/src/main/assets/Overlays/android/QSPBA/res/values-night/iconify.xml @@ -1,6 +1,9 @@ + @*android:color/black + @*android:color/black + @*android:color/black @*android:color/black @*android:color/black @*android:color/black diff --git a/app/src/main/assets/Overlays/android/QSPBD/res/values-night/iconify.xml b/app/src/main/assets/Overlays/android/QSPBD/res/values-night/iconify.xml index 799c3435e..1afddfcd9 100644 --- a/app/src/main/assets/Overlays/android/QSPBD/res/values-night/iconify.xml +++ b/app/src/main/assets/Overlays/android/QSPBD/res/values-night/iconify.xml @@ -1,6 +1,9 @@ + @*android:color/black + @*android:color/black + @*android:color/system_neutral1_800 @*android:color/black @*android:color/black @*android:color/black diff --git a/app/src/main/assets/Overlays/android/SGIC1/res/drawable/ic_signal_cellular_0_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC1/res/drawable/ic_signal_cellular_0_4_bar.xml new file mode 100644 index 000000000..834225d2d --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC1/res/drawable/ic_signal_cellular_0_4_bar.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC1/res/drawable/ic_signal_cellular_0_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC1/res/drawable/ic_signal_cellular_0_5_bar.xml new file mode 100644 index 000000000..834225d2d --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC1/res/drawable/ic_signal_cellular_0_5_bar.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC1/res/drawable/ic_signal_cellular_1_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC1/res/drawable/ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..effcde5d9 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC1/res/drawable/ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,10 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC1/res/drawable/ic_signal_cellular_1_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC1/res/drawable/ic_signal_cellular_1_5_bar.xml new file mode 100644 index 000000000..effcde5d9 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC1/res/drawable/ic_signal_cellular_1_5_bar.xml @@ -0,0 +1,10 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC1/res/drawable/ic_signal_cellular_2_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC1/res/drawable/ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..504cc95a7 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC1/res/drawable/ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC1/res/drawable/ic_signal_cellular_2_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC1/res/drawable/ic_signal_cellular_2_5_bar.xml new file mode 100644 index 000000000..504cc95a7 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC1/res/drawable/ic_signal_cellular_2_5_bar.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC1/res/drawable/ic_signal_cellular_3_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC1/res/drawable/ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..e6aad62df --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC1/res/drawable/ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC1/res/drawable/ic_signal_cellular_3_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC1/res/drawable/ic_signal_cellular_3_5_bar.xml new file mode 100644 index 000000000..e6aad62df --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC1/res/drawable/ic_signal_cellular_3_5_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC1/res/drawable/ic_signal_cellular_4_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC1/res/drawable/ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..62f871e78 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC1/res/drawable/ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC1/res/drawable/ic_signal_cellular_4_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC1/res/drawable/ic_signal_cellular_4_5_bar.xml new file mode 100644 index 000000000..62f871e78 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC1/res/drawable/ic_signal_cellular_4_5_bar.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC1/res/drawable/ic_signal_cellular_5_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC1/res/drawable/ic_signal_cellular_5_5_bar.xml new file mode 100644 index 000000000..62f871e78 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC1/res/drawable/ic_signal_cellular_5_5_bar.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC10/res/drawable/ic_signal_cellular_0_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC10/res/drawable/ic_signal_cellular_0_4_bar.xml new file mode 100644 index 000000000..79fb7f04c --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC10/res/drawable/ic_signal_cellular_0_4_bar.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC10/res/drawable/ic_signal_cellular_0_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC10/res/drawable/ic_signal_cellular_0_5_bar.xml new file mode 100644 index 000000000..79fb7f04c --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC10/res/drawable/ic_signal_cellular_0_5_bar.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC10/res/drawable/ic_signal_cellular_1_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC10/res/drawable/ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..581331608 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC10/res/drawable/ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC10/res/drawable/ic_signal_cellular_1_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC10/res/drawable/ic_signal_cellular_1_5_bar.xml new file mode 100644 index 000000000..581331608 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC10/res/drawable/ic_signal_cellular_1_5_bar.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC10/res/drawable/ic_signal_cellular_2_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC10/res/drawable/ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..7765c318e --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC10/res/drawable/ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC10/res/drawable/ic_signal_cellular_2_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC10/res/drawable/ic_signal_cellular_2_5_bar.xml new file mode 100644 index 000000000..7765c318e --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC10/res/drawable/ic_signal_cellular_2_5_bar.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC10/res/drawable/ic_signal_cellular_3_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC10/res/drawable/ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..679d52e93 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC10/res/drawable/ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC10/res/drawable/ic_signal_cellular_3_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC10/res/drawable/ic_signal_cellular_3_5_bar.xml new file mode 100644 index 000000000..679d52e93 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC10/res/drawable/ic_signal_cellular_3_5_bar.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC10/res/drawable/ic_signal_cellular_4_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC10/res/drawable/ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..6876c0799 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC10/res/drawable/ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC10/res/drawable/ic_signal_cellular_4_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC10/res/drawable/ic_signal_cellular_4_5_bar.xml new file mode 100644 index 000000000..6876c0799 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC10/res/drawable/ic_signal_cellular_4_5_bar.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC10/res/drawable/ic_signal_cellular_5_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC10/res/drawable/ic_signal_cellular_5_5_bar.xml new file mode 100644 index 000000000..6876c0799 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC10/res/drawable/ic_signal_cellular_5_5_bar.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC11/res/drawable/ic_signal_cellular_0_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC11/res/drawable/ic_signal_cellular_0_4_bar.xml new file mode 100644 index 000000000..66158ad22 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC11/res/drawable/ic_signal_cellular_0_4_bar.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC11/res/drawable/ic_signal_cellular_0_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC11/res/drawable/ic_signal_cellular_0_5_bar.xml new file mode 100644 index 000000000..66158ad22 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC11/res/drawable/ic_signal_cellular_0_5_bar.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC11/res/drawable/ic_signal_cellular_1_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC11/res/drawable/ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..f625c4edb --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC11/res/drawable/ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC11/res/drawable/ic_signal_cellular_1_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC11/res/drawable/ic_signal_cellular_1_5_bar.xml new file mode 100644 index 000000000..f625c4edb --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC11/res/drawable/ic_signal_cellular_1_5_bar.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC11/res/drawable/ic_signal_cellular_2_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC11/res/drawable/ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..316b0d3a5 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC11/res/drawable/ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC11/res/drawable/ic_signal_cellular_2_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC11/res/drawable/ic_signal_cellular_2_5_bar.xml new file mode 100644 index 000000000..316b0d3a5 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC11/res/drawable/ic_signal_cellular_2_5_bar.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC11/res/drawable/ic_signal_cellular_3_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC11/res/drawable/ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..4106a2347 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC11/res/drawable/ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC11/res/drawable/ic_signal_cellular_3_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC11/res/drawable/ic_signal_cellular_3_5_bar.xml new file mode 100644 index 000000000..4106a2347 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC11/res/drawable/ic_signal_cellular_3_5_bar.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC11/res/drawable/ic_signal_cellular_4_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC11/res/drawable/ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..cf10b0123 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC11/res/drawable/ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC11/res/drawable/ic_signal_cellular_4_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC11/res/drawable/ic_signal_cellular_4_5_bar.xml new file mode 100644 index 000000000..cf10b0123 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC11/res/drawable/ic_signal_cellular_4_5_bar.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC11/res/drawable/ic_signal_cellular_5_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC11/res/drawable/ic_signal_cellular_5_5_bar.xml new file mode 100644 index 000000000..cf10b0123 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC11/res/drawable/ic_signal_cellular_5_5_bar.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_1x_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_1x_mobiledata.xml new file mode 100644 index 000000000..9c394a97b --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_1x_mobiledata.xml @@ -0,0 +1,40 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_3g_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_3g_mobiledata.xml new file mode 100644 index 000000000..948ca6340 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_3g_mobiledata.xml @@ -0,0 +1,52 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_4g_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_4g_mobiledata.xml new file mode 100644 index 000000000..c20075c6c --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_4g_mobiledata.xml @@ -0,0 +1,52 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_4g_plus_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_4g_plus_mobiledata.xml new file mode 100644 index 000000000..6d0930c28 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_4g_plus_mobiledata.xml @@ -0,0 +1,60 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_5g_e_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_5g_e_mobiledata.xml new file mode 100644 index 000000000..4e6694d92 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_5g_e_mobiledata.xml @@ -0,0 +1,60 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_5g_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_5g_mobiledata.xml new file mode 100644 index 000000000..66bdfcc7b --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_5g_mobiledata.xml @@ -0,0 +1,52 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_5g_plus_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_5g_plus_mobiledata.xml new file mode 100644 index 000000000..b8b302488 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_5g_plus_mobiledata.xml @@ -0,0 +1,60 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_5g_uc_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_5g_uc_mobiledata.xml new file mode 100644 index 000000000..66bdfcc7b --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_5g_uc_mobiledata.xml @@ -0,0 +1,52 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_5g_uw_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_5g_uw_mobiledata.xml new file mode 100644 index 000000000..66bdfcc7b --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_5g_uw_mobiledata.xml @@ -0,0 +1,52 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_e_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_e_mobiledata.xml new file mode 100644 index 000000000..25138723c --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_e_mobiledata.xml @@ -0,0 +1,52 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_g_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_g_mobiledata.xml new file mode 100644 index 000000000..aae9af97f --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_g_mobiledata.xml @@ -0,0 +1,40 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_h_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_h_mobiledata.xml new file mode 100644 index 000000000..8c2fea791 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_h_mobiledata.xml @@ -0,0 +1,46 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_h_plus_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_h_plus_mobiledata.xml new file mode 100644 index 000000000..ca99c0c70 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_h_plus_mobiledata.xml @@ -0,0 +1,54 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_lte_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_lte_mobiledata.xml new file mode 100644 index 000000000..b0fbb24e0 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_lte_mobiledata.xml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_lte_plus_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_lte_plus_mobiledata.xml new file mode 100644 index 000000000..593db9ec5 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_lte_plus_mobiledata.xml @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_signal_cellular_0_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_signal_cellular_0_4_bar.xml new file mode 100644 index 000000000..c461365dd --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_signal_cellular_0_4_bar.xml @@ -0,0 +1,68 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_signal_cellular_0_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_signal_cellular_0_5_bar.xml new file mode 100644 index 000000000..c461365dd --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_signal_cellular_0_5_bar.xml @@ -0,0 +1,68 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_signal_cellular_1_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..b4bed1feb --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,60 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_signal_cellular_1_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_signal_cellular_1_5_bar.xml new file mode 100644 index 000000000..b4bed1feb --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_signal_cellular_1_5_bar.xml @@ -0,0 +1,60 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_signal_cellular_2_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..59adc2ab9 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,60 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_signal_cellular_2_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_signal_cellular_2_5_bar.xml new file mode 100644 index 000000000..ebcf3b106 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_signal_cellular_2_5_bar.xml @@ -0,0 +1,60 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_signal_cellular_3_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..b1c402dfc --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,60 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_signal_cellular_3_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_signal_cellular_3_5_bar.xml new file mode 100644 index 000000000..b1c402dfc --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_signal_cellular_3_5_bar.xml @@ -0,0 +1,60 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_signal_cellular_4_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..5836f94f2 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,60 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_signal_cellular_4_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_signal_cellular_4_5_bar.xml new file mode 100644 index 000000000..5836f94f2 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_signal_cellular_4_5_bar.xml @@ -0,0 +1,60 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_signal_cellular_5_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_signal_cellular_5_5_bar.xml new file mode 100644 index 000000000..5836f94f2 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC12/res/drawable/ic_signal_cellular_5_5_bar.xml @@ -0,0 +1,60 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC13/res/drawable/ic_signal_cellular_0_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC13/res/drawable/ic_signal_cellular_0_4_bar.xml new file mode 100644 index 000000000..51dbcbf08 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC13/res/drawable/ic_signal_cellular_0_4_bar.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC13/res/drawable/ic_signal_cellular_0_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC13/res/drawable/ic_signal_cellular_0_5_bar.xml new file mode 100644 index 000000000..51dbcbf08 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC13/res/drawable/ic_signal_cellular_0_5_bar.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC13/res/drawable/ic_signal_cellular_1_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC13/res/drawable/ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..70c43f196 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC13/res/drawable/ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC13/res/drawable/ic_signal_cellular_1_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC13/res/drawable/ic_signal_cellular_1_5_bar.xml new file mode 100644 index 000000000..70c43f196 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC13/res/drawable/ic_signal_cellular_1_5_bar.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC13/res/drawable/ic_signal_cellular_2_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC13/res/drawable/ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..3ba81ab0c --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC13/res/drawable/ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC13/res/drawable/ic_signal_cellular_2_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC13/res/drawable/ic_signal_cellular_2_5_bar.xml new file mode 100644 index 000000000..3ba81ab0c --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC13/res/drawable/ic_signal_cellular_2_5_bar.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC13/res/drawable/ic_signal_cellular_3_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC13/res/drawable/ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..7326f8eeb --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC13/res/drawable/ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC13/res/drawable/ic_signal_cellular_3_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC13/res/drawable/ic_signal_cellular_3_5_bar.xml new file mode 100644 index 000000000..7326f8eeb --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC13/res/drawable/ic_signal_cellular_3_5_bar.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC13/res/drawable/ic_signal_cellular_4_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC13/res/drawable/ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..882677438 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC13/res/drawable/ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC13/res/drawable/ic_signal_cellular_4_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC13/res/drawable/ic_signal_cellular_4_5_bar.xml new file mode 100644 index 000000000..882677438 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC13/res/drawable/ic_signal_cellular_4_5_bar.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC13/res/drawable/ic_signal_cellular_5_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC13/res/drawable/ic_signal_cellular_5_5_bar.xml new file mode 100644 index 000000000..882677438 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC13/res/drawable/ic_signal_cellular_5_5_bar.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_1x_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_1x_mobiledata.xml new file mode 100644 index 000000000..4b4a46b9c --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_1x_mobiledata.xml @@ -0,0 +1,30 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_3g_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_3g_mobiledata.xml new file mode 100644 index 000000000..72326376b --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_3g_mobiledata.xml @@ -0,0 +1,22 @@ + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_4g_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_4g_mobiledata.xml new file mode 100644 index 000000000..f5c04def5 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_4g_mobiledata.xml @@ -0,0 +1,22 @@ + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_4g_plus_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_4g_plus_mobiledata.xml new file mode 100644 index 000000000..f11915a96 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_4g_plus_mobiledata.xml @@ -0,0 +1,38 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_5g_e_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_5g_e_mobiledata.xml new file mode 100644 index 000000000..964bd1630 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_5g_e_mobiledata.xml @@ -0,0 +1,30 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_5g_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_5g_mobiledata.xml new file mode 100644 index 000000000..f63b3efad --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_5g_mobiledata.xml @@ -0,0 +1,22 @@ + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_5g_plus_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_5g_plus_mobiledata.xml new file mode 100644 index 000000000..60f758e57 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_5g_plus_mobiledata.xml @@ -0,0 +1,38 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_5g_uc_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_5g_uc_mobiledata.xml new file mode 100644 index 000000000..f63b3efad --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_5g_uc_mobiledata.xml @@ -0,0 +1,22 @@ + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_5g_uw_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_5g_uw_mobiledata.xml new file mode 100644 index 000000000..f63b3efad --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_5g_uw_mobiledata.xml @@ -0,0 +1,22 @@ + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_e_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_e_mobiledata.xml new file mode 100644 index 000000000..97ee8cf2c --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_e_mobiledata.xml @@ -0,0 +1,14 @@ + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_g_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_g_mobiledata.xml new file mode 100644 index 000000000..4651eab4a --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_g_mobiledata.xml @@ -0,0 +1,14 @@ + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_h_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_h_mobiledata.xml new file mode 100644 index 000000000..8f2438d1e --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_h_mobiledata.xml @@ -0,0 +1,30 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_h_plus_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_h_plus_mobiledata.xml new file mode 100644 index 000000000..6f9f0fdb6 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_h_plus_mobiledata.xml @@ -0,0 +1,46 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_lte_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_lte_mobiledata.xml new file mode 100644 index 000000000..43bfef140 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_lte_mobiledata.xml @@ -0,0 +1,30 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_lte_plus_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_lte_plus_mobiledata.xml new file mode 100644 index 000000000..1277d3094 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_lte_plus_mobiledata.xml @@ -0,0 +1,46 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_signal_cellular_0_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_signal_cellular_0_4_bar.xml new file mode 100644 index 000000000..8ea4c2470 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_signal_cellular_0_4_bar.xml @@ -0,0 +1,14 @@ + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_signal_cellular_0_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_signal_cellular_0_5_bar.xml new file mode 100644 index 000000000..8ea4c2470 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_signal_cellular_0_5_bar.xml @@ -0,0 +1,14 @@ + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_signal_cellular_1_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..695c5263e --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,22 @@ + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_signal_cellular_1_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_signal_cellular_1_5_bar.xml new file mode 100644 index 000000000..695c5263e --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_signal_cellular_1_5_bar.xml @@ -0,0 +1,22 @@ + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_signal_cellular_2_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..695c5263e --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,22 @@ + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_signal_cellular_2_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_signal_cellular_2_5_bar.xml new file mode 100644 index 000000000..695c5263e --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_signal_cellular_2_5_bar.xml @@ -0,0 +1,22 @@ + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_signal_cellular_3_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..83254ff81 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,22 @@ + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_signal_cellular_3_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_signal_cellular_3_5_bar.xml new file mode 100644 index 000000000..83254ff81 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_signal_cellular_3_5_bar.xml @@ -0,0 +1,22 @@ + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_signal_cellular_4_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..4f271f0a1 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,22 @@ + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_signal_cellular_4_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_signal_cellular_4_5_bar.xml new file mode 100644 index 000000000..4f271f0a1 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_signal_cellular_4_5_bar.xml @@ -0,0 +1,22 @@ + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_signal_cellular_5_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_signal_cellular_5_5_bar.xml new file mode 100644 index 000000000..4f271f0a1 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC14/res/drawable/ic_signal_cellular_5_5_bar.xml @@ -0,0 +1,22 @@ + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_1x_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_1x_mobiledata.xml new file mode 100644 index 000000000..785f1dc3c --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_1x_mobiledata.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_3g_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_3g_mobiledata.xml new file mode 100644 index 000000000..6457acd47 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_3g_mobiledata.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_4g_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_4g_mobiledata.xml new file mode 100644 index 000000000..6cd4fcdc3 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_4g_mobiledata.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_4g_plus_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_4g_plus_mobiledata.xml new file mode 100644 index 000000000..4eb5f9b78 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_4g_plus_mobiledata.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_5g_e_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_5g_e_mobiledata.xml new file mode 100644 index 000000000..0b041917a --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_5g_e_mobiledata.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_5g_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_5g_mobiledata.xml new file mode 100644 index 000000000..84c73a8b4 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_5g_mobiledata.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_5g_plus_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_5g_plus_mobiledata.xml new file mode 100644 index 000000000..ca78191d3 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_5g_plus_mobiledata.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_5g_uc_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_5g_uc_mobiledata.xml new file mode 100644 index 000000000..84c73a8b4 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_5g_uc_mobiledata.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_5g_uw_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_5g_uw_mobiledata.xml new file mode 100644 index 000000000..84c73a8b4 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_5g_uw_mobiledata.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_e_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_e_mobiledata.xml new file mode 100644 index 000000000..a2fdc1cf3 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_e_mobiledata.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_g_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_g_mobiledata.xml new file mode 100644 index 000000000..bf342c458 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_g_mobiledata.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_h_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_h_mobiledata.xml new file mode 100644 index 000000000..f0fdd2cb6 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_h_mobiledata.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_h_plus_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_h_plus_mobiledata.xml new file mode 100644 index 000000000..8e3c9beb6 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_h_plus_mobiledata.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_lte_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_lte_mobiledata.xml new file mode 100644 index 000000000..61ef7651d --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_lte_mobiledata.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_lte_plus_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_lte_plus_mobiledata.xml new file mode 100644 index 000000000..751bcd71e --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_lte_plus_mobiledata.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_signal_cellular_0_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_signal_cellular_0_4_bar.xml new file mode 100644 index 000000000..751f41b79 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_signal_cellular_0_4_bar.xml @@ -0,0 +1,183 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_signal_cellular_0_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_signal_cellular_0_5_bar.xml new file mode 100644 index 000000000..751f41b79 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_signal_cellular_0_5_bar.xml @@ -0,0 +1,183 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_signal_cellular_1_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..531a080a4 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,183 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_signal_cellular_1_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_signal_cellular_1_5_bar.xml new file mode 100644 index 000000000..531a080a4 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_signal_cellular_1_5_bar.xml @@ -0,0 +1,183 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_signal_cellular_2_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..c9e74bc8d --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,183 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_signal_cellular_2_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_signal_cellular_2_5_bar.xml new file mode 100644 index 000000000..c9e74bc8d --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_signal_cellular_2_5_bar.xml @@ -0,0 +1,183 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_signal_cellular_3_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..9da5e2d31 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,183 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_signal_cellular_3_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_signal_cellular_3_5_bar.xml new file mode 100644 index 000000000..9da5e2d31 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_signal_cellular_3_5_bar.xml @@ -0,0 +1,183 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_signal_cellular_4_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..6c8b26399 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,183 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_signal_cellular_4_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_signal_cellular_4_5_bar.xml new file mode 100644 index 000000000..6c8b26399 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_signal_cellular_4_5_bar.xml @@ -0,0 +1,183 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_signal_cellular_5_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_signal_cellular_5_5_bar.xml new file mode 100644 index 000000000..6c8b26399 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC15/res/drawable/ic_signal_cellular_5_5_bar.xml @@ -0,0 +1,183 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC16/res/drawable/ic_signal_cellular_0_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC16/res/drawable/ic_signal_cellular_0_4_bar.xml new file mode 100644 index 000000000..b3184f3c0 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC16/res/drawable/ic_signal_cellular_0_4_bar.xml @@ -0,0 +1,21 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC16/res/drawable/ic_signal_cellular_0_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC16/res/drawable/ic_signal_cellular_0_5_bar.xml new file mode 100644 index 000000000..b3184f3c0 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC16/res/drawable/ic_signal_cellular_0_5_bar.xml @@ -0,0 +1,21 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC16/res/drawable/ic_signal_cellular_1_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC16/res/drawable/ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..aceafa1c8 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC16/res/drawable/ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,21 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC16/res/drawable/ic_signal_cellular_1_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC16/res/drawable/ic_signal_cellular_1_5_bar.xml new file mode 100644 index 000000000..aceafa1c8 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC16/res/drawable/ic_signal_cellular_1_5_bar.xml @@ -0,0 +1,21 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC16/res/drawable/ic_signal_cellular_2_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC16/res/drawable/ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..dcfadbe81 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC16/res/drawable/ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,21 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC16/res/drawable/ic_signal_cellular_2_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC16/res/drawable/ic_signal_cellular_2_5_bar.xml new file mode 100644 index 000000000..dcfadbe81 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC16/res/drawable/ic_signal_cellular_2_5_bar.xml @@ -0,0 +1,21 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC16/res/drawable/ic_signal_cellular_3_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC16/res/drawable/ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..8407c90b2 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC16/res/drawable/ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,21 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC16/res/drawable/ic_signal_cellular_3_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC16/res/drawable/ic_signal_cellular_3_5_bar.xml new file mode 100644 index 000000000..8407c90b2 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC16/res/drawable/ic_signal_cellular_3_5_bar.xml @@ -0,0 +1,21 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC16/res/drawable/ic_signal_cellular_4_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC16/res/drawable/ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..3c485ea27 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC16/res/drawable/ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,21 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC16/res/drawable/ic_signal_cellular_4_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC16/res/drawable/ic_signal_cellular_4_5_bar.xml new file mode 100644 index 000000000..3c485ea27 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC16/res/drawable/ic_signal_cellular_4_5_bar.xml @@ -0,0 +1,21 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC16/res/drawable/ic_signal_cellular_5_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC16/res/drawable/ic_signal_cellular_5_5_bar.xml new file mode 100644 index 000000000..3c485ea27 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC16/res/drawable/ic_signal_cellular_5_5_bar.xml @@ -0,0 +1,21 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC17/res/drawable/ic_signal_cellular_0_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC17/res/drawable/ic_signal_cellular_0_4_bar.xml new file mode 100644 index 000000000..f1c0efb42 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC17/res/drawable/ic_signal_cellular_0_4_bar.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC17/res/drawable/ic_signal_cellular_0_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC17/res/drawable/ic_signal_cellular_0_5_bar.xml new file mode 100644 index 000000000..f1c0efb42 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC17/res/drawable/ic_signal_cellular_0_5_bar.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC17/res/drawable/ic_signal_cellular_1_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC17/res/drawable/ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..785eacb11 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC17/res/drawable/ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC17/res/drawable/ic_signal_cellular_1_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC17/res/drawable/ic_signal_cellular_1_5_bar.xml new file mode 100644 index 000000000..785eacb11 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC17/res/drawable/ic_signal_cellular_1_5_bar.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC17/res/drawable/ic_signal_cellular_2_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC17/res/drawable/ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..07de2487d --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC17/res/drawable/ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC17/res/drawable/ic_signal_cellular_2_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC17/res/drawable/ic_signal_cellular_2_5_bar.xml new file mode 100644 index 000000000..0a24a937d --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC17/res/drawable/ic_signal_cellular_2_5_bar.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC17/res/drawable/ic_signal_cellular_3_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC17/res/drawable/ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..0a24a937d --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC17/res/drawable/ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC17/res/drawable/ic_signal_cellular_3_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC17/res/drawable/ic_signal_cellular_3_5_bar.xml new file mode 100644 index 000000000..07de2487d --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC17/res/drawable/ic_signal_cellular_3_5_bar.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC17/res/drawable/ic_signal_cellular_4_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC17/res/drawable/ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..1333943e8 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC17/res/drawable/ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC17/res/drawable/ic_signal_cellular_4_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC17/res/drawable/ic_signal_cellular_4_5_bar.xml new file mode 100644 index 000000000..1333943e8 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC17/res/drawable/ic_signal_cellular_4_5_bar.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC17/res/drawable/ic_signal_cellular_5_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC17/res/drawable/ic_signal_cellular_5_5_bar.xml new file mode 100644 index 000000000..1333943e8 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC17/res/drawable/ic_signal_cellular_5_5_bar.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC18/res/drawable/ic_signal_cellular_0_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC18/res/drawable/ic_signal_cellular_0_4_bar.xml new file mode 100644 index 000000000..148a4f0ae --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC18/res/drawable/ic_signal_cellular_0_4_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC18/res/drawable/ic_signal_cellular_0_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC18/res/drawable/ic_signal_cellular_0_5_bar.xml new file mode 100644 index 000000000..148a4f0ae --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC18/res/drawable/ic_signal_cellular_0_5_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC18/res/drawable/ic_signal_cellular_1_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC18/res/drawable/ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..579843a31 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC18/res/drawable/ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC18/res/drawable/ic_signal_cellular_1_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC18/res/drawable/ic_signal_cellular_1_5_bar.xml new file mode 100644 index 000000000..579843a31 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC18/res/drawable/ic_signal_cellular_1_5_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC18/res/drawable/ic_signal_cellular_2_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC18/res/drawable/ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..0284f9ea2 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC18/res/drawable/ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC18/res/drawable/ic_signal_cellular_2_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC18/res/drawable/ic_signal_cellular_2_5_bar.xml new file mode 100644 index 000000000..0284f9ea2 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC18/res/drawable/ic_signal_cellular_2_5_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC18/res/drawable/ic_signal_cellular_3_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC18/res/drawable/ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..49dce55ce --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC18/res/drawable/ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC18/res/drawable/ic_signal_cellular_3_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC18/res/drawable/ic_signal_cellular_3_5_bar.xml new file mode 100644 index 000000000..49dce55ce --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC18/res/drawable/ic_signal_cellular_3_5_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC18/res/drawable/ic_signal_cellular_4_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC18/res/drawable/ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..c6cc45a68 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC18/res/drawable/ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC18/res/drawable/ic_signal_cellular_4_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC18/res/drawable/ic_signal_cellular_4_5_bar.xml new file mode 100644 index 000000000..c6cc45a68 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC18/res/drawable/ic_signal_cellular_4_5_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC18/res/drawable/ic_signal_cellular_5_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC18/res/drawable/ic_signal_cellular_5_5_bar.xml new file mode 100644 index 000000000..c6cc45a68 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC18/res/drawable/ic_signal_cellular_5_5_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC19/res/drawable/ic_signal_cellular_0_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC19/res/drawable/ic_signal_cellular_0_4_bar.xml new file mode 100644 index 000000000..991a4621f --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC19/res/drawable/ic_signal_cellular_0_4_bar.xml @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC19/res/drawable/ic_signal_cellular_0_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC19/res/drawable/ic_signal_cellular_0_5_bar.xml new file mode 100644 index 000000000..991a4621f --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC19/res/drawable/ic_signal_cellular_0_5_bar.xml @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC19/res/drawable/ic_signal_cellular_1_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC19/res/drawable/ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..57cf89631 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC19/res/drawable/ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC19/res/drawable/ic_signal_cellular_1_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC19/res/drawable/ic_signal_cellular_1_5_bar.xml new file mode 100644 index 000000000..57cf89631 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC19/res/drawable/ic_signal_cellular_1_5_bar.xml @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC19/res/drawable/ic_signal_cellular_2_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC19/res/drawable/ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..d609fdc79 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC19/res/drawable/ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC19/res/drawable/ic_signal_cellular_2_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC19/res/drawable/ic_signal_cellular_2_5_bar.xml new file mode 100644 index 000000000..d609fdc79 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC19/res/drawable/ic_signal_cellular_2_5_bar.xml @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC19/res/drawable/ic_signal_cellular_3_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC19/res/drawable/ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..f291f636e --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC19/res/drawable/ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC19/res/drawable/ic_signal_cellular_3_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC19/res/drawable/ic_signal_cellular_3_5_bar.xml new file mode 100644 index 000000000..f291f636e --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC19/res/drawable/ic_signal_cellular_3_5_bar.xml @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC19/res/drawable/ic_signal_cellular_4_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC19/res/drawable/ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..fbe8dbc5c --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC19/res/drawable/ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC19/res/drawable/ic_signal_cellular_4_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC19/res/drawable/ic_signal_cellular_4_5_bar.xml new file mode 100644 index 000000000..fbe8dbc5c --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC19/res/drawable/ic_signal_cellular_4_5_bar.xml @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC19/res/drawable/ic_signal_cellular_5_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC19/res/drawable/ic_signal_cellular_5_5_bar.xml new file mode 100644 index 000000000..fbe8dbc5c --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC19/res/drawable/ic_signal_cellular_5_5_bar.xml @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_1x_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_1x_mobiledata.xml new file mode 100644 index 000000000..926bb3490 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_1x_mobiledata.xml @@ -0,0 +1,46 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_3g_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_3g_mobiledata.xml new file mode 100644 index 000000000..e4bf66a40 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_3g_mobiledata.xml @@ -0,0 +1,38 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_4g_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_4g_mobiledata.xml new file mode 100644 index 000000000..4a6497c26 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_4g_mobiledata.xml @@ -0,0 +1,46 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_4g_plus_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_4g_plus_mobiledata.xml new file mode 100644 index 000000000..cc53478fa --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_4g_plus_mobiledata.xml @@ -0,0 +1,62 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_5g_e_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_5g_e_mobiledata.xml new file mode 100644 index 000000000..f2f842bb8 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_5g_e_mobiledata.xml @@ -0,0 +1,54 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_5g_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_5g_mobiledata.xml new file mode 100644 index 000000000..71f201fe0 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_5g_mobiledata.xml @@ -0,0 +1,38 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_5g_plus_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_5g_plus_mobiledata.xml new file mode 100644 index 000000000..e39ea5879 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_5g_plus_mobiledata.xml @@ -0,0 +1,54 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_5g_uc_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_5g_uc_mobiledata.xml new file mode 100644 index 000000000..71f201fe0 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_5g_uc_mobiledata.xml @@ -0,0 +1,38 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_5g_uw_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_5g_uw_mobiledata.xml new file mode 100644 index 000000000..71f201fe0 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_5g_uw_mobiledata.xml @@ -0,0 +1,38 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_e_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_e_mobiledata.xml new file mode 100644 index 000000000..adb8b8e50 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_e_mobiledata.xml @@ -0,0 +1,38 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_g_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_g_mobiledata.xml new file mode 100644 index 000000000..c68267042 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_g_mobiledata.xml @@ -0,0 +1,30 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_h_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_h_mobiledata.xml new file mode 100644 index 000000000..71e635477 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_h_mobiledata.xml @@ -0,0 +1,46 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_h_plus_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_h_plus_mobiledata.xml new file mode 100644 index 000000000..59fdfe45b --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_h_plus_mobiledata.xml @@ -0,0 +1,62 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_lte_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_lte_mobiledata.xml new file mode 100644 index 000000000..b9e4bdd7f --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_lte_mobiledata.xml @@ -0,0 +1,62 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_lte_plus_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_lte_plus_mobiledata.xml new file mode 100644 index 000000000..347a152be --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_lte_plus_mobiledata.xml @@ -0,0 +1,78 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_signal_cellular_0_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_signal_cellular_0_4_bar.xml new file mode 100644 index 000000000..01ed78578 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_signal_cellular_0_4_bar.xml @@ -0,0 +1,14 @@ + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_signal_cellular_0_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_signal_cellular_0_5_bar.xml new file mode 100644 index 000000000..01ed78578 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_signal_cellular_0_5_bar.xml @@ -0,0 +1,14 @@ + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_signal_cellular_1_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..add7e5812 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,22 @@ + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_signal_cellular_1_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_signal_cellular_1_5_bar.xml new file mode 100644 index 000000000..add7e5812 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_signal_cellular_1_5_bar.xml @@ -0,0 +1,22 @@ + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_signal_cellular_2_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..c4a9923ea --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,30 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_signal_cellular_2_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_signal_cellular_2_5_bar.xml new file mode 100644 index 000000000..c4a9923ea --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_signal_cellular_2_5_bar.xml @@ -0,0 +1,30 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_signal_cellular_3_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..88825e53a --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,38 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_signal_cellular_3_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_signal_cellular_3_5_bar.xml new file mode 100644 index 000000000..88825e53a --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_signal_cellular_3_5_bar.xml @@ -0,0 +1,38 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_signal_cellular_4_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..e65bc2f95 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,38 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_signal_cellular_4_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_signal_cellular_4_5_bar.xml new file mode 100644 index 000000000..e65bc2f95 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_signal_cellular_4_5_bar.xml @@ -0,0 +1,38 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_signal_cellular_5_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_signal_cellular_5_5_bar.xml new file mode 100644 index 000000000..e65bc2f95 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC2/res/drawable/ic_signal_cellular_5_5_bar.xml @@ -0,0 +1,38 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC20/res/drawable/ic_signal_cellular_0_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC20/res/drawable/ic_signal_cellular_0_4_bar.xml new file mode 100644 index 000000000..af92178ce --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC20/res/drawable/ic_signal_cellular_0_4_bar.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC20/res/drawable/ic_signal_cellular_0_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC20/res/drawable/ic_signal_cellular_0_5_bar.xml new file mode 100644 index 000000000..af92178ce --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC20/res/drawable/ic_signal_cellular_0_5_bar.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC20/res/drawable/ic_signal_cellular_1_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC20/res/drawable/ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..4cefd75ae --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC20/res/drawable/ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC20/res/drawable/ic_signal_cellular_1_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC20/res/drawable/ic_signal_cellular_1_5_bar.xml new file mode 100644 index 000000000..4cefd75ae --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC20/res/drawable/ic_signal_cellular_1_5_bar.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC20/res/drawable/ic_signal_cellular_2_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC20/res/drawable/ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..c03935468 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC20/res/drawable/ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC20/res/drawable/ic_signal_cellular_2_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC20/res/drawable/ic_signal_cellular_2_5_bar.xml new file mode 100644 index 000000000..c03935468 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC20/res/drawable/ic_signal_cellular_2_5_bar.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC20/res/drawable/ic_signal_cellular_3_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC20/res/drawable/ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..3bfb02198 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC20/res/drawable/ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC20/res/drawable/ic_signal_cellular_3_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC20/res/drawable/ic_signal_cellular_3_5_bar.xml new file mode 100644 index 000000000..3bfb02198 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC20/res/drawable/ic_signal_cellular_3_5_bar.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC20/res/drawable/ic_signal_cellular_4_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC20/res/drawable/ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..2f0a9bf75 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC20/res/drawable/ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC20/res/drawable/ic_signal_cellular_4_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC20/res/drawable/ic_signal_cellular_4_5_bar.xml new file mode 100644 index 000000000..2f0a9bf75 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC20/res/drawable/ic_signal_cellular_4_5_bar.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC20/res/drawable/ic_signal_cellular_5_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC20/res/drawable/ic_signal_cellular_5_5_bar.xml new file mode 100644 index 000000000..2f0a9bf75 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC20/res/drawable/ic_signal_cellular_5_5_bar.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC20/res/drawable/ic_signal_location.xml b/app/src/main/assets/Overlays/android/SGIC20/res/drawable/ic_signal_location.xml new file mode 100644 index 000000000..5d10df06a --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC20/res/drawable/ic_signal_location.xml @@ -0,0 +1,4 @@ + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC21/res/drawable/ic_signal_cellular_0_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC21/res/drawable/ic_signal_cellular_0_4_bar.xml new file mode 100644 index 000000000..e9aa8e2e9 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC21/res/drawable/ic_signal_cellular_0_4_bar.xml @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC21/res/drawable/ic_signal_cellular_0_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC21/res/drawable/ic_signal_cellular_0_5_bar.xml new file mode 100644 index 000000000..e9aa8e2e9 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC21/res/drawable/ic_signal_cellular_0_5_bar.xml @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC21/res/drawable/ic_signal_cellular_1_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC21/res/drawable/ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..1fa47ca92 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC21/res/drawable/ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC21/res/drawable/ic_signal_cellular_1_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC21/res/drawable/ic_signal_cellular_1_5_bar.xml new file mode 100644 index 000000000..1fa47ca92 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC21/res/drawable/ic_signal_cellular_1_5_bar.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC21/res/drawable/ic_signal_cellular_2_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC21/res/drawable/ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..60c215086 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC21/res/drawable/ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC21/res/drawable/ic_signal_cellular_2_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC21/res/drawable/ic_signal_cellular_2_5_bar.xml new file mode 100644 index 000000000..60c215086 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC21/res/drawable/ic_signal_cellular_2_5_bar.xml @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC21/res/drawable/ic_signal_cellular_3_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC21/res/drawable/ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..a11914a63 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC21/res/drawable/ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC21/res/drawable/ic_signal_cellular_3_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC21/res/drawable/ic_signal_cellular_3_5_bar.xml new file mode 100644 index 000000000..a11914a63 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC21/res/drawable/ic_signal_cellular_3_5_bar.xml @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC21/res/drawable/ic_signal_cellular_4_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC21/res/drawable/ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..ba2da49b0 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC21/res/drawable/ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC21/res/drawable/ic_signal_cellular_4_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC21/res/drawable/ic_signal_cellular_4_5_bar.xml new file mode 100644 index 000000000..ba2da49b0 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC21/res/drawable/ic_signal_cellular_4_5_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC21/res/drawable/ic_signal_cellular_5_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC21/res/drawable/ic_signal_cellular_5_5_bar.xml new file mode 100644 index 000000000..ba2da49b0 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC21/res/drawable/ic_signal_cellular_5_5_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC22/res/drawable/ic_signal_cellular_0_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC22/res/drawable/ic_signal_cellular_0_4_bar.xml new file mode 100644 index 000000000..ee33520fc --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC22/res/drawable/ic_signal_cellular_0_4_bar.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC22/res/drawable/ic_signal_cellular_0_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC22/res/drawable/ic_signal_cellular_0_5_bar.xml new file mode 100644 index 000000000..ee33520fc --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC22/res/drawable/ic_signal_cellular_0_5_bar.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC22/res/drawable/ic_signal_cellular_1_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC22/res/drawable/ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..b9178b2f4 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC22/res/drawable/ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC22/res/drawable/ic_signal_cellular_1_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC22/res/drawable/ic_signal_cellular_1_5_bar.xml new file mode 100644 index 000000000..b9178b2f4 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC22/res/drawable/ic_signal_cellular_1_5_bar.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC22/res/drawable/ic_signal_cellular_2_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC22/res/drawable/ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..3d12a6fd1 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC22/res/drawable/ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC22/res/drawable/ic_signal_cellular_2_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC22/res/drawable/ic_signal_cellular_2_5_bar.xml new file mode 100644 index 000000000..3d12a6fd1 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC22/res/drawable/ic_signal_cellular_2_5_bar.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC22/res/drawable/ic_signal_cellular_3_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC22/res/drawable/ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..590dd2c2e --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC22/res/drawable/ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC22/res/drawable/ic_signal_cellular_3_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC22/res/drawable/ic_signal_cellular_3_5_bar.xml new file mode 100644 index 000000000..590dd2c2e --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC22/res/drawable/ic_signal_cellular_3_5_bar.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC22/res/drawable/ic_signal_cellular_4_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC22/res/drawable/ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..74f9d4730 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC22/res/drawable/ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC22/res/drawable/ic_signal_cellular_4_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC22/res/drawable/ic_signal_cellular_4_5_bar.xml new file mode 100644 index 000000000..74f9d4730 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC22/res/drawable/ic_signal_cellular_4_5_bar.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC22/res/drawable/ic_signal_cellular_5_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC22/res/drawable/ic_signal_cellular_5_5_bar.xml new file mode 100644 index 000000000..74f9d4730 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC22/res/drawable/ic_signal_cellular_5_5_bar.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_1x_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_1x_mobiledata.xml new file mode 100644 index 000000000..fcab9e628 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_1x_mobiledata.xml @@ -0,0 +1,30 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_3g_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_3g_mobiledata.xml new file mode 100644 index 000000000..7d8f22d89 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_3g_mobiledata.xml @@ -0,0 +1,27 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_4g_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_4g_mobiledata.xml new file mode 100644 index 000000000..50073bdae --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_4g_mobiledata.xml @@ -0,0 +1,27 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_4g_plus_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_4g_plus_mobiledata.xml new file mode 100644 index 000000000..1c8e393ab --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_4g_plus_mobiledata.xml @@ -0,0 +1,37 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_5g_e_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_5g_e_mobiledata.xml new file mode 100644 index 000000000..bb771755f --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_5g_e_mobiledata.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_5g_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_5g_mobiledata.xml new file mode 100644 index 000000000..4030daa2f --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_5g_mobiledata.xml @@ -0,0 +1,27 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_5g_plus_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_5g_plus_mobiledata.xml new file mode 100644 index 000000000..d4fa9acc9 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_5g_plus_mobiledata.xml @@ -0,0 +1,37 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_5g_uc_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_5g_uc_mobiledata.xml new file mode 100644 index 000000000..4030daa2f --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_5g_uc_mobiledata.xml @@ -0,0 +1,27 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_5g_uw_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_5g_uw_mobiledata.xml new file mode 100644 index 000000000..4030daa2f --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_5g_uw_mobiledata.xml @@ -0,0 +1,27 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_e_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_e_mobiledata.xml new file mode 100644 index 000000000..895593be1 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_e_mobiledata.xml @@ -0,0 +1,27 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_g_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_g_mobiledata.xml new file mode 100644 index 000000000..89a6470a1 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_g_mobiledata.xml @@ -0,0 +1,17 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_h_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_h_mobiledata.xml new file mode 100644 index 000000000..b0262ab8e --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_h_mobiledata.xml @@ -0,0 +1,22 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_h_plus_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_h_plus_mobiledata.xml new file mode 100644 index 000000000..945e8bde8 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_h_plus_mobiledata.xml @@ -0,0 +1,32 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_lte_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_lte_mobiledata.xml new file mode 100644 index 000000000..3fb88a30a --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_lte_mobiledata.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_lte_plus_mobiledata.xml b/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_lte_plus_mobiledata.xml new file mode 100644 index 000000000..6fdc6ac5d --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_lte_plus_mobiledata.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_signal_cellular_0_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_signal_cellular_0_4_bar.xml new file mode 100644 index 000000000..712c49391 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_signal_cellular_0_4_bar.xml @@ -0,0 +1,22 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_signal_cellular_0_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_signal_cellular_0_5_bar.xml new file mode 100644 index 000000000..712c49391 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_signal_cellular_0_5_bar.xml @@ -0,0 +1,22 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_signal_cellular_1_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..f08da03ca --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,22 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_signal_cellular_1_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_signal_cellular_1_5_bar.xml new file mode 100644 index 000000000..f08da03ca --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_signal_cellular_1_5_bar.xml @@ -0,0 +1,22 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_signal_cellular_2_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..900bbd66d --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,22 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_signal_cellular_2_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_signal_cellular_2_5_bar.xml new file mode 100644 index 000000000..9646f98a0 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_signal_cellular_2_5_bar.xml @@ -0,0 +1,27 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_signal_cellular_3_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..97dc06545 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,22 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_signal_cellular_3_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_signal_cellular_3_5_bar.xml new file mode 100644 index 000000000..900bbd66d --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_signal_cellular_3_5_bar.xml @@ -0,0 +1,22 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_signal_cellular_4_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..5e4c24270 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,22 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_signal_cellular_4_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_signal_cellular_4_5_bar.xml new file mode 100644 index 000000000..acf1ac807 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_signal_cellular_4_5_bar.xml @@ -0,0 +1,27 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_signal_cellular_5_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_signal_cellular_5_5_bar.xml new file mode 100644 index 000000000..5e4c24270 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC23/res/drawable/ic_signal_cellular_5_5_bar.xml @@ -0,0 +1,22 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC24/res/drawable/ic_signal_cellular_0_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC24/res/drawable/ic_signal_cellular_0_4_bar.xml new file mode 100644 index 000000000..36166b1b7 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC24/res/drawable/ic_signal_cellular_0_4_bar.xml @@ -0,0 +1,19 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC24/res/drawable/ic_signal_cellular_0_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC24/res/drawable/ic_signal_cellular_0_5_bar.xml new file mode 100644 index 000000000..36166b1b7 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC24/res/drawable/ic_signal_cellular_0_5_bar.xml @@ -0,0 +1,19 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC24/res/drawable/ic_signal_cellular_1_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC24/res/drawable/ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..e683bbefd --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC24/res/drawable/ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,19 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC24/res/drawable/ic_signal_cellular_1_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC24/res/drawable/ic_signal_cellular_1_5_bar.xml new file mode 100644 index 000000000..e683bbefd --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC24/res/drawable/ic_signal_cellular_1_5_bar.xml @@ -0,0 +1,19 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC24/res/drawable/ic_signal_cellular_2_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC24/res/drawable/ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..e75b2a6d5 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC24/res/drawable/ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,19 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC24/res/drawable/ic_signal_cellular_2_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC24/res/drawable/ic_signal_cellular_2_5_bar.xml new file mode 100644 index 000000000..e75b2a6d5 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC24/res/drawable/ic_signal_cellular_2_5_bar.xml @@ -0,0 +1,19 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC24/res/drawable/ic_signal_cellular_3_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC24/res/drawable/ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..50f76bd71 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC24/res/drawable/ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,19 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC24/res/drawable/ic_signal_cellular_3_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC24/res/drawable/ic_signal_cellular_3_5_bar.xml new file mode 100644 index 000000000..50f76bd71 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC24/res/drawable/ic_signal_cellular_3_5_bar.xml @@ -0,0 +1,19 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC24/res/drawable/ic_signal_cellular_4_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC24/res/drawable/ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..4f18862b0 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC24/res/drawable/ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,19 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC24/res/drawable/ic_signal_cellular_4_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC24/res/drawable/ic_signal_cellular_4_5_bar.xml new file mode 100644 index 000000000..4f18862b0 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC24/res/drawable/ic_signal_cellular_4_5_bar.xml @@ -0,0 +1,19 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC24/res/drawable/ic_signal_cellular_5_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC24/res/drawable/ic_signal_cellular_5_5_bar.xml new file mode 100644 index 000000000..4f18862b0 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC24/res/drawable/ic_signal_cellular_5_5_bar.xml @@ -0,0 +1,19 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC25/res/drawable/ic_signal_cellular_0_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC25/res/drawable/ic_signal_cellular_0_4_bar.xml new file mode 100644 index 000000000..d4883b2f8 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC25/res/drawable/ic_signal_cellular_0_4_bar.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC25/res/drawable/ic_signal_cellular_0_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC25/res/drawable/ic_signal_cellular_0_5_bar.xml new file mode 100644 index 000000000..d4883b2f8 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC25/res/drawable/ic_signal_cellular_0_5_bar.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC25/res/drawable/ic_signal_cellular_1_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC25/res/drawable/ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..e4eb791c5 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC25/res/drawable/ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC25/res/drawable/ic_signal_cellular_1_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC25/res/drawable/ic_signal_cellular_1_5_bar.xml new file mode 100644 index 000000000..e4eb791c5 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC25/res/drawable/ic_signal_cellular_1_5_bar.xml @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC25/res/drawable/ic_signal_cellular_2_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC25/res/drawable/ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..2ce739f0c --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC25/res/drawable/ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC25/res/drawable/ic_signal_cellular_2_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC25/res/drawable/ic_signal_cellular_2_5_bar.xml new file mode 100644 index 000000000..2ce739f0c --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC25/res/drawable/ic_signal_cellular_2_5_bar.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC25/res/drawable/ic_signal_cellular_3_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC25/res/drawable/ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..6e33da8da --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC25/res/drawable/ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC25/res/drawable/ic_signal_cellular_3_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC25/res/drawable/ic_signal_cellular_3_5_bar.xml new file mode 100644 index 000000000..6e33da8da --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC25/res/drawable/ic_signal_cellular_3_5_bar.xml @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC25/res/drawable/ic_signal_cellular_4_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC25/res/drawable/ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..a36c4b048 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC25/res/drawable/ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC25/res/drawable/ic_signal_cellular_4_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC25/res/drawable/ic_signal_cellular_4_5_bar.xml new file mode 100644 index 000000000..a36c4b048 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC25/res/drawable/ic_signal_cellular_4_5_bar.xml @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC25/res/drawable/ic_signal_cellular_5_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC25/res/drawable/ic_signal_cellular_5_5_bar.xml new file mode 100644 index 000000000..c8033e14d --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC25/res/drawable/ic_signal_cellular_5_5_bar.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC26/res/drawable/ic_signal_cellular_0_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC26/res/drawable/ic_signal_cellular_0_4_bar.xml new file mode 100644 index 000000000..df71163ce --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC26/res/drawable/ic_signal_cellular_0_4_bar.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC26/res/drawable/ic_signal_cellular_0_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC26/res/drawable/ic_signal_cellular_0_5_bar.xml new file mode 100644 index 000000000..df71163ce --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC26/res/drawable/ic_signal_cellular_0_5_bar.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC26/res/drawable/ic_signal_cellular_1_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC26/res/drawable/ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..6ea3f7147 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC26/res/drawable/ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC26/res/drawable/ic_signal_cellular_1_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC26/res/drawable/ic_signal_cellular_1_5_bar.xml new file mode 100644 index 000000000..6ea3f7147 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC26/res/drawable/ic_signal_cellular_1_5_bar.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC26/res/drawable/ic_signal_cellular_2_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC26/res/drawable/ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..7d8ba2f21 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC26/res/drawable/ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC26/res/drawable/ic_signal_cellular_2_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC26/res/drawable/ic_signal_cellular_2_5_bar.xml new file mode 100644 index 000000000..7d8ba2f21 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC26/res/drawable/ic_signal_cellular_2_5_bar.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC26/res/drawable/ic_signal_cellular_3_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC26/res/drawable/ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..db5411db2 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC26/res/drawable/ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC26/res/drawable/ic_signal_cellular_3_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC26/res/drawable/ic_signal_cellular_3_5_bar.xml new file mode 100644 index 000000000..db5411db2 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC26/res/drawable/ic_signal_cellular_3_5_bar.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC26/res/drawable/ic_signal_cellular_4_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC26/res/drawable/ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..29c3ea284 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC26/res/drawable/ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC26/res/drawable/ic_signal_cellular_4_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC26/res/drawable/ic_signal_cellular_4_5_bar.xml new file mode 100644 index 000000000..29c3ea284 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC26/res/drawable/ic_signal_cellular_4_5_bar.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC26/res/drawable/ic_signal_cellular_5_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC26/res/drawable/ic_signal_cellular_5_5_bar.xml new file mode 100644 index 000000000..29c3ea284 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC26/res/drawable/ic_signal_cellular_5_5_bar.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC27/res/drawable/ic_signal_cellular_0_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC27/res/drawable/ic_signal_cellular_0_4_bar.xml new file mode 100644 index 000000000..bd435406d --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC27/res/drawable/ic_signal_cellular_0_4_bar.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC27/res/drawable/ic_signal_cellular_0_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC27/res/drawable/ic_signal_cellular_0_5_bar.xml new file mode 100644 index 000000000..bd435406d --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC27/res/drawable/ic_signal_cellular_0_5_bar.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC27/res/drawable/ic_signal_cellular_1_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC27/res/drawable/ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..6164e201b --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC27/res/drawable/ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC27/res/drawable/ic_signal_cellular_1_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC27/res/drawable/ic_signal_cellular_1_5_bar.xml new file mode 100644 index 000000000..6164e201b --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC27/res/drawable/ic_signal_cellular_1_5_bar.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC27/res/drawable/ic_signal_cellular_2_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC27/res/drawable/ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..e771017df --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC27/res/drawable/ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC27/res/drawable/ic_signal_cellular_2_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC27/res/drawable/ic_signal_cellular_2_5_bar.xml new file mode 100644 index 000000000..e771017df --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC27/res/drawable/ic_signal_cellular_2_5_bar.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC27/res/drawable/ic_signal_cellular_3_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC27/res/drawable/ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..8934ed54f --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC27/res/drawable/ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC27/res/drawable/ic_signal_cellular_3_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC27/res/drawable/ic_signal_cellular_3_5_bar.xml new file mode 100644 index 000000000..8934ed54f --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC27/res/drawable/ic_signal_cellular_3_5_bar.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC27/res/drawable/ic_signal_cellular_4_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC27/res/drawable/ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..52285595a --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC27/res/drawable/ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC27/res/drawable/ic_signal_cellular_4_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC27/res/drawable/ic_signal_cellular_4_5_bar.xml new file mode 100644 index 000000000..52285595a --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC27/res/drawable/ic_signal_cellular_4_5_bar.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC27/res/drawable/ic_signal_cellular_5_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC27/res/drawable/ic_signal_cellular_5_5_bar.xml new file mode 100644 index 000000000..52285595a --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC27/res/drawable/ic_signal_cellular_5_5_bar.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC28/res/drawable/ic_signal_cellular_0_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC28/res/drawable/ic_signal_cellular_0_4_bar.xml new file mode 100644 index 000000000..079641719 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC28/res/drawable/ic_signal_cellular_0_4_bar.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC28/res/drawable/ic_signal_cellular_0_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC28/res/drawable/ic_signal_cellular_0_5_bar.xml new file mode 100644 index 000000000..079641719 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC28/res/drawable/ic_signal_cellular_0_5_bar.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC28/res/drawable/ic_signal_cellular_1_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC28/res/drawable/ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..4c767ccba --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC28/res/drawable/ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC28/res/drawable/ic_signal_cellular_1_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC28/res/drawable/ic_signal_cellular_1_5_bar.xml new file mode 100644 index 000000000..4c767ccba --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC28/res/drawable/ic_signal_cellular_1_5_bar.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC28/res/drawable/ic_signal_cellular_2_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC28/res/drawable/ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..561b1fd55 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC28/res/drawable/ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC28/res/drawable/ic_signal_cellular_2_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC28/res/drawable/ic_signal_cellular_2_5_bar.xml new file mode 100644 index 000000000..561b1fd55 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC28/res/drawable/ic_signal_cellular_2_5_bar.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC28/res/drawable/ic_signal_cellular_3_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC28/res/drawable/ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..53c8458db --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC28/res/drawable/ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC28/res/drawable/ic_signal_cellular_3_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC28/res/drawable/ic_signal_cellular_3_5_bar.xml new file mode 100644 index 000000000..53c8458db --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC28/res/drawable/ic_signal_cellular_3_5_bar.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC28/res/drawable/ic_signal_cellular_4_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC28/res/drawable/ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..9f93ea0b8 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC28/res/drawable/ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC28/res/drawable/ic_signal_cellular_4_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC28/res/drawable/ic_signal_cellular_4_5_bar.xml new file mode 100644 index 000000000..d51c89c81 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC28/res/drawable/ic_signal_cellular_4_5_bar.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC28/res/drawable/ic_signal_cellular_5_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC28/res/drawable/ic_signal_cellular_5_5_bar.xml new file mode 100644 index 000000000..d51c89c81 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC28/res/drawable/ic_signal_cellular_5_5_bar.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC29/res/drawable/ic_signal_cellular_0_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC29/res/drawable/ic_signal_cellular_0_4_bar.xml new file mode 100644 index 000000000..689d5664d --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC29/res/drawable/ic_signal_cellular_0_4_bar.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC29/res/drawable/ic_signal_cellular_0_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC29/res/drawable/ic_signal_cellular_0_5_bar.xml new file mode 100644 index 000000000..689d5664d --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC29/res/drawable/ic_signal_cellular_0_5_bar.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC29/res/drawable/ic_signal_cellular_1_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC29/res/drawable/ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..2d71803c7 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC29/res/drawable/ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC29/res/drawable/ic_signal_cellular_1_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC29/res/drawable/ic_signal_cellular_1_5_bar.xml new file mode 100644 index 000000000..2d71803c7 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC29/res/drawable/ic_signal_cellular_1_5_bar.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC29/res/drawable/ic_signal_cellular_2_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC29/res/drawable/ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..72f83cf96 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC29/res/drawable/ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC29/res/drawable/ic_signal_cellular_2_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC29/res/drawable/ic_signal_cellular_2_5_bar.xml new file mode 100644 index 000000000..72f83cf96 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC29/res/drawable/ic_signal_cellular_2_5_bar.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC29/res/drawable/ic_signal_cellular_3_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC29/res/drawable/ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..c2af388b9 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC29/res/drawable/ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC29/res/drawable/ic_signal_cellular_3_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC29/res/drawable/ic_signal_cellular_3_5_bar.xml new file mode 100644 index 000000000..c2af388b9 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC29/res/drawable/ic_signal_cellular_3_5_bar.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC29/res/drawable/ic_signal_cellular_4_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC29/res/drawable/ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..04d4d2702 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC29/res/drawable/ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC29/res/drawable/ic_signal_cellular_4_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC29/res/drawable/ic_signal_cellular_4_5_bar.xml new file mode 100644 index 000000000..04d4d2702 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC29/res/drawable/ic_signal_cellular_4_5_bar.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC29/res/drawable/ic_signal_cellular_5_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC29/res/drawable/ic_signal_cellular_5_5_bar.xml new file mode 100644 index 000000000..04d4d2702 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC29/res/drawable/ic_signal_cellular_5_5_bar.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC3/res/drawable/ic_signal_cellular_0_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC3/res/drawable/ic_signal_cellular_0_4_bar.xml new file mode 100644 index 000000000..38b31011a --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC3/res/drawable/ic_signal_cellular_0_4_bar.xml @@ -0,0 +1,10 @@ + + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC3/res/drawable/ic_signal_cellular_0_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC3/res/drawable/ic_signal_cellular_0_5_bar.xml new file mode 100644 index 000000000..38b31011a --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC3/res/drawable/ic_signal_cellular_0_5_bar.xml @@ -0,0 +1,10 @@ + + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC3/res/drawable/ic_signal_cellular_1_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC3/res/drawable/ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..1ecbce706 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC3/res/drawable/ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,9 @@ + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC3/res/drawable/ic_signal_cellular_1_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC3/res/drawable/ic_signal_cellular_1_5_bar.xml new file mode 100644 index 000000000..1ecbce706 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC3/res/drawable/ic_signal_cellular_1_5_bar.xml @@ -0,0 +1,9 @@ + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC3/res/drawable/ic_signal_cellular_2_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC3/res/drawable/ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..7b7b7ec05 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC3/res/drawable/ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,9 @@ + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC3/res/drawable/ic_signal_cellular_2_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC3/res/drawable/ic_signal_cellular_2_5_bar.xml new file mode 100644 index 000000000..7b7b7ec05 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC3/res/drawable/ic_signal_cellular_2_5_bar.xml @@ -0,0 +1,9 @@ + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC3/res/drawable/ic_signal_cellular_3_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC3/res/drawable/ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..28bcab505 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC3/res/drawable/ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,9 @@ + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC3/res/drawable/ic_signal_cellular_3_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC3/res/drawable/ic_signal_cellular_3_5_bar.xml new file mode 100644 index 000000000..28bcab505 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC3/res/drawable/ic_signal_cellular_3_5_bar.xml @@ -0,0 +1,9 @@ + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC3/res/drawable/ic_signal_cellular_4_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC3/res/drawable/ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..06c36c0fd --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC3/res/drawable/ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,9 @@ + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC3/res/drawable/ic_signal_cellular_4_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC3/res/drawable/ic_signal_cellular_4_5_bar.xml new file mode 100644 index 000000000..06c36c0fd --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC3/res/drawable/ic_signal_cellular_4_5_bar.xml @@ -0,0 +1,9 @@ + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC3/res/drawable/ic_signal_cellular_5_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC3/res/drawable/ic_signal_cellular_5_5_bar.xml new file mode 100644 index 000000000..06c36c0fd --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC3/res/drawable/ic_signal_cellular_5_5_bar.xml @@ -0,0 +1,9 @@ + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC30/res/drawable/ic_signal_cellular_0_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC30/res/drawable/ic_signal_cellular_0_4_bar.xml new file mode 100644 index 000000000..ab2c36147 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC30/res/drawable/ic_signal_cellular_0_4_bar.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC30/res/drawable/ic_signal_cellular_0_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC30/res/drawable/ic_signal_cellular_0_5_bar.xml new file mode 100644 index 000000000..ab2c36147 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC30/res/drawable/ic_signal_cellular_0_5_bar.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC30/res/drawable/ic_signal_cellular_1_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC30/res/drawable/ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..016a3a8fc --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC30/res/drawable/ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC30/res/drawable/ic_signal_cellular_1_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC30/res/drawable/ic_signal_cellular_1_5_bar.xml new file mode 100644 index 000000000..a4e13b2a5 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC30/res/drawable/ic_signal_cellular_1_5_bar.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC30/res/drawable/ic_signal_cellular_2_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC30/res/drawable/ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..71f52d4bd --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC30/res/drawable/ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC30/res/drawable/ic_signal_cellular_2_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC30/res/drawable/ic_signal_cellular_2_5_bar.xml new file mode 100644 index 000000000..71f52d4bd --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC30/res/drawable/ic_signal_cellular_2_5_bar.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC30/res/drawable/ic_signal_cellular_3_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC30/res/drawable/ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..852c1dac1 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC30/res/drawable/ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC30/res/drawable/ic_signal_cellular_3_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC30/res/drawable/ic_signal_cellular_3_5_bar.xml new file mode 100644 index 000000000..852c1dac1 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC30/res/drawable/ic_signal_cellular_3_5_bar.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC30/res/drawable/ic_signal_cellular_4_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC30/res/drawable/ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..8f7b90a15 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC30/res/drawable/ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC30/res/drawable/ic_signal_cellular_4_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC30/res/drawable/ic_signal_cellular_4_5_bar.xml new file mode 100644 index 000000000..8f7b90a15 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC30/res/drawable/ic_signal_cellular_4_5_bar.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC30/res/drawable/ic_signal_cellular_5_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC30/res/drawable/ic_signal_cellular_5_5_bar.xml new file mode 100644 index 000000000..8f7b90a15 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC30/res/drawable/ic_signal_cellular_5_5_bar.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC31/res/drawable/ic_signal_cellular_0_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC31/res/drawable/ic_signal_cellular_0_4_bar.xml new file mode 100644 index 000000000..ebe7e8878 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC31/res/drawable/ic_signal_cellular_0_4_bar.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC31/res/drawable/ic_signal_cellular_0_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC31/res/drawable/ic_signal_cellular_0_5_bar.xml new file mode 100644 index 000000000..ebe7e8878 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC31/res/drawable/ic_signal_cellular_0_5_bar.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC31/res/drawable/ic_signal_cellular_1_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC31/res/drawable/ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..b149a1d54 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC31/res/drawable/ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC31/res/drawable/ic_signal_cellular_1_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC31/res/drawable/ic_signal_cellular_1_5_bar.xml new file mode 100644 index 000000000..b149a1d54 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC31/res/drawable/ic_signal_cellular_1_5_bar.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC31/res/drawable/ic_signal_cellular_2_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC31/res/drawable/ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..ceb7d5095 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC31/res/drawable/ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC31/res/drawable/ic_signal_cellular_2_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC31/res/drawable/ic_signal_cellular_2_5_bar.xml new file mode 100644 index 000000000..ceb7d5095 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC31/res/drawable/ic_signal_cellular_2_5_bar.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC31/res/drawable/ic_signal_cellular_3_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC31/res/drawable/ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..d355efa26 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC31/res/drawable/ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC31/res/drawable/ic_signal_cellular_3_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC31/res/drawable/ic_signal_cellular_3_5_bar.xml new file mode 100644 index 000000000..d355efa26 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC31/res/drawable/ic_signal_cellular_3_5_bar.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC31/res/drawable/ic_signal_cellular_4_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC31/res/drawable/ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..ffb465530 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC31/res/drawable/ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC31/res/drawable/ic_signal_cellular_4_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC31/res/drawable/ic_signal_cellular_4_5_bar.xml new file mode 100644 index 000000000..ffb465530 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC31/res/drawable/ic_signal_cellular_4_5_bar.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC31/res/drawable/ic_signal_cellular_5_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC31/res/drawable/ic_signal_cellular_5_5_bar.xml new file mode 100644 index 000000000..ffb465530 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC31/res/drawable/ic_signal_cellular_5_5_bar.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC32/res/drawable/ic_signal_cellular_0_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC32/res/drawable/ic_signal_cellular_0_4_bar.xml new file mode 100644 index 000000000..58c2ac214 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC32/res/drawable/ic_signal_cellular_0_4_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC32/res/drawable/ic_signal_cellular_0_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC32/res/drawable/ic_signal_cellular_0_5_bar.xml new file mode 100644 index 000000000..58c2ac214 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC32/res/drawable/ic_signal_cellular_0_5_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC32/res/drawable/ic_signal_cellular_1_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC32/res/drawable/ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..052a63233 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC32/res/drawable/ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC32/res/drawable/ic_signal_cellular_1_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC32/res/drawable/ic_signal_cellular_1_5_bar.xml new file mode 100644 index 000000000..052a63233 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC32/res/drawable/ic_signal_cellular_1_5_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC32/res/drawable/ic_signal_cellular_2_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC32/res/drawable/ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..64c1aff54 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC32/res/drawable/ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC32/res/drawable/ic_signal_cellular_2_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC32/res/drawable/ic_signal_cellular_2_5_bar.xml new file mode 100644 index 000000000..64c1aff54 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC32/res/drawable/ic_signal_cellular_2_5_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC32/res/drawable/ic_signal_cellular_3_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC32/res/drawable/ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..8b6edabe9 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC32/res/drawable/ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC32/res/drawable/ic_signal_cellular_3_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC32/res/drawable/ic_signal_cellular_3_5_bar.xml new file mode 100644 index 000000000..8b6edabe9 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC32/res/drawable/ic_signal_cellular_3_5_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC32/res/drawable/ic_signal_cellular_4_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC32/res/drawable/ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..1aa6aa09a --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC32/res/drawable/ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC32/res/drawable/ic_signal_cellular_4_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC32/res/drawable/ic_signal_cellular_4_5_bar.xml new file mode 100644 index 000000000..1aa6aa09a --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC32/res/drawable/ic_signal_cellular_4_5_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC32/res/drawable/ic_signal_cellular_5_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC32/res/drawable/ic_signal_cellular_5_5_bar.xml new file mode 100644 index 000000000..1aa6aa09a --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC32/res/drawable/ic_signal_cellular_5_5_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC33/res/drawable/ic_signal_cellular_0_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC33/res/drawable/ic_signal_cellular_0_4_bar.xml new file mode 100644 index 000000000..ea3d909f3 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC33/res/drawable/ic_signal_cellular_0_4_bar.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC33/res/drawable/ic_signal_cellular_0_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC33/res/drawable/ic_signal_cellular_0_5_bar.xml new file mode 100644 index 000000000..ea3d909f3 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC33/res/drawable/ic_signal_cellular_0_5_bar.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC33/res/drawable/ic_signal_cellular_1_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC33/res/drawable/ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..0c9074b83 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC33/res/drawable/ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC33/res/drawable/ic_signal_cellular_1_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC33/res/drawable/ic_signal_cellular_1_5_bar.xml new file mode 100644 index 000000000..0c9074b83 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC33/res/drawable/ic_signal_cellular_1_5_bar.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC33/res/drawable/ic_signal_cellular_2_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC33/res/drawable/ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..ac81a3de8 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC33/res/drawable/ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC33/res/drawable/ic_signal_cellular_2_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC33/res/drawable/ic_signal_cellular_2_5_bar.xml new file mode 100644 index 000000000..ac81a3de8 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC33/res/drawable/ic_signal_cellular_2_5_bar.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC33/res/drawable/ic_signal_cellular_3_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC33/res/drawable/ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..c2259b10b --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC33/res/drawable/ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC33/res/drawable/ic_signal_cellular_3_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC33/res/drawable/ic_signal_cellular_3_5_bar.xml new file mode 100644 index 000000000..c2259b10b --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC33/res/drawable/ic_signal_cellular_3_5_bar.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC33/res/drawable/ic_signal_cellular_4_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC33/res/drawable/ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..b71c4c6c7 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC33/res/drawable/ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC33/res/drawable/ic_signal_cellular_4_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC33/res/drawable/ic_signal_cellular_4_5_bar.xml new file mode 100644 index 000000000..b71c4c6c7 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC33/res/drawable/ic_signal_cellular_4_5_bar.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC33/res/drawable/ic_signal_cellular_5_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC33/res/drawable/ic_signal_cellular_5_5_bar.xml new file mode 100644 index 000000000..b71c4c6c7 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC33/res/drawable/ic_signal_cellular_5_5_bar.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC34/res/drawable/ic_signal_cellular_0_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC34/res/drawable/ic_signal_cellular_0_4_bar.xml new file mode 100644 index 000000000..358b914fc --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC34/res/drawable/ic_signal_cellular_0_4_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC34/res/drawable/ic_signal_cellular_0_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC34/res/drawable/ic_signal_cellular_0_5_bar.xml new file mode 100644 index 000000000..358b914fc --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC34/res/drawable/ic_signal_cellular_0_5_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC34/res/drawable/ic_signal_cellular_1_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC34/res/drawable/ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..c5b3d1692 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC34/res/drawable/ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC34/res/drawable/ic_signal_cellular_1_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC34/res/drawable/ic_signal_cellular_1_5_bar.xml new file mode 100644 index 000000000..c5b3d1692 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC34/res/drawable/ic_signal_cellular_1_5_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC34/res/drawable/ic_signal_cellular_2_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC34/res/drawable/ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..ecb0f760b --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC34/res/drawable/ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC34/res/drawable/ic_signal_cellular_2_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC34/res/drawable/ic_signal_cellular_2_5_bar.xml new file mode 100644 index 000000000..ecb0f760b --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC34/res/drawable/ic_signal_cellular_2_5_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC34/res/drawable/ic_signal_cellular_3_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC34/res/drawable/ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..407fbdee0 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC34/res/drawable/ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC34/res/drawable/ic_signal_cellular_3_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC34/res/drawable/ic_signal_cellular_3_5_bar.xml new file mode 100644 index 000000000..407fbdee0 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC34/res/drawable/ic_signal_cellular_3_5_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC34/res/drawable/ic_signal_cellular_4_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC34/res/drawable/ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..0cc865c10 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC34/res/drawable/ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC34/res/drawable/ic_signal_cellular_4_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC34/res/drawable/ic_signal_cellular_4_5_bar.xml new file mode 100644 index 000000000..0cc865c10 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC34/res/drawable/ic_signal_cellular_4_5_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC34/res/drawable/ic_signal_cellular_5_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC34/res/drawable/ic_signal_cellular_5_5_bar.xml new file mode 100644 index 000000000..0cc865c10 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC34/res/drawable/ic_signal_cellular_5_5_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC35/res/drawable/ic_signal_cellular_0_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC35/res/drawable/ic_signal_cellular_0_4_bar.xml new file mode 100644 index 000000000..2bf2fb31a --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC35/res/drawable/ic_signal_cellular_0_4_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC35/res/drawable/ic_signal_cellular_0_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC35/res/drawable/ic_signal_cellular_0_5_bar.xml new file mode 100644 index 000000000..2bf2fb31a --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC35/res/drawable/ic_signal_cellular_0_5_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC35/res/drawable/ic_signal_cellular_1_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC35/res/drawable/ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..3ed9275ee --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC35/res/drawable/ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC35/res/drawable/ic_signal_cellular_1_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC35/res/drawable/ic_signal_cellular_1_5_bar.xml new file mode 100644 index 000000000..3ed9275ee --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC35/res/drawable/ic_signal_cellular_1_5_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC35/res/drawable/ic_signal_cellular_2_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC35/res/drawable/ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..2ef8f395c --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC35/res/drawable/ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC35/res/drawable/ic_signal_cellular_2_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC35/res/drawable/ic_signal_cellular_2_5_bar.xml new file mode 100644 index 000000000..2ef8f395c --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC35/res/drawable/ic_signal_cellular_2_5_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC35/res/drawable/ic_signal_cellular_3_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC35/res/drawable/ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..288ebe57c --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC35/res/drawable/ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC35/res/drawable/ic_signal_cellular_3_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC35/res/drawable/ic_signal_cellular_3_5_bar.xml new file mode 100644 index 000000000..288ebe57c --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC35/res/drawable/ic_signal_cellular_3_5_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC35/res/drawable/ic_signal_cellular_4_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC35/res/drawable/ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..d341b92d4 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC35/res/drawable/ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC35/res/drawable/ic_signal_cellular_4_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC35/res/drawable/ic_signal_cellular_4_5_bar.xml new file mode 100644 index 000000000..d341b92d4 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC35/res/drawable/ic_signal_cellular_4_5_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC35/res/drawable/ic_signal_cellular_5_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC35/res/drawable/ic_signal_cellular_5_5_bar.xml new file mode 100644 index 000000000..d341b92d4 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC35/res/drawable/ic_signal_cellular_5_5_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC36/res/drawable/ic_signal_cellular_0_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC36/res/drawable/ic_signal_cellular_0_4_bar.xml new file mode 100644 index 000000000..86139d1cc --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC36/res/drawable/ic_signal_cellular_0_4_bar.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC36/res/drawable/ic_signal_cellular_0_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC36/res/drawable/ic_signal_cellular_0_5_bar.xml new file mode 100644 index 000000000..86139d1cc --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC36/res/drawable/ic_signal_cellular_0_5_bar.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC36/res/drawable/ic_signal_cellular_1_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC36/res/drawable/ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..bc74851e3 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC36/res/drawable/ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC36/res/drawable/ic_signal_cellular_1_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC36/res/drawable/ic_signal_cellular_1_5_bar.xml new file mode 100644 index 000000000..bc74851e3 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC36/res/drawable/ic_signal_cellular_1_5_bar.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC36/res/drawable/ic_signal_cellular_2_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC36/res/drawable/ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..09a9de7dc --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC36/res/drawable/ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC36/res/drawable/ic_signal_cellular_2_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC36/res/drawable/ic_signal_cellular_2_5_bar.xml new file mode 100644 index 000000000..09a9de7dc --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC36/res/drawable/ic_signal_cellular_2_5_bar.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC36/res/drawable/ic_signal_cellular_3_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC36/res/drawable/ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..aebc5b341 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC36/res/drawable/ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC36/res/drawable/ic_signal_cellular_3_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC36/res/drawable/ic_signal_cellular_3_5_bar.xml new file mode 100644 index 000000000..aebc5b341 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC36/res/drawable/ic_signal_cellular_3_5_bar.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC36/res/drawable/ic_signal_cellular_4_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC36/res/drawable/ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..e6f8c660c --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC36/res/drawable/ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC36/res/drawable/ic_signal_cellular_4_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC36/res/drawable/ic_signal_cellular_4_5_bar.xml new file mode 100644 index 000000000..e6f8c660c --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC36/res/drawable/ic_signal_cellular_4_5_bar.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC36/res/drawable/ic_signal_cellular_5_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC36/res/drawable/ic_signal_cellular_5_5_bar.xml new file mode 100644 index 000000000..e6f8c660c --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC36/res/drawable/ic_signal_cellular_5_5_bar.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/SGIC4/res/drawable/ic_signal_cellular_0_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC4/res/drawable/ic_signal_cellular_0_4_bar.xml new file mode 100644 index 000000000..e19d4a6fb --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC4/res/drawable/ic_signal_cellular_0_4_bar.xml @@ -0,0 +1,17 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC4/res/drawable/ic_signal_cellular_0_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC4/res/drawable/ic_signal_cellular_0_5_bar.xml new file mode 100644 index 000000000..ae2e215f3 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC4/res/drawable/ic_signal_cellular_0_5_bar.xml @@ -0,0 +1,17 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC4/res/drawable/ic_signal_cellular_1_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC4/res/drawable/ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..39fa79c91 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC4/res/drawable/ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,17 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC4/res/drawable/ic_signal_cellular_1_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC4/res/drawable/ic_signal_cellular_1_5_bar.xml new file mode 100644 index 000000000..049aed57b --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC4/res/drawable/ic_signal_cellular_1_5_bar.xml @@ -0,0 +1,17 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC4/res/drawable/ic_signal_cellular_2_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC4/res/drawable/ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..185ee1072 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC4/res/drawable/ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,17 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC4/res/drawable/ic_signal_cellular_2_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC4/res/drawable/ic_signal_cellular_2_5_bar.xml new file mode 100644 index 000000000..185ee1072 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC4/res/drawable/ic_signal_cellular_2_5_bar.xml @@ -0,0 +1,17 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC4/res/drawable/ic_signal_cellular_3_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC4/res/drawable/ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..b8f1b43b5 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC4/res/drawable/ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,17 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC4/res/drawable/ic_signal_cellular_3_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC4/res/drawable/ic_signal_cellular_3_5_bar.xml new file mode 100644 index 000000000..b8f1b43b5 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC4/res/drawable/ic_signal_cellular_3_5_bar.xml @@ -0,0 +1,17 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC4/res/drawable/ic_signal_cellular_4_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC4/res/drawable/ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..bf29c73d1 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC4/res/drawable/ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,17 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC4/res/drawable/ic_signal_cellular_4_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC4/res/drawable/ic_signal_cellular_4_5_bar.xml new file mode 100644 index 000000000..bf29c73d1 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC4/res/drawable/ic_signal_cellular_4_5_bar.xml @@ -0,0 +1,17 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC4/res/drawable/ic_signal_cellular_5_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC4/res/drawable/ic_signal_cellular_5_5_bar.xml new file mode 100644 index 000000000..bf29c73d1 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC4/res/drawable/ic_signal_cellular_5_5_bar.xml @@ -0,0 +1,17 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC5/res/drawable/ic_signal_cellular_0_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC5/res/drawable/ic_signal_cellular_0_4_bar.xml new file mode 100644 index 000000000..49c8e9217 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC5/res/drawable/ic_signal_cellular_0_4_bar.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC5/res/drawable/ic_signal_cellular_0_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC5/res/drawable/ic_signal_cellular_0_5_bar.xml new file mode 100644 index 000000000..49c8e9217 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC5/res/drawable/ic_signal_cellular_0_5_bar.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC5/res/drawable/ic_signal_cellular_1_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC5/res/drawable/ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..d1312a6f0 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC5/res/drawable/ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC5/res/drawable/ic_signal_cellular_1_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC5/res/drawable/ic_signal_cellular_1_5_bar.xml new file mode 100644 index 000000000..d1312a6f0 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC5/res/drawable/ic_signal_cellular_1_5_bar.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC5/res/drawable/ic_signal_cellular_2_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC5/res/drawable/ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..36143d3c8 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC5/res/drawable/ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC5/res/drawable/ic_signal_cellular_2_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC5/res/drawable/ic_signal_cellular_2_5_bar.xml new file mode 100644 index 000000000..36143d3c8 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC5/res/drawable/ic_signal_cellular_2_5_bar.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC5/res/drawable/ic_signal_cellular_3_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC5/res/drawable/ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..554850966 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC5/res/drawable/ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC5/res/drawable/ic_signal_cellular_3_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC5/res/drawable/ic_signal_cellular_3_5_bar.xml new file mode 100644 index 000000000..554850966 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC5/res/drawable/ic_signal_cellular_3_5_bar.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC5/res/drawable/ic_signal_cellular_4_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC5/res/drawable/ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..725a41460 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC5/res/drawable/ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC5/res/drawable/ic_signal_cellular_4_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC5/res/drawable/ic_signal_cellular_4_5_bar.xml new file mode 100644 index 000000000..725a41460 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC5/res/drawable/ic_signal_cellular_4_5_bar.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC5/res/drawable/ic_signal_cellular_5_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC5/res/drawable/ic_signal_cellular_5_5_bar.xml new file mode 100644 index 000000000..725a41460 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC5/res/drawable/ic_signal_cellular_5_5_bar.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC6/res/drawable/ic_signal_cellular_0_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC6/res/drawable/ic_signal_cellular_0_4_bar.xml new file mode 100644 index 000000000..145fd05bd --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC6/res/drawable/ic_signal_cellular_0_4_bar.xml @@ -0,0 +1,17 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC6/res/drawable/ic_signal_cellular_0_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC6/res/drawable/ic_signal_cellular_0_5_bar.xml new file mode 100644 index 000000000..145fd05bd --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC6/res/drawable/ic_signal_cellular_0_5_bar.xml @@ -0,0 +1,17 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC6/res/drawable/ic_signal_cellular_1_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC6/res/drawable/ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..b10190819 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC6/res/drawable/ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,17 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC6/res/drawable/ic_signal_cellular_1_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC6/res/drawable/ic_signal_cellular_1_5_bar.xml new file mode 100644 index 000000000..b10190819 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC6/res/drawable/ic_signal_cellular_1_5_bar.xml @@ -0,0 +1,17 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC6/res/drawable/ic_signal_cellular_2_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC6/res/drawable/ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..ae4b4ad54 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC6/res/drawable/ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,17 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC6/res/drawable/ic_signal_cellular_2_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC6/res/drawable/ic_signal_cellular_2_5_bar.xml new file mode 100644 index 000000000..ae4b4ad54 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC6/res/drawable/ic_signal_cellular_2_5_bar.xml @@ -0,0 +1,17 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC6/res/drawable/ic_signal_cellular_3_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC6/res/drawable/ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..a9ec0f75e --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC6/res/drawable/ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,17 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC6/res/drawable/ic_signal_cellular_3_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC6/res/drawable/ic_signal_cellular_3_5_bar.xml new file mode 100644 index 000000000..a9ec0f75e --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC6/res/drawable/ic_signal_cellular_3_5_bar.xml @@ -0,0 +1,17 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC6/res/drawable/ic_signal_cellular_4_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC6/res/drawable/ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..3f6137d42 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC6/res/drawable/ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,17 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC6/res/drawable/ic_signal_cellular_4_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC6/res/drawable/ic_signal_cellular_4_5_bar.xml new file mode 100644 index 000000000..3f6137d42 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC6/res/drawable/ic_signal_cellular_4_5_bar.xml @@ -0,0 +1,17 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC6/res/drawable/ic_signal_cellular_5_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC6/res/drawable/ic_signal_cellular_5_5_bar.xml new file mode 100644 index 000000000..3f6137d42 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC6/res/drawable/ic_signal_cellular_5_5_bar.xml @@ -0,0 +1,17 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC7/res/drawable/ic_signal_cellular_0_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC7/res/drawable/ic_signal_cellular_0_4_bar.xml new file mode 100644 index 000000000..91105c9f4 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC7/res/drawable/ic_signal_cellular_0_4_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC7/res/drawable/ic_signal_cellular_0_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC7/res/drawable/ic_signal_cellular_0_5_bar.xml new file mode 100644 index 000000000..91105c9f4 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC7/res/drawable/ic_signal_cellular_0_5_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC7/res/drawable/ic_signal_cellular_1_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC7/res/drawable/ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..91105c9f4 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC7/res/drawable/ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC7/res/drawable/ic_signal_cellular_1_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC7/res/drawable/ic_signal_cellular_1_5_bar.xml new file mode 100644 index 000000000..91105c9f4 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC7/res/drawable/ic_signal_cellular_1_5_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC7/res/drawable/ic_signal_cellular_2_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC7/res/drawable/ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..df462a481 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC7/res/drawable/ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC7/res/drawable/ic_signal_cellular_2_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC7/res/drawable/ic_signal_cellular_2_5_bar.xml new file mode 100644 index 000000000..df462a481 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC7/res/drawable/ic_signal_cellular_2_5_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC7/res/drawable/ic_signal_cellular_3_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC7/res/drawable/ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..72af92adb --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC7/res/drawable/ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC7/res/drawable/ic_signal_cellular_3_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC7/res/drawable/ic_signal_cellular_3_5_bar.xml new file mode 100644 index 000000000..72af92adb --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC7/res/drawable/ic_signal_cellular_3_5_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC7/res/drawable/ic_signal_cellular_4_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC7/res/drawable/ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..9df8b17db --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC7/res/drawable/ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC7/res/drawable/ic_signal_cellular_4_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC7/res/drawable/ic_signal_cellular_4_5_bar.xml new file mode 100644 index 000000000..9df8b17db --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC7/res/drawable/ic_signal_cellular_4_5_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC7/res/drawable/ic_signal_cellular_5_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC7/res/drawable/ic_signal_cellular_5_5_bar.xml new file mode 100644 index 000000000..9df8b17db --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC7/res/drawable/ic_signal_cellular_5_5_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC8/res/drawable/ic_signal_cellular_0_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC8/res/drawable/ic_signal_cellular_0_4_bar.xml new file mode 100644 index 000000000..ba55e06c5 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC8/res/drawable/ic_signal_cellular_0_4_bar.xml @@ -0,0 +1,17 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC8/res/drawable/ic_signal_cellular_0_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC8/res/drawable/ic_signal_cellular_0_5_bar.xml new file mode 100644 index 000000000..ba55e06c5 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC8/res/drawable/ic_signal_cellular_0_5_bar.xml @@ -0,0 +1,17 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC8/res/drawable/ic_signal_cellular_1_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC8/res/drawable/ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..c096b8452 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC8/res/drawable/ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,17 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC8/res/drawable/ic_signal_cellular_1_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC8/res/drawable/ic_signal_cellular_1_5_bar.xml new file mode 100644 index 000000000..c096b8452 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC8/res/drawable/ic_signal_cellular_1_5_bar.xml @@ -0,0 +1,17 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC8/res/drawable/ic_signal_cellular_2_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC8/res/drawable/ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..f1133a5eb --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC8/res/drawable/ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,17 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC8/res/drawable/ic_signal_cellular_2_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC8/res/drawable/ic_signal_cellular_2_5_bar.xml new file mode 100644 index 000000000..f1133a5eb --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC8/res/drawable/ic_signal_cellular_2_5_bar.xml @@ -0,0 +1,17 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC8/res/drawable/ic_signal_cellular_3_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC8/res/drawable/ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..ac4d88565 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC8/res/drawable/ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,17 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC8/res/drawable/ic_signal_cellular_3_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC8/res/drawable/ic_signal_cellular_3_5_bar.xml new file mode 100644 index 000000000..ac4d88565 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC8/res/drawable/ic_signal_cellular_3_5_bar.xml @@ -0,0 +1,17 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC8/res/drawable/ic_signal_cellular_4_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC8/res/drawable/ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..b7e93666c --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC8/res/drawable/ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,17 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC8/res/drawable/ic_signal_cellular_4_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC8/res/drawable/ic_signal_cellular_4_5_bar.xml new file mode 100644 index 000000000..b7e93666c --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC8/res/drawable/ic_signal_cellular_4_5_bar.xml @@ -0,0 +1,17 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC8/res/drawable/ic_signal_cellular_5_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC8/res/drawable/ic_signal_cellular_5_5_bar.xml new file mode 100644 index 000000000..b7e93666c --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC8/res/drawable/ic_signal_cellular_5_5_bar.xml @@ -0,0 +1,17 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC9/res/drawable/ic_signal_cellular_0_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC9/res/drawable/ic_signal_cellular_0_4_bar.xml new file mode 100644 index 000000000..c60ad0495 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC9/res/drawable/ic_signal_cellular_0_4_bar.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC9/res/drawable/ic_signal_cellular_0_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC9/res/drawable/ic_signal_cellular_0_5_bar.xml new file mode 100644 index 000000000..c60ad0495 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC9/res/drawable/ic_signal_cellular_0_5_bar.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC9/res/drawable/ic_signal_cellular_1_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC9/res/drawable/ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..445681baa --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC9/res/drawable/ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC9/res/drawable/ic_signal_cellular_1_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC9/res/drawable/ic_signal_cellular_1_5_bar.xml new file mode 100644 index 000000000..445681baa --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC9/res/drawable/ic_signal_cellular_1_5_bar.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC9/res/drawable/ic_signal_cellular_2_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC9/res/drawable/ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..b2d37469d --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC9/res/drawable/ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC9/res/drawable/ic_signal_cellular_2_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC9/res/drawable/ic_signal_cellular_2_5_bar.xml new file mode 100644 index 000000000..b2d37469d --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC9/res/drawable/ic_signal_cellular_2_5_bar.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC9/res/drawable/ic_signal_cellular_3_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC9/res/drawable/ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..49d9ecd88 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC9/res/drawable/ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC9/res/drawable/ic_signal_cellular_3_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC9/res/drawable/ic_signal_cellular_3_5_bar.xml new file mode 100644 index 000000000..49d9ecd88 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC9/res/drawable/ic_signal_cellular_3_5_bar.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC9/res/drawable/ic_signal_cellular_4_4_bar.xml b/app/src/main/assets/Overlays/android/SGIC9/res/drawable/ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..11b7d92a9 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC9/res/drawable/ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC9/res/drawable/ic_signal_cellular_4_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC9/res/drawable/ic_signal_cellular_4_5_bar.xml new file mode 100644 index 000000000..11b7d92a9 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC9/res/drawable/ic_signal_cellular_4_5_bar.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/SGIC9/res/drawable/ic_signal_cellular_5_5_bar.xml b/app/src/main/assets/Overlays/android/SGIC9/res/drawable/ic_signal_cellular_5_5_bar.xml new file mode 100644 index 000000000..11b7d92a9 --- /dev/null +++ b/app/src/main/assets/Overlays/android/SGIC9/res/drawable/ic_signal_cellular_5_5_bar.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_signal_wifi_transient_animation.xml b/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_signal_wifi_transient_animation.xml new file mode 100644 index 000000000..17a804f7d --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_signal_wifi_transient_animation.xml @@ -0,0 +1,14 @@ + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_signal_wifi_transient_animation_drawable.xml b/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_signal_wifi_transient_animation_drawable.xml new file mode 100644 index 000000000..17a804f7d --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_signal_wifi_transient_animation_drawable.xml @@ -0,0 +1,14 @@ + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_4_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_4_signal_0.xml new file mode 100644 index 000000000..17a804f7d --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_4_signal_0.xml @@ -0,0 +1,14 @@ + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_4_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_4_signal_1.xml new file mode 100644 index 000000000..fec096e70 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_4_signal_1.xml @@ -0,0 +1,22 @@ + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_4_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_4_signal_2.xml new file mode 100644 index 000000000..5dd08b195 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_4_signal_2.xml @@ -0,0 +1,30 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_4_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_4_signal_3.xml new file mode 100644 index 000000000..1974b4d26 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_4_signal_3.xml @@ -0,0 +1,38 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_4_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_4_signal_4.xml new file mode 100644 index 000000000..18eec4e44 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_4_signal_4.xml @@ -0,0 +1,38 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_5_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_5_signal_0.xml new file mode 100644 index 000000000..17a804f7d --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_5_signal_0.xml @@ -0,0 +1,14 @@ + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_5_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_5_signal_1.xml new file mode 100644 index 000000000..fec096e70 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_5_signal_1.xml @@ -0,0 +1,22 @@ + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_5_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_5_signal_2.xml new file mode 100644 index 000000000..5dd08b195 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_5_signal_2.xml @@ -0,0 +1,30 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_5_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_5_signal_3.xml new file mode 100644 index 000000000..1974b4d26 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_5_signal_3.xml @@ -0,0 +1,38 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_5_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_5_signal_4.xml new file mode 100644 index 000000000..18eec4e44 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_5_signal_4.xml @@ -0,0 +1,38 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_6_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_6_signal_0.xml new file mode 100644 index 000000000..17a804f7d --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_6_signal_0.xml @@ -0,0 +1,14 @@ + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_6_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_6_signal_1.xml new file mode 100644 index 000000000..fec096e70 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_6_signal_1.xml @@ -0,0 +1,22 @@ + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_6_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_6_signal_2.xml new file mode 100644 index 000000000..5dd08b195 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_6_signal_2.xml @@ -0,0 +1,30 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_6_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_6_signal_3.xml new file mode 100644 index 000000000..1974b4d26 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_6_signal_3.xml @@ -0,0 +1,38 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_6_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_6_signal_4.xml new file mode 100644 index 000000000..18eec4e44 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_6_signal_4.xml @@ -0,0 +1,38 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_signal_0.xml new file mode 100644 index 000000000..17a804f7d --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_signal_0.xml @@ -0,0 +1,14 @@ + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_signal_1.xml new file mode 100644 index 000000000..fec096e70 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_signal_1.xml @@ -0,0 +1,22 @@ + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_signal_2.xml new file mode 100644 index 000000000..5dd08b195 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_signal_2.xml @@ -0,0 +1,30 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_signal_3.xml new file mode 100644 index 000000000..1974b4d26 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_signal_3.xml @@ -0,0 +1,38 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_signal_4.xml new file mode 100644 index 000000000..18eec4e44 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI1/res/drawable/ic_wifi_signal_4.xml @@ -0,0 +1,38 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_signal_wifi_transient_animation.xml b/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_signal_wifi_transient_animation.xml new file mode 100644 index 000000000..de80ec9e8 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_signal_wifi_transient_animation.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_signal_wifi_transient_animation_drawable.xml b/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_signal_wifi_transient_animation_drawable.xml new file mode 100644 index 000000000..de80ec9e8 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_signal_wifi_transient_animation_drawable.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_4_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_4_signal_0.xml new file mode 100644 index 000000000..de80ec9e8 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_4_signal_0.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_4_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_4_signal_1.xml new file mode 100644 index 000000000..f8fbf1e32 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_4_signal_1.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_4_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_4_signal_2.xml new file mode 100644 index 000000000..226d28263 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_4_signal_2.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_4_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_4_signal_3.xml new file mode 100644 index 000000000..de80ec9e8 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_4_signal_3.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_4_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_4_signal_4.xml new file mode 100644 index 000000000..de80ec9e8 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_4_signal_4.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_5_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_5_signal_0.xml new file mode 100644 index 000000000..de80ec9e8 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_5_signal_0.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_5_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_5_signal_1.xml new file mode 100644 index 000000000..f8fbf1e32 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_5_signal_1.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_5_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_5_signal_2.xml new file mode 100644 index 000000000..226d28263 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_5_signal_2.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_5_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_5_signal_3.xml new file mode 100644 index 000000000..de80ec9e8 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_5_signal_3.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_5_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_5_signal_4.xml new file mode 100644 index 000000000..de80ec9e8 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_5_signal_4.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_6_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_6_signal_0.xml new file mode 100644 index 000000000..de80ec9e8 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_6_signal_0.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_6_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_6_signal_1.xml new file mode 100644 index 000000000..f8fbf1e32 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_6_signal_1.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_6_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_6_signal_2.xml new file mode 100644 index 000000000..226d28263 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_6_signal_2.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_6_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_6_signal_3.xml new file mode 100644 index 000000000..de80ec9e8 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_6_signal_3.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_6_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_6_signal_4.xml new file mode 100644 index 000000000..de80ec9e8 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_6_signal_4.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_signal_0.xml new file mode 100644 index 000000000..de80ec9e8 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_signal_0.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_signal_1.xml new file mode 100644 index 000000000..f8fbf1e32 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_signal_1.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_signal_2.xml new file mode 100644 index 000000000..226d28263 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_signal_2.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_signal_3.xml new file mode 100644 index 000000000..de80ec9e8 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_signal_3.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_signal_4.xml new file mode 100644 index 000000000..de80ec9e8 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI10/res/drawable/ic_wifi_signal_4.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_signal_wifi_transient_animation.xml b/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_signal_wifi_transient_animation.xml new file mode 100644 index 000000000..abc3a1a1b --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_signal_wifi_transient_animation.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_signal_wifi_transient_animation_drawable.xml b/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_signal_wifi_transient_animation_drawable.xml new file mode 100644 index 000000000..abc3a1a1b --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_signal_wifi_transient_animation_drawable.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_4_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_4_signal_0.xml new file mode 100644 index 000000000..abc3a1a1b --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_4_signal_0.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_4_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_4_signal_1.xml new file mode 100644 index 000000000..465a729ab --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_4_signal_1.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_4_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_4_signal_2.xml new file mode 100644 index 000000000..a4553d7ec --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_4_signal_2.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_4_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_4_signal_3.xml new file mode 100644 index 000000000..df7b1d63a --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_4_signal_3.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_4_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_4_signal_4.xml new file mode 100644 index 000000000..abc3a1a1b --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_4_signal_4.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_5_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_5_signal_0.xml new file mode 100644 index 000000000..abc3a1a1b --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_5_signal_0.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_5_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_5_signal_1.xml new file mode 100644 index 000000000..465a729ab --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_5_signal_1.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_5_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_5_signal_2.xml new file mode 100644 index 000000000..a4553d7ec --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_5_signal_2.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_5_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_5_signal_3.xml new file mode 100644 index 000000000..df7b1d63a --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_5_signal_3.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_5_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_5_signal_4.xml new file mode 100644 index 000000000..abc3a1a1b --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_5_signal_4.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_6_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_6_signal_0.xml new file mode 100644 index 000000000..abc3a1a1b --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_6_signal_0.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_6_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_6_signal_1.xml new file mode 100644 index 000000000..465a729ab --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_6_signal_1.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_6_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_6_signal_2.xml new file mode 100644 index 000000000..a4553d7ec --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_6_signal_2.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_6_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_6_signal_3.xml new file mode 100644 index 000000000..df7b1d63a --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_6_signal_3.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_6_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_6_signal_4.xml new file mode 100644 index 000000000..abc3a1a1b --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_6_signal_4.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_signal_0.xml new file mode 100644 index 000000000..abc3a1a1b --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_signal_0.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_signal_1.xml new file mode 100644 index 000000000..465a729ab --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_signal_1.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_signal_2.xml new file mode 100644 index 000000000..a4553d7ec --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_signal_2.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_signal_3.xml new file mode 100644 index 000000000..df7b1d63a --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_signal_3.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_signal_4.xml new file mode 100644 index 000000000..abc3a1a1b --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI11/res/drawable/ic_wifi_signal_4.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_signal_wifi_transient_animation.xml b/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_signal_wifi_transient_animation.xml new file mode 100644 index 000000000..1119f8131 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_signal_wifi_transient_animation.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_signal_wifi_transient_animation_drawable.xml b/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_signal_wifi_transient_animation_drawable.xml new file mode 100644 index 000000000..1119f8131 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_signal_wifi_transient_animation_drawable.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_4_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_4_signal_0.xml new file mode 100644 index 000000000..1119f8131 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_4_signal_0.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_4_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_4_signal_1.xml new file mode 100644 index 000000000..d33292b6b --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_4_signal_1.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_4_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_4_signal_2.xml new file mode 100644 index 000000000..16a2e9902 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_4_signal_2.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_4_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_4_signal_3.xml new file mode 100644 index 000000000..aa17764ba --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_4_signal_3.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_4_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_4_signal_4.xml new file mode 100644 index 000000000..894c47966 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_4_signal_4.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_5_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_5_signal_0.xml new file mode 100644 index 000000000..1119f8131 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_5_signal_0.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_5_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_5_signal_1.xml new file mode 100644 index 000000000..d33292b6b --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_5_signal_1.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_5_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_5_signal_2.xml new file mode 100644 index 000000000..16a2e9902 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_5_signal_2.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_5_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_5_signal_3.xml new file mode 100644 index 000000000..aa17764ba --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_5_signal_3.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_5_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_5_signal_4.xml new file mode 100644 index 000000000..894c47966 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_5_signal_4.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_6_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_6_signal_0.xml new file mode 100644 index 000000000..1119f8131 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_6_signal_0.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_6_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_6_signal_1.xml new file mode 100644 index 000000000..d33292b6b --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_6_signal_1.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_6_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_6_signal_2.xml new file mode 100644 index 000000000..16a2e9902 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_6_signal_2.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_6_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_6_signal_3.xml new file mode 100644 index 000000000..aa17764ba --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_6_signal_3.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_6_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_6_signal_4.xml new file mode 100644 index 000000000..894c47966 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_6_signal_4.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_signal_0.xml new file mode 100644 index 000000000..1119f8131 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_signal_0.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_signal_1.xml new file mode 100644 index 000000000..d33292b6b --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_signal_1.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_signal_2.xml new file mode 100644 index 000000000..16a2e9902 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_signal_2.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_signal_3.xml new file mode 100644 index 000000000..aa17764ba --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_signal_3.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_signal_4.xml new file mode 100644 index 000000000..894c47966 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI12/res/drawable/ic_wifi_signal_4.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_signal_wifi_transient_animation.xml b/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_signal_wifi_transient_animation.xml new file mode 100644 index 000000000..502071544 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_signal_wifi_transient_animation.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_signal_wifi_transient_animation_drawable.xml b/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_signal_wifi_transient_animation_drawable.xml new file mode 100644 index 000000000..502071544 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_signal_wifi_transient_animation_drawable.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_4_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_4_signal_0.xml new file mode 100644 index 000000000..502071544 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_4_signal_0.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_4_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_4_signal_1.xml new file mode 100644 index 000000000..6b42ba14a --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_4_signal_1.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_4_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_4_signal_2.xml new file mode 100644 index 000000000..7617c3fbd --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_4_signal_2.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_4_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_4_signal_3.xml new file mode 100644 index 000000000..746887bc3 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_4_signal_3.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_4_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_4_signal_4.xml new file mode 100644 index 000000000..88ae44047 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_4_signal_4.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_5_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_5_signal_0.xml new file mode 100644 index 000000000..502071544 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_5_signal_0.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_5_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_5_signal_1.xml new file mode 100644 index 000000000..6b42ba14a --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_5_signal_1.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_5_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_5_signal_2.xml new file mode 100644 index 000000000..7617c3fbd --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_5_signal_2.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_5_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_5_signal_3.xml new file mode 100644 index 000000000..746887bc3 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_5_signal_3.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_5_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_5_signal_4.xml new file mode 100644 index 000000000..88ae44047 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_5_signal_4.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_6_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_6_signal_0.xml new file mode 100644 index 000000000..502071544 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_6_signal_0.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_6_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_6_signal_1.xml new file mode 100644 index 000000000..6b42ba14a --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_6_signal_1.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_6_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_6_signal_2.xml new file mode 100644 index 000000000..7617c3fbd --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_6_signal_2.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_6_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_6_signal_3.xml new file mode 100644 index 000000000..746887bc3 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_6_signal_3.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_6_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_6_signal_4.xml new file mode 100644 index 000000000..88ae44047 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_6_signal_4.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_signal_0.xml new file mode 100644 index 000000000..502071544 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_signal_0.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_signal_1.xml new file mode 100644 index 000000000..6b42ba14a --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_signal_1.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_signal_2.xml new file mode 100644 index 000000000..7617c3fbd --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_signal_2.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_signal_3.xml new file mode 100644 index 000000000..746887bc3 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_signal_3.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_signal_4.xml new file mode 100644 index 000000000..88ae44047 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI13/res/drawable/ic_wifi_signal_4.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_signal_wifi_transient_animation.xml b/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_signal_wifi_transient_animation.xml new file mode 100644 index 000000000..3e389c657 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_signal_wifi_transient_animation.xml @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_signal_wifi_transient_animation_drawable.xml b/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_signal_wifi_transient_animation_drawable.xml new file mode 100644 index 000000000..3e389c657 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_signal_wifi_transient_animation_drawable.xml @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_4_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_4_signal_0.xml new file mode 100644 index 000000000..3e389c657 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_4_signal_0.xml @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_4_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_4_signal_1.xml new file mode 100644 index 000000000..204e906b2 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_4_signal_1.xml @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_4_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_4_signal_2.xml new file mode 100644 index 000000000..f5a538cdb --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_4_signal_2.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_4_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_4_signal_3.xml new file mode 100644 index 000000000..b57747aa4 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_4_signal_3.xml @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_4_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_4_signal_4.xml new file mode 100644 index 000000000..66fb6e362 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_4_signal_4.xml @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_5_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_5_signal_0.xml new file mode 100644 index 000000000..3e389c657 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_5_signal_0.xml @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_5_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_5_signal_1.xml new file mode 100644 index 000000000..204e906b2 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_5_signal_1.xml @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_5_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_5_signal_2.xml new file mode 100644 index 000000000..f5a538cdb --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_5_signal_2.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_5_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_5_signal_3.xml new file mode 100644 index 000000000..b57747aa4 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_5_signal_3.xml @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_5_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_5_signal_4.xml new file mode 100644 index 000000000..66fb6e362 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_5_signal_4.xml @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_6_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_6_signal_0.xml new file mode 100644 index 000000000..3e389c657 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_6_signal_0.xml @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_6_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_6_signal_1.xml new file mode 100644 index 000000000..204e906b2 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_6_signal_1.xml @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_6_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_6_signal_2.xml new file mode 100644 index 000000000..f5a538cdb --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_6_signal_2.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_6_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_6_signal_3.xml new file mode 100644 index 000000000..b57747aa4 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_6_signal_3.xml @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_6_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_6_signal_4.xml new file mode 100644 index 000000000..66fb6e362 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_6_signal_4.xml @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_signal_0.xml new file mode 100644 index 000000000..3e389c657 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_signal_0.xml @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_signal_1.xml new file mode 100644 index 000000000..204e906b2 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_signal_1.xml @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_signal_2.xml new file mode 100644 index 000000000..f5a538cdb --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_signal_2.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_signal_3.xml new file mode 100644 index 000000000..b57747aa4 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_signal_3.xml @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_signal_4.xml new file mode 100644 index 000000000..66fb6e362 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI14/res/drawable/ic_wifi_signal_4.xml @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_signal_wifi_transient_animation.xml b/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_signal_wifi_transient_animation.xml new file mode 100644 index 000000000..056f813de --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_signal_wifi_transient_animation.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_signal_wifi_transient_animation_drawable.xml b/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_signal_wifi_transient_animation_drawable.xml new file mode 100644 index 000000000..056f813de --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_signal_wifi_transient_animation_drawable.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_4_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_4_signal_0.xml new file mode 100644 index 000000000..056f813de --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_4_signal_0.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_4_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_4_signal_1.xml new file mode 100644 index 000000000..d1a978fa8 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_4_signal_1.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_4_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_4_signal_2.xml new file mode 100644 index 000000000..f9e7b669c --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_4_signal_2.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_4_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_4_signal_3.xml new file mode 100644 index 000000000..056f813de --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_4_signal_3.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_4_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_4_signal_4.xml new file mode 100644 index 000000000..056f813de --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_4_signal_4.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_5_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_5_signal_0.xml new file mode 100644 index 000000000..056f813de --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_5_signal_0.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_5_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_5_signal_1.xml new file mode 100644 index 000000000..d1a978fa8 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_5_signal_1.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_5_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_5_signal_2.xml new file mode 100644 index 000000000..f9e7b669c --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_5_signal_2.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_5_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_5_signal_3.xml new file mode 100644 index 000000000..056f813de --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_5_signal_3.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_5_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_5_signal_4.xml new file mode 100644 index 000000000..056f813de --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_5_signal_4.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_6_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_6_signal_0.xml new file mode 100644 index 000000000..056f813de --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_6_signal_0.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_6_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_6_signal_1.xml new file mode 100644 index 000000000..d1a978fa8 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_6_signal_1.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_6_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_6_signal_2.xml new file mode 100644 index 000000000..f9e7b669c --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_6_signal_2.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_6_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_6_signal_3.xml new file mode 100644 index 000000000..056f813de --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_6_signal_3.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_6_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_6_signal_4.xml new file mode 100644 index 000000000..056f813de --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_6_signal_4.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_signal_0.xml new file mode 100644 index 000000000..056f813de --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_signal_0.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_signal_1.xml new file mode 100644 index 000000000..d1a978fa8 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_signal_1.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_signal_2.xml new file mode 100644 index 000000000..f9e7b669c --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_signal_2.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_signal_3.xml new file mode 100644 index 000000000..056f813de --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_signal_3.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_signal_4.xml new file mode 100644 index 000000000..056f813de --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI15/res/drawable/ic_wifi_signal_4.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_signal_wifi_transient_animation.xml b/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_signal_wifi_transient_animation.xml new file mode 100644 index 000000000..b4c6a3445 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_signal_wifi_transient_animation.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_signal_wifi_transient_animation_drawable.xml b/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_signal_wifi_transient_animation_drawable.xml new file mode 100644 index 000000000..b4c6a3445 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_signal_wifi_transient_animation_drawable.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_4_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_4_signal_0.xml new file mode 100644 index 000000000..b4c6a3445 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_4_signal_0.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_4_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_4_signal_1.xml new file mode 100644 index 000000000..e33ba2644 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_4_signal_1.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_4_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_4_signal_2.xml new file mode 100644 index 000000000..83908487d --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_4_signal_2.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_4_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_4_signal_3.xml new file mode 100644 index 000000000..6195b24b0 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_4_signal_3.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_4_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_4_signal_4.xml new file mode 100644 index 000000000..76c0868a4 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_4_signal_4.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_5_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_5_signal_0.xml new file mode 100644 index 000000000..b4c6a3445 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_5_signal_0.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_5_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_5_signal_1.xml new file mode 100644 index 000000000..e33ba2644 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_5_signal_1.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_5_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_5_signal_2.xml new file mode 100644 index 000000000..83908487d --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_5_signal_2.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_5_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_5_signal_3.xml new file mode 100644 index 000000000..6195b24b0 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_5_signal_3.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_5_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_5_signal_4.xml new file mode 100644 index 000000000..76c0868a4 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_5_signal_4.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_6_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_6_signal_0.xml new file mode 100644 index 000000000..b4c6a3445 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_6_signal_0.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_6_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_6_signal_1.xml new file mode 100644 index 000000000..e33ba2644 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_6_signal_1.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_6_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_6_signal_2.xml new file mode 100644 index 000000000..83908487d --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_6_signal_2.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_6_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_6_signal_3.xml new file mode 100644 index 000000000..6195b24b0 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_6_signal_3.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_6_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_6_signal_4.xml new file mode 100644 index 000000000..76c0868a4 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_6_signal_4.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_signal_0.xml new file mode 100644 index 000000000..b4c6a3445 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_signal_0.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_signal_1.xml new file mode 100644 index 000000000..e33ba2644 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_signal_1.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_signal_2.xml new file mode 100644 index 000000000..83908487d --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_signal_2.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_signal_3.xml new file mode 100644 index 000000000..6195b24b0 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_signal_3.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_signal_4.xml new file mode 100644 index 000000000..76c0868a4 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI16/res/drawable/ic_wifi_signal_4.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_signal_wifi_transient_animation.xml b/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_signal_wifi_transient_animation.xml new file mode 100644 index 000000000..2a4327571 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_signal_wifi_transient_animation.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_signal_wifi_transient_animation_drawable.xml b/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_signal_wifi_transient_animation_drawable.xml new file mode 100644 index 000000000..2a4327571 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_signal_wifi_transient_animation_drawable.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_4_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_4_signal_0.xml new file mode 100644 index 000000000..2a4327571 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_4_signal_0.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_4_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_4_signal_1.xml new file mode 100644 index 000000000..f05deda6a --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_4_signal_1.xml @@ -0,0 +1,11 @@ + + + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_4_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_4_signal_2.xml new file mode 100644 index 000000000..a6d1cf1be --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_4_signal_2.xml @@ -0,0 +1,11 @@ + + + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_4_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_4_signal_3.xml new file mode 100644 index 000000000..b668f00d7 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_4_signal_3.xml @@ -0,0 +1,11 @@ + + + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_4_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_4_signal_4.xml new file mode 100644 index 000000000..82cf3b616 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_4_signal_4.xml @@ -0,0 +1,10 @@ + + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_5_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_5_signal_0.xml new file mode 100644 index 000000000..2a4327571 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_5_signal_0.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_5_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_5_signal_1.xml new file mode 100644 index 000000000..f05deda6a --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_5_signal_1.xml @@ -0,0 +1,11 @@ + + + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_5_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_5_signal_2.xml new file mode 100644 index 000000000..a6d1cf1be --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_5_signal_2.xml @@ -0,0 +1,11 @@ + + + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_5_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_5_signal_3.xml new file mode 100644 index 000000000..b668f00d7 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_5_signal_3.xml @@ -0,0 +1,11 @@ + + + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_5_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_5_signal_4.xml new file mode 100644 index 000000000..82cf3b616 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_5_signal_4.xml @@ -0,0 +1,10 @@ + + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_6_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_6_signal_0.xml new file mode 100644 index 000000000..2a4327571 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_6_signal_0.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_6_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_6_signal_1.xml new file mode 100644 index 000000000..f05deda6a --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_6_signal_1.xml @@ -0,0 +1,11 @@ + + + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_6_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_6_signal_2.xml new file mode 100644 index 000000000..a6d1cf1be --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_6_signal_2.xml @@ -0,0 +1,11 @@ + + + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_6_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_6_signal_3.xml new file mode 100644 index 000000000..b668f00d7 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_6_signal_3.xml @@ -0,0 +1,11 @@ + + + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_6_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_6_signal_4.xml new file mode 100644 index 000000000..82cf3b616 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_6_signal_4.xml @@ -0,0 +1,10 @@ + + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_signal_0.xml new file mode 100644 index 000000000..2a4327571 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_signal_0.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_signal_1.xml new file mode 100644 index 000000000..f05deda6a --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_signal_1.xml @@ -0,0 +1,11 @@ + + + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_signal_2.xml new file mode 100644 index 000000000..a6d1cf1be --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_signal_2.xml @@ -0,0 +1,11 @@ + + + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_signal_3.xml new file mode 100644 index 000000000..b668f00d7 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_signal_3.xml @@ -0,0 +1,11 @@ + + + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_signal_4.xml new file mode 100644 index 000000000..82cf3b616 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI2/res/drawable/ic_wifi_signal_4.xml @@ -0,0 +1,10 @@ + + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_signal_wifi_transient_animation.xml b/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_signal_wifi_transient_animation.xml new file mode 100644 index 000000000..f96ae041a --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_signal_wifi_transient_animation.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_signal_wifi_transient_animation_drawable.xml b/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_signal_wifi_transient_animation_drawable.xml new file mode 100644 index 000000000..17297d38a --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_signal_wifi_transient_animation_drawable.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_4_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_4_signal_0.xml new file mode 100644 index 000000000..17297d38a --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_4_signal_0.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_4_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_4_signal_1.xml new file mode 100644 index 000000000..361725009 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_4_signal_1.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_4_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_4_signal_2.xml new file mode 100644 index 000000000..a9c6992e5 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_4_signal_2.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_4_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_4_signal_3.xml new file mode 100644 index 000000000..d902c2970 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_4_signal_3.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_4_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_4_signal_4.xml new file mode 100644 index 000000000..f96ae041a --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_4_signal_4.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_5_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_5_signal_0.xml new file mode 100644 index 000000000..17297d38a --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_5_signal_0.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_5_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_5_signal_1.xml new file mode 100644 index 000000000..361725009 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_5_signal_1.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_5_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_5_signal_2.xml new file mode 100644 index 000000000..a9c6992e5 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_5_signal_2.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_5_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_5_signal_3.xml new file mode 100644 index 000000000..d902c2970 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_5_signal_3.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_5_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_5_signal_4.xml new file mode 100644 index 000000000..f96ae041a --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_5_signal_4.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_6_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_6_signal_0.xml new file mode 100644 index 000000000..17297d38a --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_6_signal_0.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_6_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_6_signal_1.xml new file mode 100644 index 000000000..361725009 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_6_signal_1.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_6_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_6_signal_2.xml new file mode 100644 index 000000000..a9c6992e5 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_6_signal_2.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_6_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_6_signal_3.xml new file mode 100644 index 000000000..d902c2970 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_6_signal_3.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_6_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_6_signal_4.xml new file mode 100644 index 000000000..f96ae041a --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_6_signal_4.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_signal_0.xml new file mode 100644 index 000000000..17297d38a --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_signal_0.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_signal_1.xml new file mode 100644 index 000000000..361725009 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_signal_1.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_signal_2.xml new file mode 100644 index 000000000..a9c6992e5 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_signal_2.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_signal_3.xml new file mode 100644 index 000000000..d902c2970 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_signal_3.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_signal_4.xml new file mode 100644 index 000000000..f96ae041a --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI3/res/drawable/ic_wifi_signal_4.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_signal_wifi_transient_animation.xml b/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_signal_wifi_transient_animation.xml new file mode 100644 index 000000000..59db1a957 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_signal_wifi_transient_animation.xml @@ -0,0 +1,38 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_signal_wifi_transient_animation_drawable.xml b/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_signal_wifi_transient_animation_drawable.xml new file mode 100644 index 000000000..59db1a957 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_signal_wifi_transient_animation_drawable.xml @@ -0,0 +1,38 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_4_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_4_signal_0.xml new file mode 100644 index 000000000..59db1a957 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_4_signal_0.xml @@ -0,0 +1,38 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_4_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_4_signal_1.xml new file mode 100644 index 000000000..1ea85488b --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_4_signal_1.xml @@ -0,0 +1,30 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_4_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_4_signal_2.xml new file mode 100644 index 000000000..b366d77d9 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_4_signal_2.xml @@ -0,0 +1,38 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_4_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_4_signal_3.xml new file mode 100644 index 000000000..d827bca42 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_4_signal_3.xml @@ -0,0 +1,46 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_4_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_4_signal_4.xml new file mode 100644 index 000000000..7c0a964be --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_4_signal_4.xml @@ -0,0 +1,46 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_5_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_5_signal_0.xml new file mode 100644 index 000000000..59db1a957 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_5_signal_0.xml @@ -0,0 +1,38 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_5_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_5_signal_1.xml new file mode 100644 index 000000000..1ea85488b --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_5_signal_1.xml @@ -0,0 +1,30 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_5_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_5_signal_2.xml new file mode 100644 index 000000000..b366d77d9 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_5_signal_2.xml @@ -0,0 +1,38 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_5_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_5_signal_3.xml new file mode 100644 index 000000000..d827bca42 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_5_signal_3.xml @@ -0,0 +1,46 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_5_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_5_signal_4.xml new file mode 100644 index 000000000..7c0a964be --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_5_signal_4.xml @@ -0,0 +1,46 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_6_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_6_signal_0.xml new file mode 100644 index 000000000..59db1a957 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_6_signal_0.xml @@ -0,0 +1,38 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_6_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_6_signal_1.xml new file mode 100644 index 000000000..1ea85488b --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_6_signal_1.xml @@ -0,0 +1,30 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_6_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_6_signal_2.xml new file mode 100644 index 000000000..b366d77d9 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_6_signal_2.xml @@ -0,0 +1,38 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_6_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_6_signal_3.xml new file mode 100644 index 000000000..d827bca42 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_6_signal_3.xml @@ -0,0 +1,46 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_6_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_6_signal_4.xml new file mode 100644 index 000000000..7c0a964be --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_6_signal_4.xml @@ -0,0 +1,46 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_signal_0.xml new file mode 100644 index 000000000..59db1a957 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_signal_0.xml @@ -0,0 +1,38 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_signal_1.xml new file mode 100644 index 000000000..1ea85488b --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_signal_1.xml @@ -0,0 +1,30 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_signal_2.xml new file mode 100644 index 000000000..b366d77d9 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_signal_2.xml @@ -0,0 +1,38 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_signal_3.xml new file mode 100644 index 000000000..d827bca42 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_signal_3.xml @@ -0,0 +1,46 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_signal_4.xml new file mode 100644 index 000000000..7c0a964be --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI4/res/drawable/ic_wifi_signal_4.xml @@ -0,0 +1,46 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_signal_wifi_transient_animation.xml b/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_signal_wifi_transient_animation.xml new file mode 100644 index 000000000..85643697a --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_signal_wifi_transient_animation.xml @@ -0,0 +1,30 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_signal_wifi_transient_animation_drawable.xml b/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_signal_wifi_transient_animation_drawable.xml new file mode 100644 index 000000000..85643697a --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_signal_wifi_transient_animation_drawable.xml @@ -0,0 +1,30 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_4_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_4_signal_0.xml new file mode 100644 index 000000000..85643697a --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_4_signal_0.xml @@ -0,0 +1,30 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_4_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_4_signal_1.xml new file mode 100644 index 000000000..500617c4b --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_4_signal_1.xml @@ -0,0 +1,22 @@ + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_4_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_4_signal_2.xml new file mode 100644 index 000000000..f0aa6e016 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_4_signal_2.xml @@ -0,0 +1,22 @@ + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_4_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_4_signal_3.xml new file mode 100644 index 000000000..23c0e7f0f --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_4_signal_3.xml @@ -0,0 +1,22 @@ + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_4_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_4_signal_4.xml new file mode 100644 index 000000000..23c0e7f0f --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_4_signal_4.xml @@ -0,0 +1,22 @@ + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_5_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_5_signal_0.xml new file mode 100644 index 000000000..85643697a --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_5_signal_0.xml @@ -0,0 +1,30 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_5_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_5_signal_1.xml new file mode 100644 index 000000000..500617c4b --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_5_signal_1.xml @@ -0,0 +1,22 @@ + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_5_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_5_signal_2.xml new file mode 100644 index 000000000..f0aa6e016 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_5_signal_2.xml @@ -0,0 +1,22 @@ + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_5_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_5_signal_3.xml new file mode 100644 index 000000000..23c0e7f0f --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_5_signal_3.xml @@ -0,0 +1,22 @@ + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_5_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_5_signal_4.xml new file mode 100644 index 000000000..23c0e7f0f --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_5_signal_4.xml @@ -0,0 +1,22 @@ + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_6_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_6_signal_0.xml new file mode 100644 index 000000000..85643697a --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_6_signal_0.xml @@ -0,0 +1,30 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_6_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_6_signal_1.xml new file mode 100644 index 000000000..500617c4b --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_6_signal_1.xml @@ -0,0 +1,22 @@ + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_6_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_6_signal_2.xml new file mode 100644 index 000000000..f0aa6e016 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_6_signal_2.xml @@ -0,0 +1,22 @@ + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_6_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_6_signal_3.xml new file mode 100644 index 000000000..23c0e7f0f --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_6_signal_3.xml @@ -0,0 +1,22 @@ + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_6_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_6_signal_4.xml new file mode 100644 index 000000000..23c0e7f0f --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_6_signal_4.xml @@ -0,0 +1,22 @@ + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_signal_0.xml new file mode 100644 index 000000000..85643697a --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_signal_0.xml @@ -0,0 +1,30 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_signal_1.xml new file mode 100644 index 000000000..500617c4b --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_signal_1.xml @@ -0,0 +1,22 @@ + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_signal_2.xml new file mode 100644 index 000000000..f0aa6e016 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_signal_2.xml @@ -0,0 +1,22 @@ + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_signal_3.xml new file mode 100644 index 000000000..23c0e7f0f --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_signal_3.xml @@ -0,0 +1,22 @@ + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_signal_4.xml new file mode 100644 index 000000000..23c0e7f0f --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI5/res/drawable/ic_wifi_signal_4.xml @@ -0,0 +1,22 @@ + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_signal_wifi_transient_animation.xml b/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_signal_wifi_transient_animation.xml new file mode 100644 index 000000000..eef571d59 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_signal_wifi_transient_animation.xml @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_signal_wifi_transient_animation_drawable.xml b/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_signal_wifi_transient_animation_drawable.xml new file mode 100644 index 000000000..eef571d59 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_signal_wifi_transient_animation_drawable.xml @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_4_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_4_signal_0.xml new file mode 100644 index 000000000..927d22325 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_4_signal_0.xml @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_4_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_4_signal_1.xml new file mode 100644 index 000000000..867de6807 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_4_signal_1.xml @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_4_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_4_signal_2.xml new file mode 100644 index 000000000..e2207408d --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_4_signal_2.xml @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_4_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_4_signal_3.xml new file mode 100644 index 000000000..eef571d59 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_4_signal_3.xml @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_4_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_4_signal_4.xml new file mode 100644 index 000000000..eef571d59 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_4_signal_4.xml @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_5_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_5_signal_0.xml new file mode 100644 index 000000000..927d22325 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_5_signal_0.xml @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_5_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_5_signal_1.xml new file mode 100644 index 000000000..867de6807 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_5_signal_1.xml @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_5_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_5_signal_2.xml new file mode 100644 index 000000000..e2207408d --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_5_signal_2.xml @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_5_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_5_signal_3.xml new file mode 100644 index 000000000..eef571d59 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_5_signal_3.xml @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_5_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_5_signal_4.xml new file mode 100644 index 000000000..eef571d59 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_5_signal_4.xml @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_6_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_6_signal_0.xml new file mode 100644 index 000000000..927d22325 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_6_signal_0.xml @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_6_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_6_signal_1.xml new file mode 100644 index 000000000..867de6807 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_6_signal_1.xml @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_6_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_6_signal_2.xml new file mode 100644 index 000000000..e2207408d --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_6_signal_2.xml @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_6_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_6_signal_3.xml new file mode 100644 index 000000000..eef571d59 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_6_signal_3.xml @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_6_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_6_signal_4.xml new file mode 100644 index 000000000..eef571d59 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_6_signal_4.xml @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_signal_0.xml new file mode 100644 index 000000000..927d22325 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_signal_0.xml @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_signal_1.xml new file mode 100644 index 000000000..867de6807 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_signal_1.xml @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_signal_2.xml new file mode 100644 index 000000000..e2207408d --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_signal_2.xml @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_signal_3.xml new file mode 100644 index 000000000..eef571d59 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_signal_3.xml @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_signal_4.xml new file mode 100644 index 000000000..eef571d59 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI6/res/drawable/ic_wifi_signal_4.xml @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_signal_wifi_transient_animation.xml b/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_signal_wifi_transient_animation.xml new file mode 100644 index 000000000..4df9bc617 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_signal_wifi_transient_animation.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_signal_wifi_transient_animation_drawable.xml b/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_signal_wifi_transient_animation_drawable.xml new file mode 100644 index 000000000..4df9bc617 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_signal_wifi_transient_animation_drawable.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_4_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_4_signal_0.xml new file mode 100644 index 000000000..4df9bc617 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_4_signal_0.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_4_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_4_signal_1.xml new file mode 100644 index 000000000..ece630995 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_4_signal_1.xml @@ -0,0 +1,9 @@ + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_4_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_4_signal_2.xml new file mode 100644 index 000000000..41e4caea8 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_4_signal_2.xml @@ -0,0 +1,9 @@ + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_4_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_4_signal_3.xml new file mode 100644 index 000000000..6e7a27fb8 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_4_signal_3.xml @@ -0,0 +1,9 @@ + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_4_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_4_signal_4.xml new file mode 100644 index 000000000..70e9d7a9e --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_4_signal_4.xml @@ -0,0 +1,9 @@ + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_5_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_5_signal_0.xml new file mode 100644 index 000000000..4df9bc617 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_5_signal_0.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_5_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_5_signal_1.xml new file mode 100644 index 000000000..ece630995 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_5_signal_1.xml @@ -0,0 +1,9 @@ + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_5_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_5_signal_2.xml new file mode 100644 index 000000000..41e4caea8 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_5_signal_2.xml @@ -0,0 +1,9 @@ + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_5_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_5_signal_3.xml new file mode 100644 index 000000000..6e7a27fb8 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_5_signal_3.xml @@ -0,0 +1,9 @@ + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_5_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_5_signal_4.xml new file mode 100644 index 000000000..70e9d7a9e --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_5_signal_4.xml @@ -0,0 +1,9 @@ + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_6_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_6_signal_0.xml new file mode 100644 index 000000000..4df9bc617 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_6_signal_0.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_6_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_6_signal_1.xml new file mode 100644 index 000000000..ece630995 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_6_signal_1.xml @@ -0,0 +1,9 @@ + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_6_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_6_signal_2.xml new file mode 100644 index 000000000..41e4caea8 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_6_signal_2.xml @@ -0,0 +1,9 @@ + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_6_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_6_signal_3.xml new file mode 100644 index 000000000..6e7a27fb8 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_6_signal_3.xml @@ -0,0 +1,9 @@ + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_6_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_6_signal_4.xml new file mode 100644 index 000000000..70e9d7a9e --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_6_signal_4.xml @@ -0,0 +1,9 @@ + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_signal_0.xml new file mode 100644 index 000000000..4df9bc617 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_signal_0.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_signal_1.xml new file mode 100644 index 000000000..ece630995 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_signal_1.xml @@ -0,0 +1,9 @@ + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_signal_2.xml new file mode 100644 index 000000000..41e4caea8 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_signal_2.xml @@ -0,0 +1,9 @@ + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_signal_3.xml new file mode 100644 index 000000000..6e7a27fb8 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_signal_3.xml @@ -0,0 +1,9 @@ + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_signal_4.xml new file mode 100644 index 000000000..70e9d7a9e --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI7/res/drawable/ic_wifi_signal_4.xml @@ -0,0 +1,9 @@ + + + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_signal_wifi_transient_animation.xml b/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_signal_wifi_transient_animation.xml new file mode 100644 index 000000000..e17d81062 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_signal_wifi_transient_animation.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_signal_wifi_transient_animation_drawable.xml b/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_signal_wifi_transient_animation_drawable.xml new file mode 100644 index 000000000..e17d81062 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_signal_wifi_transient_animation_drawable.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_4_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_4_signal_0.xml new file mode 100644 index 000000000..e17d81062 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_4_signal_0.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_4_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_4_signal_1.xml new file mode 100644 index 000000000..a3865f829 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_4_signal_1.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_4_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_4_signal_2.xml new file mode 100644 index 000000000..eb32dd9a8 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_4_signal_2.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_4_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_4_signal_3.xml new file mode 100644 index 000000000..aaae51a35 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_4_signal_3.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_4_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_4_signal_4.xml new file mode 100644 index 000000000..4f2da1a5d --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_4_signal_4.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_5_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_5_signal_0.xml new file mode 100644 index 000000000..e17d81062 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_5_signal_0.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_5_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_5_signal_1.xml new file mode 100644 index 000000000..a3865f829 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_5_signal_1.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_5_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_5_signal_2.xml new file mode 100644 index 000000000..eb32dd9a8 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_5_signal_2.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_5_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_5_signal_3.xml new file mode 100644 index 000000000..aaae51a35 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_5_signal_3.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_5_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_5_signal_4.xml new file mode 100644 index 000000000..4f2da1a5d --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_5_signal_4.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_6_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_6_signal_0.xml new file mode 100644 index 000000000..e17d81062 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_6_signal_0.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_6_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_6_signal_1.xml new file mode 100644 index 000000000..a3865f829 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_6_signal_1.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_6_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_6_signal_2.xml new file mode 100644 index 000000000..eb32dd9a8 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_6_signal_2.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_6_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_6_signal_3.xml new file mode 100644 index 000000000..aaae51a35 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_6_signal_3.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_6_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_6_signal_4.xml new file mode 100644 index 000000000..4f2da1a5d --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_6_signal_4.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_signal_0.xml new file mode 100644 index 000000000..e17d81062 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_signal_0.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_signal_1.xml new file mode 100644 index 000000000..a3865f829 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_signal_1.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_signal_2.xml new file mode 100644 index 000000000..eb32dd9a8 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_signal_2.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_signal_3.xml new file mode 100644 index 000000000..aaae51a35 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_signal_3.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_signal_4.xml new file mode 100644 index 000000000..4f2da1a5d --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI8/res/drawable/ic_wifi_signal_4.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_signal_wifi_transient_animation.xml b/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_signal_wifi_transient_animation.xml new file mode 100644 index 000000000..3509c4ead --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_signal_wifi_transient_animation.xml @@ -0,0 +1,22 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_signal_wifi_transient_animation_drawable.xml b/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_signal_wifi_transient_animation_drawable.xml new file mode 100644 index 000000000..3509c4ead --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_signal_wifi_transient_animation_drawable.xml @@ -0,0 +1,22 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_4_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_4_signal_0.xml new file mode 100644 index 000000000..3509c4ead --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_4_signal_0.xml @@ -0,0 +1,22 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_4_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_4_signal_1.xml new file mode 100644 index 000000000..175ec6658 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_4_signal_1.xml @@ -0,0 +1,22 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_4_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_4_signal_2.xml new file mode 100644 index 000000000..702a4471f --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_4_signal_2.xml @@ -0,0 +1,22 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_4_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_4_signal_3.xml new file mode 100644 index 000000000..2b58058e3 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_4_signal_3.xml @@ -0,0 +1,22 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_4_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_4_signal_4.xml new file mode 100644 index 000000000..f84d7689d --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_4_signal_4.xml @@ -0,0 +1,22 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_5_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_5_signal_0.xml new file mode 100644 index 000000000..3509c4ead --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_5_signal_0.xml @@ -0,0 +1,22 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_5_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_5_signal_1.xml new file mode 100644 index 000000000..175ec6658 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_5_signal_1.xml @@ -0,0 +1,22 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_5_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_5_signal_2.xml new file mode 100644 index 000000000..702a4471f --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_5_signal_2.xml @@ -0,0 +1,22 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_5_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_5_signal_3.xml new file mode 100644 index 000000000..2b58058e3 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_5_signal_3.xml @@ -0,0 +1,22 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_5_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_5_signal_4.xml new file mode 100644 index 000000000..f84d7689d --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_5_signal_4.xml @@ -0,0 +1,22 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_6_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_6_signal_0.xml new file mode 100644 index 000000000..3509c4ead --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_6_signal_0.xml @@ -0,0 +1,22 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_6_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_6_signal_1.xml new file mode 100644 index 000000000..175ec6658 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_6_signal_1.xml @@ -0,0 +1,22 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_6_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_6_signal_2.xml new file mode 100644 index 000000000..702a4471f --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_6_signal_2.xml @@ -0,0 +1,22 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_6_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_6_signal_3.xml new file mode 100644 index 000000000..2b58058e3 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_6_signal_3.xml @@ -0,0 +1,22 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_6_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_6_signal_4.xml new file mode 100644 index 000000000..f84d7689d --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_6_signal_4.xml @@ -0,0 +1,22 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_signal_0.xml b/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_signal_0.xml new file mode 100644 index 000000000..3509c4ead --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_signal_0.xml @@ -0,0 +1,22 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_signal_1.xml b/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_signal_1.xml new file mode 100644 index 000000000..175ec6658 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_signal_1.xml @@ -0,0 +1,22 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_signal_2.xml b/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_signal_2.xml new file mode 100644 index 000000000..702a4471f --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_signal_2.xml @@ -0,0 +1,22 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_signal_3.xml b/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_signal_3.xml new file mode 100644 index 000000000..2b58058e3 --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_signal_3.xml @@ -0,0 +1,22 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_signal_4.xml b/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_signal_4.xml new file mode 100644 index 000000000..f84d7689d --- /dev/null +++ b/app/src/main/assets/Overlays/android/WIFI9/res/drawable/ic_wifi_signal_4.xml @@ -0,0 +1,22 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/Overlays/com.android.systemui/IPSUI1/res/raw/udfps_aod_fp.json b/app/src/main/assets/Overlays/com.android.systemui/IPSUI1/res/raw/udfps_aod_fp.json deleted file mode 100644 index bc5045b9e..000000000 --- a/app/src/main/assets/Overlays/com.android.systemui/IPSUI1/res/raw/udfps_aod_fp.json +++ /dev/null @@ -1,1559 +0,0 @@ -{ - "nm": "Untitled file", - "ddd": 0, - "h": 24, - "w": 24, - "meta": { - "g": "@lottiefiles/creator 1.9.0" - }, - "layers": [ - { - "ty": 4, - "nm": "Shape Layer 1", - "sr": 1, - "st": 0, - "op": 60, - "ip": 0, - "hd": false, - "ddd": 0, - "bm": 0, - "hasMask": false, - "ao": 0, - "ks": { - "a": { - "a": 0, - "k": [ - 12, - 12 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 12, - 12 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 100 - } - }, - "shapes": [ - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 1", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 1", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - 0.8819999999999979, - 1.205 - ], - [ - -0.4460000000000015, - 0.3259999999999996 - ], - [ - -0.3269999999999982, - -0.44700000000000006 - ], - [ - 0, - -1.9250000000000007 - ], - [ - 0, - 0 - ], - [ - 0.5530000000000008, - 0 - ] - ], - "o": [ - [ - -0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -1.4969999999999999 - ], - [ - -0.3249999999999993, - -0.4449999999999994 - ], - [ - 0.4469999999999992, - -0.3260000000000005 - ], - [ - 1.1329999999999991, - 1.5490000000000004 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 20, - 20 - ], - [ - 19, - 19 - ], - [ - 19, - 12 - ], - [ - 17.652, - 7.869 - ], - [ - 17.869, - 6.472 - ], - [ - 19.267, - 6.69 - ], - [ - 21, - 12 - ], - [ - 21, - 19 - ], - [ - 20, - 20 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 1, - 1, - 1, - 1 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 19.22976779937744, - 13.139584064483643 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 19.22976779937744, - 13.139584064483643 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 100 - } - } - ] - }, - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 2", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 2", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - -4.963, - 0 - ], - [ - -1.2600000000000016, - -0.6339999999999999 - ], - [ - 0.2480000000000011, - -0.4930000000000003 - ], - [ - 0.4900000000000002, - 0.24600000000000044 - ], - [ - 1.1050000000000004, - 0 - ], - [ - 0, - -3.859 - ], - [ - 0, - 0 - ], - [ - 0.5529999999999999, - 0 - ] - ], - "o": [ - [ - -0.5529999999999999, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -4.963 - ], - [ - 1.4209999999999994, - 0 - ], - [ - 0.49299999999999855, - 0.24800000000000022 - ], - [ - -0.2480000000000011, - 0.4939999999999998 - ], - [ - -0.9779999999999998, - -0.492 - ], - [ - -3.859, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 4, - 14 - ], - [ - 3, - 13 - ], - [ - 3, - 12 - ], - [ - 12, - 3 - ], - [ - 16.039, - 3.955 - ], - [ - 16.483, - 5.298 - ], - [ - 15.14, - 5.742 - ], - [ - 12, - 5 - ], - [ - 5, - 12 - ], - [ - 5, - 13 - ], - [ - 4, - 14 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 1, - 1, - 1, - 1 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 9.789691925048828, - 8.5 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 9.789691925048828, - 8.5 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 100 - } - } - ] - }, - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 3", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 3", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - -0.5529999999999999, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - 0.5529999999999999, - 0 - ] - ], - "o": [ - [ - -0.5529999999999999, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0.5529999999999999, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 4, - 20 - ], - [ - 3, - 19 - ], - [ - 3, - 16 - ], - [ - 4, - 15 - ], - [ - 5, - 16 - ], - [ - 5, - 19 - ], - [ - 4, - 20 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 1, - 1, - 1, - 1 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 4, - 17.5 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 4, - 17.5 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 100 - } - } - ] - }, - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 4", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 4", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - -0.5530000000000008, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - 0.5530000000000008, - 0 - ] - ], - "o": [ - [ - -0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 16, - 21 - ], - [ - 15, - 20 - ], - [ - 15, - 17 - ], - [ - 16, - 16 - ], - [ - 17, - 17 - ], - [ - 17, - 20 - ], - [ - 16, - 21 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 1, - 1, - 1, - 1 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 16, - 18.5 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 16, - 18.5 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 100 - } - } - ] - }, - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 5", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 5", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - 1.654, - 0 - ], - [ - 0.4339999999999993, - -1.1679999999999993 - ], - [ - 0.5140000000000002, - 0.18900000000000006 - ], - [ - -0.19199999999999928, - 0.5169999999999995 - ], - [ - -2.0790000000000006, - 0 - ], - [ - 0, - -2.7569999999999997 - ], - [ - 0, - 0 - ], - [ - 0.5530000000000008, - 0 - ] - ], - "o": [ - [ - -0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -1.654 - ], - [ - -1.2469999999999999, - 0 - ], - [ - -0.1930000000000014, - 0.5200000000000014 - ], - [ - -0.5179999999999998, - -0.19299999999999962 - ], - [ - 0.7250000000000005, - -1.947000000000001 - ], - [ - 2.7569999999999997, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 16, - 15 - ], - [ - 15, - 14 - ], - [ - 15, - 12 - ], - [ - 12, - 9 - ], - [ - 9.188, - 10.953 - ], - [ - 7.902, - 11.542 - ], - [ - 7.313, - 10.256 - ], - [ - 12, - 7 - ], - [ - 17, - 12 - ], - [ - 17, - 14 - ], - [ - 16, - 15 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 1, - 1, - 1, - 1 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 12.125400066375732, - 11 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 12.125400066375732, - 11 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 100 - } - } - ] - }, - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 6", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 6", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - -0.5529999999999999, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - 0.5530000000000008, - 0 - ] - ], - "o": [ - [ - -0.5529999999999999, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 8, - 21 - ], - [ - 7, - 20 - ], - [ - 7, - 14 - ], - [ - 8, - 13 - ], - [ - 9, - 14 - ], - [ - 9, - 20 - ], - [ - 8, - 21 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 1, - 1, - 1, - 1 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 8, - 17 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 8, - 17 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 100 - } - } - ] - }, - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 7", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 7", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - -0.5530000000000008, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - 0.5530000000000008, - 0 - ] - ], - "o": [ - [ - -0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 12, - 15 - ], - [ - 11, - 14 - ], - [ - 11, - 12 - ], - [ - 12, - 11 - ], - [ - 13, - 12 - ], - [ - 13, - 14 - ], - [ - 12, - 15 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 1, - 1, - 1, - 1 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 12, - 13 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 12, - 13 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 100 - } - } - ] - }, - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 8", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 8", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - -0.5530000000000008, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - 0.5530000000000008, - 0 - ] - ], - "o": [ - [ - -0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 12, - 21 - ], - [ - 11, - 20 - ], - [ - 11, - 17 - ], - [ - 12, - 16 - ], - [ - 13, - 17 - ], - [ - 13, - 20 - ], - [ - 12, - 21 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 1, - 1, - 1, - 1 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 12, - 18.5 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 12, - 18.5 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 100 - } - } - ] - } - ], - "ind": 1 - } - ], - "v": "5.7.0", - "fr": 30, - "op": 60, - "ip": 0, - "assets": [] -} \ No newline at end of file diff --git a/app/src/main/assets/Overlays/com.android.systemui/IPSUI1/res/raw/udfps_lockscreen_fp.json b/app/src/main/assets/Overlays/com.android.systemui/IPSUI1/res/raw/udfps_lockscreen_fp.json deleted file mode 100644 index 0e73de39b..000000000 --- a/app/src/main/assets/Overlays/com.android.systemui/IPSUI1/res/raw/udfps_lockscreen_fp.json +++ /dev/null @@ -1,1551 +0,0 @@ -{ - "nm": "fingerprint_burn_in_loop", - "ddd": 0, - "h": 24, - "w": 24, - "meta": { - "g": "@lottiefiles/creator 1.9.0" - }, - "layers": [ - { - "ty": 4, - "nm": "Shape Layer 1", - "sr": 1, - "st": 0, - "op": 45, - "ip": 0, - "hd": false, - "ddd": 0, - "bm": 0, - "hasMask": false, - "ao": 0, - "ks": { - "a": { - "a": 0, - "k": [ - 12, - 12 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 12, - 12 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 100 - } - }, - "shapes": [ - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 1", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 1", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - 0.8819999999999979, - 1.205 - ], - [ - -0.4460000000000015, - 0.3259999999999996 - ], - [ - -0.3269999999999982, - -0.44700000000000006 - ], - [ - 0, - -1.9250000000000007 - ], - [ - 0, - 0 - ], - [ - 0.5530000000000008, - 0 - ] - ], - "o": [ - [ - -0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -1.4969999999999999 - ], - [ - -0.3249999999999993, - -0.4449999999999994 - ], - [ - 0.4469999999999992, - -0.3260000000000005 - ], - [ - 1.1329999999999991, - 1.5490000000000004 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 20, - 20 - ], - [ - 19, - 19 - ], - [ - 19, - 12 - ], - [ - 17.652, - 7.869 - ], - [ - 17.869, - 6.472 - ], - [ - 19.267, - 6.69 - ], - [ - 21, - 12 - ], - [ - 21, - 19 - ], - [ - 20, - 20 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 0, - 0, - 0 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 35 - } - } - ] - }, - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 2", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 2", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - -4.963, - 0 - ], - [ - -1.2600000000000016, - -0.6339999999999999 - ], - [ - 0.2480000000000011, - -0.4930000000000003 - ], - [ - 0.4900000000000002, - 0.24600000000000044 - ], - [ - 1.1050000000000004, - 0 - ], - [ - 0, - -3.859 - ], - [ - 0, - 0 - ], - [ - 0.5529999999999999, - 0 - ] - ], - "o": [ - [ - -0.5529999999999999, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -4.963 - ], - [ - 1.4209999999999994, - 0 - ], - [ - 0.49299999999999855, - 0.24800000000000022 - ], - [ - -0.2480000000000011, - 0.4939999999999998 - ], - [ - -0.9779999999999998, - -0.492 - ], - [ - -3.859, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 4, - 14 - ], - [ - 3, - 13 - ], - [ - 3, - 12 - ], - [ - 12, - 3 - ], - [ - 16.039, - 3.955 - ], - [ - 16.483, - 5.298 - ], - [ - 15.14, - 5.742 - ], - [ - 12, - 5 - ], - [ - 5, - 12 - ], - [ - 5, - 13 - ], - [ - 4, - 14 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 0, - 0, - 0 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 100 - } - } - ] - }, - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 3", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 3", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - -0.5529999999999999, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - 0.5529999999999999, - 0 - ] - ], - "o": [ - [ - -0.5529999999999999, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0.5529999999999999, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 4, - 20 - ], - [ - 3, - 19 - ], - [ - 3, - 16 - ], - [ - 4, - 15 - ], - [ - 5, - 16 - ], - [ - 5, - 19 - ], - [ - 4, - 20 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 0, - 0, - 0 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 35 - } - } - ] - }, - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 4", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 4", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - -0.5530000000000008, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - 0.5530000000000008, - 0 - ] - ], - "o": [ - [ - -0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 16, - 21 - ], - [ - 15, - 20 - ], - [ - 15, - 17 - ], - [ - 16, - 16 - ], - [ - 17, - 17 - ], - [ - 17, - 20 - ], - [ - 16, - 21 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 0, - 0, - 0 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 35 - } - } - ] - }, - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 5", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 5", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - 1.654, - 0 - ], - [ - 0.4339999999999993, - -1.1679999999999993 - ], - [ - 0.5140000000000002, - 0.18900000000000006 - ], - [ - -0.19199999999999928, - 0.5169999999999995 - ], - [ - -2.0790000000000006, - 0 - ], - [ - 0, - -2.7569999999999997 - ], - [ - 0, - 0 - ], - [ - 0.5530000000000008, - 0 - ] - ], - "o": [ - [ - -0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -1.654 - ], - [ - -1.2469999999999999, - 0 - ], - [ - -0.1930000000000014, - 0.5200000000000014 - ], - [ - -0.5179999999999998, - -0.19299999999999962 - ], - [ - 0.7250000000000005, - -1.947000000000001 - ], - [ - 2.7569999999999997, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 16, - 15 - ], - [ - 15, - 14 - ], - [ - 15, - 12 - ], - [ - 12, - 9 - ], - [ - 9.188, - 10.953 - ], - [ - 7.902, - 11.542 - ], - [ - 7.313, - 10.256 - ], - [ - 12, - 7 - ], - [ - 17, - 12 - ], - [ - 17, - 14 - ], - [ - 16, - 15 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 0, - 0, - 0 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 100 - } - } - ] - }, - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 6", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 6", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - -0.5529999999999999, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - 0.5530000000000008, - 0 - ] - ], - "o": [ - [ - -0.5529999999999999, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 8, - 21 - ], - [ - 7, - 20 - ], - [ - 7, - 14 - ], - [ - 8, - 13 - ], - [ - 9, - 14 - ], - [ - 9, - 20 - ], - [ - 8, - 21 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 0, - 0, - 0 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 35 - } - } - ] - }, - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 7", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 7", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - -0.5530000000000008, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - 0.5530000000000008, - 0 - ] - ], - "o": [ - [ - -0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 12, - 15 - ], - [ - 11, - 14 - ], - [ - 11, - 12 - ], - [ - 12, - 11 - ], - [ - 13, - 12 - ], - [ - 13, - 14 - ], - [ - 12, - 15 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 0, - 0, - 0 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 35 - } - } - ] - }, - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 8", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 8", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - -0.5530000000000008, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - 0.5530000000000008, - 0 - ] - ], - "o": [ - [ - -0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 12, - 21 - ], - [ - 11, - 20 - ], - [ - 11, - 17 - ], - [ - 12, - 16 - ], - [ - 13, - 17 - ], - [ - 13, - 20 - ], - [ - 12, - 21 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 0, - 0, - 0 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 100 - } - } - ] - } - ], - "ind": 1 - } - ], - "v": "5.7.0", - "fr": 15, - "op": 15, - "ip": 0, - "assets": [] -} \ No newline at end of file diff --git a/app/src/main/assets/Overlays/com.android.systemui/IPSUI2/res/raw/udfps_aod_fp.json b/app/src/main/assets/Overlays/com.android.systemui/IPSUI2/res/raw/udfps_aod_fp.json deleted file mode 100644 index bc5045b9e..000000000 --- a/app/src/main/assets/Overlays/com.android.systemui/IPSUI2/res/raw/udfps_aod_fp.json +++ /dev/null @@ -1,1559 +0,0 @@ -{ - "nm": "Untitled file", - "ddd": 0, - "h": 24, - "w": 24, - "meta": { - "g": "@lottiefiles/creator 1.9.0" - }, - "layers": [ - { - "ty": 4, - "nm": "Shape Layer 1", - "sr": 1, - "st": 0, - "op": 60, - "ip": 0, - "hd": false, - "ddd": 0, - "bm": 0, - "hasMask": false, - "ao": 0, - "ks": { - "a": { - "a": 0, - "k": [ - 12, - 12 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 12, - 12 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 100 - } - }, - "shapes": [ - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 1", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 1", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - 0.8819999999999979, - 1.205 - ], - [ - -0.4460000000000015, - 0.3259999999999996 - ], - [ - -0.3269999999999982, - -0.44700000000000006 - ], - [ - 0, - -1.9250000000000007 - ], - [ - 0, - 0 - ], - [ - 0.5530000000000008, - 0 - ] - ], - "o": [ - [ - -0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -1.4969999999999999 - ], - [ - -0.3249999999999993, - -0.4449999999999994 - ], - [ - 0.4469999999999992, - -0.3260000000000005 - ], - [ - 1.1329999999999991, - 1.5490000000000004 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 20, - 20 - ], - [ - 19, - 19 - ], - [ - 19, - 12 - ], - [ - 17.652, - 7.869 - ], - [ - 17.869, - 6.472 - ], - [ - 19.267, - 6.69 - ], - [ - 21, - 12 - ], - [ - 21, - 19 - ], - [ - 20, - 20 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 1, - 1, - 1, - 1 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 19.22976779937744, - 13.139584064483643 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 19.22976779937744, - 13.139584064483643 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 100 - } - } - ] - }, - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 2", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 2", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - -4.963, - 0 - ], - [ - -1.2600000000000016, - -0.6339999999999999 - ], - [ - 0.2480000000000011, - -0.4930000000000003 - ], - [ - 0.4900000000000002, - 0.24600000000000044 - ], - [ - 1.1050000000000004, - 0 - ], - [ - 0, - -3.859 - ], - [ - 0, - 0 - ], - [ - 0.5529999999999999, - 0 - ] - ], - "o": [ - [ - -0.5529999999999999, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -4.963 - ], - [ - 1.4209999999999994, - 0 - ], - [ - 0.49299999999999855, - 0.24800000000000022 - ], - [ - -0.2480000000000011, - 0.4939999999999998 - ], - [ - -0.9779999999999998, - -0.492 - ], - [ - -3.859, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 4, - 14 - ], - [ - 3, - 13 - ], - [ - 3, - 12 - ], - [ - 12, - 3 - ], - [ - 16.039, - 3.955 - ], - [ - 16.483, - 5.298 - ], - [ - 15.14, - 5.742 - ], - [ - 12, - 5 - ], - [ - 5, - 12 - ], - [ - 5, - 13 - ], - [ - 4, - 14 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 1, - 1, - 1, - 1 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 9.789691925048828, - 8.5 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 9.789691925048828, - 8.5 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 100 - } - } - ] - }, - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 3", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 3", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - -0.5529999999999999, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - 0.5529999999999999, - 0 - ] - ], - "o": [ - [ - -0.5529999999999999, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0.5529999999999999, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 4, - 20 - ], - [ - 3, - 19 - ], - [ - 3, - 16 - ], - [ - 4, - 15 - ], - [ - 5, - 16 - ], - [ - 5, - 19 - ], - [ - 4, - 20 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 1, - 1, - 1, - 1 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 4, - 17.5 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 4, - 17.5 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 100 - } - } - ] - }, - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 4", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 4", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - -0.5530000000000008, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - 0.5530000000000008, - 0 - ] - ], - "o": [ - [ - -0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 16, - 21 - ], - [ - 15, - 20 - ], - [ - 15, - 17 - ], - [ - 16, - 16 - ], - [ - 17, - 17 - ], - [ - 17, - 20 - ], - [ - 16, - 21 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 1, - 1, - 1, - 1 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 16, - 18.5 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 16, - 18.5 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 100 - } - } - ] - }, - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 5", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 5", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - 1.654, - 0 - ], - [ - 0.4339999999999993, - -1.1679999999999993 - ], - [ - 0.5140000000000002, - 0.18900000000000006 - ], - [ - -0.19199999999999928, - 0.5169999999999995 - ], - [ - -2.0790000000000006, - 0 - ], - [ - 0, - -2.7569999999999997 - ], - [ - 0, - 0 - ], - [ - 0.5530000000000008, - 0 - ] - ], - "o": [ - [ - -0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -1.654 - ], - [ - -1.2469999999999999, - 0 - ], - [ - -0.1930000000000014, - 0.5200000000000014 - ], - [ - -0.5179999999999998, - -0.19299999999999962 - ], - [ - 0.7250000000000005, - -1.947000000000001 - ], - [ - 2.7569999999999997, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 16, - 15 - ], - [ - 15, - 14 - ], - [ - 15, - 12 - ], - [ - 12, - 9 - ], - [ - 9.188, - 10.953 - ], - [ - 7.902, - 11.542 - ], - [ - 7.313, - 10.256 - ], - [ - 12, - 7 - ], - [ - 17, - 12 - ], - [ - 17, - 14 - ], - [ - 16, - 15 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 1, - 1, - 1, - 1 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 12.125400066375732, - 11 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 12.125400066375732, - 11 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 100 - } - } - ] - }, - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 6", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 6", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - -0.5529999999999999, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - 0.5530000000000008, - 0 - ] - ], - "o": [ - [ - -0.5529999999999999, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 8, - 21 - ], - [ - 7, - 20 - ], - [ - 7, - 14 - ], - [ - 8, - 13 - ], - [ - 9, - 14 - ], - [ - 9, - 20 - ], - [ - 8, - 21 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 1, - 1, - 1, - 1 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 8, - 17 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 8, - 17 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 100 - } - } - ] - }, - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 7", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 7", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - -0.5530000000000008, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - 0.5530000000000008, - 0 - ] - ], - "o": [ - [ - -0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 12, - 15 - ], - [ - 11, - 14 - ], - [ - 11, - 12 - ], - [ - 12, - 11 - ], - [ - 13, - 12 - ], - [ - 13, - 14 - ], - [ - 12, - 15 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 1, - 1, - 1, - 1 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 12, - 13 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 12, - 13 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 100 - } - } - ] - }, - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 8", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 8", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - -0.5530000000000008, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - 0.5530000000000008, - 0 - ] - ], - "o": [ - [ - -0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 12, - 21 - ], - [ - 11, - 20 - ], - [ - 11, - 17 - ], - [ - 12, - 16 - ], - [ - 13, - 17 - ], - [ - 13, - 20 - ], - [ - 12, - 21 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 1, - 1, - 1, - 1 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 12, - 18.5 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 12, - 18.5 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 100 - } - } - ] - } - ], - "ind": 1 - } - ], - "v": "5.7.0", - "fr": 30, - "op": 60, - "ip": 0, - "assets": [] -} \ No newline at end of file diff --git a/app/src/main/assets/Overlays/com.android.systemui/IPSUI2/res/raw/udfps_lockscreen_fp.json b/app/src/main/assets/Overlays/com.android.systemui/IPSUI2/res/raw/udfps_lockscreen_fp.json deleted file mode 100644 index 0e73de39b..000000000 --- a/app/src/main/assets/Overlays/com.android.systemui/IPSUI2/res/raw/udfps_lockscreen_fp.json +++ /dev/null @@ -1,1551 +0,0 @@ -{ - "nm": "fingerprint_burn_in_loop", - "ddd": 0, - "h": 24, - "w": 24, - "meta": { - "g": "@lottiefiles/creator 1.9.0" - }, - "layers": [ - { - "ty": 4, - "nm": "Shape Layer 1", - "sr": 1, - "st": 0, - "op": 45, - "ip": 0, - "hd": false, - "ddd": 0, - "bm": 0, - "hasMask": false, - "ao": 0, - "ks": { - "a": { - "a": 0, - "k": [ - 12, - 12 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 12, - 12 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 100 - } - }, - "shapes": [ - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 1", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 1", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - 0.8819999999999979, - 1.205 - ], - [ - -0.4460000000000015, - 0.3259999999999996 - ], - [ - -0.3269999999999982, - -0.44700000000000006 - ], - [ - 0, - -1.9250000000000007 - ], - [ - 0, - 0 - ], - [ - 0.5530000000000008, - 0 - ] - ], - "o": [ - [ - -0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -1.4969999999999999 - ], - [ - -0.3249999999999993, - -0.4449999999999994 - ], - [ - 0.4469999999999992, - -0.3260000000000005 - ], - [ - 1.1329999999999991, - 1.5490000000000004 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 20, - 20 - ], - [ - 19, - 19 - ], - [ - 19, - 12 - ], - [ - 17.652, - 7.869 - ], - [ - 17.869, - 6.472 - ], - [ - 19.267, - 6.69 - ], - [ - 21, - 12 - ], - [ - 21, - 19 - ], - [ - 20, - 20 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 0, - 0, - 0 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 35 - } - } - ] - }, - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 2", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 2", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - -4.963, - 0 - ], - [ - -1.2600000000000016, - -0.6339999999999999 - ], - [ - 0.2480000000000011, - -0.4930000000000003 - ], - [ - 0.4900000000000002, - 0.24600000000000044 - ], - [ - 1.1050000000000004, - 0 - ], - [ - 0, - -3.859 - ], - [ - 0, - 0 - ], - [ - 0.5529999999999999, - 0 - ] - ], - "o": [ - [ - -0.5529999999999999, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -4.963 - ], - [ - 1.4209999999999994, - 0 - ], - [ - 0.49299999999999855, - 0.24800000000000022 - ], - [ - -0.2480000000000011, - 0.4939999999999998 - ], - [ - -0.9779999999999998, - -0.492 - ], - [ - -3.859, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 4, - 14 - ], - [ - 3, - 13 - ], - [ - 3, - 12 - ], - [ - 12, - 3 - ], - [ - 16.039, - 3.955 - ], - [ - 16.483, - 5.298 - ], - [ - 15.14, - 5.742 - ], - [ - 12, - 5 - ], - [ - 5, - 12 - ], - [ - 5, - 13 - ], - [ - 4, - 14 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 0, - 0, - 0 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 100 - } - } - ] - }, - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 3", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 3", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - -0.5529999999999999, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - 0.5529999999999999, - 0 - ] - ], - "o": [ - [ - -0.5529999999999999, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0.5529999999999999, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 4, - 20 - ], - [ - 3, - 19 - ], - [ - 3, - 16 - ], - [ - 4, - 15 - ], - [ - 5, - 16 - ], - [ - 5, - 19 - ], - [ - 4, - 20 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 0, - 0, - 0 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 35 - } - } - ] - }, - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 4", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 4", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - -0.5530000000000008, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - 0.5530000000000008, - 0 - ] - ], - "o": [ - [ - -0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 16, - 21 - ], - [ - 15, - 20 - ], - [ - 15, - 17 - ], - [ - 16, - 16 - ], - [ - 17, - 17 - ], - [ - 17, - 20 - ], - [ - 16, - 21 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 0, - 0, - 0 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 35 - } - } - ] - }, - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 5", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 5", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - 1.654, - 0 - ], - [ - 0.4339999999999993, - -1.1679999999999993 - ], - [ - 0.5140000000000002, - 0.18900000000000006 - ], - [ - -0.19199999999999928, - 0.5169999999999995 - ], - [ - -2.0790000000000006, - 0 - ], - [ - 0, - -2.7569999999999997 - ], - [ - 0, - 0 - ], - [ - 0.5530000000000008, - 0 - ] - ], - "o": [ - [ - -0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -1.654 - ], - [ - -1.2469999999999999, - 0 - ], - [ - -0.1930000000000014, - 0.5200000000000014 - ], - [ - -0.5179999999999998, - -0.19299999999999962 - ], - [ - 0.7250000000000005, - -1.947000000000001 - ], - [ - 2.7569999999999997, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 16, - 15 - ], - [ - 15, - 14 - ], - [ - 15, - 12 - ], - [ - 12, - 9 - ], - [ - 9.188, - 10.953 - ], - [ - 7.902, - 11.542 - ], - [ - 7.313, - 10.256 - ], - [ - 12, - 7 - ], - [ - 17, - 12 - ], - [ - 17, - 14 - ], - [ - 16, - 15 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 0, - 0, - 0 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 100 - } - } - ] - }, - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 6", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 6", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - -0.5529999999999999, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - 0.5530000000000008, - 0 - ] - ], - "o": [ - [ - -0.5529999999999999, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 8, - 21 - ], - [ - 7, - 20 - ], - [ - 7, - 14 - ], - [ - 8, - 13 - ], - [ - 9, - 14 - ], - [ - 9, - 20 - ], - [ - 8, - 21 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 0, - 0, - 0 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 35 - } - } - ] - }, - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 7", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 7", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - -0.5530000000000008, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - 0.5530000000000008, - 0 - ] - ], - "o": [ - [ - -0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 12, - 15 - ], - [ - 11, - 14 - ], - [ - 11, - 12 - ], - [ - 12, - 11 - ], - [ - 13, - 12 - ], - [ - 13, - 14 - ], - [ - 12, - 15 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 0, - 0, - 0 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 35 - } - } - ] - }, - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 8", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 8", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - -0.5530000000000008, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - 0.5530000000000008, - 0 - ] - ], - "o": [ - [ - -0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 12, - 21 - ], - [ - 11, - 20 - ], - [ - 11, - 17 - ], - [ - 12, - 16 - ], - [ - 13, - 17 - ], - [ - 13, - 20 - ], - [ - 12, - 21 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 0, - 0, - 0 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 100 - } - } - ] - } - ], - "ind": 1 - } - ], - "v": "5.7.0", - "fr": 15, - "op": 15, - "ip": 0, - "assets": [] -} \ No newline at end of file diff --git a/app/src/main/assets/Overlays/com.android.systemui/IPSUI3/res/raw/udfps_aod_fp.json b/app/src/main/assets/Overlays/com.android.systemui/IPSUI3/res/raw/udfps_aod_fp.json deleted file mode 100644 index bc5045b9e..000000000 --- a/app/src/main/assets/Overlays/com.android.systemui/IPSUI3/res/raw/udfps_aod_fp.json +++ /dev/null @@ -1,1559 +0,0 @@ -{ - "nm": "Untitled file", - "ddd": 0, - "h": 24, - "w": 24, - "meta": { - "g": "@lottiefiles/creator 1.9.0" - }, - "layers": [ - { - "ty": 4, - "nm": "Shape Layer 1", - "sr": 1, - "st": 0, - "op": 60, - "ip": 0, - "hd": false, - "ddd": 0, - "bm": 0, - "hasMask": false, - "ao": 0, - "ks": { - "a": { - "a": 0, - "k": [ - 12, - 12 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 12, - 12 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 100 - } - }, - "shapes": [ - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 1", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 1", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - 0.8819999999999979, - 1.205 - ], - [ - -0.4460000000000015, - 0.3259999999999996 - ], - [ - -0.3269999999999982, - -0.44700000000000006 - ], - [ - 0, - -1.9250000000000007 - ], - [ - 0, - 0 - ], - [ - 0.5530000000000008, - 0 - ] - ], - "o": [ - [ - -0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -1.4969999999999999 - ], - [ - -0.3249999999999993, - -0.4449999999999994 - ], - [ - 0.4469999999999992, - -0.3260000000000005 - ], - [ - 1.1329999999999991, - 1.5490000000000004 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 20, - 20 - ], - [ - 19, - 19 - ], - [ - 19, - 12 - ], - [ - 17.652, - 7.869 - ], - [ - 17.869, - 6.472 - ], - [ - 19.267, - 6.69 - ], - [ - 21, - 12 - ], - [ - 21, - 19 - ], - [ - 20, - 20 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 1, - 1, - 1, - 1 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 19.22976779937744, - 13.139584064483643 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 19.22976779937744, - 13.139584064483643 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 100 - } - } - ] - }, - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 2", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 2", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - -4.963, - 0 - ], - [ - -1.2600000000000016, - -0.6339999999999999 - ], - [ - 0.2480000000000011, - -0.4930000000000003 - ], - [ - 0.4900000000000002, - 0.24600000000000044 - ], - [ - 1.1050000000000004, - 0 - ], - [ - 0, - -3.859 - ], - [ - 0, - 0 - ], - [ - 0.5529999999999999, - 0 - ] - ], - "o": [ - [ - -0.5529999999999999, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -4.963 - ], - [ - 1.4209999999999994, - 0 - ], - [ - 0.49299999999999855, - 0.24800000000000022 - ], - [ - -0.2480000000000011, - 0.4939999999999998 - ], - [ - -0.9779999999999998, - -0.492 - ], - [ - -3.859, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 4, - 14 - ], - [ - 3, - 13 - ], - [ - 3, - 12 - ], - [ - 12, - 3 - ], - [ - 16.039, - 3.955 - ], - [ - 16.483, - 5.298 - ], - [ - 15.14, - 5.742 - ], - [ - 12, - 5 - ], - [ - 5, - 12 - ], - [ - 5, - 13 - ], - [ - 4, - 14 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 1, - 1, - 1, - 1 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 9.789691925048828, - 8.5 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 9.789691925048828, - 8.5 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 100 - } - } - ] - }, - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 3", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 3", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - -0.5529999999999999, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - 0.5529999999999999, - 0 - ] - ], - "o": [ - [ - -0.5529999999999999, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0.5529999999999999, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 4, - 20 - ], - [ - 3, - 19 - ], - [ - 3, - 16 - ], - [ - 4, - 15 - ], - [ - 5, - 16 - ], - [ - 5, - 19 - ], - [ - 4, - 20 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 1, - 1, - 1, - 1 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 4, - 17.5 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 4, - 17.5 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 100 - } - } - ] - }, - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 4", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 4", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - -0.5530000000000008, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - 0.5530000000000008, - 0 - ] - ], - "o": [ - [ - -0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 16, - 21 - ], - [ - 15, - 20 - ], - [ - 15, - 17 - ], - [ - 16, - 16 - ], - [ - 17, - 17 - ], - [ - 17, - 20 - ], - [ - 16, - 21 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 1, - 1, - 1, - 1 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 16, - 18.5 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 16, - 18.5 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 100 - } - } - ] - }, - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 5", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 5", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - 1.654, - 0 - ], - [ - 0.4339999999999993, - -1.1679999999999993 - ], - [ - 0.5140000000000002, - 0.18900000000000006 - ], - [ - -0.19199999999999928, - 0.5169999999999995 - ], - [ - -2.0790000000000006, - 0 - ], - [ - 0, - -2.7569999999999997 - ], - [ - 0, - 0 - ], - [ - 0.5530000000000008, - 0 - ] - ], - "o": [ - [ - -0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -1.654 - ], - [ - -1.2469999999999999, - 0 - ], - [ - -0.1930000000000014, - 0.5200000000000014 - ], - [ - -0.5179999999999998, - -0.19299999999999962 - ], - [ - 0.7250000000000005, - -1.947000000000001 - ], - [ - 2.7569999999999997, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 16, - 15 - ], - [ - 15, - 14 - ], - [ - 15, - 12 - ], - [ - 12, - 9 - ], - [ - 9.188, - 10.953 - ], - [ - 7.902, - 11.542 - ], - [ - 7.313, - 10.256 - ], - [ - 12, - 7 - ], - [ - 17, - 12 - ], - [ - 17, - 14 - ], - [ - 16, - 15 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 1, - 1, - 1, - 1 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 12.125400066375732, - 11 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 12.125400066375732, - 11 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 100 - } - } - ] - }, - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 6", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 6", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - -0.5529999999999999, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - 0.5530000000000008, - 0 - ] - ], - "o": [ - [ - -0.5529999999999999, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 8, - 21 - ], - [ - 7, - 20 - ], - [ - 7, - 14 - ], - [ - 8, - 13 - ], - [ - 9, - 14 - ], - [ - 9, - 20 - ], - [ - 8, - 21 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 1, - 1, - 1, - 1 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 8, - 17 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 8, - 17 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 100 - } - } - ] - }, - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 7", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 7", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - -0.5530000000000008, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - 0.5530000000000008, - 0 - ] - ], - "o": [ - [ - -0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 12, - 15 - ], - [ - 11, - 14 - ], - [ - 11, - 12 - ], - [ - 12, - 11 - ], - [ - 13, - 12 - ], - [ - 13, - 14 - ], - [ - 12, - 15 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 1, - 1, - 1, - 1 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 12, - 13 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 12, - 13 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 100 - } - } - ] - }, - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 8", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 8", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - -0.5530000000000008, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - 0.5530000000000008, - 0 - ] - ], - "o": [ - [ - -0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 12, - 21 - ], - [ - 11, - 20 - ], - [ - 11, - 17 - ], - [ - 12, - 16 - ], - [ - 13, - 17 - ], - [ - 13, - 20 - ], - [ - 12, - 21 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 1, - 1, - 1, - 1 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 12, - 18.5 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 12, - 18.5 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 100 - } - } - ] - } - ], - "ind": 1 - } - ], - "v": "5.7.0", - "fr": 30, - "op": 60, - "ip": 0, - "assets": [] -} \ No newline at end of file diff --git a/app/src/main/assets/Overlays/com.android.systemui/IPSUI3/res/raw/udfps_lockscreen_fp.json b/app/src/main/assets/Overlays/com.android.systemui/IPSUI3/res/raw/udfps_lockscreen_fp.json deleted file mode 100644 index 0e73de39b..000000000 --- a/app/src/main/assets/Overlays/com.android.systemui/IPSUI3/res/raw/udfps_lockscreen_fp.json +++ /dev/null @@ -1,1551 +0,0 @@ -{ - "nm": "fingerprint_burn_in_loop", - "ddd": 0, - "h": 24, - "w": 24, - "meta": { - "g": "@lottiefiles/creator 1.9.0" - }, - "layers": [ - { - "ty": 4, - "nm": "Shape Layer 1", - "sr": 1, - "st": 0, - "op": 45, - "ip": 0, - "hd": false, - "ddd": 0, - "bm": 0, - "hasMask": false, - "ao": 0, - "ks": { - "a": { - "a": 0, - "k": [ - 12, - 12 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 12, - 12 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 100 - } - }, - "shapes": [ - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 1", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 1", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - 0.8819999999999979, - 1.205 - ], - [ - -0.4460000000000015, - 0.3259999999999996 - ], - [ - -0.3269999999999982, - -0.44700000000000006 - ], - [ - 0, - -1.9250000000000007 - ], - [ - 0, - 0 - ], - [ - 0.5530000000000008, - 0 - ] - ], - "o": [ - [ - -0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -1.4969999999999999 - ], - [ - -0.3249999999999993, - -0.4449999999999994 - ], - [ - 0.4469999999999992, - -0.3260000000000005 - ], - [ - 1.1329999999999991, - 1.5490000000000004 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 20, - 20 - ], - [ - 19, - 19 - ], - [ - 19, - 12 - ], - [ - 17.652, - 7.869 - ], - [ - 17.869, - 6.472 - ], - [ - 19.267, - 6.69 - ], - [ - 21, - 12 - ], - [ - 21, - 19 - ], - [ - 20, - 20 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 0, - 0, - 0 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 35 - } - } - ] - }, - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 2", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 2", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - -4.963, - 0 - ], - [ - -1.2600000000000016, - -0.6339999999999999 - ], - [ - 0.2480000000000011, - -0.4930000000000003 - ], - [ - 0.4900000000000002, - 0.24600000000000044 - ], - [ - 1.1050000000000004, - 0 - ], - [ - 0, - -3.859 - ], - [ - 0, - 0 - ], - [ - 0.5529999999999999, - 0 - ] - ], - "o": [ - [ - -0.5529999999999999, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -4.963 - ], - [ - 1.4209999999999994, - 0 - ], - [ - 0.49299999999999855, - 0.24800000000000022 - ], - [ - -0.2480000000000011, - 0.4939999999999998 - ], - [ - -0.9779999999999998, - -0.492 - ], - [ - -3.859, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 4, - 14 - ], - [ - 3, - 13 - ], - [ - 3, - 12 - ], - [ - 12, - 3 - ], - [ - 16.039, - 3.955 - ], - [ - 16.483, - 5.298 - ], - [ - 15.14, - 5.742 - ], - [ - 12, - 5 - ], - [ - 5, - 12 - ], - [ - 5, - 13 - ], - [ - 4, - 14 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 0, - 0, - 0 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 100 - } - } - ] - }, - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 3", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 3", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - -0.5529999999999999, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - 0.5529999999999999, - 0 - ] - ], - "o": [ - [ - -0.5529999999999999, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0.5529999999999999, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 4, - 20 - ], - [ - 3, - 19 - ], - [ - 3, - 16 - ], - [ - 4, - 15 - ], - [ - 5, - 16 - ], - [ - 5, - 19 - ], - [ - 4, - 20 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 0, - 0, - 0 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 35 - } - } - ] - }, - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 4", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 4", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - -0.5530000000000008, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - 0.5530000000000008, - 0 - ] - ], - "o": [ - [ - -0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 16, - 21 - ], - [ - 15, - 20 - ], - [ - 15, - 17 - ], - [ - 16, - 16 - ], - [ - 17, - 17 - ], - [ - 17, - 20 - ], - [ - 16, - 21 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 0, - 0, - 0 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 35 - } - } - ] - }, - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 5", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 5", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - 1.654, - 0 - ], - [ - 0.4339999999999993, - -1.1679999999999993 - ], - [ - 0.5140000000000002, - 0.18900000000000006 - ], - [ - -0.19199999999999928, - 0.5169999999999995 - ], - [ - -2.0790000000000006, - 0 - ], - [ - 0, - -2.7569999999999997 - ], - [ - 0, - 0 - ], - [ - 0.5530000000000008, - 0 - ] - ], - "o": [ - [ - -0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -1.654 - ], - [ - -1.2469999999999999, - 0 - ], - [ - -0.1930000000000014, - 0.5200000000000014 - ], - [ - -0.5179999999999998, - -0.19299999999999962 - ], - [ - 0.7250000000000005, - -1.947000000000001 - ], - [ - 2.7569999999999997, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 16, - 15 - ], - [ - 15, - 14 - ], - [ - 15, - 12 - ], - [ - 12, - 9 - ], - [ - 9.188, - 10.953 - ], - [ - 7.902, - 11.542 - ], - [ - 7.313, - 10.256 - ], - [ - 12, - 7 - ], - [ - 17, - 12 - ], - [ - 17, - 14 - ], - [ - 16, - 15 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 0, - 0, - 0 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 100 - } - } - ] - }, - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 6", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 6", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - -0.5529999999999999, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - 0.5530000000000008, - 0 - ] - ], - "o": [ - [ - -0.5529999999999999, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 8, - 21 - ], - [ - 7, - 20 - ], - [ - 7, - 14 - ], - [ - 8, - 13 - ], - [ - 9, - 14 - ], - [ - 9, - 20 - ], - [ - 8, - 21 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 0, - 0, - 0 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 35 - } - } - ] - }, - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 7", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 7", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - -0.5530000000000008, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - 0.5530000000000008, - 0 - ] - ], - "o": [ - [ - -0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 12, - 15 - ], - [ - 11, - 14 - ], - [ - 11, - 12 - ], - [ - 12, - 11 - ], - [ - 13, - 12 - ], - [ - 13, - 14 - ], - [ - 12, - 15 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 0, - 0, - 0 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 35 - } - } - ] - }, - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 8", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 8", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - -0.5530000000000008, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - 0.5530000000000008, - 0 - ] - ], - "o": [ - [ - -0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 12, - 21 - ], - [ - 11, - 20 - ], - [ - 11, - 17 - ], - [ - 12, - 16 - ], - [ - 13, - 17 - ], - [ - 13, - 20 - ], - [ - 12, - 21 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 0, - 0, - 0 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 100 - } - } - ] - } - ], - "ind": 1 - } - ], - "v": "5.7.0", - "fr": 15, - "op": 15, - "ip": 0, - "assets": [] -} \ No newline at end of file diff --git a/app/src/main/assets/Overlays/com.android.systemui/IPSUI4/res/raw/udfps_aod_fp.json b/app/src/main/assets/Overlays/com.android.systemui/IPSUI4/res/raw/udfps_aod_fp.json deleted file mode 100644 index bc5045b9e..000000000 --- a/app/src/main/assets/Overlays/com.android.systemui/IPSUI4/res/raw/udfps_aod_fp.json +++ /dev/null @@ -1,1559 +0,0 @@ -{ - "nm": "Untitled file", - "ddd": 0, - "h": 24, - "w": 24, - "meta": { - "g": "@lottiefiles/creator 1.9.0" - }, - "layers": [ - { - "ty": 4, - "nm": "Shape Layer 1", - "sr": 1, - "st": 0, - "op": 60, - "ip": 0, - "hd": false, - "ddd": 0, - "bm": 0, - "hasMask": false, - "ao": 0, - "ks": { - "a": { - "a": 0, - "k": [ - 12, - 12 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 12, - 12 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 100 - } - }, - "shapes": [ - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 1", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 1", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - 0.8819999999999979, - 1.205 - ], - [ - -0.4460000000000015, - 0.3259999999999996 - ], - [ - -0.3269999999999982, - -0.44700000000000006 - ], - [ - 0, - -1.9250000000000007 - ], - [ - 0, - 0 - ], - [ - 0.5530000000000008, - 0 - ] - ], - "o": [ - [ - -0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -1.4969999999999999 - ], - [ - -0.3249999999999993, - -0.4449999999999994 - ], - [ - 0.4469999999999992, - -0.3260000000000005 - ], - [ - 1.1329999999999991, - 1.5490000000000004 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 20, - 20 - ], - [ - 19, - 19 - ], - [ - 19, - 12 - ], - [ - 17.652, - 7.869 - ], - [ - 17.869, - 6.472 - ], - [ - 19.267, - 6.69 - ], - [ - 21, - 12 - ], - [ - 21, - 19 - ], - [ - 20, - 20 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 1, - 1, - 1, - 1 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 19.22976779937744, - 13.139584064483643 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 19.22976779937744, - 13.139584064483643 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 100 - } - } - ] - }, - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 2", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 2", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - -4.963, - 0 - ], - [ - -1.2600000000000016, - -0.6339999999999999 - ], - [ - 0.2480000000000011, - -0.4930000000000003 - ], - [ - 0.4900000000000002, - 0.24600000000000044 - ], - [ - 1.1050000000000004, - 0 - ], - [ - 0, - -3.859 - ], - [ - 0, - 0 - ], - [ - 0.5529999999999999, - 0 - ] - ], - "o": [ - [ - -0.5529999999999999, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -4.963 - ], - [ - 1.4209999999999994, - 0 - ], - [ - 0.49299999999999855, - 0.24800000000000022 - ], - [ - -0.2480000000000011, - 0.4939999999999998 - ], - [ - -0.9779999999999998, - -0.492 - ], - [ - -3.859, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 4, - 14 - ], - [ - 3, - 13 - ], - [ - 3, - 12 - ], - [ - 12, - 3 - ], - [ - 16.039, - 3.955 - ], - [ - 16.483, - 5.298 - ], - [ - 15.14, - 5.742 - ], - [ - 12, - 5 - ], - [ - 5, - 12 - ], - [ - 5, - 13 - ], - [ - 4, - 14 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 1, - 1, - 1, - 1 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 9.789691925048828, - 8.5 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 9.789691925048828, - 8.5 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 100 - } - } - ] - }, - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 3", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 3", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - -0.5529999999999999, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - 0.5529999999999999, - 0 - ] - ], - "o": [ - [ - -0.5529999999999999, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0.5529999999999999, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 4, - 20 - ], - [ - 3, - 19 - ], - [ - 3, - 16 - ], - [ - 4, - 15 - ], - [ - 5, - 16 - ], - [ - 5, - 19 - ], - [ - 4, - 20 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 1, - 1, - 1, - 1 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 4, - 17.5 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 4, - 17.5 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 100 - } - } - ] - }, - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 4", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 4", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - -0.5530000000000008, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - 0.5530000000000008, - 0 - ] - ], - "o": [ - [ - -0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 16, - 21 - ], - [ - 15, - 20 - ], - [ - 15, - 17 - ], - [ - 16, - 16 - ], - [ - 17, - 17 - ], - [ - 17, - 20 - ], - [ - 16, - 21 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 1, - 1, - 1, - 1 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 16, - 18.5 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 16, - 18.5 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 100 - } - } - ] - }, - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 5", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 5", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - 1.654, - 0 - ], - [ - 0.4339999999999993, - -1.1679999999999993 - ], - [ - 0.5140000000000002, - 0.18900000000000006 - ], - [ - -0.19199999999999928, - 0.5169999999999995 - ], - [ - -2.0790000000000006, - 0 - ], - [ - 0, - -2.7569999999999997 - ], - [ - 0, - 0 - ], - [ - 0.5530000000000008, - 0 - ] - ], - "o": [ - [ - -0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -1.654 - ], - [ - -1.2469999999999999, - 0 - ], - [ - -0.1930000000000014, - 0.5200000000000014 - ], - [ - -0.5179999999999998, - -0.19299999999999962 - ], - [ - 0.7250000000000005, - -1.947000000000001 - ], - [ - 2.7569999999999997, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 16, - 15 - ], - [ - 15, - 14 - ], - [ - 15, - 12 - ], - [ - 12, - 9 - ], - [ - 9.188, - 10.953 - ], - [ - 7.902, - 11.542 - ], - [ - 7.313, - 10.256 - ], - [ - 12, - 7 - ], - [ - 17, - 12 - ], - [ - 17, - 14 - ], - [ - 16, - 15 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 1, - 1, - 1, - 1 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 12.125400066375732, - 11 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 12.125400066375732, - 11 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 100 - } - } - ] - }, - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 6", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 6", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - -0.5529999999999999, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - 0.5530000000000008, - 0 - ] - ], - "o": [ - [ - -0.5529999999999999, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 8, - 21 - ], - [ - 7, - 20 - ], - [ - 7, - 14 - ], - [ - 8, - 13 - ], - [ - 9, - 14 - ], - [ - 9, - 20 - ], - [ - 8, - 21 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 1, - 1, - 1, - 1 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 8, - 17 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 8, - 17 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 100 - } - } - ] - }, - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 7", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 7", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - -0.5530000000000008, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - 0.5530000000000008, - 0 - ] - ], - "o": [ - [ - -0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 12, - 15 - ], - [ - 11, - 14 - ], - [ - 11, - 12 - ], - [ - 12, - 11 - ], - [ - 13, - 12 - ], - [ - 13, - 14 - ], - [ - 12, - 15 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 1, - 1, - 1, - 1 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 12, - 13 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 12, - 13 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 100 - } - } - ] - }, - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 8", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 8", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - -0.5530000000000008, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - 0.5530000000000008, - 0 - ] - ], - "o": [ - [ - -0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 12, - 21 - ], - [ - 11, - 20 - ], - [ - 11, - 17 - ], - [ - 12, - 16 - ], - [ - 13, - 17 - ], - [ - 13, - 20 - ], - [ - 12, - 21 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 1, - 1, - 1, - 1 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 12, - 18.5 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 12, - 18.5 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 100 - } - } - ] - } - ], - "ind": 1 - } - ], - "v": "5.7.0", - "fr": 30, - "op": 60, - "ip": 0, - "assets": [] -} \ No newline at end of file diff --git a/app/src/main/assets/Overlays/com.android.systemui/IPSUI4/res/raw/udfps_lockscreen_fp.json b/app/src/main/assets/Overlays/com.android.systemui/IPSUI4/res/raw/udfps_lockscreen_fp.json deleted file mode 100644 index 0e73de39b..000000000 --- a/app/src/main/assets/Overlays/com.android.systemui/IPSUI4/res/raw/udfps_lockscreen_fp.json +++ /dev/null @@ -1,1551 +0,0 @@ -{ - "nm": "fingerprint_burn_in_loop", - "ddd": 0, - "h": 24, - "w": 24, - "meta": { - "g": "@lottiefiles/creator 1.9.0" - }, - "layers": [ - { - "ty": 4, - "nm": "Shape Layer 1", - "sr": 1, - "st": 0, - "op": 45, - "ip": 0, - "hd": false, - "ddd": 0, - "bm": 0, - "hasMask": false, - "ao": 0, - "ks": { - "a": { - "a": 0, - "k": [ - 12, - 12 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 12, - 12 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 100 - } - }, - "shapes": [ - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 1", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 1", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - 0.8819999999999979, - 1.205 - ], - [ - -0.4460000000000015, - 0.3259999999999996 - ], - [ - -0.3269999999999982, - -0.44700000000000006 - ], - [ - 0, - -1.9250000000000007 - ], - [ - 0, - 0 - ], - [ - 0.5530000000000008, - 0 - ] - ], - "o": [ - [ - -0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -1.4969999999999999 - ], - [ - -0.3249999999999993, - -0.4449999999999994 - ], - [ - 0.4469999999999992, - -0.3260000000000005 - ], - [ - 1.1329999999999991, - 1.5490000000000004 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 20, - 20 - ], - [ - 19, - 19 - ], - [ - 19, - 12 - ], - [ - 17.652, - 7.869 - ], - [ - 17.869, - 6.472 - ], - [ - 19.267, - 6.69 - ], - [ - 21, - 12 - ], - [ - 21, - 19 - ], - [ - 20, - 20 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 0, - 0, - 0 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 35 - } - } - ] - }, - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 2", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 2", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - -4.963, - 0 - ], - [ - -1.2600000000000016, - -0.6339999999999999 - ], - [ - 0.2480000000000011, - -0.4930000000000003 - ], - [ - 0.4900000000000002, - 0.24600000000000044 - ], - [ - 1.1050000000000004, - 0 - ], - [ - 0, - -3.859 - ], - [ - 0, - 0 - ], - [ - 0.5529999999999999, - 0 - ] - ], - "o": [ - [ - -0.5529999999999999, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -4.963 - ], - [ - 1.4209999999999994, - 0 - ], - [ - 0.49299999999999855, - 0.24800000000000022 - ], - [ - -0.2480000000000011, - 0.4939999999999998 - ], - [ - -0.9779999999999998, - -0.492 - ], - [ - -3.859, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 4, - 14 - ], - [ - 3, - 13 - ], - [ - 3, - 12 - ], - [ - 12, - 3 - ], - [ - 16.039, - 3.955 - ], - [ - 16.483, - 5.298 - ], - [ - 15.14, - 5.742 - ], - [ - 12, - 5 - ], - [ - 5, - 12 - ], - [ - 5, - 13 - ], - [ - 4, - 14 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 0, - 0, - 0 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 100 - } - } - ] - }, - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 3", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 3", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - -0.5529999999999999, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - 0.5529999999999999, - 0 - ] - ], - "o": [ - [ - -0.5529999999999999, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0.5529999999999999, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 4, - 20 - ], - [ - 3, - 19 - ], - [ - 3, - 16 - ], - [ - 4, - 15 - ], - [ - 5, - 16 - ], - [ - 5, - 19 - ], - [ - 4, - 20 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 0, - 0, - 0 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 35 - } - } - ] - }, - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 4", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 4", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - -0.5530000000000008, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - 0.5530000000000008, - 0 - ] - ], - "o": [ - [ - -0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 16, - 21 - ], - [ - 15, - 20 - ], - [ - 15, - 17 - ], - [ - 16, - 16 - ], - [ - 17, - 17 - ], - [ - 17, - 20 - ], - [ - 16, - 21 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 0, - 0, - 0 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 35 - } - } - ] - }, - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 5", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 5", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - 1.654, - 0 - ], - [ - 0.4339999999999993, - -1.1679999999999993 - ], - [ - 0.5140000000000002, - 0.18900000000000006 - ], - [ - -0.19199999999999928, - 0.5169999999999995 - ], - [ - -2.0790000000000006, - 0 - ], - [ - 0, - -2.7569999999999997 - ], - [ - 0, - 0 - ], - [ - 0.5530000000000008, - 0 - ] - ], - "o": [ - [ - -0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -1.654 - ], - [ - -1.2469999999999999, - 0 - ], - [ - -0.1930000000000014, - 0.5200000000000014 - ], - [ - -0.5179999999999998, - -0.19299999999999962 - ], - [ - 0.7250000000000005, - -1.947000000000001 - ], - [ - 2.7569999999999997, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 16, - 15 - ], - [ - 15, - 14 - ], - [ - 15, - 12 - ], - [ - 12, - 9 - ], - [ - 9.188, - 10.953 - ], - [ - 7.902, - 11.542 - ], - [ - 7.313, - 10.256 - ], - [ - 12, - 7 - ], - [ - 17, - 12 - ], - [ - 17, - 14 - ], - [ - 16, - 15 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 0, - 0, - 0 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 100 - } - } - ] - }, - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 6", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 6", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - -0.5529999999999999, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - 0.5530000000000008, - 0 - ] - ], - "o": [ - [ - -0.5529999999999999, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 8, - 21 - ], - [ - 7, - 20 - ], - [ - 7, - 14 - ], - [ - 8, - 13 - ], - [ - 9, - 14 - ], - [ - 9, - 20 - ], - [ - 8, - 21 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 0, - 0, - 0 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 35 - } - } - ] - }, - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 7", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 7", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - -0.5530000000000008, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - 0.5530000000000008, - 0 - ] - ], - "o": [ - [ - -0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 12, - 15 - ], - [ - 11, - 14 - ], - [ - 11, - 12 - ], - [ - 12, - 11 - ], - [ - 13, - 12 - ], - [ - 13, - 14 - ], - [ - 12, - 15 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 0, - 0, - 0 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 35 - } - } - ] - }, - { - "ty": "gr", - "bm": 0, - "hd": false, - "nm": "Group 8", - "it": [ - { - "ty": "sh", - "bm": 0, - "hd": false, - "nm": "Path 8", - "d": 1, - "ks": { - "a": 0, - "k": { - "c": true, - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - -0.5530000000000008, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0, - 0 - ], - [ - 0.5530000000000008, - 0 - ] - ], - "o": [ - [ - -0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -0.5530000000000008 - ], - [ - 0.5530000000000008, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0.5530000000000008 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 12, - 21 - ], - [ - 11, - 20 - ], - [ - 11, - 17 - ], - [ - 12, - 16 - ], - [ - 13, - 17 - ], - [ - 13, - 20 - ], - [ - 12, - 21 - ] - ] - } - } - }, - { - "ty": "fl", - "bm": 0, - "hd": false, - "nm": "Fill", - "c": { - "a": 0, - "k": [ - 0, - 0, - 0 - ] - }, - "r": 1, - "o": { - "a": 0, - "k": 100 - } - }, - { - "ty": "tr", - "a": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ] - }, - "sk": { - "a": 0, - "k": 0 - }, - "p": { - "a": 0, - "k": [ - 0, - 0 - ] - }, - "r": { - "a": 0, - "k": 0 - }, - "sa": { - "a": 0, - "k": 0 - }, - "o": { - "a": 0, - "k": 100 - } - } - ] - } - ], - "ind": 1 - } - ], - "v": "5.7.0", - "fr": 15, - "op": 15, - "ip": 0, - "assets": [] -} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/SplashActivity.kt b/app/src/main/java/com/drdisagree/iconify/SplashActivity.kt index a5e7d79d2..4160c3837 100644 --- a/app/src/main/java/com/drdisagree/iconify/SplashActivity.kt +++ b/app/src/main/java/com/drdisagree/iconify/SplashActivity.kt @@ -2,18 +2,20 @@ package com.drdisagree.iconify import android.annotation.SuppressLint import android.content.Intent +import android.os.Build import android.os.Bundle import androidx.appcompat.app.AppCompatActivity import androidx.core.splashscreen.SplashScreen import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen import com.drdisagree.iconify.common.Preferences.XPOSED_ONLY_MODE -import com.drdisagree.iconify.config.Prefs +import com.drdisagree.iconify.config.RPrefs import com.drdisagree.iconify.ui.activities.MainActivity import com.drdisagree.iconify.ui.activities.OnboardingActivity -import com.drdisagree.iconify.utils.ModuleUtil -import com.drdisagree.iconify.utils.RootUtil -import com.drdisagree.iconify.utils.SystemUtil -import com.drdisagree.iconify.utils.overlay.OverlayUtil +import com.drdisagree.iconify.utils.ModuleUtils +import com.drdisagree.iconify.utils.RootUtils +import com.drdisagree.iconify.utils.SystemUtils +import com.drdisagree.iconify.utils.overlay.OverlayUtils +import com.drdisagree.iconify.xposed.modules.utils.BitmapSubjectSegmenter import com.google.android.material.color.DynamicColors import com.topjohnwu.superuser.Shell @@ -23,17 +25,17 @@ class SplashActivity : AppCompatActivity() { private var keepShowing = true private val runner = Runnable { Shell.getShell { _: Shell? -> - val isRooted = RootUtil.deviceProperlyRooted() - val isModuleInstalled = ModuleUtil.moduleExists() - val isOverlayInstalled = OverlayUtil.overlayExists() - var isXposedOnlyMode = Prefs.getBoolean(XPOSED_ONLY_MODE, false) - val isVersionCodeCorrect = BuildConfig.VERSION_CODE == SystemUtil.savedVersionCode + val isRooted = RootUtils.deviceProperlyRooted() + val isModuleInstalled = ModuleUtils.moduleExists() + val isOverlayInstalled = OverlayUtils.overlayExists() + var isXposedOnlyMode = RPrefs.getBoolean(XPOSED_ONLY_MODE, false) + val isVersionCodeCorrect = BuildConfig.VERSION_CODE == SystemUtils.savedVersionCode if (isRooted) { if (isOverlayInstalled) { - Prefs.putBoolean(XPOSED_ONLY_MODE, false) + RPrefs.putBoolean(XPOSED_ONLY_MODE, false) } else if (isModuleInstalled) { - Prefs.putBoolean(XPOSED_ONLY_MODE, true) + RPrefs.putBoolean(XPOSED_ONLY_MODE, true) isXposedOnlyMode = true } } @@ -48,6 +50,9 @@ class SplashActivity : AppCompatActivity() { isVersionCodeCorrect ) { keepShowing = false + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { + BitmapSubjectSegmenter(this@SplashActivity) + } Intent(this@SplashActivity, MainActivity::class.java) } else { keepShowing = false diff --git a/app/src/main/java/com/drdisagree/iconify/common/Const.kt b/app/src/main/java/com/drdisagree/iconify/common/Const.kt index 9b4303d4d..cf4a25227 100644 --- a/app/src/main/java/com/drdisagree/iconify/common/Const.kt +++ b/app/src/main/java/com/drdisagree/iconify/common/Const.kt @@ -13,7 +13,6 @@ object Const { const val WELLBEING_PACKAGE = "com.google.android.apps.wellbeing" const val GMS_PACKAGE = "com.google.android.gms" - @JvmField val SYSTEM_PACKAGES = listOf( SYSTEMUI_PACKAGE, FRAMEWORK_PACKAGE, @@ -26,6 +25,9 @@ object Const { // Telegram group const val TELEGRAM_GROUP = "https://t.me/IconifyDiscussion" + // Crowdin + const val ICONIFY_CROWDIN = "https://crowdin.com/project/iconify" + // Parse new update const val LATEST_VERSION_URL = "https://raw.githubusercontent.com/Mahmud0808/Iconify/stable/latestVersion.json" @@ -45,9 +47,10 @@ object Const { ) const val ACTION_HOOK_CHECK_REQUEST = "${BuildConfig.APPLICATION_ID}.ACTION_HOOK_CHECK_REQUEST" const val ACTION_HOOK_CHECK_RESULT = "${BuildConfig.APPLICATION_ID}.ACTION_HOOK_CHECK_RESULT" + const val ACTION_BOOT_COMPLETED = "${BuildConfig.APPLICATION_ID}.ACTION_BOOT_COMPLETED" + const val ACTION_WEATHER_INFLATED = "${BuildConfig.APPLICATION_ID}.ACTION_WEATHER_INFLATED" // Module script - @JvmField val MAGISK_UPDATE_BINARY = """ #!/sbin/sh diff --git a/app/src/main/java/com/drdisagree/iconify/common/Dynamic.kt b/app/src/main/java/com/drdisagree/iconify/common/Dynamic.kt index b2d362115..dcc395d7a 100644 --- a/app/src/main/java/com/drdisagree/iconify/common/Dynamic.kt +++ b/app/src/main/java/com/drdisagree/iconify/common/Dynamic.kt @@ -8,61 +8,47 @@ import java.io.File object Dynamic { // Grab number of overlays dynamically for each variant - @JvmField val TOTAL_BRIGHTNESSBARS = Shell.cmd("cmd overlay list | grep '....IconifyComponentBBN'").exec().out.size - @JvmField val TOTAL_BRIGHTNESSBARSPIXEL = Shell.cmd("cmd overlay list | grep '....IconifyComponentBBP'").exec().out.size - @JvmField - val TOTAL_ICONPACKS = - Shell.cmd("cmd overlay list | grep '....IconifyComponentIPAS'").exec().out.size - - @JvmField val TOTAL_NOTIFICATIONS = Shell.cmd("cmd overlay list | grep '....IconifyComponentNFN'").exec().out.size - @JvmField val TOTAL_NOTIFICATIONSPIXEL = Shell.cmd("cmd overlay list | grep '....IconifyComponentNFP'").exec().out.size - @JvmField val TOTAL_QSSHAPES = Shell.cmd("cmd overlay list | grep '....IconifyComponentQSSN'").exec().out.size - @JvmField val TOTAL_QSSHAPESPIXEL = Shell.cmd("cmd overlay list | grep '....IconifyComponentQSSP'").exec().out.size // Overlay compiler tools - @JvmField val NATIVE_LIBRARY_DIR: String = appContext.applicationInfo.nativeLibraryDir - @JvmField val AAPTLIB = File(NATIVE_LIBRARY_DIR, "libaapt.so") - @JvmField val AAPT2LIB = File(NATIVE_LIBRARY_DIR, "libaapt2.so") - @JvmField val AAPT = File(Resources.BIN_DIR, "aapt") - @JvmField val AAPT2 = File(Resources.BIN_DIR, "aapt2") - @JvmField val ZIPALIGNLIB = File(NATIVE_LIBRARY_DIR, "libzipalign.so") - @JvmField val ZIPALIGN = File(Resources.BIN_DIR, "zipalign") // Onboarding overlay installation - @JvmField var skippedInstallation = false // Device information - @JvmField val isAtleastA14 = Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE + val isAndroid14 = Build.VERSION.SDK_INT == Build.VERSION_CODES.UPSIDE_DOWN_CAKE + + // Floating action buttons + var requiresSystemUiRestart = false + var requiresDeviceRestart = false } diff --git a/app/src/main/java/com/drdisagree/iconify/common/Preferences.kt b/app/src/main/java/com/drdisagree/iconify/common/Preferences.kt index b3d4f9511..e5311c190 100644 --- a/app/src/main/java/com/drdisagree/iconify/common/Preferences.kt +++ b/app/src/main/java/com/drdisagree/iconify/common/Preferences.kt @@ -1,26 +1,70 @@ package com.drdisagree.iconify.common import com.drdisagree.iconify.SplashActivity -import com.drdisagree.iconify.config.Prefs.getBoolean +import com.drdisagree.iconify.config.RPrefs.getBoolean object Preferences { // Xposed mods + const val XPOSED_HOOK_CHECK = "xposedHookCheck" const val FORCE_RELOAD_OVERLAY_STATE = "xposed_force_reload_overlay_state" const val QS_TRANSPARENCY_SWITCH = "xposed_qstransparency" const val NOTIF_TRANSPARENCY_SWITCH = "xposed_notiftransparency" const val LOCKSCREEN_SHADE_SWITCH = "xposed_lockscreen_shade" const val QSALPHA_LEVEL = "xposed_qsalpha" const val STATUSBAR_CLOCKBG_SWITCH = "xposed_sbclockbg" - const val STATUSBAR_CLOCK_COLOR_OPTION = "xposed_sbclockcolor" - const val STATUSBAR_CLOCK_COLOR_CODE = "xposed_sbclockcolorcode" - const val CHIP_STATUSBAR_CLOCKBG_STYLE = "xposed_chipstatusbarclockbgstyle" + const val CHIP_STATUSBAR_CLOCK_SWITCH = "xposed_chipstatusbarclock" + const val CHIP_STATUSBAR_CLOCK_STYLE_CHANGED = "xposed_chipstatusbarclockstylechanged" + const val CHIP_STATUSBAR_CLOCK_TEXT_COLOR_OPTION = "xposed_sbclockcolor" + const val CHIP_STATUSBAR_CLOCK_TEXT_COLOR_CODE = "xposed_sbclockcolorcode" + const val CHIP_STATUSBAR_CLOCK_ACCENT = "xposed_chipstatusbarclockaccent" + const val CHIP_STATUSBAR_CLOCK_START_COLOR = "xposed_chipstatusbarclockstartcolor" + const val CHIP_STATUSBAR_CLOCK_END_COLOR = "xposed_chipstatusbarclockendcolor" + const val CHIP_STATUSBAR_CLOCK_GRADIENT_DIRECTION = "xposed_chipstatusbarclockgradientdirection" + const val CHIP_STATUSBAR_CLOCK_PADDING_LEFT = "xposed_chipstatusbarclockpaddingleft" + const val CHIP_STATUSBAR_CLOCK_PADDING_RIGHT = "xposed_chipstatusbarclockpaddingright" + const val CHIP_STATUSBAR_CLOCK_PADDING_TOP = "xposed_chipstatusbarclockpaddingtop" + const val CHIP_STATUSBAR_CLOCK_PADDING_BOTTOM = "xposed_chipstatusbarclockpaddingbottom" + const val CHIP_STATUSBAR_CLOCK_STROKE_SWITCH = "xposed_chipstatusbarclockstroke" + const val CHIP_STATUSBAR_CLOCK_STROKE_WIDTH = "xposed_chipstatusbarclockstrokewidth" + const val CHIP_STATUSBAR_CLOCK_STROKE_ACCENT = "xposed_chipstatusbarclockstrokeaccent" + const val CHIP_STATUSBAR_CLOCK_STROKE_COLOR = "xposed_chipstatusbarclockstrokecolor" + const val CHIP_STATUSBAR_CLOCK_STROKE_DASH = "xposed_chipstatusbarclockstrokedash" + const val CHIP_STATUSBAR_CLOCK_STROKE_DASH_WIDTH = "xposed_chipstatusbarclockstrokedashwidth" + const val CHIP_STATUSBAR_CLOCK_STROKE_DASH_GAP = "xposed_chipstatusbarclockstrokedashgap" + const val CHIP_STATUSBAR_CLOCK_RADIUS_TOP_LEFT = "xposed_chipstatusbarclockradiustopleft" + const val CHIP_STATUSBAR_CLOCK_RADIUS_TOP_RIGHT = "xposed_chipstatusbarclockradiustopright" + const val CHIP_STATUSBAR_CLOCK_RADIUS_BOTTOM_RIGHT = + "xposed_chipstatusbarclockradiusbottomright" + const val CHIP_STATUSBAR_CLOCK_RADIUS_BOTTOM_LEFT = "xposed_chipstatusbarclockradiusbottomleft" + const val CHIP_STATUS_ICONS_SWITCH = "xposed_chipstatusicons" + const val CHIP_STATUS_ICONS_STYLE_CHANGED = "xposed_chipstatusiconsstylechanged" + const val CHIP_STATUS_ICONS_ACCENT = "xposed_chipstatusiconsaccent" + const val CHIP_STATUS_ICONS_START_COLOR = "xposed_chipstatusiconsstartcolor" + const val CHIP_STATUS_ICONS_END_COLOR = "xposed_chipstatusiconsendcolor" + const val CHIP_STATUS_ICONS_GRADIENT_DIRECTION = "xposed_chipstatusiconsgradientdirection" + const val CHIP_STATUS_ICONS_PADDING_LEFT = "xposed_chipstatusiconspaddingleft" + const val CHIP_STATUS_ICONS_PADDING_RIGHT = "xposed_chipstatusiconspaddingright" + const val CHIP_STATUS_ICONS_PADDING_TOP = "xposed_chipstatusiconspaddingtop" + const val CHIP_STATUS_ICONS_PADDING_BOTTOM = "xposed_chipstatusiconspaddingbottom" + const val CHIP_STATUS_ICONS_STROKE_SWITCH = "xposed_chipstatusiconsstroke" + const val CHIP_STATUS_ICONS_STROKE_WIDTH = "xposed_chipstatusiconsstrokewidth" + const val CHIP_STATUS_ICONS_STROKE_ACCENT = "xposed_chipstatusiconsstrokeaccent" + const val CHIP_STATUS_ICONS_STROKE_COLOR = "xposed_chipstatusiconsstrokecolor" + const val CHIP_STATUS_ICONS_STROKE_DASH = "xposed_chipstatusiconsstrokedash" + const val CHIP_STATUS_ICONS_STROKE_DASH_WIDTH = "xposed_chipstatusiconsstrokedashwidth" + const val CHIP_STATUS_ICONS_STROKE_DASH_GAP = "xposed_chipstatusiconsstrokedashgap" + const val CHIP_STATUS_ICONS_RADIUS_TOP_LEFT = "xposed_chipstatusiconsradiustopleft" + const val CHIP_STATUS_ICONS_RADIUS_TOP_RIGHT = "xposed_chipstatusiconsradiustopright" + const val CHIP_STATUS_ICONS_RADIUS_BOTTOM_RIGHT = "xposed_chipstatusiconsradiusbottomright" + const val CHIP_STATUS_ICONS_RADIUS_BOTTOM_LEFT = "xposed_chipstatusiconsradiusbottomleft" const val QSPANEL_STATUSICONSBG_SWITCH = "xposed_qsstatusiconsbg" const val CHIP_QSSTATUSICONS_STYLE = "xposed_chipqsstatusiconsstyle" const val VERTICAL_QSTILE_SWITCH = "xposed_verticalqstile" const val HIDE_QSLABEL_SWITCH = "xposed_hideqslabel" const val VOLUME_PANEL_PERCENTAGE = "xposed_volumepanelpercentage" const val VOLUME_PANEL_SAFETY_WARNING = "xposed_volumepanelsafetywarning" + const val VOLUME_COLORED_RINGER_ICON = "xposed_volumecoloredringericon" const val HEADER_IMAGE_SWITCH = "xposed_headerimage" const val HEADER_IMAGE_LANDSCAPE_SWITCH = "xposed_headerimagelandscape" const val HEADER_IMAGE_BOTTOM_FADE_AMOUNT = "xposed_headerimagebottomfadeamount" @@ -42,6 +86,7 @@ object Preferences { const val HEADER_CLOCK_COLOR_CODE_ACCENT3 = "xposed_headerclockcolorcodeaccent3" const val HEADER_CLOCK_COLOR_CODE_TEXT1 = "xposed_headerclockcolorcodetext1" const val HEADER_CLOCK_COLOR_CODE_TEXT2 = "xposed_headerclockcolorcodetext2" + const val HEADER_CLOCK_EXPANSION_Y = "xposed_headerclockexpansiony" const val HEADER_CLOCK_FONT_TEXT_SCALING = "xposed_headerclocktextscaling" const val QSPANEL_HIDE_CARRIER = "xposed_qspanelhidecarrier" const val LSCLOCK_SWITCH = "xposed_lockscreenclock" @@ -57,10 +102,49 @@ object Preferences { const val LSCLOCK_FONT_SWITCH = "xposed_lockscreenclockfont" const val LSCLOCK_FONT_LINEHEIGHT = "xposed_lockscreenclockfontlineheight" const val LSCLOCK_FONT_TEXT_SCALING = "xposed_lockscreenclocktextscaling" + const val LSCLOCK_USERNAME = "xposed_lockscreenclockcustomusername" + const val LSCLOCK_DEVICENAME = "xposed_lockscreenclockcustomdevicename" + + // LS Widgets + const val LOCKSCREEN_WIDGETS_ENABLED: String = "lockscreen_widgets_enabled" + const val LOCKSCREEN_WIDGETS_DEVICE_WIDGET: String = "lockscreen_device_widget" + const val LOCKSCREEN_WIDGETS: String = "lockscreen_widgets" + const val LOCKSCREEN_WIDGETS_EXTRAS: String = "lockscreen_widgets_extras" + const val MAIN_WIDGET_1_KEY: String = "main_custom_widgets1" + const val MAIN_WIDGET_2_KEY: String = "main_custom_widgets2" + const val EXTRA_WIDGET_1_KEY: String = "custom_widgets1" + const val EXTRA_WIDGET_2_KEY: String = "custom_widgets2" + const val EXTRA_WIDGET_3_KEY: String = "custom_widgets3" + const val EXTRA_WIDGET_4_KEY: String = "custom_widgets4" + const val LOCKSCREEN_WIDGETS_DEVICE_WIDGET_CUSTOM_COLOR_SWITCH: String = + "lockscreen_device_widget_custom_color" + const val LOCKSCREEN_WIDGETS_DEVICE_WIDGET_LINEAR_COLOR: String = + "lockscreen_device_widget_linear_progress_color" + const val LOCKSCREEN_WIDGETS_DEVICE_WIDGET_CIRCULAR_COLOR: String = + "lockscreen_device_widget_circular_progress_color" + const val LOCKSCREEN_WIDGETS_DEVICE_WIDGET_TEXT_COLOR: String = + "lockscreen_device_widget_text_color" + const val LOCKSCREEN_WIDGETS_DEVICE_WIDGET_DEVICE: String = + "lockscreen_device_widget_device_name" + const val LOCKSCREEN_WIDGETS_CUSTOM_COLOR: String = "lockscreen_widgets_custom_color" + const val LOCKSCREEN_WIDGETS_BIG_ACTIVE: String = "lockscreen_widgets_big_active" + const val LOCKSCREEN_WIDGETS_BIG_INACTIVE: String = "lockscreen_widgets_big_inactive" + const val LOCKSCREEN_WIDGETS_SMALL_ACTIVE: String = "lockscreen_widgets_small_active" + const val LOCKSCREEN_WIDGETS_SMALL_INACTIVE: String = "lockscreen_widgets_small_inactive" + const val LOCKSCREEN_WIDGETS_BIG_ICON_ACTIVE: String = "lockscreen_widgets_big_icon_active" + const val LOCKSCREEN_WIDGETS_BIG_ICON_INACTIVE: String = "lockscreen_widgets_big_icon_inactive" + const val LOCKSCREEN_WIDGETS_SMALL_ICON_ACTIVE: String = "lockscreen_widgets_small_icon_active" + const val LOCKSCREEN_WIDGETS_SMALL_ICON_INACTIVE: String = + "lockscreen_widgets_small_icon_inactive" + const val LOCKSCREEN_WIDGETS_BOTTOM_MARGIN: String = "lockscreen_widgets_bottom_margin" + const val LOCKSCREEN_WIDGETS_SCALE: String = "lockscreen_widgets_scale" const val FIXED_STATUS_ICONS_SWITCH = "xposed_fixedstatusicons" const val FIXED_STATUS_ICONS_SIDEMARGIN = "xposed_fixedstatusiconssidemargin" const val FIXED_STATUS_ICONS_TOPMARGIN = "xposed_fixedstatusiconstopmargin" const val HIDE_LOCKSCREEN_STATUSBAR = "xposed_hidelockscreenstatusbar" + const val SB_CLOCK_SIZE_SWITCH = "xposed_sbclocksizeswitch" + const val SB_CLOCK_SIZE = "xposed_sbclocksize" + const val COLORED_STATUSBAR_ICON = "xposed_coloredstatusbaricon" const val HIDE_LOCKSCREEN_CARRIER = "xposed_hidelockscreencarrier" const val HIDE_LOCKSCREEN_LOCK_ICON = "xposed_hidelockscreenlockicon" const val LIGHT_QSPANEL = "xposed_lightqspanel" @@ -74,11 +158,15 @@ object Preferences { const val CUSTOM_BATTERY_HEIGHT = "xposed_custombatteryheight" const val HIDE_DATA_DISABLED_ICON = "xposed_hideDataDisabledIcon" const val DEPTH_WALLPAPER_SWITCH = "xposed_depthwallpaper" + const val CUSTOM_DEPTH_WALLPAPER_SWITCH = "xposed_customdepthwallpaper" const val DEPTH_WALLPAPER_FOREGROUND_ALPHA = "xposed_depthwallpaperforegroundalpha" + const val DEPTH_WALLPAPER_ON_AOD = "xposed_depthwallpaperaonaod" const val DEPTH_WALLPAPER_FADE_ANIMATION = "xposed_depthwallpaperfadeanimation" const val DEPTH_WALLPAPER_PARALLAX_EFFECT = "xposed_depthwallpaperparallaxeffect" - const val DEPTH_WALLPAPER_BACKGROUND_MOVEMENT_MULTIPLIER = "xposed_depthwallpaperbackgroundmovementmultiplier" - const val DEPTH_WALLPAPER_FOREGROUND_MOVEMENT_MULTIPLIER = "xposed_depthwallpaperforegroundmovementmultiplier" + const val DEPTH_WALLPAPER_BACKGROUND_MOVEMENT_MULTIPLIER = + "xposed_depthwallpaperbackgroundmovementmultiplier" + const val DEPTH_WALLPAPER_FOREGROUND_MOVEMENT_MULTIPLIER = + "xposed_depthwallpaperforegroundmovementmultiplier" const val DEPTH_WALLPAPER_CHANGED = "xposed_depthwallpaperchanged" const val UNZOOM_DEPTH_WALLPAPER = "xposed_unzoomdepthwallpaper" const val CUSTOM_BATTERY_LAYOUT_REVERSE = "xposed_custombatterylayoutreverse" @@ -110,20 +198,32 @@ object Preferences { const val CUSTOM_BATTERY_INSIDE_PERCENTAGE = "xposed_custombatteryinsidepercentage" const val CUSTOM_BATTERY_HIDE_BATTERY = "xposed_custombatteryhidebattery" const val BLUR_RADIUS_VALUE = "xposed_blurradiusvalue" + const val CUSTOM_QS_MARGIN = "xposed_customqsmargin" const val QQS_TOPMARGIN = "xposed_qqspanelTopMargin" const val QS_TOPMARGIN = "xposed_qspanelTopMargin" const val FIX_QS_TILE_COLOR = "xposed_fixqstilecolor" const val FIX_NOTIFICATION_COLOR = "xposed_fixnotificationcolor" + const val FIX_NOTIFICATION_FOOTER_BUTTON_COLOR = "xposed_fixnotificationfooterbuttoncolor" const val HIDE_QS_SILENT_TEXT = "xposed_hideqssilenttext" + const val HIDE_QS_ON_LOCKSCREEN = "xposed_hideqsonlockscreen" const val HIDE_QS_FOOTER_BUTTONS = "xposed_hideqsfooterbuttons" const val QS_TEXT_ALWAYS_WHITE = "xposed_qstextalwayswhite" const val QS_TEXT_FOLLOW_ACCENT = "xposed_qstextfollowaccent" + const val OP_QS_HEADER_SWITCH = "xposed_opqsheader" + const val OP_QS_HEADER_VIBRATE = "xposed_opqsheadervibrate" + const val OP_QS_HEADER_HIDE_STOCK_MEDIA = "xposed_opqsheaderhidestockmedia" + const val OP_QS_HEADER_BLUR_LEVEL = "xposed_opqsheaderblurlevel" + const val OP_QS_HEADER_TOP_MARGIN = "xposed_opqsheadertopmargin" + const val OP_QS_HEADER_EXPANSION_Y = "xposed_opqsheaderexpansiony" + const val OP_QS_HEADER_GAP_EXPANDED = "xposed_opqsheadergapexpanded" // Xposed view tags const val ICONIFY_HEADER_CLOCK_TAG = "iconify_header_clock" const val ICONIFY_LOCKSCREEN_CLOCK_TAG = "iconify_lockscreen_clock" const val ICONIFY_DEPTH_WALLPAPER_TAG = "iconify_depth_wallpaper" const val ICONIFY_CHARGING_ICON_TAG = "iconify_charging_icon" + const val ICONIFY_QS_HEADER_CONTAINER_TAG = "iconify_qs_header_container" + const val ICONIFY_QS_HEADER_CONTAINER_SHADE_TAG = "iconify_qs_header_container_shade" // Battery styles const val BATTERY_STYLE_DEFAULT = 0 @@ -172,10 +272,10 @@ object Preferences { const val RESTART_SYSUI_BEHAVIOR_EXT = "IconifyRestartSysuiBehaviorExtended" // Preference keys - const val STR_NULL = "null" const val UPDATE_SCHEDULE = "iconify_update_schedule" const val UPDATE_CHECK_TIME = "iconify_update_check_time" const val LAST_UPDATE_CHECK_TIME = "iconify_last_update_check_time" + const val NEW_UPDATE_VERSION_CODE = "iconify_new_update_version_code" const val FIRST_INSTALL = "firstInstall" const val UPDATE_DETECTED = "updateDetected" const val ON_HOME_PAGE = "onHomePage" @@ -239,26 +339,46 @@ object Preferences { const val NAVBAR_LOW_SENS = "navbarlowsens" const val NAVBAR_HIDE_PILL = "navbarhidepill" + // Weather + const val WEATHER_SWITCH: String = "weather_switch" + const val PREF_KEY_UPDATE_STATUS: String = "update_status" + const val WEATHER_ICON_PACK: String = "weather_icon_pack" + const val WEATHER_UPDATE_INTERVAL: String = "weather_update_interval" + const val WEATHER_SHOW_LOCATION: String = "weather_show_location" + const val WEATHER_SHOW_CONDITION: String = "weather_show_condition" + const val WEATHER_SHOW_HUMIDITY: String = "weather_show_humidity" + const val WEATHER_SHOW_WIND: String = "weather_show_wind" + const val WEATHER_TEXT_SIZE: String = "weather_text_size" + const val WEATHER_ICON_SIZE: String = "weather_icon_size" + const val WEATHER_TEXT_COLOR_SWITCH: String = "weather_text_color_switch" + const val WEATHER_TEXT_COLOR: String = "weather_text_color" + const val WEATHER_OWM_KEY: String = "owm_key" + const val WEATHER_UNITS: String = "weather_units" + const val WEATHER_PROVIDER: String = "weather_provider" + const val WEATHER_CUSTOM_LOCATION: String = "weather_custom_location_switch" + const val WEATHER_CUSTOM_LOCATION_PICKER: String = "weather_custom_location_picker" + const val WEATHER_CUSTOM_MARGINS_TOP: String = "weather_custom_margins_top" + const val WEATHER_CUSTOM_MARGINS_SIDE: String = "weather_custom_margins_side" + const val WEATHER_CUSTOM_MARGINS_BOTTOM: String = "weather_custom_margins_bottom" + const val WEATHER_STYLE: String = "weather_style" + const val WEATHER_CENTER_VIEW: String = "weather_center_view" + // Settings const val APP_LANGUAGE = "IconifyAppLanguage" const val APP_ICON = "IconifyAppIcon" const val APP_THEME = "IconifyAppTheme" const val AUTO_UPDATE = "IconifyAutoUpdate" const val UPDATE_OVER_WIFI = "IconifyUpdateOverWifi" - const val SHOW_XPOSED_WARN = "IconifyShowXposedWarn" const val SHOW_HOME_CARD = "IconifyShowHomeCard" + const val VIBRATE_UI = "IconifyUiVibration" const val XPOSED_ONLY_MODE = "IconifyXposedOnlyMode" - @JvmField + const val NEW_UPDATE_FOUND = "newUpdateFound" + var isXposedOnlyMode = getBoolean(XPOSED_ONLY_MODE, true) && !SplashActivity.SKIP_TO_HOMEPAGE_FOR_TESTING // Others const val BOOT_ID = "boot_id" const val VER_CODE = "versionCode" - const val EASTER_EGG = "iconify_easter_egg" const val ALERT_DIALOG_QSROWCOL = "alertDialogQsRowCol" - const val SHOW_QS_TILE_NORMAL_WARN = "showQsTileNormalWarn" - const val SHOW_QS_TILE_PIXEL_WARN = "showQsTilePixelWarn" - const val SHOW_NOTIFICATION_NORMAL_WARN = "showNotificationNormalWarn" - const val SHOW_NOTIFICATION_PIXEL_WARN = "showNotificationPixelWarn" } diff --git a/app/src/main/java/com/drdisagree/iconify/common/References.kt b/app/src/main/java/com/drdisagree/iconify/common/References.kt index 34a5eccc5..3eca82c85 100644 --- a/app/src/main/java/com/drdisagree/iconify/common/References.kt +++ b/app/src/main/java/com/drdisagree/iconify/common/References.kt @@ -41,6 +41,5 @@ object References { const val METADATA_THEME_CATEGORY = "THEME_CATEGORY" // Overlay categories - @JvmField val OVERLAY_CATEGORY_PREFIX = BuildConfig.APPLICATION_ID.replace(".debug", "") + ".category." } diff --git a/app/src/main/java/com/drdisagree/iconify/common/Resources.kt b/app/src/main/java/com/drdisagree/iconify/common/Resources.kt index da53b4e2b..654ce73e2 100644 --- a/app/src/main/java/com/drdisagree/iconify/common/Resources.kt +++ b/app/src/main/java/com/drdisagree/iconify/common/Resources.kt @@ -1,9 +1,34 @@ package com.drdisagree.iconify.common +import android.os.Build import android.os.Environment import com.drdisagree.iconify.BuildConfig -import com.drdisagree.iconify.Iconify import com.drdisagree.iconify.Iconify.Companion.appContext +import com.drdisagree.iconify.R +import com.drdisagree.iconify.common.Preferences.FIRST_INSTALL +import com.drdisagree.iconify.common.Preferences.UPDATE_DETECTED +import com.drdisagree.iconify.config.RPrefs.getBoolean +import com.drdisagree.iconify.ui.fragments.home.Home +import com.drdisagree.iconify.ui.fragments.settings.Settings +import com.drdisagree.iconify.ui.fragments.tweaks.Tweaks +import com.drdisagree.iconify.ui.fragments.xposed.BackgroundChip +import com.drdisagree.iconify.ui.fragments.xposed.BatteryStyle +import com.drdisagree.iconify.ui.fragments.xposed.DepthWallpaper +import com.drdisagree.iconify.ui.fragments.xposed.HeaderClock +import com.drdisagree.iconify.ui.fragments.xposed.LockscreenClock +import com.drdisagree.iconify.ui.fragments.xposed.LockscreenWeather +import com.drdisagree.iconify.ui.fragments.xposed.LockscreenWidget +import com.drdisagree.iconify.ui.fragments.xposed.OpQsHeader +import com.drdisagree.iconify.ui.fragments.xposed.Others +import com.drdisagree.iconify.ui.fragments.xposed.QuickSettings +import com.drdisagree.iconify.ui.fragments.xposed.Statusbar +import com.drdisagree.iconify.ui.fragments.xposed.Themes +import com.drdisagree.iconify.ui.fragments.xposed.TransparencyBlur +import com.drdisagree.iconify.ui.fragments.xposed.VolumePanel +import com.drdisagree.iconify.ui.fragments.xposed.Xposed +import com.drdisagree.iconify.ui.models.SearchPreferenceItem +import com.drdisagree.iconify.ui.preferences.preferencesearch.SearchConfiguration +import com.drdisagree.iconify.utils.RootUtils.folderExists object Resources { @@ -12,94 +37,171 @@ object Resources { const val SHARED_XPREFERENCES = BuildConfig.APPLICATION_ID + "_xpreference" // Storage location - @JvmField val DOCUMENTS_DIR: String = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS).absolutePath - @JvmField val DOWNLOADS_DIR: String = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).absolutePath - @JvmField val LOG_DIR = "$DOCUMENTS_DIR/Iconify" const val MODULE_DIR = "/data/adb/modules/Iconify" const val SYSTEM_OVERLAY_DIR = "/system/product/overlay" - @JvmField val DATA_DIR: String = appContext.filesDir.absolutePath const val OVERLAY_DIR = "$MODULE_DIR/system/product/overlay" - @JvmField val BIN_DIR = appContext.dataDir.toString() + "/bin" - @JvmField val BACKUP_DIR = Environment.getExternalStorageDirectory().absolutePath + "/.iconify_backup" - @JvmField val TEMP_DIR = Environment.getExternalStorageDirectory().absolutePath + "/.iconify" - @JvmField val TEMP_MODULE_DIR = "$TEMP_DIR/Iconify" - @JvmField val TEMP_MODULE_OVERLAY_DIR = "$TEMP_MODULE_DIR/system/product/overlay" - @JvmField val TEMP_OVERLAY_DIR = "$TEMP_DIR/overlays" - @JvmField val TEMP_CACHE_DIR = "$TEMP_OVERLAY_DIR/cache" - @JvmField val UNSIGNED_UNALIGNED_DIR = "$TEMP_OVERLAY_DIR/unsigned_unaligned" - @JvmField val UNSIGNED_DIR = "$TEMP_OVERLAY_DIR/unsigned" - @JvmField val SIGNED_DIR = "$TEMP_OVERLAY_DIR/signed" - @JvmField val COMPANION_TEMP_DIR = "$TEMP_DIR/companion" - @JvmField val COMPANION_COMPILED_DIR = "$COMPANION_TEMP_DIR/compiled" - @JvmField val COMPANION_MODULE_DIR = "$TEMP_DIR/module/IconifyCompanion" private val COMPANION_RES_DIR = "$COMPANION_MODULE_DIR/substratumXML/SystemUI/res" - @JvmField val COMPANION_DRAWABLE_DIR = "$COMPANION_RES_DIR/drawable" - @JvmField val COMPANION_LAYOUT_DIR = "$COMPANION_RES_DIR/layout" // File resources const val FRAMEWORK_DIR = "/system/framework/framework-res.apk" // Xposed resource dir - @JvmField val XPOSED_RESOURCE_TEMP_DIR = "${Environment.getExternalStorageDirectory()}/.iconify_files" - @JvmField val LSCLOCK_FONT_DIR = "$XPOSED_RESOURCE_TEMP_DIR/lsclock_font.ttf" - @JvmField val HEADER_CLOCK_FONT_DIR = "$XPOSED_RESOURCE_TEMP_DIR/headerclock_font.ttf" - @JvmField val HEADER_IMAGE_DIR = "$XPOSED_RESOURCE_TEMP_DIR/header_image.png" - @JvmField val DEPTH_WALL_FG_DIR = "$XPOSED_RESOURCE_TEMP_DIR/depth_wallpaper_fg.png" - @JvmField val DEPTH_WALL_BG_DIR = "$XPOSED_RESOURCE_TEMP_DIR/depth_wallpaper_bg.png" // Resource names const val HEADER_CLOCK_LAYOUT = "preview_header_clock_" const val LOCKSCREEN_CLOCK_LAYOUT = "preview_lockscreen_clock_" - const val LOCKSCREEN_CLOCK_LOTTIE = "lottie_lockscreen_clock_" + + fun shouldShowRebootDialog() = (!getBoolean(FIRST_INSTALL) && getBoolean(UPDATE_DETECTED)) || + folderExists("/data/adb/modules_update/Iconify") + + val searchConfiguration = SearchConfiguration() + + val searchableFragments = arrayOf( + SearchPreferenceItem( + R.xml.home, + R.string.navbar_home, + Home(), + !Preferences.isXposedOnlyMode + ), + SearchPreferenceItem( + R.xml.tweaks, + R.string.navbar_tweaks, + Tweaks(), + !Preferences.isXposedOnlyMode + ), + SearchPreferenceItem( + R.xml.xposed, + R.string.navbar_xposed, + Xposed() + ), + SearchPreferenceItem( + R.xml.settings, + R.string.navbar_settings, + Settings() + ), + SearchPreferenceItem( + R.xml.xposed_transparency_blur, + R.string.activity_title_transparency_blur, + TransparencyBlur() + ), + SearchPreferenceItem( + R.xml.xposed_background_chip, + R.string.activity_title_background_chip, + BackgroundChip() + ), + SearchPreferenceItem( + R.xml.xposed_quick_settings, + R.string.activity_title_quick_settings, + QuickSettings() + ), + SearchPreferenceItem( + R.xml.xposed_themes, + R.string.activity_title_themes, + Themes() + ), + SearchPreferenceItem( + R.xml.xposed_battery_style, + R.string.activity_title_battery_style, + BatteryStyle() + ), + SearchPreferenceItem( + R.xml.xposed_statusbar, + R.string.activity_title_statusbar, + Statusbar() + ), + SearchPreferenceItem( + R.xml.xposed_volume_panel, + R.string.activity_title_volume_panel, + VolumePanel() + ), + SearchPreferenceItem( + R.xml.xposed_op_qs_header, + R.string.activity_title_op_qs_header, + OpQsHeader(), + Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE + ), + SearchPreferenceItem( + R.xml.xposed_header_clock, + R.string.activity_title_header_clock, + HeaderClock() + ), + SearchPreferenceItem( + R.xml.xposed_lockscreen_clock, + R.string.activity_title_lockscreen_clock, + LockscreenClock() + ), + SearchPreferenceItem( + R.xml.xposed_lockscreen_weather, + R.string.activity_title_lockscreen_weather, + LockscreenWeather() + ), + SearchPreferenceItem( + R.xml.xposed_lockscreen_widget, + R.string.activity_title_lockscreen_widget, + LockscreenWidget() + ), + SearchPreferenceItem( + R.xml.xposed_depth_wallpaper, + R.string.activity_title_depth_wallpaper, + DepthWallpaper() + ), + SearchPreferenceItem( + R.xml.xposed_others, + R.string.activity_title_xposed_others, + Others() + ) + ).filter { it.shouldAdd } + .distinctBy { it.fragment::class.java } + .toTypedArray() } diff --git a/app/src/main/java/com/drdisagree/iconify/config/Prefs.kt b/app/src/main/java/com/drdisagree/iconify/config/Prefs.kt deleted file mode 100644 index 581c0b06f..000000000 --- a/app/src/main/java/com/drdisagree/iconify/config/Prefs.kt +++ /dev/null @@ -1,93 +0,0 @@ -package com.drdisagree.iconify.config - -import android.content.Context -import android.content.SharedPreferences -import com.drdisagree.iconify.Iconify -import com.drdisagree.iconify.Iconify.Companion.appContext -import com.drdisagree.iconify.common.Preferences.STR_NULL -import com.drdisagree.iconify.common.Resources.SHARED_PREFERENCES - -@Suppress("unused") -object Prefs { - - @JvmField - var prefs: SharedPreferences = appContext.getSharedPreferences(SHARED_PREFERENCES, Context.MODE_PRIVATE) - private var editor: SharedPreferences.Editor = prefs.edit() - - @JvmStatic - fun putBoolean(key: String?, `val`: Boolean) { - editor.putBoolean(key, `val`).apply() - } - - @JvmStatic - fun putInt(key: String?, `val`: Int) { - editor.putInt(key, `val`).apply() - } - - @JvmStatic - fun putLong(key: String?, `val`: Long) { - editor.putLong(key, `val`).apply() - } - - @JvmStatic - fun putString(key: String?, `val`: String?) { - editor.putString(key, `val`).apply() - } - - @JvmStatic - fun getBoolean(key: String?): Boolean { - return prefs.getBoolean(key, false) - } - - @JvmStatic - fun getBoolean(key: String?, defValue: Boolean?): Boolean { - return prefs.getBoolean(key, defValue!!) - } - - @JvmStatic - fun getInt(key: String?): Int { - return prefs.getInt(key, 0) - } - - @JvmStatic - fun getInt(key: String?, defValue: Int): Int { - return prefs.getInt(key, defValue) - } - - @JvmStatic - fun getLong(key: String?): Long { - return prefs.getLong(key, 0) - } - - @JvmStatic - fun getLong(key: String?, defValue: Long): Long { - return prefs.getLong(key, defValue) - } - - @JvmStatic - fun getString(key: String?): String? { - return prefs.getString(key, STR_NULL) - } - - @JvmStatic - fun getString(key: String?, defValue: String?): String? { - return prefs.getString(key, defValue) - } - - @JvmStatic - fun clearPref(key: String?) { - editor.remove(key).apply() - } - - @JvmStatic - fun clearPrefs(vararg keys: String?) { - for (key in keys) { - editor.remove(key).apply() - } - } - - @JvmStatic - fun clearAllPrefs() { - editor.clear().apply() - } -} diff --git a/app/src/main/java/com/drdisagree/iconify/config/PrefsHelper.kt b/app/src/main/java/com/drdisagree/iconify/config/PrefsHelper.kt new file mode 100644 index 000000000..af91603e5 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/config/PrefsHelper.kt @@ -0,0 +1,580 @@ +package com.drdisagree.iconify.config + +import android.annotation.SuppressLint +import android.content.Context +import android.os.Build +import androidx.preference.Preference +import androidx.preference.PreferenceGroup +import com.drdisagree.iconify.BuildConfig +import com.drdisagree.iconify.Iconify.Companion.appContext +import com.drdisagree.iconify.Iconify.Companion.appContextLocale +import com.drdisagree.iconify.R +import com.drdisagree.iconify.common.Dynamic.isAtleastA14 +import com.drdisagree.iconify.common.Preferences.AGGRESSIVE_QSPANEL_BLUR_SWITCH +import com.drdisagree.iconify.common.Preferences.APP_LANGUAGE +import com.drdisagree.iconify.common.Preferences.AUTO_UPDATE +import com.drdisagree.iconify.common.Preferences.BATTERY_STYLE_CIRCLE +import com.drdisagree.iconify.common.Preferences.BATTERY_STYLE_DEFAULT +import com.drdisagree.iconify.common.Preferences.BATTERY_STYLE_DEFAULT_LANDSCAPE +import com.drdisagree.iconify.common.Preferences.BATTERY_STYLE_DEFAULT_RLANDSCAPE +import com.drdisagree.iconify.common.Preferences.BATTERY_STYLE_DOTTED_CIRCLE +import com.drdisagree.iconify.common.Preferences.BATTERY_STYLE_FILLED_CIRCLE +import com.drdisagree.iconify.common.Preferences.BATTERY_STYLE_LANDSCAPE_BATTERYA +import com.drdisagree.iconify.common.Preferences.BATTERY_STYLE_LANDSCAPE_BATTERYI +import com.drdisagree.iconify.common.Preferences.BATTERY_STYLE_LANDSCAPE_BATTERYJ +import com.drdisagree.iconify.common.Preferences.BATTERY_STYLE_LANDSCAPE_BATTERYL +import com.drdisagree.iconify.common.Preferences.BATTERY_STYLE_LANDSCAPE_BATTERYM +import com.drdisagree.iconify.common.Preferences.BATTERY_STYLE_LANDSCAPE_BATTERYO +import com.drdisagree.iconify.common.Preferences.BATTERY_STYLE_LANDSCAPE_IOS_16 +import com.drdisagree.iconify.common.Preferences.BLUR_RADIUS_VALUE +import com.drdisagree.iconify.common.Preferences.CHIP_STATUS_ICONS_SWITCH +import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_BLEND_COLOR +import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_CHARGING_COLOR +import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_CHARGING_ICON_MARGIN_LEFT +import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_CHARGING_ICON_MARGIN_RIGHT +import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_CHARGING_ICON_STYLE +import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_CHARGING_ICON_SWITCH +import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_CHARGING_ICON_WIDTH_HEIGHT +import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_DIMENSION +import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_FILL_ALPHA +import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_FILL_COLOR +import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_FILL_GRAD_COLOR +import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_HEIGHT +import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_HIDE_BATTERY +import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_HIDE_PERCENTAGE +import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_INSIDE_PERCENTAGE +import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_LAYOUT_REVERSE +import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_MARGIN_BOTTOM +import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_MARGIN_LEFT +import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_MARGIN_RIGHT +import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_MARGIN_TOP +import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_PERIMETER_ALPHA +import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_POWERSAVE_FILL_COLOR +import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_POWERSAVE_INDICATOR_COLOR +import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_RAINBOW_FILL_COLOR +import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_STYLE +import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_SWAP_PERCENTAGE +import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_WIDTH +import com.drdisagree.iconify.common.Preferences.CUSTOM_DEPTH_WALLPAPER_SWITCH +import com.drdisagree.iconify.common.Preferences.CUSTOM_QS_MARGIN +import com.drdisagree.iconify.common.Preferences.DEPTH_WALLPAPER_BACKGROUND_MOVEMENT_MULTIPLIER +import com.drdisagree.iconify.common.Preferences.DEPTH_WALLPAPER_FADE_ANIMATION +import com.drdisagree.iconify.common.Preferences.DEPTH_WALLPAPER_FOREGROUND_ALPHA +import com.drdisagree.iconify.common.Preferences.DEPTH_WALLPAPER_FOREGROUND_MOVEMENT_MULTIPLIER +import com.drdisagree.iconify.common.Preferences.DEPTH_WALLPAPER_ON_AOD +import com.drdisagree.iconify.common.Preferences.DEPTH_WALLPAPER_PARALLAX_EFFECT +import com.drdisagree.iconify.common.Preferences.DUALTONE_QSPANEL +import com.drdisagree.iconify.common.Preferences.FIXED_STATUS_ICONS_SIDEMARGIN +import com.drdisagree.iconify.common.Preferences.FIXED_STATUS_ICONS_SWITCH +import com.drdisagree.iconify.common.Preferences.FIXED_STATUS_ICONS_TOPMARGIN +import com.drdisagree.iconify.common.Preferences.FIX_NOTIFICATION_COLOR +import com.drdisagree.iconify.common.Preferences.FIX_NOTIFICATION_FOOTER_BUTTON_COLOR +import com.drdisagree.iconify.common.Preferences.FIX_QS_TILE_COLOR +import com.drdisagree.iconify.common.Preferences.FLUID_NOTIF_TRANSPARENCY +import com.drdisagree.iconify.common.Preferences.FLUID_POWERMENU_TRANSPARENCY +import com.drdisagree.iconify.common.Preferences.FLUID_QSPANEL +import com.drdisagree.iconify.common.Preferences.HEADER_CLOCK_COLOR_CODE_ACCENT1 +import com.drdisagree.iconify.common.Preferences.HEADER_CLOCK_COLOR_CODE_ACCENT2 +import com.drdisagree.iconify.common.Preferences.HEADER_CLOCK_COLOR_CODE_ACCENT3 +import com.drdisagree.iconify.common.Preferences.HEADER_CLOCK_COLOR_CODE_TEXT1 +import com.drdisagree.iconify.common.Preferences.HEADER_CLOCK_COLOR_CODE_TEXT2 +import com.drdisagree.iconify.common.Preferences.HEADER_CLOCK_COLOR_SWITCH +import com.drdisagree.iconify.common.Preferences.HEADER_CLOCK_EXPANSION_Y +import com.drdisagree.iconify.common.Preferences.HEADER_CLOCK_FONT_TEXT_SCALING +import com.drdisagree.iconify.common.Preferences.HEADER_CLOCK_LANDSCAPE_SWITCH +import com.drdisagree.iconify.common.Preferences.HEADER_CLOCK_SIDEMARGIN +import com.drdisagree.iconify.common.Preferences.HEADER_CLOCK_TOPMARGIN +import com.drdisagree.iconify.common.Preferences.HEADER_IMAGE_ALPHA +import com.drdisagree.iconify.common.Preferences.HEADER_IMAGE_BOTTOM_FADE_AMOUNT +import com.drdisagree.iconify.common.Preferences.HEADER_IMAGE_HEIGHT +import com.drdisagree.iconify.common.Preferences.HIDE_QSLABEL_SWITCH +import com.drdisagree.iconify.common.Preferences.LIGHT_QSPANEL +import com.drdisagree.iconify.common.Preferences.LOCKSCREEN_SHADE_SWITCH +import com.drdisagree.iconify.common.Preferences.LOCKSCREEN_WIDGETS_BIG_ACTIVE +import com.drdisagree.iconify.common.Preferences.LOCKSCREEN_WIDGETS_BIG_ICON_ACTIVE +import com.drdisagree.iconify.common.Preferences.LOCKSCREEN_WIDGETS_BIG_ICON_INACTIVE +import com.drdisagree.iconify.common.Preferences.LOCKSCREEN_WIDGETS_BIG_INACTIVE +import com.drdisagree.iconify.common.Preferences.LOCKSCREEN_WIDGETS_BOTTOM_MARGIN +import com.drdisagree.iconify.common.Preferences.LOCKSCREEN_WIDGETS_CUSTOM_COLOR +import com.drdisagree.iconify.common.Preferences.LOCKSCREEN_WIDGETS_DEVICE_WIDGET +import com.drdisagree.iconify.common.Preferences.LOCKSCREEN_WIDGETS_DEVICE_WIDGET_CIRCULAR_COLOR +import com.drdisagree.iconify.common.Preferences.LOCKSCREEN_WIDGETS_DEVICE_WIDGET_CUSTOM_COLOR_SWITCH +import com.drdisagree.iconify.common.Preferences.LOCKSCREEN_WIDGETS_DEVICE_WIDGET_DEVICE +import com.drdisagree.iconify.common.Preferences.LOCKSCREEN_WIDGETS_DEVICE_WIDGET_LINEAR_COLOR +import com.drdisagree.iconify.common.Preferences.LOCKSCREEN_WIDGETS_DEVICE_WIDGET_TEXT_COLOR +import com.drdisagree.iconify.common.Preferences.LOCKSCREEN_WIDGETS_SCALE +import com.drdisagree.iconify.common.Preferences.LOCKSCREEN_WIDGETS_SMALL_ACTIVE +import com.drdisagree.iconify.common.Preferences.LOCKSCREEN_WIDGETS_SMALL_ICON_ACTIVE +import com.drdisagree.iconify.common.Preferences.LOCKSCREEN_WIDGETS_SMALL_ICON_INACTIVE +import com.drdisagree.iconify.common.Preferences.LOCKSCREEN_WIDGETS_SMALL_INACTIVE +import com.drdisagree.iconify.common.Preferences.LSCLOCK_BOTTOMMARGIN +import com.drdisagree.iconify.common.Preferences.LSCLOCK_COLOR_CODE_ACCENT1 +import com.drdisagree.iconify.common.Preferences.LSCLOCK_COLOR_CODE_ACCENT2 +import com.drdisagree.iconify.common.Preferences.LSCLOCK_COLOR_CODE_ACCENT3 +import com.drdisagree.iconify.common.Preferences.LSCLOCK_COLOR_CODE_TEXT1 +import com.drdisagree.iconify.common.Preferences.LSCLOCK_COLOR_CODE_TEXT2 +import com.drdisagree.iconify.common.Preferences.LSCLOCK_COLOR_SWITCH +import com.drdisagree.iconify.common.Preferences.LSCLOCK_DEVICENAME +import com.drdisagree.iconify.common.Preferences.LSCLOCK_FONT_LINEHEIGHT +import com.drdisagree.iconify.common.Preferences.LSCLOCK_FONT_TEXT_SCALING +import com.drdisagree.iconify.common.Preferences.LSCLOCK_STYLE +import com.drdisagree.iconify.common.Preferences.LSCLOCK_TOPMARGIN +import com.drdisagree.iconify.common.Preferences.LSCLOCK_USERNAME +import com.drdisagree.iconify.common.Preferences.NEW_UPDATE_FOUND +import com.drdisagree.iconify.common.Preferences.NOTIF_TRANSPARENCY_SWITCH +import com.drdisagree.iconify.common.Preferences.OP_QS_HEADER_BLUR_LEVEL +import com.drdisagree.iconify.common.Preferences.OP_QS_HEADER_EXPANSION_Y +import com.drdisagree.iconify.common.Preferences.OP_QS_HEADER_TOP_MARGIN +import com.drdisagree.iconify.common.Preferences.PREF_KEY_UPDATE_STATUS +import com.drdisagree.iconify.common.Preferences.QQS_TOPMARGIN +import com.drdisagree.iconify.common.Preferences.QSALPHA_LEVEL +import com.drdisagree.iconify.common.Preferences.QSPANEL_BLUR_SWITCH +import com.drdisagree.iconify.common.Preferences.QS_TOPMARGIN +import com.drdisagree.iconify.common.Preferences.QS_TRANSPARENCY_SWITCH +import com.drdisagree.iconify.common.Preferences.SB_CLOCK_SIZE +import com.drdisagree.iconify.common.Preferences.SB_CLOCK_SIZE_SWITCH +import com.drdisagree.iconify.common.Preferences.SHOW_HOME_CARD +import com.drdisagree.iconify.common.Preferences.UNZOOM_DEPTH_WALLPAPER +import com.drdisagree.iconify.common.Preferences.UPDATE_OVER_WIFI +import com.drdisagree.iconify.common.Preferences.VERTICAL_QSTILE_SWITCH +import com.drdisagree.iconify.common.Preferences.WEATHER_CUSTOM_LOCATION +import com.drdisagree.iconify.common.Preferences.WEATHER_CUSTOM_LOCATION_PICKER +import com.drdisagree.iconify.common.Preferences.WEATHER_CUSTOM_MARGINS_BOTTOM +import com.drdisagree.iconify.common.Preferences.WEATHER_CUSTOM_MARGINS_SIDE +import com.drdisagree.iconify.common.Preferences.WEATHER_CUSTOM_MARGINS_TOP +import com.drdisagree.iconify.common.Preferences.WEATHER_ICON_PACK +import com.drdisagree.iconify.common.Preferences.WEATHER_ICON_SIZE +import com.drdisagree.iconify.common.Preferences.WEATHER_OWM_KEY +import com.drdisagree.iconify.common.Preferences.WEATHER_PROVIDER +import com.drdisagree.iconify.common.Preferences.WEATHER_TEXT_COLOR +import com.drdisagree.iconify.common.Preferences.WEATHER_TEXT_COLOR_SWITCH +import com.drdisagree.iconify.common.Preferences.WEATHER_TEXT_SIZE +import com.drdisagree.iconify.common.Preferences.WEATHER_UNITS +import com.drdisagree.iconify.common.Preferences.WEATHER_UPDATE_INTERVAL +import com.drdisagree.iconify.common.Preferences.XPOSED_HOOK_CHECK +import com.drdisagree.iconify.common.Resources.shouldShowRebootDialog +import com.drdisagree.iconify.config.RPrefs.getBoolean +import com.drdisagree.iconify.config.RPrefs.getInt +import com.drdisagree.iconify.config.RPrefs.getSliderFloat +import com.drdisagree.iconify.config.RPrefs.getSliderInt +import com.drdisagree.iconify.config.RPrefs.getString +import com.drdisagree.iconify.config.RPrefs.getStringSet +import com.drdisagree.iconify.ui.preferences.SliderPreference +import com.drdisagree.iconify.utils.weather.WeatherConfig + +object PrefsHelper { + + fun isVisible(key: String?): Boolean { + return when (key) { + UPDATE_OVER_WIFI -> getBoolean(AUTO_UPDATE, true) + + "iconifyHomeCard" -> getBoolean(SHOW_HOME_CARD, true) + + "rebootReminder" -> shouldShowRebootDialog() + + "newUpdate" -> getBoolean(NEW_UPDATE_FOUND) + + XPOSED_HOOK_CHECK -> !getBoolean(key) + + LOCKSCREEN_SHADE_SWITCH, + QSALPHA_LEVEL -> getBoolean(QS_TRANSPARENCY_SWITCH) || + getBoolean(NOTIF_TRANSPARENCY_SWITCH) + + AGGRESSIVE_QSPANEL_BLUR_SWITCH -> getBoolean(QSPANEL_BLUR_SWITCH) + + HIDE_QSLABEL_SWITCH -> getBoolean(VERTICAL_QSTILE_SWITCH) + + QQS_TOPMARGIN, + QS_TOPMARGIN -> getBoolean(CUSTOM_QS_MARGIN) + + SB_CLOCK_SIZE -> getBoolean(SB_CLOCK_SIZE_SWITCH) + + LSCLOCK_COLOR_CODE_ACCENT1, + LSCLOCK_COLOR_CODE_ACCENT2, + LSCLOCK_COLOR_CODE_ACCENT3, + LSCLOCK_COLOR_CODE_TEXT1, + LSCLOCK_COLOR_CODE_TEXT2 -> getBoolean(LSCLOCK_COLOR_SWITCH) + + LSCLOCK_DEVICENAME -> getInt(LSCLOCK_STYLE, 0) == 19 + + LSCLOCK_USERNAME -> getInt(LSCLOCK_STYLE, 0) == 7 + + // Weather Common + WEATHER_OWM_KEY -> getString(WEATHER_PROVIDER, "0") == "1" + WEATHER_CUSTOM_LOCATION_PICKER -> getBoolean(WEATHER_CUSTOM_LOCATION) + + // Lockscreen Weather + WEATHER_TEXT_COLOR -> getBoolean(WEATHER_TEXT_COLOR_SWITCH) + + HEADER_CLOCK_COLOR_CODE_ACCENT1, + HEADER_CLOCK_COLOR_CODE_ACCENT2, + HEADER_CLOCK_COLOR_CODE_ACCENT3, + HEADER_CLOCK_COLOR_CODE_TEXT1, + HEADER_CLOCK_COLOR_CODE_TEXT2 -> getBoolean(HEADER_CLOCK_COLOR_SWITCH) + + DUALTONE_QSPANEL -> getBoolean(LIGHT_QSPANEL) + + FLUID_NOTIF_TRANSPARENCY, + FLUID_POWERMENU_TRANSPARENCY -> getBoolean(FLUID_QSPANEL) + + "xposedThemesOthers", + FIX_QS_TILE_COLOR, + FIX_NOTIFICATION_COLOR, + FIX_NOTIFICATION_FOOTER_BUTTON_COLOR -> isAtleastA14 + + CUSTOM_DEPTH_WALLPAPER_SWITCH, + DEPTH_WALLPAPER_ON_AOD -> Build.VERSION.SDK_INT > Build.VERSION_CODES.TIRAMISU + + DEPTH_WALLPAPER_FADE_ANIMATION, + DEPTH_WALLPAPER_PARALLAX_EFFECT, + DEPTH_WALLPAPER_BACKGROUND_MOVEMENT_MULTIPLIER, + DEPTH_WALLPAPER_FOREGROUND_MOVEMENT_MULTIPLIER, + UNZOOM_DEPTH_WALLPAPER -> Build.VERSION.SDK_INT <= Build.VERSION_CODES.TIRAMISU + + "xposed_depthwallpaperbgimagepicker", + "xposed_depthwallpaperfgimagepicker" -> getBoolean(CUSTOM_DEPTH_WALLPAPER_SWITCH) || + Build.VERSION.SDK_INT <= Build.VERSION_CODES.TIRAMISU + + LOCKSCREEN_WIDGETS_DEVICE_WIDGET_CUSTOM_COLOR_SWITCH, + LOCKSCREEN_WIDGETS_DEVICE_WIDGET_DEVICE -> getBoolean(LOCKSCREEN_WIDGETS_DEVICE_WIDGET) + + LOCKSCREEN_WIDGETS_DEVICE_WIDGET_LINEAR_COLOR, + LOCKSCREEN_WIDGETS_DEVICE_WIDGET_CIRCULAR_COLOR, + LOCKSCREEN_WIDGETS_DEVICE_WIDGET_TEXT_COLOR -> getBoolean( + LOCKSCREEN_WIDGETS_DEVICE_WIDGET_CUSTOM_COLOR_SWITCH + ) + + LOCKSCREEN_WIDGETS_BIG_ACTIVE, + LOCKSCREEN_WIDGETS_BIG_INACTIVE, + LOCKSCREEN_WIDGETS_BIG_ICON_ACTIVE, + LOCKSCREEN_WIDGETS_BIG_ICON_INACTIVE, + LOCKSCREEN_WIDGETS_SMALL_ACTIVE, + LOCKSCREEN_WIDGETS_SMALL_INACTIVE, + LOCKSCREEN_WIDGETS_SMALL_ICON_ACTIVE, + LOCKSCREEN_WIDGETS_SMALL_ICON_INACTIVE -> getBoolean(LOCKSCREEN_WIDGETS_CUSTOM_COLOR) + + "xposed_lockscreenwidget_weather_settings" -> WeatherConfig.isEnabled(appContext) + + CUSTOM_BATTERY_STYLE, + CUSTOM_BATTERY_WIDTH, + CUSTOM_BATTERY_HEIGHT, + CUSTOM_BATTERY_HIDE_PERCENTAGE, + CUSTOM_BATTERY_INSIDE_PERCENTAGE, + CUSTOM_BATTERY_HIDE_BATTERY, + CUSTOM_BATTERY_SWAP_PERCENTAGE, + CUSTOM_BATTERY_LAYOUT_REVERSE, + CUSTOM_BATTERY_PERIMETER_ALPHA, + CUSTOM_BATTERY_FILL_ALPHA, + CUSTOM_BATTERY_RAINBOW_FILL_COLOR, + CUSTOM_BATTERY_BLEND_COLOR, + CUSTOM_BATTERY_FILL_COLOR, + CUSTOM_BATTERY_FILL_GRAD_COLOR, + CUSTOM_BATTERY_CHARGING_COLOR, + CUSTOM_BATTERY_POWERSAVE_FILL_COLOR, + CUSTOM_BATTERY_POWERSAVE_INDICATOR_COLOR, + CUSTOM_BATTERY_DIMENSION, + CUSTOM_BATTERY_MARGIN_LEFT, + CUSTOM_BATTERY_MARGIN_RIGHT, + CUSTOM_BATTERY_MARGIN_TOP, + CUSTOM_BATTERY_MARGIN_BOTTOM, + CUSTOM_BATTERY_CHARGING_ICON_SWITCH, + CUSTOM_BATTERY_CHARGING_ICON_STYLE, + CUSTOM_BATTERY_CHARGING_ICON_MARGIN_LEFT, + CUSTOM_BATTERY_CHARGING_ICON_MARGIN_RIGHT, + CUSTOM_BATTERY_CHARGING_ICON_WIDTH_HEIGHT -> { + return isBatteryPrefsVisible(key) + } + + // Status icons + "xposedStatusIcons", + CHIP_STATUS_ICONS_SWITCH, + "xposed_chipstatusiconscustomizer" -> { + return Build.VERSION.SDK_INT < Build.VERSION_CODES.UPSIDE_DOWN_CAKE + } + + "mediaPlayerTweaks" -> Build.VERSION.SDK_INT < Build.VERSION_CODES.UPSIDE_DOWN_CAKE + + HEADER_CLOCK_LANDSCAPE_SWITCH -> Build.VERSION.SDK_INT < Build.VERSION_CODES.UPSIDE_DOWN_CAKE + + HEADER_CLOCK_EXPANSION_Y -> Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE + + "xposedOthersStatusIcons", + FIXED_STATUS_ICONS_SWITCH -> Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU + + FIXED_STATUS_ICONS_SIDEMARGIN, + FIXED_STATUS_ICONS_TOPMARGIN -> Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU && + getBoolean(FIXED_STATUS_ICONS_SWITCH) + + "xposedOpQsHeader" -> Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE + + else -> true + } + } + + private fun isBatteryPrefsVisible(key: String): Boolean { + val batteryStyle: Int = getString(CUSTOM_BATTERY_STYLE, 0.toString())!!.toInt() + + val showAdvancedCustomizations = + batteryStyle in BATTERY_STYLE_LANDSCAPE_BATTERYA..BATTERY_STYLE_LANDSCAPE_BATTERYO + + val showColorPickers: Boolean = getBoolean(CUSTOM_BATTERY_BLEND_COLOR, false) + + val showRainbowBattery = batteryStyle == BATTERY_STYLE_LANDSCAPE_BATTERYI || + batteryStyle == BATTERY_STYLE_LANDSCAPE_BATTERYJ + + val showBatteryDimensions = batteryStyle > BATTERY_STYLE_DEFAULT_LANDSCAPE && + getBoolean(CUSTOM_BATTERY_DIMENSION) + + val showPercentage = batteryStyle != BATTERY_STYLE_DEFAULT && + batteryStyle != BATTERY_STYLE_DEFAULT_LANDSCAPE && + batteryStyle != BATTERY_STYLE_DEFAULT_RLANDSCAPE && + batteryStyle != BATTERY_STYLE_LANDSCAPE_IOS_16 && + batteryStyle != BATTERY_STYLE_LANDSCAPE_BATTERYL && + batteryStyle != BATTERY_STYLE_LANDSCAPE_BATTERYM + + val showInsidePercentage = showPercentage && !getBoolean( + CUSTOM_BATTERY_HIDE_PERCENTAGE, + false + ) + + val showChargingIconCustomization: Boolean = + batteryStyle > BATTERY_STYLE_DEFAULT_LANDSCAPE && + getBoolean(CUSTOM_BATTERY_CHARGING_ICON_SWITCH, false) + + val showSwapLayout: Boolean = showInsidePercentage && + batteryStyle > BATTERY_STYLE_DEFAULT_LANDSCAPE + + val circleBattery = batteryStyle == BATTERY_STYLE_CIRCLE || + batteryStyle == BATTERY_STYLE_DOTTED_CIRCLE || + batteryStyle == BATTERY_STYLE_FILLED_CIRCLE + + return when (key) { + CUSTOM_BATTERY_LAYOUT_REVERSE, + CUSTOM_BATTERY_PERIMETER_ALPHA, + CUSTOM_BATTERY_FILL_ALPHA -> showAdvancedCustomizations + + CUSTOM_BATTERY_BLEND_COLOR -> showAdvancedCustomizations || circleBattery + + CUSTOM_BATTERY_FILL_COLOR, + CUSTOM_BATTERY_FILL_GRAD_COLOR, + CUSTOM_BATTERY_CHARGING_COLOR, + CUSTOM_BATTERY_POWERSAVE_FILL_COLOR, + CUSTOM_BATTERY_POWERSAVE_INDICATOR_COLOR -> (showAdvancedCustomizations || circleBattery) && + showColorPickers + + CUSTOM_BATTERY_RAINBOW_FILL_COLOR -> (showAdvancedCustomizations || circleBattery) && + showRainbowBattery + + CUSTOM_BATTERY_DIMENSION -> batteryStyle > BATTERY_STYLE_DEFAULT_LANDSCAPE + + CUSTOM_BATTERY_MARGIN_LEFT, + CUSTOM_BATTERY_MARGIN_RIGHT, + CUSTOM_BATTERY_MARGIN_TOP, + CUSTOM_BATTERY_MARGIN_BOTTOM -> showBatteryDimensions + + CUSTOM_BATTERY_HIDE_PERCENTAGE -> showPercentage + + CUSTOM_BATTERY_INSIDE_PERCENTAGE -> showInsidePercentage + + CUSTOM_BATTERY_SWAP_PERCENTAGE -> showSwapLayout + + CUSTOM_BATTERY_HIDE_BATTERY, + CUSTOM_BATTERY_CHARGING_ICON_SWITCH -> batteryStyle > BATTERY_STYLE_DEFAULT_LANDSCAPE + + CUSTOM_BATTERY_CHARGING_ICON_STYLE, + CUSTOM_BATTERY_CHARGING_ICON_MARGIN_LEFT, + CUSTOM_BATTERY_CHARGING_ICON_MARGIN_RIGHT, + CUSTOM_BATTERY_CHARGING_ICON_WIDTH_HEIGHT -> showChargingIconCustomization + + else -> true + } + } + + fun isEnabled(key: String): Boolean { + return when (key) { + + // Weather Common Prefs + WEATHER_UPDATE_INTERVAL, + PREF_KEY_UPDATE_STATUS, + WEATHER_PROVIDER, + WEATHER_UNITS, + WEATHER_CUSTOM_LOCATION, + WEATHER_ICON_PACK -> WeatherConfig.isEnabled(appContext) + + WEATHER_OWM_KEY -> getString(WEATHER_PROVIDER, "0") == "1" && + WeatherConfig.isEnabled(appContext) + + CUSTOM_BATTERY_WIDTH, + CUSTOM_BATTERY_HEIGHT -> getString(CUSTOM_BATTERY_STYLE, 0.toString())!!.toInt() != 0 + + else -> true + } + } + + @SuppressLint("DefaultLocale") + fun getSummary(fragmentCompat: Context, key: String): String? { + if (key.endsWith("Slider")) { + return String.format("%.2f", RPrefs.getSliderFloat(key, 0f)) + } + if (key.endsWith("List")) { + return getString(key, "") + } + if (key.endsWith("EditText")) { + return getString(key, "") + } + if (key.endsWith("MultiSelect")) { + return getStringSet(key, emptySet()).toString() + } + + return when (key) { + APP_LANGUAGE -> { + val currentLanguageCode = + listOf(*fragmentCompat.resources.getStringArray(R.array.locale_code)) + .indexOf( + getString( + APP_LANGUAGE, + fragmentCompat.resources.configuration.locales[0].language + ) + ) + val selectedLanguageCode = if (currentLanguageCode < 0) listOf( + *fragmentCompat.resources.getStringArray(R.array.locale_code) + ).indexOf("en-US") else currentLanguageCode + + return listOf(*fragmentCompat.resources.getStringArray(R.array.locale_name))[selectedLanguageCode] + } + + "checkForUpdatePref" -> BuildConfig.VERSION_NAME + + QSALPHA_LEVEL -> "${getSliderInt(key, 60)}%" + + BLUR_RADIUS_VALUE -> "${getSliderInt(key, 23)}px" + + QQS_TOPMARGIN, + QS_TOPMARGIN -> "${getSliderInt(key, 100)}dp" + + SB_CLOCK_SIZE -> "${getSliderInt(key, 14)}px" + + FIXED_STATUS_ICONS_TOPMARGIN -> "${getSliderInt(key, 8)}dp" + + FIXED_STATUS_ICONS_SIDEMARGIN -> "${getSliderInt(key, 0)}dp" + + LSCLOCK_FONT_LINEHEIGHT -> "${getSliderInt(key, 0)}dp" + + HEADER_CLOCK_FONT_TEXT_SCALING, + LSCLOCK_FONT_TEXT_SCALING -> "${String.format("%.1f", getSliderInt(key, 10) / 10f)}x" + + LSCLOCK_TOPMARGIN -> "${getSliderInt(key, 100)}dp" + + LSCLOCK_BOTTOMMARGIN -> "${getSliderInt(key, 40)}dp" + + HEADER_CLOCK_SIDEMARGIN -> "${getSliderInt(key, 0)}dp" + + HEADER_CLOCK_TOPMARGIN -> "${getSliderInt(key, 8)}dp" + + HEADER_IMAGE_HEIGHT -> "${getSliderInt(key, 140)}dp" + + HEADER_IMAGE_ALPHA -> "${getSliderInt(key, 100)}%" + + HEADER_IMAGE_BOTTOM_FADE_AMOUNT -> "${getSliderInt(key, 40)}dp" + + WEATHER_CUSTOM_MARGINS_TOP, + WEATHER_CUSTOM_MARGINS_BOTTOM -> "${getSliderInt(key, 0)}dp" + + WEATHER_CUSTOM_MARGINS_SIDE -> "${getSliderInt(key, 32)}dp" + + WEATHER_TEXT_SIZE -> "${getSliderInt(key, 16)}sp" + + WEATHER_ICON_SIZE -> "${getSliderInt(key, 18)}dp" + + LOCKSCREEN_WIDGETS_BOTTOM_MARGIN -> "${getSliderInt(key, 0)}dp" + LOCKSCREEN_WIDGETS_SCALE -> "${String.format("%.2f", getSliderFloat(key, 1f))}%" + + WEATHER_CUSTOM_LOCATION_PICKER -> { + WeatherConfig.getLocationName(appContext).let { + if (it.isNullOrEmpty()) appContextLocale.getString(R.string.not_available) else it + } + } + + WEATHER_OWM_KEY -> { + val owmKey = getString(WEATHER_OWM_KEY, "")!! + + if (owmKey.length > 4) { + "*".repeat(owmKey.length - 4) + owmKey.takeLast( + 4 + ) + } else if (owmKey.isNotEmpty()) { + "*".repeat(owmKey.length) + } else { + appContextLocale.getString(R.string.not_available) + } + } + + CUSTOM_BATTERY_WIDTH, + CUSTOM_BATTERY_HEIGHT -> "${getSliderInt(key, 20)}dp" + + CUSTOM_BATTERY_MARGIN_LEFT, + CUSTOM_BATTERY_MARGIN_RIGHT -> "${getSliderInt(key, 4)}dp" + + CUSTOM_BATTERY_MARGIN_TOP, + CUSTOM_BATTERY_MARGIN_BOTTOM -> "${getSliderInt(key, 0)}dp" + + CUSTOM_BATTERY_CHARGING_ICON_MARGIN_LEFT -> "${getSliderInt(key, 1)}dp" + + CUSTOM_BATTERY_CHARGING_ICON_MARGIN_RIGHT -> "${getSliderInt(key, 0)}dp" + + CUSTOM_BATTERY_CHARGING_ICON_WIDTH_HEIGHT -> "${getSliderInt(key, 14)}dp" + + HEADER_CLOCK_EXPANSION_Y -> "${getSliderInt(key, 24)}dp" + + DEPTH_WALLPAPER_FOREGROUND_ALPHA -> "${getSliderInt(key, 80)}%" + + OP_QS_HEADER_BLUR_LEVEL -> "${getSliderInt(key, 10)}px" + + OP_QS_HEADER_TOP_MARGIN, + OP_QS_HEADER_EXPANSION_Y -> "${getSliderInt(key, 0)}dp" + + else -> null + } + } + + fun setupAllPreferences(group: PreferenceGroup) { + var i = 0 + while (true) { + try { + val thisPreference = group.getPreference(i) + + setupPreference(thisPreference) + + if (thisPreference is PreferenceGroup) { + setupAllPreferences(thisPreference) + } + } catch (ignored: Throwable) { + break + } + i++ + } + } + + private fun setupPreference(preference: Preference) { + try { + val key = preference.key + + preference.isVisible = isVisible(key) + preference.isEnabled = isEnabled(key) + + getSummary(preference.context, key)?.let { + preference.summary = it + } + + if (preference is SliderPreference) { + preference.slider.setLabelFormatter { value: Float -> + if (value == preference.defaultValue[0]) return@setLabelFormatter appContext.getString( + R.string.opt_default + ) + else return@setLabelFormatter Math.round(value).toString() + } + } + } catch (ignored: Throwable) { + } + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/config/RPrefs.kt b/app/src/main/java/com/drdisagree/iconify/config/RPrefs.kt index 6a5695374..cb8a86f90 100644 --- a/app/src/main/java/com/drdisagree/iconify/config/RPrefs.kt +++ b/app/src/main/java/com/drdisagree/iconify/config/RPrefs.kt @@ -2,110 +2,140 @@ package com.drdisagree.iconify.config import android.content.Context.MODE_PRIVATE import android.content.SharedPreferences -import com.drdisagree.iconify.Iconify +import android.content.SharedPreferences.OnSharedPreferenceChangeListener import com.drdisagree.iconify.Iconify.Companion.appContext -import com.drdisagree.iconify.common.Preferences.STR_NULL import com.drdisagree.iconify.common.Resources.SHARED_XPREFERENCES +import com.drdisagree.iconify.ui.preferences.SliderPreference @Suppress("unused") -object RPrefs { +object RPrefs : SharedPreferences { - @JvmField - var prefs: SharedPreferences = + private val prefs: SharedPreferences by lazy { appContext.createDeviceProtectedStorageContext().getSharedPreferences( SHARED_XPREFERENCES, MODE_PRIVATE ) - private var editor: SharedPreferences.Editor = prefs.edit() + } + + private val editor: SharedPreferences.Editor by lazy { prefs.edit() } + + val instance: RPrefs + get() = this - @JvmStatic - fun putBoolean(key: String?, `val`: Boolean) { - editor.putBoolean(key, `val`).apply() + val getPrefs: SharedPreferences + get() = prefs + + // Basic put methods + fun putBoolean(key: String?, value: Boolean) { + editor.putBoolean(key, value).apply() } - @JvmStatic - fun putInt(key: String?, `val`: Int) { - editor.putInt(key, `val`).apply() + fun putInt(key: String?, value: Int) { + editor.putInt(key, value).apply() } - @JvmStatic - fun putLong(key: String?, `val`: Long) { - editor.putLong(key, `val`).apply() + fun putFloat(key: String?, value: Float) { + editor.putFloat(key, value).apply() } - @JvmStatic - fun putFloat(key: String?, `val`: Float) { - editor.putFloat(key, `val`).apply() + fun putLong(key: String?, value: Long) { + editor.putLong(key, value).apply() } - @JvmStatic - fun putString(key: String?, `val`: String?) { - editor.putString(key, `val`).apply() + fun putString(key: String?, value: String?) { + editor.putString(key, value).apply() } - @JvmStatic + // Basic get methods fun getBoolean(key: String?): Boolean { return prefs.getBoolean(key, false) } - @JvmStatic - fun getBoolean(key: String?, defValue: Boolean?): Boolean { - return prefs.getBoolean(key, defValue!!) - } - - @JvmStatic fun getInt(key: String?): Int { return prefs.getInt(key, 0) } - @JvmStatic - fun getInt(key: String?, defValue: Int): Int { - return prefs.getInt(key, defValue) - } - - @JvmStatic fun getLong(key: String?): Long { return prefs.getLong(key, 0) } - @JvmStatic - fun getLong(key: String?, defValue: Long): Long { - return prefs.getLong(key, defValue) - } - - @JvmStatic fun getFloat(key: String?): Float { return prefs.getFloat(key, 0f) } - @JvmStatic - fun getFloat(key: String?, defValue: Float): Float { - return prefs.getFloat(key, defValue) + fun getString(key: String?): String? { + return prefs.getString(key, null) } - @JvmStatic - fun getString(key: String?): String? { - return prefs.getString(key, STR_NULL) + // Custom slider preference methods + fun getSliderInt(key: String?, defaultVal: Int): Int { + return SliderPreference.getSingleIntValue(this, key, defaultVal) } - @JvmStatic - fun getString(key: String?, defValue: String?): String? { - return prefs.getString(key, defValue) + fun getSliderValues(key: String?, defaultValue: Float): List { + return SliderPreference.getValues(this, key, defaultValue) } - @JvmStatic + fun getSliderFloat(key: String?, defaultVal: Float): Float { + return SliderPreference.getSingleFloatValue(this, key, defaultVal) + } + + // Clear methods fun clearPref(key: String?) { editor.remove(key).apply() } - @JvmStatic fun clearPrefs(vararg keys: String?) { - for (key in keys) { + keys.forEach { key -> editor.remove(key).apply() } } - @JvmStatic fun clearAllPrefs() { editor.clear().apply() } + + // Implementing SharedPreferences interface + override fun getAll(): Map { + return prefs.all + } + + override fun getBoolean(key: String?, defValue: Boolean): Boolean { + return prefs.getBoolean(key, defValue) + } + + override fun getInt(key: String?, defValue: Int): Int { + return prefs.getInt(key, defValue) + } + + override fun getLong(key: String?, defValue: Long): Long { + return prefs.getLong(key, defValue) + } + + override fun getFloat(key: String?, defValue: Float): Float { + return prefs.getFloat(key, defValue) + } + + override fun getString(key: String?, defValue: String?): String? { + return prefs.getString(key, defValue) + } + + override fun getStringSet(key: String, defValues: Set?): Set? { + return prefs.getStringSet(key, defValues) + } + + override fun contains(key: String): Boolean { + return prefs.contains(key) + } + + override fun edit(): SharedPreferences.Editor { + return editor + } + + override fun registerOnSharedPreferenceChangeListener(listener: OnSharedPreferenceChangeListener) { + prefs.registerOnSharedPreferenceChangeListener(listener) + } + + override fun unregisterOnSharedPreferenceChangeListener(listener: OnSharedPreferenceChangeListener) { + prefs.unregisterOnSharedPreferenceChangeListener(listener) + } } diff --git a/app/src/main/java/com/drdisagree/iconify/config/XPrefs.kt b/app/src/main/java/com/drdisagree/iconify/config/XPrefs.kt deleted file mode 100644 index 624561d1a..000000000 --- a/app/src/main/java/com/drdisagree/iconify/config/XPrefs.kt +++ /dev/null @@ -1,42 +0,0 @@ -package com.drdisagree.iconify.config - -import android.content.Context -import android.content.SharedPreferences -import android.content.SharedPreferences.OnSharedPreferenceChangeListener -import com.crossbowffs.remotepreferences.RemotePreferences -import com.drdisagree.iconify.BuildConfig -import com.drdisagree.iconify.common.Const.PREF_UPDATE_EXCLUSIONS -import com.drdisagree.iconify.common.Resources.SHARED_XPREFERENCES -import com.drdisagree.iconify.xposed.HookEntry - -object XPrefs { - - @JvmField - var Xprefs: SharedPreferences? = null - private var packageName: String? = null - private val listener = - OnSharedPreferenceChangeListener { _: SharedPreferences?, key: String? -> - loadEverything( - key - ) - } - - @JvmStatic - fun init(context: Context) { - packageName = context.packageName - Xprefs = RemotePreferences(context, BuildConfig.APPLICATION_ID, SHARED_XPREFERENCES, true) - (Xprefs as RemotePreferences).registerOnSharedPreferenceChangeListener(listener) - } - - private fun loadEverything(vararg key: String?) { - if (key.isEmpty() || key[0].isNullOrEmpty() || PREF_UPDATE_EXCLUSIONS.any { exclusion -> - key[0]?.equals(exclusion) == true - }) { - return - } - - HookEntry.runningMods.forEach { thisMod -> - thisMod.updatePrefs(*key.filterNotNull().toTypedArray()) - } - } -} diff --git a/app/src/main/java/com/drdisagree/iconify/receiver/BootReceiver.kt b/app/src/main/java/com/drdisagree/iconify/receiver/BootReceiver.kt index 41e3e0d0d..12f75fb90 100644 --- a/app/src/main/java/com/drdisagree/iconify/receiver/BootReceiver.kt +++ b/app/src/main/java/com/drdisagree/iconify/receiver/BootReceiver.kt @@ -4,16 +4,29 @@ import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import android.util.Log +import com.drdisagree.iconify.common.Const.ACTION_BOOT_COMPLETED +import com.drdisagree.iconify.common.Const.SYSTEMUI_PACKAGE import com.drdisagree.iconify.services.UpdateScheduler +import com.drdisagree.iconify.services.WeatherScheduler class BootReceiver : BroadcastReceiver() { - private val tag =this::class.java.simpleName + private val tag = this::class.java.simpleName override fun onReceive(context: Context, intent: Intent) { if (Intent.ACTION_BOOT_COMPLETED == intent.action) { Log.i(tag, "Broadcast received: " + intent.action) + + // Schedule updates UpdateScheduler.scheduleUpdates(context) + + // Schedule Weather Updates + WeatherScheduler.scheduleUpdates(context) + + // Update QS clock on boot + val broadcast: Intent = Intent(ACTION_BOOT_COMPLETED) + broadcast.putExtra("packageName", SYSTEMUI_PACKAGE) + context.sendBroadcast(broadcast) } } } \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/services/RootProviderProxy.kt b/app/src/main/java/com/drdisagree/iconify/services/RootProviderProxy.kt new file mode 100644 index 000000000..eae52ebcf --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/services/RootProviderProxy.kt @@ -0,0 +1,193 @@ +package com.drdisagree.iconify.services + +import android.app.Service +import android.content.Context +import android.content.Intent +import android.graphics.Bitmap +import android.os.IBinder +import android.os.RemoteException +import android.util.Log +import com.drdisagree.iconify.IExtractSubjectCallback +import com.drdisagree.iconify.IRootProviderProxy +import com.drdisagree.iconify.R +import com.drdisagree.iconify.utils.FileUtils +import com.drdisagree.iconify.xposed.modules.utils.BitmapSubjectSegmenter +import com.drdisagree.iconify.xposed.modules.utils.BitmapSubjectSegmenter.SegmentResultListener +import com.google.android.gms.common.moduleinstall.ModuleAvailabilityResponse +import com.topjohnwu.superuser.Shell +import java.io.File +import java.io.FileOutputStream + +class RootProviderProxy : Service() { + + override fun onBind(intent: Intent): IBinder { + return RootProviderProxyIPC(this) + } + + internal inner class RootProviderProxyIPC(context: Context) : IRootProviderProxy.Stub() { + + init { + try { + Shell.setDefaultBuilder( + Shell.Builder.create() + .setFlags(Shell.FLAG_MOUNT_MASTER) + .setFlags(Shell.FLAG_REDIRECT_STDERR) + .setTimeout(20) + ) + } catch (ignored: Throwable) { + } + + rootGranted = Shell.getShell().isRoot + + rootAllowedPacks = listOf( + *context.resources.getStringArray(R.array.root_requirement) + ) + } + + @Throws(RemoteException::class) + override fun runCommand(command: String): Array { + try { + ensureEnvironment() + + val result = Shell.cmd(command).exec().out + return result.toTypedArray() + } catch (ignored: Throwable) { + return arrayOfNulls(0) + } + } + + @Throws(RemoteException::class) + override fun enableOverlay(packageName: String) { + ensureEnvironment() + + try { + Shell.cmd( + "cmd overlay enable --user current $packageName", + "cmd overlay set-priority $packageName highest" + ).submit() + } catch (throwable: Throwable) { + Log.e(TAG, "enableOverlay: ", throwable) + } + } + + @Throws(RemoteException::class) + override fun disableOverlay(packageName: String) { + ensureEnvironment() + + try { + Shell.cmd( + "cmd overlay disable --user current $packageName", + ).submit() + } catch (throwable: Throwable) { + Log.e(TAG, "disableOverlay: ", throwable) + } + } + + @Throws(RemoteException::class) + override fun extractSubject( + input: Bitmap, + resultPath: String, + callback: IExtractSubjectCallback + ) { + ensureEnvironment() + + try { + val bitmapSubjectSegmenter = BitmapSubjectSegmenter(applicationContext) + + bitmapSubjectSegmenter + .segmentSubject( + input, + object : SegmentResultListener { + override fun onStart() { + callback.onStart(getString(R.string.depth_wallpaper_subject_extraction_started)) + } + + override fun onSuccess(result: Bitmap?) { + try { + val tempFile = File.createTempFile( + "depth_wallpaper_fg", + ".png" + ) + + val outputStream = FileOutputStream(tempFile) + result!!.compress(Bitmap.CompressFormat.PNG, 100, outputStream) + + outputStream.close() + result.recycle() + + val isSuccess = FileUtils.moveToIconifyHiddenDir( + tempFile.absolutePath, + resultPath + ) + + tempFile.delete() + + callback.onResult( + isSuccess, + if (isSuccess) { + getString(R.string.depth_wallpaper_subject_extraction_success) + } else { + getString(R.string.depth_wallpaper_subject_extraction_failed) + } + ) + } catch (throwable: Throwable) { + Log.e( + TAG, + "BitmapSubjectSegmenter - onSuccess: $throwable" + ) + + callback.onResult( + false, + getString(R.string.depth_wallpaper_subject_extraction_failed) + ) + } + } + + override fun onFail() { + bitmapSubjectSegmenter.checkModelAvailability { moduleAvailabilityResponse: ModuleAvailabilityResponse? -> + callback.onResult( + false, + if (moduleAvailabilityResponse?.areModulesAvailable() == true) { + getString(R.string.depth_wallpaper_subject_extraction_failed) + } else { + getString(R.string.depth_wallpaper_missing_ai_model) + } + ) + } + } + }) + } catch (throwable: Throwable) { + Log.e(TAG, "BitmapSubjectSegmenter - segmentSubject: $throwable") + + callback.onResult( + false, + getString(R.string.depth_wallpaper_subject_extraction_failed) + ) + } + } + + @Throws(RemoteException::class) + private fun ensureEnvironment() { + if (!rootGranted) { + throw RemoteException("Root permission denied") + } + + ensureSecurity(getCallingUid()) + } + + @Throws(RemoteException::class) + private fun ensureSecurity(uid: Int) { + for (packageName in packageManager.getPackagesForUid(uid)!!) { + if (rootAllowedPacks.contains(packageName)) return + } + + throw RemoteException("$packageName is not allowed to use root commands") + } + } + + companion object { + var TAG: String = "Iconify - ${RootProviderProxy::class.java.simpleName}: " + private var rootAllowedPacks: List = listOf() + private var rootGranted: Boolean = false + } +} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/services/TileMonetEngine.kt b/app/src/main/java/com/drdisagree/iconify/services/TileMonetEngine.kt index 18be615dd..108802bf9 100644 --- a/app/src/main/java/com/drdisagree/iconify/services/TileMonetEngine.kt +++ b/app/src/main/java/com/drdisagree/iconify/services/TileMonetEngine.kt @@ -4,9 +4,9 @@ import android.service.quicksettings.Tile import android.service.quicksettings.TileService import com.drdisagree.iconify.R import com.drdisagree.iconify.common.Preferences.MONET_ENGINE_SWITCH -import com.drdisagree.iconify.config.Prefs.getBoolean -import com.drdisagree.iconify.config.Prefs.putBoolean -import com.drdisagree.iconify.utils.overlay.OverlayUtil +import com.drdisagree.iconify.config.RPrefs.getBoolean +import com.drdisagree.iconify.config.RPrefs.putBoolean +import com.drdisagree.iconify.utils.overlay.OverlayUtils class TileMonetEngine : TileService() { @@ -25,19 +25,19 @@ class TileMonetEngine : TileService() { super.onClick() if (isCustomMonetEnabled) { - OverlayUtil.disableOverlays("IconifyComponentDM.overlay", "IconifyComponentME.overlay") + OverlayUtils.disableOverlays("IconifyComponentDM.overlay", "IconifyComponentME.overlay") } else { - OverlayUtil.enableOverlays("IconifyComponentDM.overlay", "IconifyComponentME.overlay") + OverlayUtils.enableOverlays("IconifyComponentDM.overlay", "IconifyComponentME.overlay") if (getBoolean("IconifyComponentQSPBD.overlay")) { - OverlayUtil.changeOverlayState( + OverlayUtils.changeOverlayState( "IconifyComponentQSPBD.overlay", false, "IconifyComponentQSPBD.overlay", true ) } else if (getBoolean("IconifyComponentQSPBA.overlay")) { - OverlayUtil.changeOverlayState( + OverlayUtils.changeOverlayState( "IconifyComponentQSPBA.overlay", false, "IconifyComponentQSPBA.overlay", diff --git a/app/src/main/java/com/drdisagree/iconify/services/TileNotchBarKiller.kt b/app/src/main/java/com/drdisagree/iconify/services/TileNotchBarKiller.kt index 25941c462..749f09cfc 100644 --- a/app/src/main/java/com/drdisagree/iconify/services/TileNotchBarKiller.kt +++ b/app/src/main/java/com/drdisagree/iconify/services/TileNotchBarKiller.kt @@ -5,9 +5,9 @@ import android.service.quicksettings.TileService import com.drdisagree.iconify.R import com.drdisagree.iconify.common.Const.FRAMEWORK_PACKAGE import com.drdisagree.iconify.common.Preferences.NOTCH_BAR_KILLER_SWITCH -import com.drdisagree.iconify.config.Prefs.getBoolean -import com.drdisagree.iconify.config.Prefs.putBoolean -import com.drdisagree.iconify.utils.SystemUtil +import com.drdisagree.iconify.config.RPrefs.getBoolean +import com.drdisagree.iconify.config.RPrefs.putBoolean +import com.drdisagree.iconify.utils.SystemUtils import com.drdisagree.iconify.utils.overlay.manager.resource.ResourceEntry import com.drdisagree.iconify.utils.overlay.manager.resource.ResourceManager @@ -26,7 +26,7 @@ class TileNotchBarKiller : TileService() { override fun onClick() { super.onClick() - if (!SystemUtil.hasStoragePermission()) { + if (!SystemUtils.hasStoragePermission()) { val tile = qsTile tile.subtitle = resources.getString(R.string.need_storage_perm_title) tile.updateTile() diff --git a/app/src/main/java/com/drdisagree/iconify/services/TilePitchBlack.kt b/app/src/main/java/com/drdisagree/iconify/services/TilePitchBlack.kt index b09ccd336..3a27843db 100644 --- a/app/src/main/java/com/drdisagree/iconify/services/TilePitchBlack.kt +++ b/app/src/main/java/com/drdisagree/iconify/services/TilePitchBlack.kt @@ -3,8 +3,8 @@ package com.drdisagree.iconify.services import android.service.quicksettings.Tile import android.service.quicksettings.TileService import com.drdisagree.iconify.R -import com.drdisagree.iconify.config.Prefs.getBoolean -import com.drdisagree.iconify.utils.overlay.OverlayUtil +import com.drdisagree.iconify.config.RPrefs.getBoolean +import com.drdisagree.iconify.utils.overlay.OverlayUtils class TilePitchBlack : TileService() { @@ -23,7 +23,7 @@ class TilePitchBlack : TileService() { super.onClick() isPitchBlackEnabled = if (getBoolean("IconifyComponentQSPBD.overlay")) { - OverlayUtil.changeOverlayState( + OverlayUtils.changeOverlayState( "IconifyComponentQSPBD.overlay", false, "IconifyComponentQSPBA.overlay", @@ -31,10 +31,10 @@ class TilePitchBlack : TileService() { ) true } else if (getBoolean("IconifyComponentQSPBA.overlay")) { - OverlayUtil.disableOverlay("IconifyComponentQSPBA.overlay") + OverlayUtils.disableOverlay("IconifyComponentQSPBA.overlay") false } else { - OverlayUtil.enableOverlay("IconifyComponentQSPBD.overlay") + OverlayUtils.enableOverlay("IconifyComponentQSPBD.overlay") true } diff --git a/app/src/main/java/com/drdisagree/iconify/services/TileRestartSystemUI.kt b/app/src/main/java/com/drdisagree/iconify/services/TileRestartSystemUI.kt index f36668c03..1669a4c12 100644 --- a/app/src/main/java/com/drdisagree/iconify/services/TileRestartSystemUI.kt +++ b/app/src/main/java/com/drdisagree/iconify/services/TileRestartSystemUI.kt @@ -4,8 +4,8 @@ import android.graphics.drawable.Icon import android.service.quicksettings.Tile import android.service.quicksettings.TileService import com.drdisagree.iconify.R -import com.drdisagree.iconify.utils.SystemUtil -import com.drdisagree.iconify.utils.overlay.OverlayUtil +import com.drdisagree.iconify.utils.SystemUtils +import com.drdisagree.iconify.utils.overlay.OverlayUtils class TileRestartSystemUI : TileService() { @@ -30,7 +30,7 @@ class TileRestartSystemUI : TileService() { override fun onClick() { super.onClick() - SystemUtil.restartSystemUI() + SystemUtils.restartSystemUI() val tile = qsTile tile.state = Tile.STATE_INACTIVE tile.label = resources.getString(R.string.restart_sysui_title) @@ -44,13 +44,13 @@ class TileRestartSystemUI : TileService() { private fun updateTileIcon(tile: Tile) { var iconResId = R.drawable.ic_tile_restart_systemui - if (OverlayUtil.isOverlayEnabled("IconifyComponentIPAS1.overlay")) { + if (OverlayUtils.isOverlayEnabled("IconifyComponentIPAS1.overlay")) { iconResId = R.drawable.ic_tile_restart_systemui_aurora - } else if (OverlayUtil.isOverlayEnabled("IconifyComponentIPAS2.overlay")) { + } else if (OverlayUtils.isOverlayEnabled("IconifyComponentIPAS2.overlay")) { iconResId = R.drawable.ic_tile_restart_systemui_gradicon - } else if (OverlayUtil.isOverlayEnabled("IconifyComponentIPAS3.overlay")) { + } else if (OverlayUtils.isOverlayEnabled("IconifyComponentIPAS3.overlay")) { iconResId = R.drawable.ic_tile_restart_systemui_lorn - } else if (OverlayUtil.isOverlayEnabled("IconifyComponentIPAS4.overlay")) { + } else if (OverlayUtils.isOverlayEnabled("IconifyComponentIPAS4.overlay")) { iconResId = R.drawable.ic_tile_restart_systemui_plumpy } diff --git a/app/src/main/java/com/drdisagree/iconify/services/UpdateScheduler.kt b/app/src/main/java/com/drdisagree/iconify/services/UpdateScheduler.kt index c1770c34a..fccbcf54b 100644 --- a/app/src/main/java/com/drdisagree/iconify/services/UpdateScheduler.kt +++ b/app/src/main/java/com/drdisagree/iconify/services/UpdateScheduler.kt @@ -10,8 +10,8 @@ import androidx.work.WorkManager import com.drdisagree.iconify.BuildConfig import com.drdisagree.iconify.common.Preferences.AUTO_UPDATE import com.drdisagree.iconify.common.Preferences.UPDATE_CHECK_TIME -import com.drdisagree.iconify.config.Prefs.getBoolean -import com.drdisagree.iconify.config.Prefs.getLong +import com.drdisagree.iconify.config.RPrefs.getBoolean +import com.drdisagree.iconify.config.RPrefs.getLong import java.util.concurrent.TimeUnit object UpdateScheduler { @@ -20,7 +20,6 @@ object UpdateScheduler { private val UPDATE_WORK_NAME = BuildConfig.APPLICATION_ID .replace(".debug", "") + ".services.UpdateScheduler" - @JvmStatic fun scheduleUpdates(context: Context?) { Log.i(TAG, "Updating update schedule...") diff --git a/app/src/main/java/com/drdisagree/iconify/services/UpdateWorker.kt b/app/src/main/java/com/drdisagree/iconify/services/UpdateWorker.kt index ee54f277a..d1ee25334 100644 --- a/app/src/main/java/com/drdisagree/iconify/services/UpdateWorker.kt +++ b/app/src/main/java/com/drdisagree/iconify/services/UpdateWorker.kt @@ -16,9 +16,9 @@ import com.drdisagree.iconify.R import com.drdisagree.iconify.common.Const.LATEST_VERSION_URL import com.drdisagree.iconify.common.Preferences.UPDATE_OVER_WIFI import com.drdisagree.iconify.common.Preferences.VER_CODE -import com.drdisagree.iconify.config.Prefs +import com.drdisagree.iconify.config.RPrefs import com.drdisagree.iconify.ui.activities.MainActivity -import com.drdisagree.iconify.ui.fragments.AppUpdates +import com.drdisagree.iconify.ui.fragments.settings.AppUpdates import com.topjohnwu.superuser.Shell import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext @@ -56,7 +56,7 @@ class UpdateWorker(context: Context, params: WorkerParameters) : CoroutineWorker } private fun isGoodNetworkAvailable(): Boolean { - val updateOverWifiOnly = Prefs.getBoolean(UPDATE_OVER_WIFI, true) + val updateOverWifiOnly = RPrefs.getBoolean(UPDATE_OVER_WIFI, true) val connectivityManager = applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager val capabilities = diff --git a/app/src/main/java/com/drdisagree/iconify/services/WeatherScheduler.kt b/app/src/main/java/com/drdisagree/iconify/services/WeatherScheduler.kt new file mode 100644 index 000000000..87f84d2a9 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/services/WeatherScheduler.kt @@ -0,0 +1,76 @@ +package com.drdisagree.iconify.services + +import android.content.Context +import android.util.Log +import androidx.work.BackoffPolicy +import androidx.work.Configuration +import androidx.work.ExistingPeriodicWorkPolicy +import androidx.work.OneTimeWorkRequest +import androidx.work.PeriodicWorkRequest +import androidx.work.WorkManager +import com.drdisagree.iconify.BuildConfig +import com.drdisagree.iconify.utils.weather.WeatherConfig +import com.drdisagree.iconify.utils.weather.WeatherWork +import java.util.concurrent.TimeUnit + +object WeatherScheduler { + private const val UPDATE_WORK_NAME: String = BuildConfig.APPLICATION_ID + ".WeatherSchedule" + private val TAG = "Iconify - ${WeatherScheduler::class.java.simpleName}: " + + fun scheduleUpdates(context: Context) { + Log.d(TAG, "Updating update schedule...") + + if (!WorkManager.isInitialized()) { + WorkManager.initialize(context, Configuration.Builder().build()) + } + + val workManager = WorkManager.getInstance(context) + + val weatherEnabled: Boolean = WeatherConfig.isEnabled(context) + + Log.d(TAG, "Weather enabled: $weatherEnabled") + + if (weatherEnabled) { + Log.d(TAG, "Scheduling updates") + val builder: PeriodicWorkRequest.Builder = PeriodicWorkRequest.Builder( + WeatherWork::class.java, + WeatherConfig.getUpdateInterval(context).toLong(), TimeUnit.HOURS + ) + .setBackoffCriteria(BackoffPolicy.LINEAR, 1, TimeUnit.HOURS) + + workManager.enqueueUniquePeriodicWork( + UPDATE_WORK_NAME, + ExistingPeriodicWorkPolicy.UPDATE, + builder.build() + ) + } else { + workManager.cancelUniqueWork(UPDATE_WORK_NAME) + } + } + + fun cancelUpdates(context: Context) { + if (!WorkManager.isInitialized()) { + WorkManager.initialize(context, Configuration.Builder().build()) + } + + val workManager = WorkManager.getInstance(context) + + workManager.cancelUniqueWork(UPDATE_WORK_NAME) + } + + fun scheduleUpdateNow(context: Context) { + Log.d(TAG, "Check update now") + + if (!WorkManager.isInitialized()) { + WorkManager.initialize(context, Configuration.Builder().build()) + } + + val workManager = WorkManager.getInstance(context) + + val builder: OneTimeWorkRequest.Builder = + OneTimeWorkRequest.Builder(WeatherWork::class.java) + + workManager.enqueue(builder.build()) + } + +} diff --git a/app/src/main/java/com/drdisagree/iconify/ui/activities/MainActivity.kt b/app/src/main/java/com/drdisagree/iconify/ui/activities/MainActivity.kt index 5c9be6fcf..c9d7fc34e 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/activities/MainActivity.kt +++ b/app/src/main/java/com/drdisagree/iconify/ui/activities/MainActivity.kt @@ -1,154 +1,318 @@ package com.drdisagree.iconify.ui.activities -import android.annotation.SuppressLint +import android.animation.Animator +import android.animation.AnimatorListenerAdapter import android.os.Bundle +import android.os.Handler +import android.os.Looper import android.view.MenuItem -import androidx.navigation.NavController -import androidx.navigation.Navigation.findNavController -import androidx.navigation.fragment.NavHostFragment -import androidx.navigation.ui.NavigationUI.setupWithNavController +import android.view.View +import androidx.fragment.app.Fragment +import androidx.fragment.app.FragmentManager +import androidx.fragment.app.FragmentManager.POP_BACK_STACK_INCLUSIVE +import androidx.preference.Preference +import androidx.preference.PreferenceFragmentCompat import com.airbnb.lottie.LottieCompositionFactory import com.drdisagree.iconify.R +import com.drdisagree.iconify.common.Dynamic import com.drdisagree.iconify.common.Preferences -import com.drdisagree.iconify.common.Preferences.FORCE_RELOAD_OVERLAY_STATE -import com.drdisagree.iconify.common.Preferences.FORCE_RELOAD_PACKAGE_NAME import com.drdisagree.iconify.common.Preferences.MONET_ENGINE_SWITCH import com.drdisagree.iconify.common.Preferences.ON_HOME_PAGE -import com.drdisagree.iconify.config.Prefs +import com.drdisagree.iconify.common.Resources.searchConfiguration +import com.drdisagree.iconify.common.Resources.searchableFragments import com.drdisagree.iconify.config.RPrefs -import com.drdisagree.iconify.databinding.ActivityHomePageBinding +import com.drdisagree.iconify.databinding.ActivityMainBinding import com.drdisagree.iconify.ui.base.BaseActivity +import com.drdisagree.iconify.ui.base.BaseFragment +import com.drdisagree.iconify.ui.base.ControlledPreferenceFragmentCompat import com.drdisagree.iconify.ui.events.ColorDismissedEvent import com.drdisagree.iconify.ui.events.ColorSelectedEvent -import com.drdisagree.iconify.utils.overlay.FabricatedUtil -import com.drdisagree.iconify.utils.overlay.OverlayUtil +import com.drdisagree.iconify.ui.fragments.home.Home +import com.drdisagree.iconify.ui.fragments.settings.Settings +import com.drdisagree.iconify.ui.fragments.tweaks.Tweaks +import com.drdisagree.iconify.ui.fragments.xposed.Xposed +import com.drdisagree.iconify.ui.preferences.preferencesearch.SearchPreferenceFragment +import com.drdisagree.iconify.ui.preferences.preferencesearch.SearchPreferenceResult +import com.drdisagree.iconify.ui.preferences.preferencesearch.SearchPreferenceResultListener +import com.drdisagree.iconify.ui.utils.FragmentHelper.isInGroup +import com.drdisagree.iconify.utils.HapticUtils.weakVibrate +import com.drdisagree.iconify.utils.SystemUtils +import com.drdisagree.iconify.utils.overlay.FabricatedUtils +import com.drdisagree.iconify.utils.overlay.OverlayUtils import com.jaredrummler.android.colorpicker.ColorPickerDialog import com.jaredrummler.android.colorpicker.ColorPickerDialogListener -import com.topjohnwu.superuser.Shell +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch import org.greenrobot.eventbus.EventBus +import java.util.UUID -class MainActivity : BaseActivity(), ColorPickerDialogListener { +class MainActivity : BaseActivity(), + PreferenceFragmentCompat.OnPreferenceStartFragmentCallback, + SearchPreferenceResultListener, + ColorPickerDialogListener { - private lateinit var binding: ActivityHomePageBinding - private var selectedFragment: Int? = null - private var colorPickerDialog: ColorPickerDialog.Builder? = null + lateinit var binding: ActivityMainBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - binding = ActivityHomePageBinding.inflate(layoutInflater) + binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.getRoot()) - // Setup navigation + colorPickerDialog = ColorPickerDialog.newBuilder() + setupNavigation() - Prefs.putBoolean(ON_HOME_PAGE, true) + setupSearchConfiguration() + RPrefs.putBoolean(ON_HOME_PAGE, true) + + if (savedInstanceState == null) { + replaceFragment( + supportFragmentManager, + if (!Preferences.isXposedOnlyMode) Home() else Xposed() + ) + } + + initData() + + setupFloatingActionButtons() + } - Thread { + private fun initData() { + CoroutineScope(Dispatchers.IO).launch { // Clear lottie cache - LottieCompositionFactory.clearCache(this) + LottieCompositionFactory.clearCache(this@MainActivity) // Get list of enabled overlays - val enabledOverlays = OverlayUtil.enabledOverlayList - for (overlay in enabledOverlays) { - Prefs.putBoolean(overlay, true) + val enabledOverlays = OverlayUtils.enabledOverlayList + enabledOverlays.forEach { overlay -> + RPrefs.putBoolean(overlay, true) } - val fabricatedEnabledOverlays = FabricatedUtil.enabledOverlayList - for (overlay in fabricatedEnabledOverlays) { - Prefs.putBoolean("fabricated$overlay", true) + val fabricatedEnabledOverlays = FabricatedUtils.enabledOverlayList + fabricatedEnabledOverlays.forEach { overlay -> + if (!RPrefs.getBoolean("fabricated$overlay", false)) { + RPrefs.putBoolean("fabricated$overlay", true) + } } - Prefs.putBoolean( + RPrefs.putBoolean( MONET_ENGINE_SWITCH, enabledOverlays.contains("IconifyComponentME.overlay") ) + } + } - val state = - Shell.cmd( - "[[ $(cmd overlay list | grep -o '\\[x\\] $FORCE_RELOAD_PACKAGE_NAME') ]] && echo 1 || echo 0" - ).exec().out[0] == "1" - RPrefs.putBoolean(FORCE_RELOAD_OVERLAY_STATE, state) - }.start() + private fun setupFloatingActionButtons() { + binding.hideAll.hide() + binding.restartSystemui.hide() + binding.restartDevice.hide() + binding.pendingActions.shrink() - colorPickerDialog = ColorPickerDialog.newBuilder() + showOrHidePendingActionButton( + activityBinding = binding, + requiresSystemUiRestart = Dynamic.requiresSystemUiRestart, + requiresDeviceRestart = Dynamic.requiresDeviceRestart + ) + + binding.pendingActions.setOnClickListener { + binding.pendingActions.weakVibrate() + showOrHideFabButtons() + } + + binding.hideAll.setOnClickListener { + binding.hideAll.weakVibrate() + + Dynamic.requiresSystemUiRestart = false + Dynamic.requiresDeviceRestart = false + + showOrHidePendingActionButton( + activityBinding = binding, + requiresSystemUiRestart = false, + requiresDeviceRestart = false + ) + } + + binding.restartSystemui.setOnClickListener { + binding.restartSystemui.weakVibrate() + + Dynamic.requiresSystemUiRestart = false + + showOrHidePendingActionButton( + activityBinding = binding, + requiresSystemUiRestart = false, + requiresDeviceRestart = Dynamic.requiresDeviceRestart + ) + + Handler(Looper.getMainLooper()).postDelayed({ + SystemUtils.restartSystemUI() + }, 500) + } + + binding.restartDevice.setOnClickListener { + binding.restartDevice.weakVibrate() + + Dynamic.requiresDeviceRestart = false + + showOrHidePendingActionButton( + activityBinding = binding, + requiresSystemUiRestart = Dynamic.requiresSystemUiRestart, + requiresDeviceRestart = false + ) + + Handler(Looper.getMainLooper()).postDelayed({ + SystemUtils.restartDevice() + }, android.R.integer.config_longAnimTime.toLong()) + } } private fun setupNavigation() { - val navHostFragment = - supportFragmentManager.findFragmentById(R.id.fragmentContainerView) as NavHostFragment? - ?: return - val navController = navHostFragment.navController - if (Preferences.isXposedOnlyMode) { - navController.setGraph(R.navigation.nav_xposed_menu) binding.bottomNavigationView.menu.clear() binding.bottomNavigationView.inflateMenu(R.menu.bottom_nav_menu_xposed_only) } - setupWithNavController(binding.bottomNavigationView, navController) + supportFragmentManager.addOnBackStackChangedListener { + val fragment = getTopFragment() + val xposedOnlyMode = Preferences.isXposedOnlyMode - binding.bottomNavigationView.setOnItemSelectedListener { item: MenuItem -> - setFragment(item.itemId, navController, Preferences.isXposedOnlyMode) - true + val homeIndex = 0 + val tweaksIndex = 1 + val xposedIndex = if (!xposedOnlyMode) 2 else 0 + val settingsIndex = if (!xposedOnlyMode) 3 else 1 + + when { + isInGroup(fragment, homeIndex) && !xposedOnlyMode -> { + binding.bottomNavigationView.menu.getItem(homeIndex).setChecked(true) + } + + isInGroup(fragment, tweaksIndex) && !xposedOnlyMode -> { + binding.bottomNavigationView.menu.getItem(tweaksIndex).setChecked(true) + } + + isInGroup(fragment, xposedIndex) -> { + binding.bottomNavigationView.menu.getItem(xposedIndex).setChecked(true) + } + + isInGroup(fragment, settingsIndex) -> { + binding.bottomNavigationView.menu.getItem(settingsIndex).setChecked(true) + } + } } - } - @SuppressLint("NonConstantResourceId") - private fun setFragment(itemId: Int, navController: NavController, isXposedOnlyMode: Boolean) { - val currentDestination = navController.currentDestination ?: return + binding.bottomNavigationView.setOnItemSelectedListener { item -> + val fragmentTag: String = getTopFragmentTag() + + when (item.itemId) { + R.id.homePage -> { + if (fragmentTag != Home::class.java.simpleName) { + replaceFragment(supportFragmentManager, Home()) + binding.bottomNavigationView.weakVibrate() + } + return@setOnItemSelectedListener true + } + + R.id.tweaks -> { + if (fragmentTag != Tweaks::class.java.simpleName) { + replaceFragment(supportFragmentManager, Tweaks()) + binding.bottomNavigationView.weakVibrate() + } + return@setOnItemSelectedListener true + } - if (isXposedOnlyMode) { - when (itemId) { - R.id.xposedMenu -> { - if (currentDestination.id != itemId) { - navController.popBackStack(navController.graph.startDestinationId, false) - selectedFragment = itemId + R.id.xposed -> { + if (fragmentTag != Xposed::class.java.simpleName) { + replaceFragment(supportFragmentManager, Xposed()) + binding.bottomNavigationView.weakVibrate() } + return@setOnItemSelectedListener true } R.id.settings -> { - if (currentDestination.id != itemId) { - navController.popBackStack(navController.graph.startDestinationId, false) - findNavController( - this, - R.id.fragmentContainerView - ).navigate(R.id.action_xposedMenu_to_settings2) - selectedFragment = itemId + if (fragmentTag != Settings::class.java.simpleName) { + replaceFragment(supportFragmentManager, Settings()) + binding.bottomNavigationView.weakVibrate() } + return@setOnItemSelectedListener true + } + + else -> { + return@setOnItemSelectedListener false } } - return } + } - when (itemId) { - R.id.homePage -> { - if (currentDestination.id != itemId) { - navController.popBackStack(navController.graph.startDestinationId, false) - selectedFragment = itemId - } + private fun showOrHideFabButtons() { + try { + val pendingActionsShown = binding.pendingActions.isShown + var isAnyButtonShown: Boolean + + if (!binding.hideAll.isShown && pendingActionsShown) { + binding.hideAll.show() + binding.hideAllText.fadeIn() + isAnyButtonShown = true + } else { + binding.hideAll.hide() + binding.hideAllText.fadeOut() + isAnyButtonShown = false } - R.id.tweaks -> { - if (currentDestination.id != itemId) { - navController.popBackStack(navController.graph.startDestinationId, false) - findNavController( - this, - R.id.fragmentContainerView - ).navigate(R.id.action_home2_to_tweaks) - selectedFragment = itemId - } + if (!binding.restartSystemui.isShown && Dynamic.requiresSystemUiRestart && pendingActionsShown) { + binding.restartSystemui.show() + binding.restartSystemuiText.fadeIn() + isAnyButtonShown = true + } else { + binding.restartSystemui.hide() + binding.restartSystemuiText.fadeOut() + isAnyButtonShown = isAnyButtonShown || false } - R.id.settings -> { - if (currentDestination.id != itemId) { - navController.popBackStack(navController.graph.startDestinationId, false) - findNavController( - this, - R.id.fragmentContainerView - ).navigate(R.id.action_home2_to_settings) - selectedFragment = itemId - } + if (!binding.restartDevice.isShown && Dynamic.requiresDeviceRestart && pendingActionsShown) { + binding.restartDevice.show() + binding.restartDeviceText.fadeIn() + isAnyButtonShown = true + } else { + binding.restartDevice.hide() + binding.restartDeviceText.fadeOut() + isAnyButtonShown = isAnyButtonShown || false + } + + if (isAnyButtonShown) { + binding.pendingActions.extend() + } else { + binding.pendingActions.shrink() + } + } catch (_: Exception) { + } + } + + private fun setupSearchConfiguration() { + searchConfiguration.apply { + setActivity(this@MainActivity) + setFragmentContainerViewId(R.id.fragmentContainerView) + + searchableFragments.forEach { + index(it.xml).addBreadcrumb(resources.getString(it.title)) } + + setBreadcrumbsEnabled(true) + setHistoryEnabled(true) + setFuzzySearchEnabled(false) + } + } + + private fun getTopFragment(): Fragment { + val last: Int = supportFragmentManager.fragments.size - 1 + + if (last >= 0) { + return supportFragmentManager.fragments[last] } + + return Home() + } + + private fun getTopFragmentTag(): String { + return getTopFragment().tag ?: UUID.randomUUID().toString() } fun showColorPickerDialog( @@ -158,7 +322,7 @@ class MainActivity : BaseActivity(), ColorPickerDialogListener { showAlphaSlider: Boolean, showColorShades: Boolean ) { - colorPickerDialog!!.setDialogStyle(R.style.ColorPicker) + colorPickerDialog .setColor(defaultColor) .setDialogType(ColorPickerDialog.TYPE_CUSTOM) .setAllowCustom(false) @@ -167,19 +331,7 @@ class MainActivity : BaseActivity(), ColorPickerDialogListener { .setShowAlphaSlider(showAlphaSlider) .setShowColorShades(showColorShades) - colorPickerDialog!!.show(this) - } - - override fun onSaveInstanceState(outState: Bundle) { - super.onSaveInstanceState(outState) - - if (selectedFragment != null) outState.putInt(DATA_KEY, selectedFragment!!) - } - - public override fun onRestoreInstanceState(savedInstanceState: Bundle) { - super.onRestoreInstanceState(savedInstanceState) - - selectedFragment = savedInstanceState.getInt(DATA_KEY) + colorPickerDialog.show(this) } override fun onColorSelected(dialogId: Int, color: Int) { @@ -190,12 +342,205 @@ class MainActivity : BaseActivity(), ColorPickerDialogListener { EventBus.getDefault().post(ColorDismissedEvent(dialogId)) } - override fun onSupportNavigateUp(): Boolean { - val navController = findNavController(this, R.id.fragmentContainerView) - return navController.navigateUp() || super.onSupportNavigateUp() + @Suppress("deprecation") + override fun onPreferenceStartFragment( + caller: PreferenceFragmentCompat, + pref: Preference + ): Boolean { + replaceFragment( + supportFragmentManager, + supportFragmentManager.fragmentFactory.instantiate( + classLoader, pref.fragment!! + ).apply { + arguments = pref.extras + setTargetFragment(caller, 0) + } + ) + return true + } + + override fun onSearchResultClicked(result: SearchPreferenceResult) { + Handler(mainLooper).post { + val lastFragment = getLastFragment(supportFragmentManager, excludeSearchFragment = true) + + (lastFragment as? BaseFragment)?.onSearchResultClicked(result) + ?: (lastFragment as? ControlledPreferenceFragmentCompat) + ?.onSearchResultClicked(result) + } + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + val itemID = item.itemId + + if (itemID == android.R.id.home) { + onBackPressedDispatcher.onBackPressed() + return true + } + + return false } companion object { - private const val DATA_KEY = "mDataKey" + private lateinit var colorPickerDialog: ColorPickerDialog.Builder + + fun replaceFragment(fragmentManager: FragmentManager, fragment: Fragment) { + if (fragmentManager.isStateSaved) return + + try { + val fragmentTag = fragment.javaClass.simpleName + var currentFragment = fragmentManager.findFragmentById(R.id.fragmentContainerView) + + if (currentFragment != null && + currentFragment.javaClass.simpleName == SearchPreferenceFragment::class.java.simpleName + ) { + fragmentManager.popBackStack() + currentFragment = fragmentManager.findFragmentById(R.id.fragmentContainerView) + } + + if (currentFragment != null && + currentFragment.javaClass.simpleName == fragmentTag + ) { + popCurrentFragment(fragmentManager) + } + + for (i in 0 until fragmentManager.backStackEntryCount) { + if (fragmentManager.getBackStackEntryAt(i).name == fragmentTag) { + fragmentManager.popBackStack( + fragmentTag, + POP_BACK_STACK_INCLUSIVE + ) + break + } + } + + fragmentManager.beginTransaction().apply { + setCustomAnimations( + R.anim.fragment_fade_in, + R.anim.fragment_fade_out, + R.anim.fragment_fade_in, + R.anim.fragment_fade_out + ) + + replace(R.id.fragmentContainerView, fragment, fragmentTag) + + when (fragmentTag) { + Home::class.java.simpleName -> { + fragmentManager.popBackStack(null, POP_BACK_STACK_INCLUSIVE) + } + + Tweaks::class.java.simpleName, + Xposed::class.java.simpleName, + Settings::class.java.simpleName -> { + fragmentManager.popBackStack(null, POP_BACK_STACK_INCLUSIVE) + addToBackStack(fragmentTag) + } + + else -> { + addToBackStack(fragmentTag) + } + } + + commit() + } + } catch (ignored: IllegalStateException) { + } + } + + @Suppress("SameParameterValue") + private fun getLastFragment( + fragmentManager: FragmentManager, + excludeSearchFragment: Boolean = false + ): Fragment? { + val index = fragmentManager.backStackEntryCount - 1 + var backEntry = fragmentManager.getBackStackEntryAt(index) + var fragment = fragmentManager.findFragmentByTag(backEntry.name) + + if (excludeSearchFragment && fragment is SearchPreferenceFragment) { + backEntry = fragmentManager.getBackStackEntryAt(index - 1) + fragment = fragmentManager.findFragmentByTag(backEntry.name) + } + + return fragment + } + + fun popCurrentFragment(fragmentManager: FragmentManager) { + if (fragmentManager.isStateSaved) return + + fragmentManager.popBackStack() + } + + fun showOrHidePendingActionButton( + activityBinding: ActivityMainBinding, // Pass the binding as a parameter + requiresSystemUiRestart: Boolean = Dynamic.requiresSystemUiRestart, + requiresDeviceRestart: Boolean = Dynamic.requiresDeviceRestart, + ) { + Dynamic.requiresSystemUiRestart = + requiresSystemUiRestart || Dynamic.requiresSystemUiRestart + Dynamic.requiresDeviceRestart = requiresDeviceRestart || Dynamic.requiresDeviceRestart + + try { + with(activityBinding) { + if (!Dynamic.requiresSystemUiRestart && !Dynamic.requiresDeviceRestart) { + hideAll.hide() + hideAllText.fadeOut() + restartSystemui.hide() + restartSystemuiText.fadeOut() + restartDevice.hide() + restartDeviceText.fadeOut() + pendingActions.hide() + pendingActions.shrink() + } else { + if (hideAll.isShown && Dynamic.requiresSystemUiRestart && !restartSystemui.isShown) { + restartSystemui.show() + restartSystemuiText.fadeIn() + } else if (!Dynamic.requiresSystemUiRestart && restartSystemui.isShown) { + restartSystemui.hide() + restartSystemuiText.fadeOut() + } + + if (hideAll.isShown && Dynamic.requiresDeviceRestart && !restartDevice.isShown) { + restartDevice.show() + restartDeviceText.fadeIn() + } else if (!Dynamic.requiresDeviceRestart && restartDevice.isShown) { + restartDevice.hide() + restartDeviceText.fadeOut() + } + + if (!hideAll.isShown) { + pendingActions.shrink() + } else { + pendingActions.extend() + } + + pendingActions.show() + } + } + } catch (_: Exception) { + } + } + + private fun View.fadeIn(duration: Long = 300) { + this.apply { + alpha = 0f + visibility = View.VISIBLE + animate() + .alpha(1f) + .setDuration(duration) + .setListener(null) + } + } + + private fun View.fadeOut(duration: Long = 300) { + this.apply { + animate() + .alpha(0f) + .setDuration(duration) + .setListener(object : AnimatorListenerAdapter() { + override fun onAnimationEnd(animation: Animator) { + visibility = View.GONE + } + }) + } + } } } \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/ui/adapters/BrightnessBarAdapter.kt b/app/src/main/java/com/drdisagree/iconify/ui/adapters/BrightnessBarAdapter.kt index 3420d8cf9..7015e73cb 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/adapters/BrightnessBarAdapter.kt +++ b/app/src/main/java/com/drdisagree/iconify/ui/adapters/BrightnessBarAdapter.kt @@ -19,7 +19,7 @@ import androidx.recyclerview.widget.RecyclerView import com.drdisagree.iconify.Iconify import com.drdisagree.iconify.Iconify.Companion.appContext import com.drdisagree.iconify.R -import com.drdisagree.iconify.config.Prefs.getBoolean +import com.drdisagree.iconify.config.RPrefs.getBoolean import com.drdisagree.iconify.ui.dialogs.LoadingDialog import com.drdisagree.iconify.ui.models.BrightnessBarModel import com.drdisagree.iconify.utils.overlay.manager.BrightnessBarManager diff --git a/app/src/main/java/com/drdisagree/iconify/ui/adapters/ClockPreviewAdapter.kt b/app/src/main/java/com/drdisagree/iconify/ui/adapters/ClockPreviewAdapter.kt index 4c667be92..ded2c5f28 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/adapters/ClockPreviewAdapter.kt +++ b/app/src/main/java/com/drdisagree/iconify/ui/adapters/ClockPreviewAdapter.kt @@ -19,7 +19,7 @@ import com.drdisagree.iconify.common.Preferences.LSCLOCK_SWITCH import com.drdisagree.iconify.config.RPrefs import com.drdisagree.iconify.ui.models.ClockModel import com.drdisagree.iconify.ui.utils.ViewBindingHelpers.setBitmapWithAnimation -import com.drdisagree.iconify.utils.WallpaperUtil +import com.drdisagree.iconify.utils.WallpaperUtils import com.google.android.material.button.MaterialButton import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -31,7 +31,8 @@ class ClockPreviewAdapter( private val context: Context, private val itemList: ArrayList, prefSwitch: String?, - prefStyle: String + prefStyle: String, + private val mOnStyleSelected: OnStyleSelected? = null ) : RecyclerView.Adapter() { private val prefStyle: String @@ -67,26 +68,19 @@ class ClockPreviewAdapter( inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { - val container: LinearLayout - private val title: TextView - private val clockContainer: LinearLayout - val checkIcon: ImageView - val button: MaterialButton - private val wallpaperView: ImageView - - init { - container = itemView.findViewById(R.id.clock_preview_child) - title = itemView.findViewById(R.id.clock_title) - clockContainer = itemView.findViewById(R.id.clock_view_container) - checkIcon = itemView.findViewById(R.id.icon_selected) - button = itemView.findViewById(R.id.btn_select_style) - wallpaperView = itemView.findViewById(R.id.wallpaper_view) - } + val container: LinearLayout = itemView.findViewById(R.id.clock_preview_child) + private val title: TextView = itemView.findViewById(R.id.clock_title) + private val clockContainer: LinearLayout = itemView.findViewById(R.id.clock_view_container) + val checkIcon: ImageView = itemView.findViewById(R.id.icon_selected) + val button: MaterialButton = itemView.findViewById(R.id.btn_select_style) + private val wallpaperView: ImageView = itemView.findViewById(R.id.wallpaper_view) fun bind(model: ClockModel, position: Int) { title.text = model.title + button.setOnClickListener { RPrefs.putInt(prefStyle, position) + mOnStyleSelected?.onStyleSelected(position) refreshLayout(this) } @@ -155,10 +149,8 @@ class ClockPreviewAdapter( fun loadWallpaper(adapter: ClockPreviewAdapter) { CoroutineScope(Dispatchers.Main).launch { val bitmap = withContext(Dispatchers.IO) { - val context = adapter.context - - WallpaperUtil.getCompressedWallpaper( - context, + WallpaperUtils.getCompressedWallpaper( + adapter.context, 80, if (prefSwitch == LSCLOCK_SWITCH) { WallpaperManager.FLAG_LOCK @@ -175,6 +167,15 @@ class ClockPreviewAdapter( } } + interface OnStyleSelected { + /** + * Interface for style selection + * @param position The position of the selected style, + * in our case is the num of the layout + */ + fun onStyleSelected(position: Int) + } + companion object { private var prefSwitch: String? = null private var wallpaperBitmap: Bitmap? = null diff --git a/app/src/main/java/com/drdisagree/iconify/ui/adapters/IconPackAdapter.kt b/app/src/main/java/com/drdisagree/iconify/ui/adapters/IconPackAdapter.kt index bbd36456f..8d131d9c0 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/adapters/IconPackAdapter.kt +++ b/app/src/main/java/com/drdisagree/iconify/ui/adapters/IconPackAdapter.kt @@ -15,43 +15,77 @@ import android.widget.Toast import androidx.core.content.ContextCompat import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView -import com.drdisagree.iconify.Iconify import com.drdisagree.iconify.Iconify.Companion.appContext import com.drdisagree.iconify.R -import com.drdisagree.iconify.config.Prefs.getBoolean +import com.drdisagree.iconify.config.RPrefs.getBoolean import com.drdisagree.iconify.ui.dialogs.LoadingDialog import com.drdisagree.iconify.ui.models.IconPackModel -import com.drdisagree.iconify.utils.overlay.manager.IconPackManager class IconPackAdapter( var context: Context, private var itemList: ArrayList, - var loadingDialog: LoadingDialog + var loadingDialog: LoadingDialog, + private var componentName: String, + private var onButtonClick: OnButtonClick? = null ) : RecyclerView.Adapter() { private var iconPackKeys = ArrayList() private var linearLayoutManager: LinearLayoutManager? = null private var selectedItem = -1 + private var mComponentName = componentName + + constructor( + context: Context, + itemList: ArrayList, + loadingDialog: LoadingDialog, + compName: String + ) : this(context, itemList, loadingDialog, compName, null) init { // Preference key - for (i in 1..itemList.size) iconPackKeys.add("IconifyComponentIPAS$i.overlay") + for (i in 1..itemList.size) iconPackKeys.add( + itemList[i - 1].packageName.takeIf { !it.isNullOrEmpty() } + ?: "IconifyComponent${mComponentName}${i}.overlay" + ) } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { - val view = - LayoutInflater.from(context).inflate(R.layout.view_list_option_iconpack, parent, false) + val view = LayoutInflater.from(context).inflate( + R.layout.view_list_option_iconpack, + parent, + false + ) return ViewHolder(view) } - override fun onBindViewHolder(holder: ViewHolder, position: Int) { holder.styleName.text = itemList[position].name - holder.desc.text = context.resources.getString(itemList[position].desc) - holder.icon1.setImageResource(itemList[position].icon1) - holder.icon2.setImageResource(itemList[position].icon2) - holder.icon3.setImageResource(itemList[position].icon3) - holder.icon4.setImageResource(itemList[position].icon4) + if (itemList[position].desc != 0x0) { + holder.desc.visibility = View.VISIBLE + holder.desc.text = context.resources.getString(itemList[position].desc) + } else + holder.desc.visibility = View.GONE + + if (itemList[position].icon1 != 0x0) { + holder.icon1.setImageResource(itemList[position].icon1) + } else if (itemList[position].drawableIcon1 != null) { + holder.icon1.setImageDrawable(itemList[position].drawableIcon1) + } + if (itemList[position].icon2 != 0x0) { + holder.icon2.setImageResource(itemList[position].icon2) + } else if (itemList[position].drawableIcon2 != null) { + holder.icon2.setImageDrawable(itemList[position].drawableIcon2) + } + if (itemList[position].icon1 != 0x0) { + holder.icon3.setImageResource(itemList[position].icon3) + } else if (itemList[position].drawableIcon3 != null) { + holder.icon3.setImageDrawable(itemList[position].drawableIcon3) + } + if (itemList[position].icon4 != 0x0) { + holder.icon4.setImageResource(itemList[position].icon4) + } else if (itemList[position].drawableIcon4 != null) { + holder.icon4.setImageDrawable(itemList[position].drawableIcon4) + } refreshButton(holder) enableOnClickListener(holder) @@ -110,7 +144,12 @@ class IconPackAdapter( loadingDialog.show(context.resources.getString(R.string.loading_dialog_wait)) Thread { - IconPackManager.enableOverlay(holder.getBindingAdapterPosition() + 1) + if (onButtonClick != null) { + onButtonClick!!.onEnableClick( + holder.bindingAdapterPosition, + itemList[holder.bindingAdapterPosition] + ) + } (context as Activity).runOnUiThread { Handler(Looper.getMainLooper()).postDelayed({ @@ -139,7 +178,12 @@ class IconPackAdapter( loadingDialog.show(context.resources.getString(R.string.loading_dialog_wait)) Thread { - IconPackManager.disableOverlay(holder.getBindingAdapterPosition() + 1) + if (onButtonClick != null) { + onButtonClick!!.onDisableClick( + holder.bindingAdapterPosition, + itemList[holder.bindingAdapterPosition] + ) + } (context as Activity).runOnUiThread { Handler(Looper.getMainLooper()).postDelayed({ @@ -254,26 +298,23 @@ class IconPackAdapter( class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { - var container: LinearLayout - var styleName: TextView - var desc: TextView - var icon1: ImageView - var icon2: ImageView - var icon3: ImageView - var icon4: ImageView - var btnEnable: Button - var btnDisable: Button - - init { - container = itemView.findViewById(R.id.icon_pack_child) - styleName = itemView.findViewById(R.id.iconpack_title) - desc = itemView.findViewById(R.id.iconpack_desc) - icon1 = itemView.findViewById(R.id.iconpack_preview1) - icon2 = itemView.findViewById(R.id.iconpack_preview2) - icon3 = itemView.findViewById(R.id.iconpack_preview3) - icon4 = itemView.findViewById(R.id.iconpack_preview4) - btnEnable = itemView.findViewById(R.id.enable_iconpack) - btnDisable = itemView.findViewById(R.id.disable_iconpack) - } + var container: LinearLayout = itemView.findViewById(R.id.icon_pack_child) + var styleName: TextView = itemView.findViewById(R.id.iconpack_title) + var desc: TextView = itemView.findViewById(R.id.iconpack_desc) + var icon1: ImageView = itemView.findViewById(R.id.iconpack_preview1) + var icon2: ImageView = itemView.findViewById(R.id.iconpack_preview2) + var icon3: ImageView = itemView.findViewById(R.id.iconpack_preview3) + var icon4: ImageView = itemView.findViewById(R.id.iconpack_preview4) + var btnEnable: Button = itemView.findViewById(R.id.enable_iconpack) + var btnDisable: Button = itemView.findViewById(R.id.disable_iconpack) } + + /** + * Interface for the click on the item + */ + interface OnButtonClick { + fun onEnableClick(position: Int, item: IconPackModel) + fun onDisableClick(position: Int, item: IconPackModel) + } + } diff --git a/app/src/main/java/com/drdisagree/iconify/ui/adapters/IconShapeAdapter.kt b/app/src/main/java/com/drdisagree/iconify/ui/adapters/IconShapeAdapter.kt new file mode 100644 index 000000000..7c084db69 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/adapters/IconShapeAdapter.kt @@ -0,0 +1,100 @@ +package com.drdisagree.iconify.ui.adapters + +import android.content.Context +import android.content.res.ColorStateList +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.annotation.ColorInt +import androidx.core.content.ContextCompat +import androidx.recyclerview.widget.RecyclerView +import com.drdisagree.iconify.Iconify.Companion.appContext +import com.drdisagree.iconify.Iconify.Companion.appContextLocale +import com.drdisagree.iconify.R +import com.drdisagree.iconify.common.Preferences.SELECTED_ICON_SHAPE +import com.drdisagree.iconify.config.RPrefs +import com.drdisagree.iconify.databinding.ViewIconShapeBinding +import com.drdisagree.iconify.databinding.ViewToastFrameBinding +import com.drdisagree.iconify.ui.models.IconShapeModel + +class IconShapeAdapter ( + var context: Context, + private var itemList: ArrayList, + private var iconShapeClick: OnShapeClick +) : RecyclerView.Adapter() { + + private var selected = RPrefs.getInt(SELECTED_ICON_SHAPE, -1) + @ColorInt + val colorBackground = appContextLocale.resources.getColor( + R.color.colorBackground, + appContext.theme + ) + @ColorInt + val colorSuccess = appContextLocale.resources.getColor( + R.color.colorSuccess, + appContext.theme + ) + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + val binding: ViewIconShapeBinding = + ViewIconShapeBinding.inflate(LayoutInflater.from(parent.context), parent, false) + if (selected != -1) { + itemList[selected].selected = true + } else { + itemList[0].selected = true + } + return ViewHolder(binding) + } + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + val model = itemList[holder.bindingAdapterPosition] + holder.binding.shapeName.text = appContextLocale.resources.getString(model.title) + holder.binding.maskShapeBg.background = ContextCompat.getDrawable(appContext, model.style) + holder.binding.maskShapeFg.background = ContextCompat.getDrawable(appContext, model.style) + holder.binding.maskShapeFg.setBackgroundTintList(ColorStateList.valueOf(colorBackground)) + if (model.selected) { + holder.binding.shapeName.setTextColor(colorSuccess) + holder.binding.maskShapeBg.setBackgroundTintList(ColorStateList.valueOf(colorSuccess)) + } else { + holder.binding.shapeName.setTextColor( + appContextLocale.resources.getColor( + R.color.textColorSecondary, + appContext.theme + ) + ) + } + holder.binding.listItemShape.setOnClickListener { + iconShapeClick.onShapeClick(holder.bindingAdapterPosition, model) + } + } + + fun notifyChange() { + refresh(false) + selected = RPrefs.getInt(SELECTED_ICON_SHAPE, -1) + refresh(true) + } + + private fun refresh(select: Boolean) { + if (selected != -1) { + itemList[selected].selected = select + notifyItemChanged(selected) + } else { + itemList[0].selected = select + notifyItemChanged(0) + } + } + + override fun getItemCount(): Int { + return itemList.size + } + + class ViewHolder(val binding: ViewIconShapeBinding) : RecyclerView.ViewHolder(binding.getRoot()) { + } + + /** + * Interface for the click on the item + */ + interface OnShapeClick { + fun onShapeClick(position: Int, item: IconShapeModel) + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/ui/adapters/IconsAdapter.kt b/app/src/main/java/com/drdisagree/iconify/ui/adapters/IconsAdapter.kt index 9ba682989..405db66a0 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/adapters/IconsAdapter.kt +++ b/app/src/main/java/com/drdisagree/iconify/ui/adapters/IconsAdapter.kt @@ -10,14 +10,21 @@ import androidx.recyclerview.widget.RecyclerView import com.drdisagree.iconify.Iconify.Companion.appContext import com.drdisagree.iconify.R import com.drdisagree.iconify.databinding.ViewListIconItemBinding +import com.drdisagree.iconify.databinding.ViewListOptionWeatherIconsBinding class IconsAdapter( private val mEntries: Array, private val mEntryValues: Array, private var mValue: String, + private val mAdapterType: Int, private val onItemClickListener: OnItemClickListener ) : RecyclerView.Adapter() { + companion object { + const val ICONS_ADAPTER = 0 + const val WEATHER_ICONS_ADAPTER = 1 + } + private var mEntryDrawables: Array? = null private var mEntryResIds: IntArray? = null @@ -39,17 +46,47 @@ class IconsAdapter( } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { - return IconsViewHolder( - ViewListIconItemBinding.inflate( - LayoutInflater.from(parent.context), - parent, - false - ) - ) + when (mAdapterType) { + ICONS_ADAPTER -> { + return IconsViewHolder( + ViewListIconItemBinding.inflate( + LayoutInflater.from(parent.context), + parent, + false + ) + ) + } + + WEATHER_ICONS_ADAPTER -> { + return WeatherIconsViewHolder( + ViewListOptionWeatherIconsBinding.inflate( + LayoutInflater.from(parent.context), + parent, + false + ) + ) + } + + else -> { + throw IllegalStateException(javaClass.getSimpleName() + " - No adapter type provided") + } + } } override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { - (holder as IconsViewHolder).binding.typeTitle.text = mEntries[position] + when (mAdapterType) { + ICONS_ADAPTER -> { + bindIconsViewHolder(holder as IconsViewHolder, position) + } + + WEATHER_ICONS_ADAPTER -> { + bindWeatherIconsViewHolder(holder as WeatherIconsViewHolder, position) + } + } + } + + private fun bindIconsViewHolder(holder: IconsViewHolder, position: Int) { + holder.binding.typeTitle.text = mEntries[position] if (mEntryDrawables != null) { holder.binding.batteryIcon.setImageDrawable(mEntryDrawables!![position]) @@ -81,6 +118,39 @@ class IconsAdapter( } } + private fun bindWeatherIconsViewHolder(holder: WeatherIconsViewHolder, position: Int) { + holder.binding.text.text = mEntries[position] + + if (mEntryDrawables != null) { + holder.binding.image.setImageDrawable(mEntryDrawables!![position]) + } else if (mEntryResIds != null) { + holder.binding.image.setImageDrawable( + ContextCompat.getDrawable( + holder.binding.getRoot().context, + mEntryResIds!![position] + ) + ) + } else { + throw IllegalStateException(javaClass.getSimpleName() + " - No icons provided") + } + + if (mEntryValues[position].toString().contentEquals(mValue)) { + holder.binding.rootLayout.strokeColor = appContext.getColor(R.color.colorAccent) + } else { + holder.binding.rootLayout.strokeColor = Color.TRANSPARENT + } + + holder.binding.rootLayout.setOnClickListener { v: View -> + val previousPosition = mEntryValues.indexOf(mValue) + mValue = mEntryValues[position].toString() + + notifyItemChanged(previousPosition) + notifyItemChanged(position) + + onItemClickListener.onItemClick(v, position) + } + } + override fun getItemCount(): Int { return mEntries.size } @@ -94,6 +164,11 @@ class IconsAdapter( binding.getRoot() ) + class WeatherIconsViewHolder internal constructor(val binding: ViewListOptionWeatherIconsBinding) : + RecyclerView.ViewHolder( + binding.getRoot() + ) + /** * Interface for the click on the item */ diff --git a/app/src/main/java/com/drdisagree/iconify/ui/adapters/InfoAdapter.kt b/app/src/main/java/com/drdisagree/iconify/ui/adapters/InfoAdapter.kt index 6af6265af..c737907ee 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/adapters/InfoAdapter.kt +++ b/app/src/main/java/com/drdisagree/iconify/ui/adapters/InfoAdapter.kt @@ -45,19 +45,19 @@ class InfoAdapter( @SuppressLint("DiscouragedApi") override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { if (holder is HeaderViewHolder) { - holder.header.text = itemList[position].getTitle() + holder.header.text = itemList[position].title - if (itemList[position].getTitle() == "") { + if (itemList[position].title == "") { holder.itemView.visibility = View.GONE holder.itemView.setLayoutParams(RecyclerView.LayoutParams(0, 0)) } } else if (holder is ItemViewHolder) { - holder.icon.setImageResource(itemList[position].getIcon()) - holder.title.text = itemList[position].getTitle() - holder.desc.text = itemList[position].getDesc() - holder.container.setOnClickListener(itemList[position].getOnClickListener()) + holder.icon.setImageResource(itemList[position].icon) + holder.title.text = itemList[position].title + holder.desc.text = itemList[position].desc + holder.container.setOnClickListener(itemList[position].onClickListener) - val drawableName = context.resources.getResourceEntryName(itemList[position].getIcon()) + val drawableName = context.resources.getResourceEntryName(itemList[position].icon) val typedValue = TypedValue() context.theme.resolveAttribute( @@ -85,26 +85,15 @@ class InfoAdapter( internal class HeaderViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { - var header: TextView - - init { - header = itemView.findViewById(R.id.list_info_header) - } + var header: TextView = itemView.findViewById(R.id.list_info_header) } internal class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { - var icon: ImageView - var title: TextView - var desc: TextView - var container: RelativeLayout - - init { - icon = itemView.findViewById(R.id.icon) - title = itemView.findViewById(R.id.title) - desc = itemView.findViewById(R.id.desc) - container = itemView.findViewById(R.id.list_info_item) - } + var icon: ImageView = itemView.findViewById(R.id.icon) + var title: TextView = itemView.findViewById(R.id.title) + var desc: TextView = itemView.findViewById(R.id.desc) + var container: RelativeLayout = itemView.findViewById(R.id.list_info_item) } companion object { diff --git a/app/src/main/java/com/drdisagree/iconify/ui/adapters/ListPreferenceAdapter.kt b/app/src/main/java/com/drdisagree/iconify/ui/adapters/ListPreferenceAdapter.kt new file mode 100644 index 000000000..32bc07742 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/adapters/ListPreferenceAdapter.kt @@ -0,0 +1,169 @@ +package com.drdisagree.iconify.ui.adapters + +import android.graphics.Color +import android.graphics.drawable.Drawable +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.core.content.ContextCompat +import androidx.recyclerview.widget.RecyclerView +import com.drdisagree.iconify.Iconify.Companion.appContext +import com.drdisagree.iconify.R +import com.drdisagree.iconify.config.RPrefs +import com.drdisagree.iconify.databinding.PreferenceListItemBinding +import com.drdisagree.iconify.databinding.ViewListIconItemBinding + +class ListPreferenceAdapter : RecyclerView.Adapter { + private var mResImages: List = ArrayList() + private val mEntries: Array + private val mEntryValues: Array + private val mEntryIcons: IntArray? + private val mEntryDrawables: Array? + private val mKey: String + private val mHasImage: Boolean + private var onItemClickListener: OnItemClickListener + private var mValue: String? = null + var type: Int = DEFAULT_TYPE + private var prevPos: Int = -1 + + constructor( + entries: Array, + entryValues: Array, + entryIcons: IntArray?, + key: String, + hasImage: Boolean, + onItemClickListener: OnItemClickListener + ) { + this.mEntries = entries + this.mEntryValues = entryValues + this.mEntryIcons = entryIcons + this.mEntryDrawables = null + this.mKey = key + this.mHasImage = hasImage + this.onItemClickListener = onItemClickListener + this.type = DEFAULT_TYPE + } + + constructor( + entries: Array, + entryValues: Array, + entryDrawables: Array, + key: String, + hasImage: Boolean, + onItemClickListener: OnItemClickListener + ) { + this.mEntries = entries + this.mEntryValues = entryValues + this.mEntryDrawables = entryDrawables + this.mEntryIcons = null + this.mKey = key + this.mHasImage = hasImage + this.onItemClickListener = onItemClickListener + this.type = DEFAULT_TYPE + } + + fun setListener(onItemClickListener: OnItemClickListener) { + this.onItemClickListener = onItemClickListener + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { + mValue = RPrefs.getString(mKey, "") + val binding: PreferenceListItemBinding = + PreferenceListItemBinding.inflate(LayoutInflater.from(parent.context), parent, false) + val batteryIconOptionsBinding: ViewListIconItemBinding = + ViewListIconItemBinding.inflate(LayoutInflater.from(parent.context), parent, false) + return if (type == TYPE_BATTERY_ICONS) { + BatteryIconsViewHolder(batteryIconOptionsBinding) + } else { + ViewHolder(binding) + } + } + + override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { + if (type == TYPE_BATTERY_ICONS) { + (holder as BatteryIconsViewHolder).binding.typeTitle.text = mEntries[holder.bindingAdapterPosition] + + if (mHasImage) { + if (mEntryDrawables != null) holder.binding.batteryIcon.setImageDrawable( + mEntryDrawables[holder.bindingAdapterPosition] + ) + else holder.binding.batteryIcon.setImageDrawable( + ContextCompat.getDrawable( + holder.binding.getRoot().context, + mEntryIcons!![holder.bindingAdapterPosition] + ) + ) + } else holder.binding.batteryIcon.setVisibility(View.GONE) + + if (mEntryValues[holder.bindingAdapterPosition].toString().contentEquals(mValue)) { + prevPos = holder.bindingAdapterPosition + holder.binding.rootLayout.strokeColor = appContext.getColor(R.color.colorAccent) + } else { + holder.binding.rootLayout.strokeColor = Color.TRANSPARENT + } + + holder.binding.rootLayout.setOnClickListener { v -> + onItemClickListener.onItemClick(v, holder.bindingAdapterPosition) + mValue = mEntryValues[holder.bindingAdapterPosition].toString() + notifyItemChanged(prevPos) + notifyItemChanged(holder.bindingAdapterPosition) + } + } else { + (holder as ViewHolder).binding.text.text = mEntries[holder.bindingAdapterPosition] + if (mHasImage) { + if (mEntryIcons != null && mEntryIcons.isNotEmpty()) holder.binding.image.setImageDrawable( + ContextCompat.getDrawable( + holder.binding.getRoot().context, + mEntryIcons[holder.bindingAdapterPosition] + ) + ) + else if (!mEntryDrawables.isNullOrEmpty()) holder.binding.image.setImageDrawable( + mEntryDrawables[holder.bindingAdapterPosition] + ) + } else holder.binding.image.setVisibility(View.GONE) + + if (mEntryValues[holder.bindingAdapterPosition].toString().contentEquals(mValue)) { + prevPos = holder.bindingAdapterPosition + holder.binding.rootLayout.strokeColor = + appContext.getColor(R.color.colorAccent) + } else { + holder.binding.rootLayout.strokeColor = Color.TRANSPARENT + } + + holder.binding.rootLayout.setOnClickListener { v -> + onItemClickListener.onItemClick(v, holder.bindingAdapterPosition) + mValue = mEntryValues[holder.bindingAdapterPosition].toString() + notifyItemChanged(prevPos) + notifyItemChanged(holder.bindingAdapterPosition) + } + } + } + + override fun getItemCount(): Int { + return mEntries.size + } + + fun setImages(images: List) { + mResImages = images + } + + class ViewHolder internal constructor(val binding: PreferenceListItemBinding) : + RecyclerView.ViewHolder(binding.getRoot()) { + } + + class BatteryIconsViewHolder internal constructor(val binding: ViewListIconItemBinding) : + RecyclerView.ViewHolder(binding.getRoot()) { + } + + /** + * Interface for the click on the item + */ + interface OnItemClickListener { + fun onItemClick(view: View?, position: Int) + } + + companion object { + const val DEFAULT_TYPE: Int = 0 + const val TYPE_BATTERY_ICONS: Int = 2 + } +} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/ui/adapters/MenuAdapter.kt b/app/src/main/java/com/drdisagree/iconify/ui/adapters/MenuAdapter.kt index 8b0251cf6..0ec75e913 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/adapters/MenuAdapter.kt +++ b/app/src/main/java/com/drdisagree/iconify/ui/adapters/MenuAdapter.kt @@ -3,12 +3,14 @@ package com.drdisagree.iconify.ui.adapters import android.content.Context import android.view.View import android.view.ViewGroup -import androidx.navigation.Navigation.findNavController +import androidx.fragment.app.FragmentManager import androidx.recyclerview.widget.RecyclerView +import com.drdisagree.iconify.ui.activities.MainActivity.Companion.replaceFragment import com.drdisagree.iconify.ui.models.MenuModel import com.drdisagree.iconify.ui.widgets.MenuWidget class MenuAdapter( + private var fragmentManager: FragmentManager, var context: Context, private var itemList: ArrayList ) : RecyclerView.Adapter() { @@ -25,8 +27,8 @@ class MenuAdapter( menu.setIcon(itemList[position].icon) menu.setEndArrowVisibility(View.VISIBLE) - menu.setOnClickListener { v: View? -> - findNavController(v!!).navigate(itemList[position].id) + menu.setOnClickListener { + replaceFragment(fragmentManager, itemList[position].fragment) } } diff --git a/app/src/main/java/com/drdisagree/iconify/ui/adapters/NotificationAdapter.kt b/app/src/main/java/com/drdisagree/iconify/ui/adapters/NotificationAdapter.kt index 5c26c919c..49354f2b9 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/adapters/NotificationAdapter.kt +++ b/app/src/main/java/com/drdisagree/iconify/ui/adapters/NotificationAdapter.kt @@ -18,7 +18,7 @@ import androidx.recyclerview.widget.RecyclerView import com.drdisagree.iconify.Iconify import com.drdisagree.iconify.Iconify.Companion.appContext import com.drdisagree.iconify.R -import com.drdisagree.iconify.config.Prefs.getBoolean +import com.drdisagree.iconify.config.RPrefs.getBoolean import com.drdisagree.iconify.ui.dialogs.LoadingDialog import com.drdisagree.iconify.ui.models.NotificationModel import com.drdisagree.iconify.ui.utils.ViewBindingHelpers.setDrawable diff --git a/app/src/main/java/com/drdisagree/iconify/ui/adapters/ProgressBarAdapter.kt b/app/src/main/java/com/drdisagree/iconify/ui/adapters/ProgressBarAdapter.kt index d065a511e..f64848650 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/adapters/ProgressBarAdapter.kt +++ b/app/src/main/java/com/drdisagree/iconify/ui/adapters/ProgressBarAdapter.kt @@ -16,16 +16,15 @@ import android.widget.Toast import androidx.core.content.ContextCompat import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView -import com.drdisagree.iconify.Iconify import com.drdisagree.iconify.Iconify.Companion.appContext import com.drdisagree.iconify.R import com.drdisagree.iconify.common.Const.FRAMEWORK_PACKAGE import com.drdisagree.iconify.common.Preferences.SELECTED_PROGRESSBAR -import com.drdisagree.iconify.config.Prefs +import com.drdisagree.iconify.config.RPrefs import com.drdisagree.iconify.ui.dialogs.LoadingDialog import com.drdisagree.iconify.ui.models.ProgressBarModel -import com.drdisagree.iconify.utils.SystemUtil -import com.drdisagree.iconify.utils.overlay.OverlayUtil +import com.drdisagree.iconify.utils.SystemUtils +import com.drdisagree.iconify.utils.overlay.OverlayUtils import com.drdisagree.iconify.utils.overlay.compiler.OnDemandCompiler import java.io.IOException import java.util.concurrent.atomic.AtomicBoolean @@ -51,7 +50,7 @@ class ProgressBarAdapter( holder.progressbar.background = ContextCompat.getDrawable(context, itemList[position].progress) - itemSelected(holder.container, Prefs.getInt(SELECTED_PROGRESSBAR, -1) == position) + itemSelected(holder.container, RPrefs.getInt(SELECTED_PROGRESSBAR, -1) == position) refreshButton(holder) enableOnClickListener(holder) } @@ -65,7 +64,7 @@ class ProgressBarAdapter( itemSelected( holder.container, - Prefs.getInt(SELECTED_PROGRESSBAR, -1) == holder.getBindingAdapterPosition() + RPrefs.getInt(SELECTED_PROGRESSBAR, -1) == holder.getBindingAdapterPosition() ) refreshButton(holder) @@ -86,7 +85,7 @@ class ProgressBarAdapter( refreshLayout(holder) - if (Prefs.getInt(SELECTED_PROGRESSBAR, -1) != holder.getBindingAdapterPosition()) { + if (RPrefs.getInt(SELECTED_PROGRESSBAR, -1) != holder.getBindingAdapterPosition()) { holder.btnDisable.visibility = View.GONE if (holder.btnEnable.visibility == View.VISIBLE) { @@ -107,8 +106,8 @@ class ProgressBarAdapter( // Set onClick operation for Enable button holder.btnEnable.setOnClickListener { - if (!SystemUtil.hasStoragePermission()) { - SystemUtil.requestStoragePermission(context) + if (!SystemUtils.hasStoragePermission()) { + SystemUtils.requestStoragePermission(context) } else { // Show loading dialog loadingDialog.show(context.resources.getString(R.string.loading_dialog_wait)) @@ -116,7 +115,7 @@ class ProgressBarAdapter( Thread { val hasErroredOut = AtomicBoolean(false) - Prefs.putInt(SELECTED_PROGRESSBAR, holder.getBindingAdapterPosition()) + RPrefs.putInt(SELECTED_PROGRESSBAR, holder.getBindingAdapterPosition()) try { hasErroredOut.set( @@ -150,7 +149,7 @@ class ProgressBarAdapter( Toast.LENGTH_SHORT ).show() } else { - Prefs.putInt(SELECTED_PROGRESSBAR, -1) + RPrefs.putInt(SELECTED_PROGRESSBAR, -1) Toast.makeText( appContext, @@ -170,8 +169,8 @@ class ProgressBarAdapter( loadingDialog.show(context.resources.getString(R.string.loading_dialog_wait)) Thread { - Prefs.putInt(SELECTED_PROGRESSBAR, -1) - OverlayUtil.disableOverlay("IconifyComponentPGB.overlay") + RPrefs.putInt(SELECTED_PROGRESSBAR, -1) + OverlayUtils.disableOverlay("IconifyComponentPGB.overlay") (context as Activity).runOnUiThread { Handler(Looper.getMainLooper()).postDelayed({ // Hide loading dialog @@ -229,7 +228,7 @@ class ProgressBarAdapter( itemSelected( child, i == holder.getAbsoluteAdapterPosition() && - Prefs.getInt(SELECTED_PROGRESSBAR, -1) == + RPrefs.getInt(SELECTED_PROGRESSBAR, -1) == i - (holder.getAbsoluteAdapterPosition() - holder.getBindingAdapterPosition()) ) } @@ -242,7 +241,7 @@ class ProgressBarAdapter( holder.btnEnable.visibility = View.GONE holder.btnDisable.visibility = View.GONE } else { - if (Prefs.getInt(SELECTED_PROGRESSBAR, -1) == selectedItem) { + if (RPrefs.getInt(SELECTED_PROGRESSBAR, -1) == selectedItem) { holder.btnEnable.visibility = View.GONE holder.btnDisable.visibility = View.VISIBLE } else { diff --git a/app/src/main/java/com/drdisagree/iconify/ui/adapters/QsShapeAdapter.kt b/app/src/main/java/com/drdisagree/iconify/ui/adapters/QsShapeAdapter.kt index 0e7229a4b..ba4621324 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/adapters/QsShapeAdapter.kt +++ b/app/src/main/java/com/drdisagree/iconify/ui/adapters/QsShapeAdapter.kt @@ -19,14 +19,13 @@ import androidx.core.content.ContextCompat import androidx.core.content.res.ResourcesCompat import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView -import com.drdisagree.iconify.Iconify import com.drdisagree.iconify.Iconify.Companion.appContext import com.drdisagree.iconify.R -import com.drdisagree.iconify.config.Prefs.getBoolean +import com.drdisagree.iconify.config.RPrefs.getBoolean import com.drdisagree.iconify.ui.dialogs.LoadingDialog import com.drdisagree.iconify.ui.models.QsShapeModel import com.drdisagree.iconify.ui.utils.ViewBindingHelpers.setDrawable -import com.drdisagree.iconify.utils.SystemUtil +import com.drdisagree.iconify.utils.SystemUtils import com.drdisagree.iconify.utils.overlay.manager.QsShapeManager import com.drdisagree.iconify.utils.overlay.manager.QsShapePixelManager import com.drdisagree.iconify.xposed.modules.utils.ViewHelper.toPx @@ -92,7 +91,7 @@ class QsShapeAdapter( R.color.textColorPrimaryInverse } } else { - if (itemList[position].inverseColor && SystemUtil.isDarkMode) { + if (itemList[position].inverseColor && SystemUtils.isDarkMode) { R.color.textColorPrimary } else { R.color.textColorPrimaryInverse diff --git a/app/src/main/java/com/drdisagree/iconify/ui/adapters/SwitchAdapter.kt b/app/src/main/java/com/drdisagree/iconify/ui/adapters/SwitchAdapter.kt index 7afc47d9a..3091dce71 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/adapters/SwitchAdapter.kt +++ b/app/src/main/java/com/drdisagree/iconify/ui/adapters/SwitchAdapter.kt @@ -17,16 +17,15 @@ import android.widget.Toast import androidx.core.content.res.ResourcesCompat import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView -import com.drdisagree.iconify.Iconify import com.drdisagree.iconify.Iconify.Companion.appContext import com.drdisagree.iconify.R import com.drdisagree.iconify.common.Const.SWITCH_ANIMATION_DELAY import com.drdisagree.iconify.common.Preferences.SELECTED_SWITCH -import com.drdisagree.iconify.config.Prefs +import com.drdisagree.iconify.config.RPrefs import com.drdisagree.iconify.ui.dialogs.LoadingDialog import com.drdisagree.iconify.ui.models.SwitchModel -import com.drdisagree.iconify.utils.SystemUtil -import com.drdisagree.iconify.utils.overlay.OverlayUtil +import com.drdisagree.iconify.utils.SystemUtils +import com.drdisagree.iconify.utils.overlay.OverlayUtils import com.drdisagree.iconify.utils.overlay.compiler.SwitchCompiler import java.io.IOException import java.util.concurrent.atomic.AtomicBoolean @@ -61,7 +60,7 @@ class SwitchAdapter( null ) ) - holder.aSwitch.setChecked(Prefs.getInt(SELECTED_SWITCH, -1) == position) + holder.aSwitch.setChecked(RPrefs.getInt(SELECTED_SWITCH, -1) == position) enableOnCheckedChangeListener(holder) } @@ -74,7 +73,7 @@ class SwitchAdapter( super.onViewAttachedToWindow(holder) holder.aSwitch.setChecked( - Prefs.getInt( + RPrefs.getInt( SELECTED_SWITCH, -1 ) == holder.getBindingAdapterPosition() @@ -100,7 +99,7 @@ class SwitchAdapter( val aSwitch = view.findViewById(R.id.switch_view) aSwitch?.setChecked( - i == holder.getAbsoluteAdapterPosition() && Prefs.getInt( + i == holder.getAbsoluteAdapterPosition() && RPrefs.getInt( SELECTED_SWITCH, -1 ) == i - (holder.getAbsoluteAdapterPosition() - holder.getBindingAdapterPosition()) @@ -124,8 +123,8 @@ class SwitchAdapter( private fun switchAction(holder: ViewHolder, checked: Boolean) { Handler(Looper.getMainLooper()).postDelayed({ if (checked) { - if (!SystemUtil.hasStoragePermission()) { - SystemUtil.requestStoragePermission(context) + if (!SystemUtils.hasStoragePermission()) { + SystemUtils.requestStoragePermission(context) holder.aSwitch.setChecked(false) } else { // Show loading dialog @@ -134,7 +133,7 @@ class SwitchAdapter( Thread { val hasErroredOut = AtomicBoolean(false) - Prefs.putInt(SELECTED_SWITCH, holder.getBindingAdapterPosition()) + RPrefs.putInt(SELECTED_SWITCH, holder.getBindingAdapterPosition()) try { hasErroredOut.set( @@ -164,7 +163,7 @@ class SwitchAdapter( Toast.LENGTH_SHORT ).show() } else { - Prefs.putInt(SELECTED_SWITCH, -1) + RPrefs.putInt(SELECTED_SWITCH, -1) holder.aSwitch.setChecked(false) @@ -183,9 +182,9 @@ class SwitchAdapter( loadingDialog.show(context.resources.getString(R.string.loading_dialog_wait)) Thread { - Prefs.putInt(SELECTED_SWITCH, -1) + RPrefs.putInt(SELECTED_SWITCH, -1) - OverlayUtil.disableOverlays( + OverlayUtils.disableOverlays( "IconifyComponentSWITCH1.overlay", "IconifyComponentSWITCH2.overlay" ) diff --git a/app/src/main/java/com/drdisagree/iconify/ui/adapters/ToastAdapter.kt b/app/src/main/java/com/drdisagree/iconify/ui/adapters/ToastAdapter.kt new file mode 100644 index 000000000..0f2c512ea --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/adapters/ToastAdapter.kt @@ -0,0 +1,89 @@ +package com.drdisagree.iconify.ui.adapters + +import android.content.Context +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.core.content.ContextCompat +import androidx.recyclerview.widget.RecyclerView +import com.drdisagree.iconify.Iconify.Companion.appContext +import com.drdisagree.iconify.Iconify.Companion.appContextLocale +import com.drdisagree.iconify.R +import com.drdisagree.iconify.common.Preferences.SELECTED_TOAST_FRAME +import com.drdisagree.iconify.config.RPrefs +import com.drdisagree.iconify.databinding.ViewToastFrameBinding +import com.drdisagree.iconify.ui.models.ToastModel + +class ToastAdapter ( + var context: Context, + private var itemList: ArrayList, + private var toastClick: OnToastClick +) : RecyclerView.Adapter() { + + private var selected = RPrefs.getInt(SELECTED_TOAST_FRAME, -1) + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + val binding: ViewToastFrameBinding = + ViewToastFrameBinding.inflate(LayoutInflater.from(parent.context), parent, false) + if (selected != -1) { + itemList[selected].selected = true + } else { + itemList[0].selected = true + } + return ViewHolder(binding) + } + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + val model = itemList[holder.bindingAdapterPosition] + holder.binding.styleName.text = model.title + holder.binding.toastContainer.background = ContextCompat.getDrawable(appContext, model.style) + if (model.selected) { + holder.binding.styleName.setTextColor( + appContextLocale.resources.getColor( + R.color.colorAccent, + appContext.theme + ) + ) + } else { + holder.binding.styleName.setTextColor( + appContextLocale.resources.getColor( + R.color.textColorSecondary, + appContext.theme + ) + ) + } + holder.binding.listItemToast.setOnClickListener { + toastClick.onToastClick(holder.bindingAdapterPosition, model) + } + } + + fun notifyChange() { + refresh(false) + selected = RPrefs.getInt(SELECTED_TOAST_FRAME, -1) + refresh(true) + } + + private fun refresh(select: Boolean) { + if (selected != -1) { + itemList[selected].selected = select + notifyItemChanged(selected) + } else { + itemList[0].selected = select + notifyItemChanged(0) + } + } + + override fun getItemCount(): Int { + return itemList.size + } + + class ViewHolder(val binding: ViewToastFrameBinding) : RecyclerView.ViewHolder(binding.getRoot()) { + } + + /** + * Interface for the click on the item + */ + interface OnToastClick { + fun onToastClick(position: Int, item: ToastModel) + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/ui/base/BaseFragment.kt b/app/src/main/java/com/drdisagree/iconify/ui/base/BaseFragment.kt index 65bf5ec02..da0429413 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/base/BaseFragment.kt +++ b/app/src/main/java/com/drdisagree/iconify/ui/base/BaseFragment.kt @@ -1,11 +1,62 @@ package com.drdisagree.iconify.ui.base import android.content.Context +import android.os.Bundle +import android.os.Handler +import android.os.Looper +import android.view.LayoutInflater +import android.view.Menu +import android.view.MenuInflater +import android.view.MenuItem +import android.view.View +import android.view.ViewGroup +import androidx.activity.result.ActivityResult +import androidx.activity.result.contract.ActivityResultContracts +import androidx.core.view.MenuHost +import androidx.core.view.MenuProvider import androidx.core.view.WindowCompat import androidx.fragment.app.Fragment +import androidx.lifecycle.Lifecycle +import com.drdisagree.iconify.R +import com.drdisagree.iconify.common.Dynamic +import com.drdisagree.iconify.common.Resources.searchConfiguration +import com.drdisagree.iconify.common.Resources.searchableFragments +import com.drdisagree.iconify.ui.activities.MainActivity +import com.drdisagree.iconify.ui.activities.MainActivity.Companion.replaceFragment +import com.drdisagree.iconify.ui.dialogs.LoadingDialog +import com.drdisagree.iconify.ui.fragments.settings.Changelog +import com.drdisagree.iconify.ui.fragments.settings.Experimental +import com.drdisagree.iconify.ui.preferences.preferencesearch.SearchPreferenceResult +import com.drdisagree.iconify.utils.SystemUtils.restartSystemUI +import com.drdisagree.iconify.utils.helper.ImportExport.exportSettings +import com.drdisagree.iconify.utils.helper.ImportExport.handleExportResult +import com.drdisagree.iconify.utils.helper.ImportExport.handleImportResult +import com.drdisagree.iconify.utils.helper.ImportExport.importSettings import com.drdisagree.iconify.utils.helper.LocaleHelper -open class BaseFragment : Fragment() { +abstract class BaseFragment : Fragment() { + + private var loadingDialog: LoadingDialog? = null + + private var startExportActivityIntent = registerForActivityResult( + ActivityResultContracts.StartActivityForResult() + ) { result: ActivityResult -> + handleExportResult( + result = result, + context = requireContext(), + contentResolver = requireContext().contentResolver + ) + } + + private var startImportActivityIntent = registerForActivityResult( + ActivityResultContracts.StartActivityForResult() + ) { result: ActivityResult -> + handleImportResult( + result = result, + fragment = this, + loadingDialog = loadingDialog!! + ) + } override fun onAttach(context: Context) { super.onAttach(LocaleHelper.setLocale(context)) @@ -15,4 +66,90 @@ open class BaseFragment : Fragment() { WindowCompat.setDecorFitsSystemWindows(window, false) } } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + // Initialize loading dialog + loadingDialog = LoadingDialog(requireActivity()) + + return super.onCreateView(inflater, container, savedInstanceState) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + val menuHost: MenuHost = requireActivity() + menuHost.addMenuProvider(object : MenuProvider { + override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) { + menu.clear() + menuInflater.inflate(R.menu.default_menu, menu) + } + + override fun onMenuItemSelected(menuItem: MenuItem): Boolean { + return when (menuItem.itemId) { + R.id.action_search -> { + searchConfiguration.showSearchFragment() + true + } + + R.id.menu_changelog -> { + replaceFragment(parentFragmentManager, Changelog()) + true + } + + R.id.menu_export_settings -> { + exportSettings(this@BaseFragment, startExportActivityIntent) + true + } + + R.id.menu_import_settings -> { + importSettings(this@BaseFragment, startImportActivityIntent) + true + } + + R.id.restart_systemui -> { + Dynamic.requiresSystemUiRestart = false + + MainActivity.showOrHidePendingActionButton( + activityBinding = (requireActivity() as MainActivity).binding, + requiresSystemUiRestart = false + ) + + Handler(Looper.getMainLooper()).postDelayed({ + restartSystemUI() + }, 300) + true + } + + R.id.experimental_features -> { + replaceFragment(parentFragmentManager, Experimental()) + true + } + + else -> { + false + } + } + } + }, viewLifecycleOwner, Lifecycle.State.RESUMED) + } + + fun onSearchResultClicked(result: SearchPreferenceResult) { + for (searchableFragment in searchableFragments) { + if (searchableFragment.xml == result.resourceFile) { + replaceFragment(parentFragmentManager, searchableFragment.fragment) + SearchPreferenceResult.highlight(searchableFragment.fragment, result.key); + break + } + } + } + + override fun onDestroy() { + loadingDialog?.dismiss() + + super.onDestroy() + } } diff --git a/app/src/main/java/com/drdisagree/iconify/ui/base/ControlledPreferenceFragmentCompat.kt b/app/src/main/java/com/drdisagree/iconify/ui/base/ControlledPreferenceFragmentCompat.kt new file mode 100644 index 000000000..e61eeee51 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/base/ControlledPreferenceFragmentCompat.kt @@ -0,0 +1,250 @@ +package com.drdisagree.iconify.ui.base + +import android.content.Context +import android.content.SharedPreferences +import android.content.SharedPreferences.OnSharedPreferenceChangeListener +import android.graphics.Color +import android.graphics.drawable.ColorDrawable +import android.graphics.drawable.Drawable +import android.os.Bundle +import android.os.Handler +import android.os.Looper +import android.util.Log +import android.view.LayoutInflater +import android.view.Menu +import android.view.MenuInflater +import android.view.MenuItem +import android.view.View +import android.view.ViewGroup +import androidx.activity.result.ActivityResult +import androidx.activity.result.contract.ActivityResultContracts +import androidx.appcompat.app.AppCompatActivity +import androidx.appcompat.widget.Toolbar +import androidx.core.view.MenuHost +import androidx.core.view.MenuProvider +import androidx.core.view.WindowCompat +import androidx.lifecycle.Lifecycle +import androidx.preference.PreferenceFragmentCompat +import androidx.preference.PreferenceScreen +import androidx.recyclerview.widget.RecyclerView +import com.drdisagree.iconify.R +import com.drdisagree.iconify.common.Dynamic +import com.drdisagree.iconify.common.Resources.SHARED_XPREFERENCES +import com.drdisagree.iconify.common.Resources.searchConfiguration +import com.drdisagree.iconify.common.Resources.searchableFragments +import com.drdisagree.iconify.config.PrefsHelper +import com.drdisagree.iconify.config.RPrefs +import com.drdisagree.iconify.ui.activities.MainActivity +import com.drdisagree.iconify.ui.activities.MainActivity.Companion.popCurrentFragment +import com.drdisagree.iconify.ui.activities.MainActivity.Companion.replaceFragment +import com.drdisagree.iconify.ui.dialogs.LoadingDialog +import com.drdisagree.iconify.ui.fragments.settings.Changelog +import com.drdisagree.iconify.ui.fragments.settings.Experimental +import com.drdisagree.iconify.ui.preferences.preferencesearch.SearchPreferenceResult +import com.drdisagree.iconify.utils.SystemUtils.restartSystemUI +import com.drdisagree.iconify.utils.helper.ImportExport.exportSettings +import com.drdisagree.iconify.utils.helper.ImportExport.handleExportResult +import com.drdisagree.iconify.utils.helper.ImportExport.handleImportResult +import com.drdisagree.iconify.utils.helper.ImportExport.importSettings +import com.drdisagree.iconify.utils.helper.LocaleHelper + +abstract class ControlledPreferenceFragmentCompat : PreferenceFragmentCompat() { + + private var loadingDialog: LoadingDialog? = null + + private val changeListener = + OnSharedPreferenceChangeListener { _: SharedPreferences, key: String? -> + updateScreen( + key + ) + } + + abstract val title: String + + abstract val backButtonEnabled: Boolean + + abstract val layoutResource: Int + + open val themeResource: Int + get() = R.style.PrefsThemeToolbar + + abstract val hasMenu: Boolean + + open val menuResource: Int + get() = R.menu.default_menu + + private var startExportActivityIntent = registerForActivityResult( + ActivityResultContracts.StartActivityForResult() + ) { result: ActivityResult -> + handleExportResult( + result = result, + context = requireContext(), + contentResolver = requireContext().contentResolver + ) + } + + private var startImportActivityIntent = registerForActivityResult( + ActivityResultContracts.StartActivityForResult() + ) { result: ActivityResult -> + handleImportResult( + result = result, + fragment = this, + loadingDialog = loadingDialog!! + ) + } + + override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { + preferenceManager.setStorageDeviceProtected() + preferenceManager.sharedPreferencesName = SHARED_XPREFERENCES + preferenceManager.sharedPreferencesMode = Context.MODE_PRIVATE + + try { + setPreferencesFromResource(layoutResource, rootKey) + } catch (e: Exception) { + Log.e(TAG, "Failed to load preference from resource", e) + } + } + + override fun onAttach(context: Context) { + super.onAttach(LocaleHelper.setLocale(context)) + + if (activity != null) { + val window = requireActivity().window + WindowCompat.setDecorFitsSystemWindows(window, false) + } + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + inflater.context.setTheme(themeResource) + + // Initialize loading dialog + loadingDialog = LoadingDialog(requireActivity()) + + return super.onCreateView(inflater, container, savedInstanceState) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + val baseContext = context as AppCompatActivity + view.findViewById(R.id.toolbar)?.let { + baseContext.setSupportActionBar(it) + it.title = title + } + baseContext.supportActionBar?.setDisplayHomeAsUpEnabled(backButtonEnabled) + + if (hasMenu) { + val menuHost: MenuHost = requireActivity() + menuHost.addMenuProvider(object : MenuProvider { + override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) { + menu.clear() + menuInflater.inflate(menuResource, menu) + } + + override fun onMenuItemSelected(menuItem: MenuItem): Boolean { + return when (menuItem.itemId) { + R.id.action_search -> { + searchConfiguration.showSearchFragment() + true + } + + R.id.menu_changelog -> { + replaceFragment(parentFragmentManager, Changelog()) + true + } + + R.id.menu_export_settings -> { + exportSettings( + this@ControlledPreferenceFragmentCompat, + startExportActivityIntent + ) + true + } + + R.id.menu_import_settings -> { + importSettings( + this@ControlledPreferenceFragmentCompat, + startImportActivityIntent + ) + true + } + + R.id.restart_systemui -> { + Dynamic.requiresSystemUiRestart = false + + MainActivity.showOrHidePendingActionButton( + activityBinding = (requireActivity() as MainActivity).binding, + requiresSystemUiRestart = false + ) + + Handler(Looper.getMainLooper()).postDelayed({ + restartSystemUI() + }, 300) + true + } + + R.id.experimental_features -> { + replaceFragment(parentFragmentManager, Experimental()) + true + } + + else -> { + false + } + } + } + }, viewLifecycleOwner, Lifecycle.State.RESUMED) + } + } + + public override fun onCreateAdapter(preferenceScreen: PreferenceScreen): RecyclerView.Adapter<*> { + RPrefs.registerOnSharedPreferenceChangeListener(changeListener) + + updateScreen(null) + + return super.onCreateAdapter(preferenceScreen) + } + + fun onSearchResultClicked(result: SearchPreferenceResult) { + if (result.resourceFile == layoutResource) { + popCurrentFragment(parentFragmentManager) + SearchPreferenceResult.highlight(this, result.key) + } else { + for (searchableFragment in searchableFragments) { + if (searchableFragment.xml == result.resourceFile) { + replaceFragment(parentFragmentManager, searchableFragment.fragment) + SearchPreferenceResult.highlight(searchableFragment.fragment, result.key); + break + } + } + } + } + + override fun onDestroy() { + loadingDialog?.hide() + + RPrefs.unregisterOnSharedPreferenceChangeListener(changeListener) + + super.onDestroy() + } + + open fun updateScreen(key: String?) { + PrefsHelper.setupAllPreferences(this.preferenceScreen) + } + + override fun setDivider(divider: Drawable?) { + super.setDivider(ColorDrawable(Color.TRANSPARENT)) + } + + override fun setDividerHeight(height: Int) { + super.setDividerHeight(0) + } + + companion object { + private val TAG = ControlledPreferenceFragmentCompat::class.java.simpleName + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/ui/base/WeatherPreferenceFragment.kt b/app/src/main/java/com/drdisagree/iconify/ui/base/WeatherPreferenceFragment.kt new file mode 100644 index 000000000..056ef2dc3 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/base/WeatherPreferenceFragment.kt @@ -0,0 +1,358 @@ +package com.drdisagree.iconify.ui.base + +import android.Manifest +import android.content.Context +import android.content.DialogInterface +import android.content.Intent +import android.content.pm.PackageManager +import android.graphics.drawable.Drawable +import android.location.LocationManager +import android.net.Uri +import android.os.Bundle +import android.provider.Settings +import android.util.Log +import androidx.activity.result.ActivityResultLauncher +import androidx.activity.result.contract.ActivityResultContracts +import androidx.core.content.res.ResourcesCompat +import androidx.fragment.app.setFragmentResultListener +import androidx.preference.Preference +import com.drdisagree.iconify.BuildConfig +import com.drdisagree.iconify.Iconify.Companion.appContext +import com.drdisagree.iconify.R +import com.drdisagree.iconify.common.Preferences.PREF_KEY_UPDATE_STATUS +import com.drdisagree.iconify.common.Preferences.WEATHER_CUSTOM_LOCATION +import com.drdisagree.iconify.common.Preferences.WEATHER_ICON_PACK +import com.drdisagree.iconify.common.Preferences.WEATHER_PROVIDER +import com.drdisagree.iconify.config.RPrefs +import com.drdisagree.iconify.config.RPrefs.getBoolean +import com.drdisagree.iconify.services.WeatherScheduler +import com.drdisagree.iconify.ui.fragments.xposed.LocationBrowse.Companion.DATA_LOCATION_KEY +import com.drdisagree.iconify.ui.fragments.xposed.LocationBrowse.Companion.DATA_LOCATION_NAME +import com.drdisagree.iconify.ui.preferences.BottomSheetListPreference +import com.drdisagree.iconify.ui.preferences.SwitchPreference +import com.drdisagree.iconify.utils.OmniJawsClient +import com.drdisagree.iconify.utils.weather.WeatherConfig +import com.google.android.material.dialog.MaterialAlertDialogBuilder +import java.util.Locale + +abstract class WeatherPreferenceFragment : ControlledPreferenceFragmentCompat(), + OmniJawsClient.OmniJawsObserver { + + private var mCustomLocation: SwitchPreference? = null + private var mWeatherIconPack: BottomSheetListPreference? = null + private var mUpdateStatus: Preference? = null + private var mWeatherClient: OmniJawsClient? = null + + abstract fun getMainSwitchKey(): String + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + setFragmentResultListener(DATA_LOCATION_KEY) { _, bundle -> + val locationName = bundle.getString(DATA_LOCATION_NAME) + + Log.d("WeatherPreferenceFragment", "locationName: $locationName") + + if (WeatherConfig.isEnabled(requireContext()) + && !getBoolean(WEATHER_CUSTOM_LOCATION, false) + ) { + checkLocationEnabled(true) + } + } + } + + override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { + super.onCreatePreferences(savedInstanceState, rootKey) + mWeatherClient = OmniJawsClient(requireContext()) + + mWeatherIconPack = findPreference(WEATHER_ICON_PACK) + + var settingHeaderPackage: String = WeatherConfig.getIconPack(requireContext()).toString() + val entries: MutableList = ArrayList() + val values: MutableList = ArrayList() + val drawables: MutableList = ArrayList() + getAvailableWeatherIconPacks(entries, values, drawables) + mWeatherIconPack!!.entries = entries.toTypedArray() + mWeatherIconPack!!.entryValues = values.toTypedArray() + mWeatherIconPack!!.createDefaultAdapter( + drawables.filterNotNull().toTypedArray(), + object : BottomSheetListPreference.OnItemClickListener { + override fun onItemClick(position: Int) { + RPrefs.putString(WEATHER_ICON_PACK, values[position]) + mWeatherIconPack!!.setSummary(entries[position]) + forceRefreshWeatherSettings() + } + }) + var valueIndex: Int = mWeatherIconPack!!.findIndexOfValue(settingHeaderPackage) + if (valueIndex == -1) { + // no longer found + settingHeaderPackage = DEFAULT_WEATHER_ICON_PACKAGE + valueIndex = mWeatherIconPack!!.findIndexOfValue(settingHeaderPackage) + } + mWeatherIconPack!!.setValueIndex(if (valueIndex >= 0) valueIndex else 0) + mWeatherIconPack!!.setSummary(mWeatherIconPack!!.getEntry()) + + mUpdateStatus = findPreference(PREF_KEY_UPDATE_STATUS) + mUpdateStatus?.onPreferenceClickListener = Preference.OnPreferenceClickListener { + forceRefreshWeatherSettings() + true + } + + mCustomLocation = findPreference(WEATHER_CUSTOM_LOCATION) + mCustomLocation?.setOnPreferenceClickListener { + forceRefreshWeatherSettings() + true + } + } + + override fun onResume() { + super.onResume() + mWeatherClient!!.addObserver(this) + + handlePermissions() + } + + private fun handlePermissions() { + if (WeatherConfig.isEnabled(requireContext()) && + !getBoolean(WEATHER_CUSTOM_LOCATION, false) + ) { + checkLocationEnabled(false) + } else { + forceRefreshWeatherSettings() + } + } + + private fun hasPermissions(): Boolean { + return (requireContext().checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) + == PackageManager.PERMISSION_GRANTED) && + (requireContext().checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) + == PackageManager.PERMISSION_GRANTED) && + (requireContext().checkSelfPermission(Manifest.permission.ACCESS_BACKGROUND_LOCATION) + == PackageManager.PERMISSION_GRANTED) + } + + private fun isLocationEnabled(): Boolean { + val lm = requireContext().getSystemService(Context.LOCATION_SERVICE) as LocationManager + return lm.isLocationEnabled + } + + private fun requestLocationPermission(locationPermissionRequest: ActivityResultLauncher>) { + if (shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_FINE_LOCATION) || + shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_COARSE_LOCATION) || + shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_BACKGROUND_LOCATION) + ) { + showApplicationPermissionDialog() + } else { + locationPermissionRequest.launch( + arrayOf( + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_BACKGROUND_LOCATION + ) + ) + } + } + + private fun checkLocationEnabled(force: Boolean) { + if (!isLocationEnabled()) { + showLocationPermissionDialog() + } else { + checkLocationPermission(force) + } + } + + private fun checkLocationPermission(force: Boolean) { + if (!hasPermissions() && !getBoolean(WEATHER_CUSTOM_LOCATION, false)) { + requestLocationPermission(requestPermissionLauncher) + } else { + if (force) { + forceRefreshWeatherSettings() + } + queryAndUpdateWeather() + } + } + + private fun showLocationPermissionDialog() { + MaterialAlertDialogBuilder(requireContext()) + .setTitle(R.string.weather_retrieve_location_dialog_title) + .setMessage(R.string.weather_retrieve_location_dialog_message) + .setCancelable(false) + .setPositiveButton(R.string.weather_retrieve_location_dialog_enable_button) { _, _ -> + startActivity( + Intent( + Settings.ACTION_LOCATION_SOURCE_SETTINGS + ).apply { + setFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP) + } + ) + } + .setNegativeButton(android.R.string.cancel, null) + .create() + .show() + } + + private fun showApplicationPermissionDialog() { + MaterialAlertDialogBuilder(requireContext()) + .setTitle(R.string.weather_permission_dialog_title) + .setMessage(R.string.weather_permission_dialog_message) + .setCancelable(false) + .setPositiveButton(android.R.string.ok) { _: DialogInterface?, _: Int -> + startActivity( + Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply { + setData( + Uri.fromParts( + "package", + requireContext().packageName, + null + ) + ) + } + ) + } + .setNegativeButton(android.R.string.cancel, null) + .create() + .show() + } + + private fun enableService() { + WeatherScheduler.scheduleUpdates(requireContext()) + } + + override fun onPause() { + super.onPause() + mWeatherClient!!.removeObserver(this) + } + + override fun updateScreen(key: String?) { + super.updateScreen(key) + + if (key == null) return + + val mainKey = getMainSwitchKey() + + if (key == mainKey) { + WeatherConfig.setEnabled(requireContext(), getBoolean(mainKey, false), mainKey) + if (getBoolean(mainKey, false)) { + handlePermissions() + enableService() + forceRefreshWeatherSettings() + } + } else if (key == WEATHER_PROVIDER) { + forceRefreshWeatherSettings() + } + } + + @Suppress("DiscouragedApi") + private fun getAvailableWeatherIconPacks( + entries: MutableList, + values: MutableList, + drawables: MutableList + ) { + val i = Intent() + val packageManager = requireContext().packageManager + i.setAction(BuildConfig.APPLICATION_ID + ".WeatherIconPack") + for (r in packageManager.queryIntentActivities(i, 0)) { + val packageName = r.activityInfo.applicationInfo.packageName + if (packageName == DEFAULT_WEATHER_ICON_PACKAGE) { + values.add(0, r.activityInfo.name) + drawables.add( + 0, + ResourcesCompat.getDrawable( + resources, + resources.getIdentifier( + "google_30", + "drawable", + BuildConfig.APPLICATION_ID + ), + requireContext().theme + ) + ) + } else { + values.add(packageName + "." + r.activityInfo.name.split(".").last()) + val name = r.activityInfo.name.split("\\.".toRegex()).dropLastWhile { it.isEmpty() } + .toTypedArray() + drawables.add( + ResourcesCompat.getDrawable( + resources, resources.getIdentifier( + name[name.size - 1].lowercase( + Locale.getDefault() + ) + "_30", "drawable", BuildConfig.APPLICATION_ID + ), requireContext().theme + ) + ) + } + + val label: String = r.activityInfo.loadLabel(packageManager).toString() + if (packageName == DEFAULT_WEATHER_ICON_PACKAGE) { + entries.add(0, label) + } else { + entries.add(label) + } + } + } + + override fun weatherUpdated() { + queryAndUpdateWeather() + } + + override fun weatherError(errorReason: Int) { + val errorString: String = when (errorReason) { + OmniJawsClient.EXTRA_ERROR_DISABLED -> { + resources.getString(R.string.omnijaws_service_disabled) + } + + OmniJawsClient.EXTRA_ERROR_LOCATION -> { + resources.getString(R.string.omnijaws_service_error_location) + } + + OmniJawsClient.EXTRA_ERROR_NETWORK -> { + resources.getString(R.string.omnijaws_service_error_network) + } + + OmniJawsClient.EXTRA_ERROR_NO_PERMISSIONS -> { + resources.getString(R.string.omnijaws_service_error_permissions) + } + + else -> { + resources.getString(R.string.omnijaws_service_error_long) + } + } + + requireActivity().runOnUiThread { + mUpdateStatus?.summary = errorString + } + } + + private fun queryAndUpdateWeather() { + mWeatherClient!!.queryWeather() + if (mWeatherClient?.weatherInfo != null) { + requireActivity().runOnUiThread { + mUpdateStatus?.setSummary(mWeatherClient!!.weatherInfo!!.lastUpdateTime) + } + } + } + + private var requestPermissionLauncher: ActivityResultLauncher> = + registerForActivityResult( + ActivityResultContracts.RequestMultiplePermissions() + ) { result -> + val fineLocationGranted: Boolean = result.getOrDefault( + Manifest.permission.ACCESS_FINE_LOCATION, false + ) + val coarseLocationGranted: Boolean = result.getOrDefault( + Manifest.permission.ACCESS_COARSE_LOCATION, false + ) + if (fineLocationGranted || coarseLocationGranted) { + forceRefreshWeatherSettings() + } + } + + private fun forceRefreshWeatherSettings() { + WeatherScheduler.scheduleUpdateNow(appContext) + } + + companion object { + private const val DEFAULT_WEATHER_ICON_PACKAGE: String = + "${BuildConfig.APPLICATION_ID}.google" + } +} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/ui/core/Transform.kt b/app/src/main/java/com/drdisagree/iconify/ui/core/Transform.kt index b105bcbab..88364a2aa 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/core/Transform.kt +++ b/app/src/main/java/com/drdisagree/iconify/ui/core/Transform.kt @@ -23,7 +23,6 @@ object Transform { return pageTransformer } - @JvmStatic fun setParallaxTransformation(page: View, position: Float) { val parallaxView = page.findViewById(R.id.img) val isLandscape = diff --git a/app/src/main/java/com/drdisagree/iconify/ui/dialogs/EditTextDialog.kt b/app/src/main/java/com/drdisagree/iconify/ui/dialogs/EditTextDialog.kt new file mode 100644 index 000000000..903d07f53 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/dialogs/EditTextDialog.kt @@ -0,0 +1,99 @@ +package com.drdisagree.iconify.ui.dialogs + +import android.app.Dialog +import android.content.Context +import android.graphics.Color +import android.graphics.drawable.ColorDrawable +import android.view.LayoutInflater +import android.view.View.GONE +import android.view.ViewGroup +import android.view.WindowManager +import com.drdisagree.iconify.databinding.ViewEditTextDialogBinding +import com.drdisagree.iconify.ui.base.BaseActivity + +class EditTextDialog( + var context: Context, + private var dialogId: Int +) : BaseActivity() { + + var dialog: Dialog? = null + private var binding: ViewEditTextDialogBinding? = null + private var listener: EditTextDialogListener? = null + + + fun setDialogListener(listener: EditTextDialogListener?) { + this.listener = listener + } + + fun show(title: String, subTitle: String, hint: String, text: String) { + if (dialog != null) dialog!!.dismiss() + + dialog = Dialog(context) + binding = ViewEditTextDialogBinding.inflate(LayoutInflater.from(context)) + + dialog!!.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) + dialog!!.setCancelable(true) + dialog!!.setOnCancelListener(null) + dialog!!.setCanceledOnTouchOutside(true) + + binding!!.title.text = title + if (subTitle.isNotEmpty()) binding!!.subtitle.text = subTitle + else binding!!.subtitle.visibility = GONE + if (hint.isNotEmpty() && hint != "null") binding!!.editText.hint = hint + if (text.isNotEmpty()) binding!!.editText.setText(text) + + binding!!.confirm.setOnClickListener { + listener?.onOkPressed(dialogId, binding!!.editText.text.toString()) + dialog!!.hide() + } + + binding!!.cancel.setOnClickListener { + dialog!!.hide() + } + + dialog!!.setContentView(binding!!.root) + + val dialogParams = binding!!.root.layoutParams as ViewGroup.MarginLayoutParams + dialogParams.setMargins(28.dpToPx(), 0, 28.dpToPx(), 0) + binding!!.root.layoutParams = dialogParams + + dialog!!.create() + dialog!!.show() + + val layoutParams = WindowManager.LayoutParams() + layoutParams.copyFrom(dialog!!.window!!.attributes) + layoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT + layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT + dialog!!.window!!.setAttributes(layoutParams) + } + + fun hide() { + if (dialog?.isShowing == true) { + dialog?.dismiss() + } + } + + fun dismiss() { + dialog?.dismiss() + } + + public override fun onDestroy() { + dismiss() + super.onDestroy() + } + + /** + * Interface for the EditTextDialog + * Implement this interface in the calling class to handle the dialog actions + * @property dialogId The ID of the dialog + * @property newText The new text entered in the EditText + */ + interface EditTextDialogListener { + fun onOkPressed(dialogId: Int, newText: String) + } + + private fun Int.dpToPx(): Int { + val density = context.resources.displayMetrics.density + return (this * density).toInt() + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/ui/drawables/TintedDrawableSpan.kt b/app/src/main/java/com/drdisagree/iconify/ui/drawables/TintedDrawableSpan.kt new file mode 100644 index 000000000..b717db475 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/drawables/TintedDrawableSpan.kt @@ -0,0 +1,52 @@ +package com.drdisagree.iconify.ui.drawables + +import android.content.Context +import android.graphics.Canvas +import android.graphics.Paint +import android.graphics.Paint.FontMetricsInt +import android.graphics.drawable.Drawable +import android.text.style.DynamicDrawableSpan + + +/** + * [DynamicDrawableSpan] which draws a drawable tinted with the current paint color. + */ +class TintedDrawableSpan(context: Context, resourceId: Int) : + DynamicDrawableSpan(ALIGN_BOTTOM) { + private val mDrawable = context.getDrawable(resourceId)!!.mutate() + private var mOldTint = 0 + + init { + mDrawable.setTint(0) + } + + override fun getSize( + paint: Paint, + text: CharSequence, + start: Int, + end: Int, + fm: FontMetricsInt? + ): Int { + var fm = fm + fm = fm ?: paint.fontMetricsInt + val iconSize = fm!!.bottom - fm.top + mDrawable.setBounds(0, 0, iconSize, iconSize) + return super.getSize(paint, text, start, end, fm) + } + + override fun draw( + canvas: Canvas, text: CharSequence, + start: Int, end: Int, x: Float, top: Int, y: Int, bottom: Int, paint: Paint + ) { + val color = paint.color + if (mOldTint != color) { + mOldTint = color + mDrawable.setTint(mOldTint) + } + super.draw(canvas, text, start, end, x, top, y, bottom, paint) + } + + override fun getDrawable(): Drawable { + return mDrawable + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/ui/events/ColorSelectedEvent.kt b/app/src/main/java/com/drdisagree/iconify/ui/events/ColorSelectedEvent.kt index 701bb7057..985121bd0 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/events/ColorSelectedEvent.kt +++ b/app/src/main/java/com/drdisagree/iconify/ui/events/ColorSelectedEvent.kt @@ -1,6 +1,6 @@ package com.drdisagree.iconify.ui.events data class ColorSelectedEvent( - @JvmField val dialogId: Int, - @JvmField val selectedColor: Int + val dialogId: Int, + val selectedColor: Int ) diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/Experimental.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/Experimental.kt deleted file mode 100644 index fd0a78b1e..000000000 --- a/app/src/main/java/com/drdisagree/iconify/ui/fragments/Experimental.kt +++ /dev/null @@ -1,71 +0,0 @@ -package com.drdisagree.iconify.ui.fragments - -import android.os.Bundle -import android.os.Handler -import android.os.Looper -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.CompoundButton -import com.drdisagree.iconify.R -import com.drdisagree.iconify.common.Const.SWITCH_ANIMATION_DELAY -import com.drdisagree.iconify.common.Preferences.HEADER_IMAGE_OVERLAP -import com.drdisagree.iconify.common.Preferences.HIDE_DATA_DISABLED_ICON -import com.drdisagree.iconify.common.Preferences.UNZOOM_DEPTH_WALLPAPER -import com.drdisagree.iconify.config.RPrefs.getBoolean -import com.drdisagree.iconify.config.RPrefs.putBoolean -import com.drdisagree.iconify.databinding.FragmentExperimentalBinding -import com.drdisagree.iconify.ui.base.BaseFragment -import com.drdisagree.iconify.ui.utils.ViewHelper.setHeader -import com.drdisagree.iconify.utils.SystemUtil - -class Experimental : BaseFragment() { - - private lateinit var binding: FragmentExperimentalBinding - - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View { - binding = FragmentExperimentalBinding.inflate(inflater, container, false) - val root: View = binding.getRoot() - - // Header - setHeader( - requireContext(), - getParentFragmentManager(), - binding.header.toolbar, - R.string.activity_title_experimental - ) - - // Header image overlap - binding.headerImageOverlap.isSwitchChecked = getBoolean(HEADER_IMAGE_OVERLAP, false) - binding.headerImageOverlap.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> - putBoolean(HEADER_IMAGE_OVERLAP, isChecked) - - Handler(Looper.getMainLooper()).postDelayed( - { SystemUtil.restartSystemUI() }, - SWITCH_ANIMATION_DELAY - ) - } - - // Unzoom depth wallpaper - binding.unzoomDepthWallpaper.isSwitchChecked = getBoolean(UNZOOM_DEPTH_WALLPAPER, false) - binding.unzoomDepthWallpaper.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> - putBoolean(UNZOOM_DEPTH_WALLPAPER, isChecked) - - Handler(Looper.getMainLooper()).postDelayed( - { SystemUtil.restartSystemUI() }, - SWITCH_ANIMATION_DELAY - ) - } - - // Hide data disabled icon - binding.hideDataDisabledIcon.isSwitchChecked = getBoolean(HIDE_DATA_DISABLED_ICON, false) - binding.hideDataDisabledIcon.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> - putBoolean(HIDE_DATA_DISABLED_ICON, isChecked) - } - return root - } -} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/Home.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/Home.kt deleted file mode 100644 index ce53109b2..000000000 --- a/app/src/main/java/com/drdisagree/iconify/ui/fragments/Home.kt +++ /dev/null @@ -1,338 +0,0 @@ -package com.drdisagree.iconify.ui.fragments - -import android.os.Bundle -import android.os.Handler -import android.os.Looper -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.LinearLayout -import android.widget.TextView -import androidx.appcompat.app.AppCompatActivity -import androidx.navigation.Navigation.findNavController -import androidx.navigation.fragment.NavHostFragment -import com.drdisagree.iconify.BuildConfig -import com.drdisagree.iconify.Iconify.Companion.appContext -import com.drdisagree.iconify.Iconify.Companion.appContextLocale -import com.drdisagree.iconify.R -import com.drdisagree.iconify.common.Const.LATEST_VERSION_URL -import com.drdisagree.iconify.common.Preferences.AUTO_UPDATE -import com.drdisagree.iconify.common.Preferences.FIRST_INSTALL -import com.drdisagree.iconify.common.Preferences.LAST_UPDATE_CHECK_TIME -import com.drdisagree.iconify.common.Preferences.SHOW_HOME_CARD -import com.drdisagree.iconify.common.Preferences.UPDATE_CHECK_TIME -import com.drdisagree.iconify.common.Preferences.UPDATE_DETECTED -import com.drdisagree.iconify.common.Preferences.VER_CODE -import com.drdisagree.iconify.config.Prefs -import com.drdisagree.iconify.config.Prefs.getBoolean -import com.drdisagree.iconify.config.Prefs.getLong -import com.drdisagree.iconify.config.Prefs.putLong -import com.drdisagree.iconify.databinding.FragmentHomeBinding -import com.drdisagree.iconify.services.UpdateScheduler.scheduleUpdates -import com.drdisagree.iconify.ui.base.BaseFragment -import com.drdisagree.iconify.ui.dialogs.LoadingDialog -import com.drdisagree.iconify.ui.widgets.MenuWidget -import com.drdisagree.iconify.utils.RootUtil.folderExists -import com.drdisagree.iconify.utils.SystemUtil.restartDevice -import com.drdisagree.iconify.utils.SystemUtil.saveBootId -import com.drdisagree.iconify.utils.extension.TaskExecutor -import com.google.android.material.bottomnavigation.BottomNavigationView -import org.json.JSONObject -import java.io.BufferedReader -import java.io.InputStreamReader -import java.net.HttpURLConnection -import java.net.URL - -class Home : BaseFragment() { - - private lateinit var binding: FragmentHomeBinding - private var checkForUpdate: CheckForUpdate? = null - private var checkUpdate: LinearLayout? = null - private var updateDesc: TextView? = null - - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View { - binding = FragmentHomeBinding.inflate(inflater, container, false) - val view: View = binding.getRoot() - - // Header - binding.header.toolbar.setTitle(resources.getString(R.string.activity_title_home_page)) - (requireActivity() as AppCompatActivity).setSupportActionBar(binding.header.toolbar) - - val intent = requireActivity().intent - if (intent != null && intent.getBooleanExtra(AppUpdates.KEY_NEW_UPDATE, false)) { - (requireActivity().findViewById(R.id.bottomNavigationView) as BottomNavigationView).selectedItemId = - R.id.settings - NavHostFragment.findNavController(this).navigate(R.id.action_settings_to_appUpdates) - intent.removeExtra(AppUpdates.Companion.KEY_NEW_UPDATE) - } else { - scheduleUpdates(appContext) - } - - // New update available dialog - val listView1 = LayoutInflater.from(requireActivity()) - .inflate( - R.layout.view_new_update, - binding.homePageList, - false - ) - - checkUpdate = listView1.findViewById(R.id.check_update) - binding.homePageList.addView(listView1) - (checkUpdate as LinearLayout).visibility = View.GONE - updateDesc = binding.homePageList.findViewById(R.id.update_desc) - - if (shouldCheckForUpdate()) { - putLong(LAST_UPDATE_CHECK_TIME, System.currentTimeMillis()) - - try { - checkForUpdate = CheckForUpdate() - checkForUpdate!!.execute() - } catch (ignored: Exception) { - } - } - - // Reboot needed dialog - val listView2 = LayoutInflater.from(requireActivity()) - .inflate( - R.layout.view_reboot, - binding.homePageList, - false - ) - - val rebootReminder = listView2.findViewById(R.id.reboot_reminder) - binding.homePageList.addView(listView2) - rebootReminder.visibility = View.GONE - - if (shouldShowRebootDialog()) { - rebootReminder.visibility = View.VISIBLE - - binding.homePageList.findViewById(R.id.btn_reboot).setOnClickListener { - val rebootingDialog = LoadingDialog(requireActivity()) - - rebootingDialog.show(resources.getString(R.string.rebooting_desc)) - - Handler(Looper.getMainLooper()).postDelayed({ - rebootingDialog.hide() - restartDevice() - }, 5000) - } - } - - Prefs.putBoolean(FIRST_INSTALL, false) - Prefs.putBoolean(UPDATE_DETECTED, false) - Prefs.putInt(VER_CODE, BuildConfig.VERSION_CODE) - saveBootId - - // Home page list items - addItem(initHomePageList()) - - binding.homeCard.container.visibility = - if (getBoolean(SHOW_HOME_CARD, true)) View.VISIBLE else View.GONE - - binding.homeCard.button.setOnClickListener { - binding.homeCard - .container - .animate() - .setDuration(400) - .translationX(binding.homeCard.container.width * 2f) - .alpha(0f) - .withEndAction { - binding.homeCard.container.visibility = View.GONE - Prefs.putBoolean(SHOW_HOME_CARD, false) - } - .start() - } - - return view - } - - private fun initHomePageList(): ArrayList> { - val homePage = ArrayList>().apply { - add( - arrayOf( - R.id.action_homePage_to_iconPack, - appContextLocale.resources.getString(R.string.activity_title_icon_pack), - appContextLocale.resources.getString(R.string.activity_desc_icon_pack), - R.drawable.ic_styles_iconpack - ) - ) - add( - arrayOf( - R.id.action_homePage_to_brightnessBar, - appContextLocale.resources.getString(R.string.activity_title_brightness_bar), - appContextLocale.resources.getString(R.string.activity_desc_brightness_bar), - R.drawable.ic_styles_brightness - ) - ) - add( - arrayOf( - R.id.action_homePage_to_qsPanelTile, - appContextLocale.resources.getString(R.string.activity_title_qs_shape), - appContextLocale.resources.getString(R.string.activity_desc_qs_shape), - R.drawable.ic_styles_qs_shape - ) - ) - add( - arrayOf( - R.id.action_homePage_to_notification, - appContextLocale.resources.getString(R.string.activity_title_notification), - appContextLocale.resources.getString(R.string.activity_desc_notification), - R.drawable.ic_styles_notification - ) - ) - add( - arrayOf( - R.id.action_homePage_to_progressBar, - appContextLocale.resources.getString(R.string.activity_title_progress_bar), - appContextLocale.resources.getString(R.string.activity_desc_progress_bar), - R.drawable.ic_styles_progress - ) - ) - add( - arrayOf( - R.id.action_homePage_to_switch1, - appContextLocale.resources.getString(R.string.activity_title_switch), - appContextLocale.resources.getString(R.string.activity_desc_switch), - R.drawable.ic_styles_switch - ) - ) - add( - arrayOf( - R.id.action_homePage_to_toastFrame, - appContextLocale.resources.getString(R.string.activity_title_toast_frame), - appContextLocale.resources.getString(R.string.activity_desc_toast_frame), - R.drawable.ic_styles_toast_frame - ) - ) - add( - arrayOf( - R.id.action_homePage_to_iconShape, - appContextLocale.resources.getString(R.string.activity_title_icon_shape), - appContextLocale.resources.getString(R.string.activity_desc_icon_shape), - R.drawable.ic_styles_icon_shape - ) - ) - } - - return homePage - } - - private fun shouldShowRebootDialog() = - !getBoolean(FIRST_INSTALL) && getBoolean(UPDATE_DETECTED) || - folderExists("/data/adb/modules_update/Iconify") - - private fun shouldCheckForUpdate(): Boolean { - val lastChecked = getLong(LAST_UPDATE_CHECK_TIME, -1) - - return getBoolean( - AUTO_UPDATE, - true - ) && (lastChecked == -1L || System.currentTimeMillis() - lastChecked >= getLong( - UPDATE_CHECK_TIME, - 0 - )) - } - - // Function to add new item in list - private fun addItem(pack: ArrayList>) { - for (i in pack.indices) { - val widget = MenuWidget(requireActivity()) - - widget.setTitle(pack[i][1] as String) - widget.setSummary(pack[i][2] as String) - widget.setIcon(pack[i][3] as Int) - widget.setEndArrowVisibility(View.VISIBLE) - - widget.setOnClickListener { - findNavController( - binding.getRoot() - ).navigate((pack[i][0] as Int)) - } - - binding.homePageList.addView(widget) - } - } - - override fun onStop() { - if (checkForUpdate?.status == TaskExecutor.Status.PENDING || - checkForUpdate?.status == TaskExecutor.Status.RUNNING - ) { - checkForUpdate?.cancel(true) - } - - super.onStop() - } - - private inner class CheckForUpdate : TaskExecutor() { - - var jsonURL: String = LATEST_VERSION_URL - - override fun onPreExecute() {} - - override fun doInBackground(vararg params: Int?): String? { - var urlConnection: HttpURLConnection? = null - var bufferedReader: BufferedReader? = null - - return try { - val url = URL(jsonURL) - urlConnection = url.openConnection() as HttpURLConnection - urlConnection.connect() - - val inputStream = urlConnection.inputStream - bufferedReader = BufferedReader(InputStreamReader(inputStream)) - - val stringBuffer = StringBuilder() - var line: String? - - while (bufferedReader.readLine().also { line = it } != null) { - stringBuffer.append(line).append("\n") - } - - if (stringBuffer.isEmpty()) { - null - } else { - stringBuffer.toString() - } - } catch (e: Exception) { - null - } finally { - urlConnection?.disconnect() - - if (bufferedReader != null) { - try { - bufferedReader.close() - } catch (ignored: Exception) { - } - } - } - } - - override fun onPostExecute(result: String?) { - if (result != null) { - try { - val latestVersion = JSONObject(result) - - if (latestVersion.getString(VER_CODE).toInt() > BuildConfig.VERSION_CODE) { - checkUpdate!!.setOnClickListener { - findNavController( - requireActivity(), - R.id.fragmentContainerView - ).navigate(R.id.action_homePage_to_appUpdates) - } - - updateDesc!!.text = resources.getString( - R.string.update_dialog_desc, - latestVersion.getString("versionName") - ) - checkUpdate!!.visibility = View.VISIBLE - } - } catch (ignored: Exception) { - } - } - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/IconShape.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/IconShape.kt deleted file mode 100644 index eca72dcf1..000000000 --- a/app/src/main/java/com/drdisagree/iconify/ui/fragments/IconShape.kt +++ /dev/null @@ -1,316 +0,0 @@ -package com.drdisagree.iconify.ui.fragments - -import android.annotation.SuppressLint -import android.content.res.ColorStateList -import android.os.Bundle -import android.os.Handler -import android.os.Looper -import android.util.Log -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.LinearLayout -import android.widget.TextView -import android.widget.Toast -import androidx.annotation.ColorInt -import androidx.core.content.ContextCompat -import com.drdisagree.iconify.Iconify.Companion.appContext -import com.drdisagree.iconify.Iconify.Companion.appContextLocale -import com.drdisagree.iconify.R -import com.drdisagree.iconify.common.Const.FRAMEWORK_PACKAGE -import com.drdisagree.iconify.common.Preferences.SELECTED_ICON_SHAPE -import com.drdisagree.iconify.config.Prefs -import com.drdisagree.iconify.databinding.FragmentIconShapeBinding -import com.drdisagree.iconify.ui.base.BaseFragment -import com.drdisagree.iconify.ui.dialogs.LoadingDialog -import com.drdisagree.iconify.ui.utils.ViewHelper.setHeader -import com.drdisagree.iconify.utils.SystemUtil.hasStoragePermission -import com.drdisagree.iconify.utils.SystemUtil.requestStoragePermission -import com.drdisagree.iconify.utils.overlay.OverlayUtil -import com.drdisagree.iconify.utils.overlay.compiler.OnDemandCompiler.buildOverlay -import java.io.IOException -import java.util.concurrent.atomic.AtomicBoolean - -class IconShape : BaseFragment() { - - private lateinit var binding: FragmentIconShapeBinding - private var loadingDialog: LoadingDialog? = null - - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View { - binding = FragmentIconShapeBinding.inflate(inflater, container, false) - val view: View = binding.getRoot() - - // Header - setHeader( - requireContext(), - getParentFragmentManager(), - binding.header.toolbar, - R.string.activity_title_icon_shape - ) - - // Loading dialog while enabling or disabling pack - loadingDialog = LoadingDialog(requireContext()) - - // Icon masking shape list - addItem(initIconShapeList()) - refreshBackground() - - return view - } - - private fun initIconShapeList(): ArrayList> { - val iconShapePreviewStyles = ArrayList>().apply { - add( - arrayOf( - R.drawable.icon_shape_none, - R.string.icon_mask_style_none - ) - ) - add( - arrayOf( - R.drawable.icon_shape_pebble, - R.string.icon_mask_style_pebble - ) - ) - add( - arrayOf( - R.drawable.icon_shape_rounded_hexagon, - R.string.icon_mask_style_hexagon - ) - ) - add( - arrayOf( - R.drawable.icon_shape_samsung, - R.string.icon_mask_style_samsung - ) - ) - add( - arrayOf( - R.drawable.icon_shape_scroll, - R.string.icon_mask_style_scroll - ) - ) - add( - arrayOf( - R.drawable.icon_shape_teardrops, - R.string.icon_mask_style_teardrop - ) - ) - add( - arrayOf( - R.drawable.icon_shape_square, - R.string.icon_mask_style_square - ) - ) - add( - arrayOf( - R.drawable.icon_shape_rounded_rectangle, - R.string.icon_mask_style_rounded_rectangle - ) - ) - add( - arrayOf( - R.drawable.icon_shape_ios, - R.string.icon_mask_style_ios - ) - ) - add( - arrayOf( - R.drawable.icon_shape_cloudy, - R.string.icon_mask_style_cloudy - ) - ) - add( - arrayOf( - R.drawable.icon_shape_cylinder, - R.string.icon_mask_style_cylinder - ) - ) - add( - arrayOf( - R.drawable.icon_shape_flower, - R.string.icon_mask_style_flower - ) - ) - add( - arrayOf( - R.drawable.icon_shape_heart, - R.string.icon_mask_style_heart - ) - ) - add( - arrayOf( - R.drawable.icon_shape_leaf, - R.string.icon_mask_style_leaf - ) - ) - add( - arrayOf( - R.drawable.icon_shape_stretched, - R.string.icon_mask_style_stretched - ) - ) - add( - arrayOf( - R.drawable.icon_shape_tapered_rectangle, - R.string.icon_mask_style_tapered_rectangle - ) - ) - add( - arrayOf( - R.drawable.icon_shape_vessel, - R.string.icon_mask_style_vessel - ) - ) - add( - arrayOf( - R.drawable.icon_shape_rohie_meow, - R.string.icon_mask_style_rice_rohie_meow - ) - ) - add( - arrayOf( - R.drawable.icon_shape_force_round, - R.string.icon_mask_style_force_round - ) - ) - } - - return iconShapePreviewStyles - } - - // Function to add new item in list - @SuppressLint("UseCompatLoadingForDrawables") - private fun addItem(pack: ArrayList>) { - @ColorInt val colorBackground = appContextLocale.resources.getColor( - R.color.colorBackground, - appContext.theme - ) - - for (i in pack.indices) { - val list = LayoutInflater.from(requireContext()) - .inflate( - R.layout.view_icon_shape, - binding.iconShapePreviewContainer, - false - ) - - val iconContainerBg = list.findViewById(R.id.mask_shape_bg) - val iconContainerFg = list.findViewById(R.id.mask_shape_fg) - - iconContainerBg.background = ContextCompat.getDrawable(appContext, pack[i][0] as Int) - iconContainerFg.background = ContextCompat.getDrawable(appContext, pack[i][0] as Int) - iconContainerFg.setBackgroundTintList(ColorStateList.valueOf(colorBackground)) - - val styleName = list.findViewById(R.id.shape_name) - styleName.text = resources.getString(pack[i][1] as Int) - - list.setOnClickListener { - if (i == 0) { - Prefs.putInt(SELECTED_ICON_SHAPE, i) - OverlayUtil.disableOverlay("IconifyComponentSIS.overlay") - - Toast.makeText( - appContext, - resources.getString(R.string.toast_disabled), - Toast.LENGTH_SHORT - ).show() - - refreshBackground() - } else { - if (!hasStoragePermission()) { - requestStoragePermission( - requireContext() - ) - } else { - // Show loading dialog - loadingDialog!!.show(resources.getString(R.string.loading_dialog_wait)) - - Thread { - val hasErroredOut = AtomicBoolean(false) - - try { - hasErroredOut.set( - buildOverlay( - "SIS", - i, - FRAMEWORK_PACKAGE, - true - ) - ) - } catch (e: IOException) { - hasErroredOut.set(true) - Log.e("IconShape", e.toString()) - } - - if (!hasErroredOut.get()) { - Prefs.putInt(SELECTED_ICON_SHAPE, i) - refreshBackground() - } - - Handler(Looper.getMainLooper()).postDelayed({ - // Hide loading dialog - loadingDialog!!.hide() - if (!hasErroredOut.get()) { - Toast.makeText( - appContext, - appContextLocale.resources - .getString(R.string.toast_applied), - Toast.LENGTH_SHORT - ).show() - } else { - Toast.makeText( - appContext, - appContextLocale.resources - .getString(R.string.toast_error), - Toast.LENGTH_SHORT - ).show() - } - }, 3000) - }.start() - } - } - } - - binding.iconShapePreviewContainer.addView(list) - } - } - - // Function to check for bg drawable changes - private fun refreshBackground() { - @ColorInt val colorSuccess = appContextLocale.resources.getColor( - R.color.colorSuccess, - appContext.theme - ) - @ColorInt val textColorSecondary = appContextLocale.resources.getColor( - R.color.textColorSecondary, - appContext.theme - ) - - for (i in 0 until binding.iconShapePreviewContainer.childCount) { - val child = binding.iconShapePreviewContainer.getChildAt(i) - .findViewById(R.id.list_item_shape) - - val title = child.findViewById(R.id.shape_name) - val iconContainerBg = child.findViewById(R.id.mask_shape_bg) - - if (i == Prefs.getInt(SELECTED_ICON_SHAPE, 0)) { - iconContainerBg.setBackgroundTintList(ColorStateList.valueOf(colorSuccess)) - title.setTextColor(colorSuccess) - } else { - iconContainerBg.setBackgroundTintList(ColorStateList.valueOf(textColorSecondary)) - title.setTextColor(textColorSecondary) - } - } - } - - override fun onDestroy() { - loadingDialog?.dismiss() - - super.onDestroy() - } -} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/Settings.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/Settings.kt deleted file mode 100644 index 1008153ef..000000000 --- a/app/src/main/java/com/drdisagree/iconify/ui/fragments/Settings.kt +++ /dev/null @@ -1,515 +0,0 @@ -package com.drdisagree.iconify.ui.fragments - -import android.annotation.SuppressLint -import android.app.Activity -import android.content.ComponentName -import android.content.DialogInterface -import android.content.Intent -import android.content.pm.PackageManager -import android.net.Uri -import android.os.Bundle -import android.os.Handler -import android.os.Looper -import android.util.Log -import android.view.LayoutInflater -import android.view.Menu -import android.view.MenuInflater -import android.view.MenuItem -import android.view.View -import android.view.ViewGroup -import android.widget.CompoundButton -import android.widget.Toast -import androidx.activity.result.ActivityResult -import androidx.activity.result.contract.ActivityResultContracts -import androidx.appcompat.app.AppCompatActivity -import androidx.navigation.Navigation.findNavController -import com.drdisagree.iconify.BuildConfig -import com.drdisagree.iconify.Iconify.Companion.appContext -import com.drdisagree.iconify.Iconify.Companion.appContextLocale -import com.drdisagree.iconify.R -import com.drdisagree.iconify.common.Const -import com.drdisagree.iconify.common.Const.FRAGMENT_BACK_BUTTON_DELAY -import com.drdisagree.iconify.common.Preferences -import com.drdisagree.iconify.common.Preferences.APP_ICON -import com.drdisagree.iconify.common.Preferences.APP_LANGUAGE -import com.drdisagree.iconify.common.Preferences.APP_THEME -import com.drdisagree.iconify.common.Preferences.AUTO_UPDATE -import com.drdisagree.iconify.common.Preferences.EASTER_EGG -import com.drdisagree.iconify.common.Preferences.FIRST_INSTALL -import com.drdisagree.iconify.common.Preferences.ON_HOME_PAGE -import com.drdisagree.iconify.common.Preferences.RESTART_SYSUI_AFTER_BOOT -import com.drdisagree.iconify.common.Preferences.RESTART_SYSUI_BEHAVIOR_EXT -import com.drdisagree.iconify.common.Preferences.SHOW_HOME_CARD -import com.drdisagree.iconify.common.Preferences.SHOW_XPOSED_WARN -import com.drdisagree.iconify.common.Preferences.UPDATE_OVER_WIFI -import com.drdisagree.iconify.common.Resources.MODULE_DIR -import com.drdisagree.iconify.config.Prefs -import com.drdisagree.iconify.config.Prefs.putString -import com.drdisagree.iconify.config.RPrefs -import com.drdisagree.iconify.databinding.FragmentSettingsBinding -import com.drdisagree.iconify.services.UpdateScheduler.scheduleUpdates -import com.drdisagree.iconify.ui.base.BaseFragment -import com.drdisagree.iconify.ui.dialogs.LoadingDialog -import com.drdisagree.iconify.utils.AppUtil.restartApplication -import com.drdisagree.iconify.utils.CacheUtil.clearCache -import com.drdisagree.iconify.utils.SystemUtil.disableBlur -import com.drdisagree.iconify.utils.SystemUtil.disableRestartSystemuiAfterBoot -import com.drdisagree.iconify.utils.SystemUtil.enableRestartSystemuiAfterBoot -import com.drdisagree.iconify.utils.SystemUtil.hasStoragePermission -import com.drdisagree.iconify.utils.SystemUtil.requestStoragePermission -import com.drdisagree.iconify.utils.SystemUtil.restartSystemUI -import com.drdisagree.iconify.utils.SystemUtil.saveBootId -import com.drdisagree.iconify.utils.SystemUtil.saveVersionCode -import com.drdisagree.iconify.utils.helper.ImportExport.exportSettings -import com.drdisagree.iconify.utils.helper.ImportExport.importSettings -import com.google.android.material.dialog.MaterialAlertDialogBuilder -import com.topjohnwu.superuser.Shell -import java.util.Date -import java.util.concurrent.Executors - -class Settings : BaseFragment() { - - private lateinit var binding: FragmentSettingsBinding - private var loadingDialog: LoadingDialog? = null - private var clickTimestamps = LongArray(NUM_CLICKS_REQUIRED) - private var oldestIndex = 0 - private var nextIndex = 0 - - private var startExportActivityIntent = registerForActivityResult( - ActivityResultContracts.StartActivityForResult() - ) { result1: ActivityResult -> - if (result1.resultCode == Activity.RESULT_OK) { - val data = result1.data ?: return@registerForActivityResult - - Executors.newSingleThreadExecutor().execute { - try { - exportSettings( - Prefs.prefs, - appContext.contentResolver.openOutputStream(data.data!!)!! - ) - - Handler(Looper.getMainLooper()).post { - Toast.makeText( - appContext, - appContextLocale.resources.getString(R.string.toast_export_settings_successfull), - Toast.LENGTH_SHORT - ).show() - } - } catch (exception: Exception) { - Handler(Looper.getMainLooper()).post { - Toast.makeText( - appContext, - appContextLocale.resources.getString(R.string.toast_error), - Toast.LENGTH_SHORT - ).show() - Log.e("Settings", "Error exporting settings", exception) - } - } - } - } - } - - private var startImportActivityIntent = registerForActivityResult( - ActivityResultContracts.StartActivityForResult() - ) { result2: ActivityResult -> - if (result2.resultCode == Activity.RESULT_OK) { - val data = result2.data ?: return@registerForActivityResult - MaterialAlertDialogBuilder(requireContext()) - .setTitle(requireContext().resources.getString(R.string.import_settings_confirmation_title)) - .setMessage(requireContext().resources.getString(R.string.import_settings_confirmation_desc)) - .setPositiveButton( - requireContext().resources.getString(R.string.btn_positive) - ) { dialog: DialogInterface, _: Int -> - dialog.dismiss() - loadingDialog!!.show(resources.getString(R.string.loading_dialog_wait)) - Executors.newSingleThreadExecutor().execute { - try { - val success = importSettings( - Prefs.prefs, - appContext.contentResolver.openInputStream(data.data!!)!!, - true - ) - Handler(Looper.getMainLooper()).post { - loadingDialog!!.hide() - if (success) { - Toast.makeText( - appContext, - appContext.resources.getString(R.string.toast_import_settings_successfull), - Toast.LENGTH_SHORT - ).show() - } else { - Toast.makeText( - appContext, - appContext.resources.getString(R.string.toast_error), - Toast.LENGTH_SHORT - ).show() - } - } - } catch (exception: Exception) { - Handler(Looper.getMainLooper()).post { - Toast.makeText( - appContext, - appContext.resources.getString(R.string.toast_error), - Toast.LENGTH_SHORT - ).show() - Log.e("Settings", "Error importing settings", exception) - } - } - } - } - .setNegativeButton(requireContext().resources.getString(R.string.btn_negative)) { dialog: DialogInterface, _: Int -> dialog.dismiss() } - .show() - } - } - - @Suppress("deprecation") - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View { - binding = FragmentSettingsBinding.inflate(inflater, container, false) - val view: View = binding.getRoot() - - // Header - binding.header.toolbar.setTitle(resources.getString(R.string.activity_title_settings)) - (requireActivity() as AppCompatActivity).setSupportActionBar(binding.header.toolbar) - setHasOptionsMenu(true) - (requireActivity() as AppCompatActivity).supportActionBar?.setDisplayHomeAsUpEnabled(true) - (requireActivity() as AppCompatActivity).supportActionBar?.setDisplayShowHomeEnabled(true) - binding.header.toolbar.setNavigationOnClickListener { - Handler(Looper.getMainLooper()).postDelayed( - { getParentFragmentManager().popBackStack() }, FRAGMENT_BACK_BUTTON_DELAY.toLong() - ) - } - - // Show loading dialog - loadingDialog = LoadingDialog(requireActivity()) - - // Language - var currentLanguage = - listOf(*resources.getStringArray(R.array.locale_code)).indexOf("en-US") - val locales = resources.configuration.getLocales() - val localeCodes = listOf(*resources.getStringArray(R.array.locale_code)) - - for (i in 0 until locales.size()) { - val languageCode = locales[i].language - val countryCode = locales[i].country - val languageFormat = "$languageCode-$countryCode" - - if (localeCodes.contains(Prefs.getString(APP_LANGUAGE, languageFormat))) { - currentLanguage = - localeCodes.indexOf(Prefs.getString(APP_LANGUAGE, languageFormat)) - break - } - } - - binding.settingsGeneral.appLanguage.setSelectedIndex(currentLanguage) - binding.settingsGeneral.appLanguage.setOnItemSelectedListener { index: Int -> - putString( - APP_LANGUAGE, - listOf(*resources.getStringArray(R.array.locale_code))[index] - ) - - restartApplication(requireActivity()) - } - - // App Icon - binding.settingsGeneral.appIcon.setSelectedIndex(Prefs.getInt(APP_ICON, 0)) - binding.settingsGeneral.appIcon.setOnItemSelectedListener { index: Int -> - Prefs.putInt(APP_ICON, index) - val splashActivities = - appContextLocale.resources.getStringArray(R.array.app_icon_identifier) - - changeIcon(splashActivities[index]) - } - - // App Theme - binding.settingsGeneral.appTheme.setSelectedIndex(Prefs.getInt(APP_THEME, 2)) - binding.settingsGeneral.appTheme.setOnItemSelectedListener { index: Int -> - Prefs.putInt(APP_THEME, index) - - restartApplication(requireActivity()) - } - - // Check for update - binding.settingsUpdate.checkUpdate.setSummary( - resources.getString( - R.string.settings_current_version, - BuildConfig.VERSION_NAME - ) - ) - binding.settingsUpdate.checkUpdate.setOnClickListener { - findNavController(view).navigate( - R.id.action_settings_to_appUpdates - ) - } - - // Auto update - binding.settingsUpdate.autoUpdate.isSwitchChecked = Prefs.getBoolean(AUTO_UPDATE, true) - binding.settingsUpdate.autoUpdate.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> - Prefs.putBoolean(AUTO_UPDATE, isChecked) - scheduleUpdates(requireContext().applicationContext) - binding.settingsUpdate.autoUpdateWifiOnly.setEnabled(isChecked) - } - - // Check over wifi only - binding.settingsUpdate.autoUpdateWifiOnly.setEnabled(binding.settingsUpdate.autoUpdate.isSwitchChecked) - binding.settingsUpdate.autoUpdateWifiOnly.isSwitchChecked = - Prefs.getBoolean(UPDATE_OVER_WIFI, true) - binding.settingsUpdate.autoUpdateWifiOnly.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> - Prefs.putBoolean(UPDATE_OVER_WIFI, isChecked) - } - - // Show xposed warn - binding.settingsXposed.hideWarnMessage.isSwitchChecked = - Prefs.getBoolean(SHOW_XPOSED_WARN, true) - binding.settingsXposed.hideWarnMessage.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> - Prefs.putBoolean(SHOW_XPOSED_WARN, isChecked) - } - - // Restart systemui behavior - binding.settingsXposed.modApplyingMethod.setSelectedIndex( - RPrefs.getInt(RESTART_SYSUI_BEHAVIOR_EXT, 0) - ) - binding.settingsXposed.modApplyingMethod.setOnItemSelectedListener { index: Int -> - RPrefs.putInt(RESTART_SYSUI_BEHAVIOR_EXT, index) - } - - // Restart systemui after boot - binding.settingsMisc.restartSysuiAfterBoot.isSwitchChecked = - Prefs.getBoolean(RESTART_SYSUI_AFTER_BOOT, false) - binding.settingsMisc.restartSysuiAfterBoot.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> - Prefs.putBoolean(RESTART_SYSUI_AFTER_BOOT, isChecked) - if (isChecked) { - enableRestartSystemuiAfterBoot() - } else { - disableRestartSystemuiAfterBoot() - } - } - - // Home page card - binding.settingsMisc.homePageCard.isSwitchChecked = Prefs.getBoolean(SHOW_HOME_CARD, true) - binding.settingsMisc.homePageCard.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> - Prefs.putBoolean(SHOW_HOME_CARD, isChecked) - } - binding.settingsMisc.homePageCard.visibility = - if (Preferences.isXposedOnlyMode) { - View.GONE - } else { - View.VISIBLE - } - - // Clear App Cache - binding.settingsMisc.clearCache.setOnClickListener { - clearCache(appContext) - - Toast.makeText( - appContext, - appContextLocale.resources.getString(R.string.toast_clear_cache), - Toast.LENGTH_SHORT - ).show() - } - - // Experimental features - binding.settingsMisc.settingsMiscTitle.setOnClickListener { onEasterViewClicked() } - binding.settingsMisc.experimentalFeatures.setOnClickListener { - findNavController( - view - ).navigate(R.id.action_settings_to_experimental) - } - binding.settingsMisc.experimentalFeatures.visibility = - if (Prefs.getBoolean(EASTER_EGG)) { - View.VISIBLE - } else { - View.GONE - } - - // Disable Everything - binding.settingsMisc.buttonDisableEverything.setOnClickListener { - MaterialAlertDialogBuilder(requireActivity()) - .setCancelable(true) - .setTitle(requireContext().resources.getString(R.string.import_settings_confirmation_title)) - .setMessage(requireContext().resources.getString(R.string.import_settings_confirmation_desc)) - .setPositiveButton(getString(R.string.positive)) { dialog: DialogInterface, _: Int -> - dialog.dismiss() - - // Show loading dialog - loadingDialog!!.show(resources.getString(R.string.loading_dialog_wait)) - Executors.newSingleThreadExecutor().execute { - disableEverything() - Handler(Looper.getMainLooper()).postDelayed({ - - // Hide loading dialog - loadingDialog!!.hide() - - // Restart SystemUI - restartSystemUI() - }, 3000) - } - } - .setNegativeButton(getString(R.string.negative)) { dialog: DialogInterface, _: Int -> - dialog.dismiss() - } - .show() - } - - binding.settingsMisc.buttonDisableEverything.visibility = - if (Preferences.isXposedOnlyMode) { - View.GONE - } else { - View.VISIBLE - } - - // Github repository - binding.settingsAbout.githubRepository.setOnClickListener { - startActivity( - Intent(Intent.ACTION_VIEW).setData(Uri.parse(Const.GITHUB_REPO)) - ) - } - - // Telegram group - binding.settingsAbout.telegramGroup.setOnClickListener { - val intent = Intent(Intent.ACTION_VIEW) - intent.setData(Uri.parse(Const.TELEGRAM_GROUP)) - startActivity(intent) - } - - // Credits - binding.settingsAbout.credits.setOnClickListener { - findNavController(view).navigate( - R.id.action_settings_to_credits2 - ) - } - - return view - } - - override fun onDestroy() { - loadingDialog?.hide() - - super.onDestroy() - } - - @Suppress("deprecation") - @Deprecated("Deprecated in Java") - override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { - menu.clear() - inflater.inflate(R.menu.settings_menu, menu) - - super.onCreateOptionsMenu(menu, inflater) - } - - @Suppress("deprecation") - @Deprecated("Deprecated in Java") - @SuppressLint("NonConstantResourceId") - override fun onOptionsItemSelected(item: MenuItem): Boolean { - when (item.itemId) { - R.id.menu_changelog -> findNavController(requireView()).navigate(R.id.action_settings_to_changelog2) - R.id.menu_export_settings -> importExportSettings(true) - R.id.menu_import_settings -> importExportSettings(false) - R.id.restart_systemui -> Handler(Looper.getMainLooper()).postDelayed( - { restartSystemUI() }, - 300 - ) - } - - return super.onOptionsItemSelected(item) - } - - private fun importExportSettings(export: Boolean) { - if (!hasStoragePermission()) { - requestStoragePermission(requireContext()) - } else { - val fileIntent = Intent() - fileIntent.setAction(if (export) Intent.ACTION_CREATE_DOCUMENT else Intent.ACTION_GET_CONTENT) - fileIntent.setType("*/*") - fileIntent.putExtra(Intent.EXTRA_TITLE, "configs" + ".iconify") - - if (export) { - startExportActivityIntent.launch(fileIntent) - } else { - startImportActivityIntent.launch(fileIntent) - } - } - } - - private fun changeIcon(splash: String) { - val manager = requireActivity().packageManager - val splashActivities = - appContextLocale.resources.getStringArray(R.array.app_icon_identifier) - for (splashActivity in splashActivities) { - manager.setComponentEnabledSetting( - ComponentName( - requireActivity(), - "com.drdisagree.iconify.$splashActivity" - ), - if (splash == splashActivity) { - PackageManager.COMPONENT_ENABLED_STATE_ENABLED - } else { - PackageManager.COMPONENT_ENABLED_STATE_DISABLED - }, - PackageManager.DONT_KILL_APP - ) - } - } - - private fun onEasterViewClicked() { - val timeMillis = Date().time - - if (nextIndex == NUM_CLICKS_REQUIRED - 1 || oldestIndex > 0) { - val diff = (timeMillis - clickTimestamps[oldestIndex]).toInt() - if (diff < SECONDS_FOR_CLICKS * 1000) { - if (!Prefs.getBoolean(EASTER_EGG)) { - Prefs.putBoolean(EASTER_EGG, true) - - binding.settingsMisc.experimentalFeatures.visibility = View.VISIBLE - - Toast.makeText( - requireContext(), - requireContext().resources.getString(R.string.toast_easter_egg), - Toast.LENGTH_SHORT - ).show() - } else { - Toast.makeText( - requireContext(), - requireContext().resources.getString(R.string.toast_easter_egg_activated), - Toast.LENGTH_SHORT - ).show() - } - - oldestIndex = 0 - nextIndex = 0 - } else { - oldestIndex++ - } - } - - clickTimestamps[nextIndex] = timeMillis - nextIndex++ - - if (nextIndex == NUM_CLICKS_REQUIRED) nextIndex = 0 - if (oldestIndex == NUM_CLICKS_REQUIRED) oldestIndex = 0 - } - - companion object { - private const val SECONDS_FOR_CLICKS = 3.0 - private const val NUM_CLICKS_REQUIRED = 7 - - fun disableEverything() { - Prefs.clearAllPrefs() - RPrefs.clearAllPrefs() - - saveBootId - disableBlur(false) - saveVersionCode() - - Prefs.putBoolean(ON_HOME_PAGE, true) - Prefs.putBoolean(FIRST_INSTALL, false) - - Shell.cmd( - "> $MODULE_DIR/system.prop; > $MODULE_DIR/post-exec.sh; for ol in $(cmd overlay list | grep -E '.x.*IconifyComponent' | sed -E 's/^.x..//'); do cmd overlay disable \$ol; done; killall com.android.systemui" - ).submit() - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/Statusbar.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/Statusbar.kt deleted file mode 100644 index 9fe8e9b82..000000000 --- a/app/src/main/java/com/drdisagree/iconify/ui/fragments/Statusbar.kt +++ /dev/null @@ -1,366 +0,0 @@ -package com.drdisagree.iconify.ui.fragments - -import android.os.Bundle -import android.os.Handler -import android.os.Looper -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.RadioGroup -import com.drdisagree.iconify.Iconify.Companion.appContext -import com.drdisagree.iconify.R -import com.drdisagree.iconify.common.Const.FRAMEWORK_PACKAGE -import com.drdisagree.iconify.common.Const.SWITCH_ANIMATION_DELAY -import com.drdisagree.iconify.common.Const.SYSTEMUI_PACKAGE -import com.drdisagree.iconify.common.References.FABRICATED_SB_COLOR_SOURCE -import com.drdisagree.iconify.common.References.FABRICATED_SB_COLOR_TINT -import com.drdisagree.iconify.common.References.FABRICATED_SB_HEIGHT -import com.drdisagree.iconify.common.References.FABRICATED_SB_LEFT_PADDING -import com.drdisagree.iconify.common.References.FABRICATED_SB_RIGHT_PADDING -import com.drdisagree.iconify.config.Prefs -import com.drdisagree.iconify.config.Prefs.putString -import com.drdisagree.iconify.databinding.FragmentStatusbarBinding -import com.drdisagree.iconify.ui.activities.MainActivity -import com.drdisagree.iconify.ui.base.BaseFragment -import com.drdisagree.iconify.ui.events.ColorDismissedEvent -import com.drdisagree.iconify.ui.events.ColorSelectedEvent -import com.drdisagree.iconify.ui.utils.ViewHelper.setHeader -import com.drdisagree.iconify.utils.SystemUtil -import com.drdisagree.iconify.utils.color.ColorUtil.colorToSpecialHex -import com.drdisagree.iconify.utils.overlay.FabricatedUtil.buildAndEnableOverlays -import com.drdisagree.iconify.utils.overlay.FabricatedUtil.disableOverlays -import com.drdisagree.iconify.utils.overlay.OverlayUtil -import com.drdisagree.iconify.utils.overlay.OverlayUtil.enableOverlay -import com.drdisagree.iconify.utils.overlay.manager.resource.ResourceEntry -import com.drdisagree.iconify.utils.overlay.manager.resource.ResourceManager.buildOverlayWithResource -import com.drdisagree.iconify.utils.overlay.manager.resource.ResourceManager.removeResourceFromOverlay -import com.google.android.material.slider.Slider -import org.greenrobot.eventbus.EventBus -import org.greenrobot.eventbus.Subscribe - - -class Statusbar : BaseFragment() { - - private lateinit var binding: FragmentStatusbarBinding - private val finalSBLeftPadding = intArrayOf(Prefs.getInt(FABRICATED_SB_LEFT_PADDING, 8)) - private val finalSBRightPadding = intArrayOf(Prefs.getInt(FABRICATED_SB_RIGHT_PADDING, 8)) - private val finalSBHeight = intArrayOf(Prefs.getInt(FABRICATED_SB_HEIGHT, 28)) - - private val sbLeftPaddingListener: Slider.OnSliderTouchListener = - object : Slider.OnSliderTouchListener { - override fun onStartTrackingTouch(slider: Slider) {} - - override fun onStopTrackingTouch(slider: Slider) { - finalSBLeftPadding[0] = slider.value.toInt() - Prefs.putInt(FABRICATED_SB_LEFT_PADDING, finalSBLeftPadding[0]) - - buildOverlayWithResource( - requireContext(), - ResourceEntry( - SYSTEMUI_PACKAGE, - "dimen", - "status_bar_padding_start", - finalSBLeftPadding[0].toString() + "dp" - ) - ) - } - } - - private val sbRightPaddingListener: Slider.OnSliderTouchListener = - object : Slider.OnSliderTouchListener { - override fun onStartTrackingTouch(slider: Slider) {} - - override fun onStopTrackingTouch(slider: Slider) { - finalSBRightPadding[0] = slider.value.toInt() - Prefs.putInt(FABRICATED_SB_RIGHT_PADDING, finalSBRightPadding[0]) - - buildOverlayWithResource( - requireContext(), - ResourceEntry( - SYSTEMUI_PACKAGE, - "dimen", - "status_bar_padding_end", - finalSBRightPadding[0].toString() + "dp" - ) - ) - } - } - - private val sbHeightListener: Slider.OnSliderTouchListener = - object : Slider.OnSliderTouchListener { - override fun onStartTrackingTouch(slider: Slider) {} - - override fun onStopTrackingTouch(slider: Slider) { - finalSBHeight[0] = slider.value.toInt() - Prefs.putInt(FABRICATED_SB_HEIGHT, finalSBHeight[0]) - - buildOverlayWithResource( - requireContext(), - ResourceEntry( - FRAMEWORK_PACKAGE, - "dimen", - "status_bar_height", - finalSBHeight[0].toString() + "dp" - ), - ResourceEntry( - FRAMEWORK_PACKAGE, - "dimen", - "status_bar_height_default", - finalSBHeight[0].toString() + "dp" - ), - ResourceEntry( - FRAMEWORK_PACKAGE, - "dimen", - "status_bar_height_portrait", - finalSBHeight[0].toString() + "dp" - ), - ResourceEntry( - FRAMEWORK_PACKAGE, - "dimen", - "status_bar_height_landscape", - finalSBHeight[0].toString() + "dp" - ) - ) - } - } - - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View { - binding = FragmentStatusbarBinding.inflate(inflater, container, false) - val view: View = binding.getRoot() - - // Header - setHeader( - requireContext(), - getParentFragmentManager(), - binding.header.toolbar, - R.string.activity_title_statusbar - ) - - // Statusbar left padding - binding.sbLeftPadding.sliderValue = finalSBLeftPadding[0] - binding.sbLeftPadding.setOnSliderTouchListener(sbLeftPaddingListener) - - // Reset left padding - binding.sbLeftPadding.setResetClickListener { - Prefs.putInt(FABRICATED_SB_LEFT_PADDING, 8) - - removeResourceFromOverlay( - requireContext(), - ResourceEntry(SYSTEMUI_PACKAGE, "dimen", "status_bar_padding_start") - ) - - true - } - - // Statusbar right padding - binding.sbRightPadding.sliderValue = finalSBRightPadding[0] - binding.sbRightPadding.setOnSliderTouchListener(sbRightPaddingListener) - - // Reset right padding - binding.sbRightPadding.setResetClickListener { - Prefs.putInt(FABRICATED_SB_RIGHT_PADDING, 8) - - removeResourceFromOverlay( - requireContext(), - ResourceEntry(SYSTEMUI_PACKAGE, "dimen", "status_bar_padding_end") - ) - - true - } - - // Statusbar height - binding.sbHeight.sliderValue = finalSBHeight[0] - binding.sbHeight.setOnSliderTouchListener(sbHeightListener) - - // Reset height - binding.sbHeight.setResetClickListener { - Prefs.putInt(FABRICATED_SB_HEIGHT, 28) - - removeResourceFromOverlay( - requireContext(), - ResourceEntry(FRAMEWORK_PACKAGE, "dimen", "status_bar_height"), - ResourceEntry(FRAMEWORK_PACKAGE, "dimen", "status_bar_height_default"), - ResourceEntry(FRAMEWORK_PACKAGE, "dimen", "status_bar_height_portrait"), - ResourceEntry(FRAMEWORK_PACKAGE, "dimen", "status_bar_height_landscape") - ) - - true - } - colorSBTint = resources.getColor(R.color.colorAccent, appContext.theme).toString() - - //set current chosen style - selectedStyle = Prefs.getString(FABRICATED_SB_COLOR_SOURCE) - when { - selectedStyle == "Monet" || Prefs.getBoolean("IconifyComponentSBTint.overlay") -> { - binding.sbTintMonet.setChecked(true) - putString(FABRICATED_SB_COLOR_SOURCE, "Monet") - } - - selectedStyle == "System" -> { - binding.sbTintSystem.setChecked(true) - } - - selectedStyle == "Custom" -> { - binding.sbTintCustom.setChecked( - true - ) - } - } - - // Statusbar color source select - binding.sbTintSourceSelector.setOnCheckedChangeListener { _: RadioGroup?, checkedId: Int -> - when (checkedId) { - R.id.sb_tint_system -> { - if (selectedStyle != "System") { - putString(FABRICATED_SB_COLOR_SOURCE, "System") - resetSBColor() - } - } - - R.id.sb_tint_monet -> { - if (selectedStyle != "Monet") { - enableOverlay("IconifyComponentSBTint.overlay") - putString(FABRICATED_SB_COLOR_SOURCE, "Monet") - Handler(Looper.getMainLooper()).postDelayed( - { SystemUtil.restartSystemUI() }, - SWITCH_ANIMATION_DELAY - ) - } - } - - R.id.sb_tint_custom -> { - (requireActivity() as MainActivity).showColorPickerDialog( - dialogId = 1, - defaultColor = colorSBTint!!.toInt(), - showPresets = true, - showAlphaSlider = false, - showColorShades = true - ) - } - } - } - - return view - } - - @Suppress("unused") - @Subscribe - fun onColorSelected(event: ColorSelectedEvent) { - if (event.dialogId == 1) { - colorSBTint = event.selectedColor.toString() - putString(FABRICATED_SB_COLOR_TINT, colorSBTint) - - applySBColor() - - putString(FABRICATED_SB_COLOR_SOURCE, "Custom") - - OverlayUtil.disableOverlay("IconifyComponentSBTint.overlay") - } - } - - @Suppress("unused") - @Subscribe - fun onDialogDismissed(event: ColorDismissedEvent) { - if (event.dialogId == 1) { - selectedStyle = Prefs.getString(FABRICATED_SB_COLOR_SOURCE) - when (selectedStyle) { - "System" -> binding.sbTintSystem.setChecked(true) - "Monet" -> binding.sbTintMonet.setChecked(true) - "Custom" -> binding.sbTintCustom.setChecked(true) - } - } - } - - private fun applySBColor() { - buildAndEnableOverlays( - arrayOf( - SYSTEMUI_PACKAGE, - "colorSBTint1", - "color", - "dark_mode_icon_color_dual_tone_fill", - colorToSpecialHex(colorSBTint!!.toInt()) - ), arrayOf( - SYSTEMUI_PACKAGE, - "colorSBTint2", - "color", - "dark_mode_icon_color_single_tone", - colorToSpecialHex(colorSBTint!!.toInt()) - ), arrayOf( - SYSTEMUI_PACKAGE, - "colorSBTint3", - "color", - "dark_mode_qs_icon_color_dual_tone_fill", - colorToSpecialHex(colorSBTint!!.toInt()) - ), arrayOf( - SYSTEMUI_PACKAGE, - "colorSBTint4", - "color", - "dark_mode_qs_icon_color_single_tone", - colorToSpecialHex(colorSBTint!!.toInt()) - ), arrayOf( - SYSTEMUI_PACKAGE, - "colorSBTint5", - "color", - "light_mode_icon_color_dual_tone_fill", - colorToSpecialHex(colorSBTint!!.toInt()) - ), arrayOf( - SYSTEMUI_PACKAGE, - "colorSBTint6", - "color", - "light_mode_icon_color_single_tone", - colorToSpecialHex(colorSBTint!!.toInt()) - ), arrayOf( - SYSTEMUI_PACKAGE, - "colorSBTint7", - "color", - "status_bar_clock_color", - colorToSpecialHex(colorSBTint!!.toInt()) - ) - ) - - Handler(Looper.getMainLooper()).postDelayed( - { SystemUtil.restartSystemUI() }, - 1000 - ) - } - - private fun resetSBColor() { - disableOverlays( - "colorSBTint1", - "colorSBTint2", - "colorSBTint3", - "colorSBTint4", - "colorSBTint5", - "colorSBTint6", - "colorSBTint7" - ) - - OverlayUtil.disableOverlay("IconifyComponentSBTint.overlay") - - Handler(Looper.getMainLooper()).postDelayed( - { SystemUtil.restartSystemUI() }, - 1000 - ) - } - - override fun onStart() { - super.onStart() - - EventBus.getDefault().register(this) - } - - override fun onStop() { - super.onStop() - - EventBus.getDefault().unregister(this) - } - - companion object { - private var colorSBTint: String? = null - private var selectedStyle: String? = null - } -} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/ToastFrame.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/ToastFrame.kt deleted file mode 100644 index 2317f1c3e..000000000 --- a/app/src/main/java/com/drdisagree/iconify/ui/fragments/ToastFrame.kt +++ /dev/null @@ -1,213 +0,0 @@ -package com.drdisagree.iconify.ui.fragments - -import android.annotation.SuppressLint -import android.os.Bundle -import android.os.Handler -import android.os.Looper -import android.util.Log -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.LinearLayout -import android.widget.TextView -import android.widget.Toast -import androidx.core.content.ContextCompat -import com.drdisagree.iconify.Iconify.Companion.appContext -import com.drdisagree.iconify.Iconify.Companion.appContextLocale -import com.drdisagree.iconify.R -import com.drdisagree.iconify.common.Const.FRAMEWORK_PACKAGE -import com.drdisagree.iconify.common.Preferences.SELECTED_TOAST_FRAME -import com.drdisagree.iconify.config.Prefs -import com.drdisagree.iconify.databinding.FragmentToastFrameBinding -import com.drdisagree.iconify.ui.base.BaseFragment -import com.drdisagree.iconify.ui.dialogs.LoadingDialog -import com.drdisagree.iconify.ui.utils.ViewHelper.setHeader -import com.drdisagree.iconify.utils.SystemUtil.hasStoragePermission -import com.drdisagree.iconify.utils.SystemUtil.requestStoragePermission -import com.drdisagree.iconify.utils.overlay.OverlayUtil -import com.drdisagree.iconify.utils.overlay.compiler.OnDemandCompiler.buildOverlay -import java.io.IOException -import java.util.concurrent.atomic.AtomicBoolean - -class ToastFrame : BaseFragment() { - - private lateinit var binding: FragmentToastFrameBinding - private var loadingDialog: LoadingDialog? = null - - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View { - binding = FragmentToastFrameBinding.inflate(inflater, container, false) - val view: View = binding.getRoot() - - // Header - setHeader( - requireContext(), - getParentFragmentManager(), - binding.header.toolbar, - R.string.activity_title_toast_frame - ) - - // Loading dialog while enabling or disabling pack - loadingDialog = LoadingDialog(requireContext()) - - // Toast Frame style - addItem(initToastFrameList()) - - refreshBackground() - - return view - } - - private fun initToastFrameList(): ArrayList> { - val toastFrameStyle = ArrayList>().apply { - add(arrayOf(R.drawable.toast_frame_style_1, R.string.style_0)) - add(arrayOf(R.drawable.toast_frame_style_1, R.string.style_1)) - add(arrayOf(R.drawable.toast_frame_style_2, R.string.style_2)) - add(arrayOf(R.drawable.toast_frame_style_3, R.string.style_3)) - add(arrayOf(R.drawable.toast_frame_style_4, R.string.style_4)) - add(arrayOf(R.drawable.toast_frame_style_5, R.string.style_5)) - add(arrayOf(R.drawable.toast_frame_style_6, R.string.style_6)) - add(arrayOf(R.drawable.toast_frame_style_7, R.string.style_7)) - add(arrayOf(R.drawable.toast_frame_style_8, R.string.style_8)) - add(arrayOf(R.drawable.toast_frame_style_9, R.string.style_9)) - add(arrayOf(R.drawable.toast_frame_style_10, R.string.style_10)) - add(arrayOf(R.drawable.toast_frame_style_11, R.string.style_11)) - } - - return toastFrameStyle - } - - // Function to add new item in list - @SuppressLint("UseCompatLoadingForDrawables") - private fun addItem(pack: ArrayList>) { - for (i in pack.indices) { - val list = LayoutInflater.from(requireContext()) - .inflate(R.layout.view_toast_frame, binding.toastFrameContainer, false) - - val toastContainer = list.findViewById(R.id.toast_container) - toastContainer.background = ContextCompat.getDrawable(appContext, pack[i][0] as Int) - - val styleName = list.findViewById(R.id.style_name) - styleName.text = appContextLocale.resources.getString(pack[i][1] as Int) - - list.setOnClickListener { - if (i == 0) { - Prefs.putInt(SELECTED_TOAST_FRAME, -1) - - OverlayUtil.disableOverlay("IconifyComponentTSTFRM.overlay") - - Toast.makeText( - appContext, - appContextLocale.resources - .getString(R.string.toast_disabled), - Toast.LENGTH_SHORT - ).show() - - return@setOnClickListener - } - - if (!hasStoragePermission()) { - requestStoragePermission(requireContext()) - } else { - // Show loading dialog - loadingDialog!!.show(appContextLocale.resources.getString(R.string.loading_dialog_wait)) - - Thread { - val hasErroredOut = AtomicBoolean(false) - - try { - hasErroredOut.set( - buildOverlay( - "TSTFRM", - i, - FRAMEWORK_PACKAGE, - true - ) - ) - } catch (e: IOException) { - hasErroredOut.set(true) - Log.e("ToastFrame", e.toString()) - } - - if (!hasErroredOut.get()) { - Prefs.putInt(SELECTED_TOAST_FRAME, i) - refreshBackground() - } - - Handler(Looper.getMainLooper()).postDelayed({ - // Hide loading dialog - loadingDialog!!.hide() - - if (!hasErroredOut.get()) { - Toast.makeText( - appContext, - appContextLocale.resources.getString(R.string.toast_applied), - Toast.LENGTH_SHORT - ).show() - } else { - Toast.makeText( - appContext, - appContextLocale.resources.getString(R.string.toast_error), - Toast.LENGTH_SHORT - ).show() - } - }, 3000) - }.start() - } - } - - binding.toastFrameContainer.addView(list) - } - } - - // Function to check for bg drawable changes - private fun refreshBackground() { - var selected = false - for (i in 0 until binding.toastFrameContainer.childCount) { - val child = binding.toastFrameContainer.getChildAt(i) - .findViewById(R.id.list_item_toast) - - val title = child.findViewById(R.id.style_name) - - if (i == Prefs.getInt(SELECTED_TOAST_FRAME, -1)) { - selected = true - title.setTextColor( - appContextLocale.resources.getColor( - R.color.colorAccent, - appContext.theme - ) - ) - } else { - title.setTextColor( - appContextLocale.resources.getColor( - R.color.textColorSecondary, - appContext.theme - ) - ) - } - } - - if (!selected) { - val child = binding.toastFrameContainer.getChildAt(0) - .findViewById(R.id.list_item_toast) - - val title = child.findViewById(R.id.style_name) - - title.setTextColor( - appContextLocale.resources.getColor( - R.color.colorAccent, - appContext.theme - ) - ) - } - } - - override fun onDestroy() { - loadingDialog?.dismiss() - - super.onDestroy() - } -} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/Tweaks.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/Tweaks.kt deleted file mode 100644 index 38363031b..000000000 --- a/app/src/main/java/com/drdisagree/iconify/ui/fragments/Tweaks.kt +++ /dev/null @@ -1,184 +0,0 @@ -package com.drdisagree.iconify.ui.fragments - -import android.os.Build -import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.Toast -import androidx.navigation.Navigation.findNavController -import com.drdisagree.iconify.Iconify.Companion.appContext -import com.drdisagree.iconify.R -import com.drdisagree.iconify.databinding.FragmentTweaksBinding -import com.drdisagree.iconify.ui.base.BaseFragment -import com.drdisagree.iconify.ui.utils.ViewHelper.setHeader -import com.drdisagree.iconify.ui.widgets.MenuWidget -import com.drdisagree.iconify.utils.AppUtil.isLsposedInstalled - -class Tweaks : BaseFragment() { - - private lateinit var binding: FragmentTweaksBinding - - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View { - binding = FragmentTweaksBinding.inflate(inflater, container, false) - val view: View = binding.getRoot() - - // Header - setHeader( - requireContext(), - getParentFragmentManager(), - binding.header.toolbar, - R.string.navbar_tweaks - ) - - addItem(initTweaksItemList(view)) - - return view - } - - private fun initTweaksItemList(view: View): ArrayList> { - val tweaksList = ArrayList>().apply { - add( - arrayOf( - R.id.action_tweaks_to_colorEngine, - resources.getString(R.string.activity_title_color_engine), - resources.getString(R.string.activity_desc_color_engine), - R.drawable.ic_tweaks_color - ) - ) - add( - arrayOf( - R.id.action_tweaks_to_uiRoundness, - resources.getString(R.string.activity_title_ui_roundness), - resources.getString(R.string.activity_desc_ui_roundness), - R.drawable.ic_tweaks_roundness - ) - ) - add( - arrayOf( - R.id.action_tweaks_to_qsRowColumn, - resources.getString(R.string.activity_title_qs_row_column), - resources.getString(R.string.activity_desc_qs_row_column), - R.drawable.ic_qs_row_column - ) - ) - add( - arrayOf( - R.id.action_tweaks_to_qsIconLabel, - resources.getString(R.string.activity_title_qs_icon_label), - resources.getString(R.string.activity_desc_qs_icon_label), - R.drawable.ic_qs_icon_and_label - ) - ) - add( - arrayOf( - R.id.action_tweaks_to_qsTileSize, - resources.getString(R.string.activity_title_qs_tile_size), - resources.getString(R.string.activity_desc_qs_tile_size), - R.drawable.ic_qs_tile_size - ) - ) - add( - arrayOf( - R.id.action_tweaks_to_qsPanelMargin, - resources.getString(R.string.activity_title_qs_panel_margin), - resources.getString(R.string.activity_desc_qs_panel_margin), - R.drawable.ic_qs_top_margin - ) - ) - add( - arrayOf( - R.id.action_tweaks_to_statusbar, - resources.getString(R.string.activity_title_statusbar), - resources.getString(R.string.activity_desc_statusbar), - R.drawable.ic_tweaks_statusbar - ) - ) - add( - arrayOf( - R.id.action_tweaks_to_navigationBar, - resources.getString(R.string.activity_title_navigation_bar), - resources.getString(R.string.activity_desc_navigation_bar), - R.drawable.ic_tweaks_navbar - ) - ) - add( - arrayOf( - R.id.action_tweaks_to_mediaPlayer, - resources.getString(R.string.activity_title_media_player), - resources.getString(R.string.activity_desc_media_player), - R.drawable.ic_tweaks_media - ) - ) - add( - arrayOf( - R.id.action_tweaks_to_volumePanel, - resources.getString(R.string.activity_title_volume_panel), - resources.getString(R.string.activity_desc_volume_panel), - R.drawable.ic_tweaks_volume - ) - ) - add( - arrayOf( - R.id.action_tweaks_to_miscellaneous, - resources.getString(R.string.activity_title_miscellaneous), - resources.getString(R.string.activity_desc_miscellaneous), - R.drawable.ic_tweaks_miscellaneous - ) - ) - add( - arrayOf( - View.OnClickListener { - // Check if LSPosed is installed or not - if (!isLsposedInstalled) { - Toast.makeText( - appContext, - resources.getString(R.string.toast_lsposed_not_found), - Toast.LENGTH_SHORT - ).show() - return@OnClickListener - } - findNavController(view).navigate(R.id.action_tweaks_to_nav_xposed_menu) - }, - resources.getString(R.string.activity_title_xposed_menu), - resources.getString(R.string.activity_desc_xposed_menu), - R.drawable.ic_tweaks_xposed_menu - ) - ) - } - - return tweaksList - } - - // Function to add new item in list - private fun addItem(pack: ArrayList>) { - for (i in pack.indices) { - val menu = MenuWidget(requireActivity()) - - menu.setTitle(pack[i][1] as String) - menu.setSummary(pack[i][2] as String) - menu.setIcon(pack[i][3] as Int) - menu.setEndArrowVisibility(View.VISIBLE) - - if (pack[i][0] is View.OnClickListener) { - menu.setOnClickListener(pack[i][0] as View.OnClickListener) - } else if (pack[i][0] is Int) { - menu.setOnClickListener { - findNavController( - binding.getRoot() - ).navigate((pack[i][0] as Int)) - } - } - - if (pack[i][1] == resources.getString(R.string.activity_title_media_player) && Build.VERSION.SDK_INT >= 33) { - menu.visibility = View.GONE - } - - binding.tweaksList.addView(menu) - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/VolumePanel.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/VolumePanel.kt deleted file mode 100644 index 43dee18f2..000000000 --- a/app/src/main/java/com/drdisagree/iconify/ui/fragments/VolumePanel.kt +++ /dev/null @@ -1,463 +0,0 @@ -package com.drdisagree.iconify.ui.fragments - -import android.annotation.SuppressLint -import android.os.Bundle -import android.os.Handler -import android.os.Looper -import android.util.Log -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.RadioGroup -import android.widget.Toast -import androidx.core.content.ContextCompat -import com.drdisagree.iconify.Iconify.Companion.appContext -import com.drdisagree.iconify.Iconify.Companion.appContextLocale -import com.drdisagree.iconify.R -import com.drdisagree.iconify.common.Const.SYSTEMUI_PACKAGE -import com.drdisagree.iconify.common.Preferences.VOLUME_PANEL_BACKGROUND_WIDTH -import com.drdisagree.iconify.config.Prefs -import com.drdisagree.iconify.databinding.FragmentVolumePanelBinding -import com.drdisagree.iconify.ui.base.BaseFragment -import com.drdisagree.iconify.ui.dialogs.InfoDialog -import com.drdisagree.iconify.ui.dialogs.LoadingDialog -import com.drdisagree.iconify.ui.utils.ViewHelper.setHeader -import com.drdisagree.iconify.utils.RootUtil.isApatchInstalled -import com.drdisagree.iconify.utils.RootUtil.isKSUInstalled -import com.drdisagree.iconify.utils.RootUtil.isMagiskInstalled -import com.drdisagree.iconify.utils.SystemUtil.hasStoragePermission -import com.drdisagree.iconify.utils.SystemUtil.requestStoragePermission -import com.drdisagree.iconify.utils.overlay.compiler.VolumeCompiler.buildModule -import com.drdisagree.iconify.utils.overlay.manager.resource.ResourceEntry -import com.drdisagree.iconify.utils.overlay.manager.resource.ResourceManager.buildOverlayWithResource -import com.drdisagree.iconify.utils.overlay.manager.resource.ResourceManager.removeResourceFromOverlay -import com.google.android.material.button.MaterialButton -import java.util.concurrent.atomic.AtomicBoolean - -class VolumePanel : BaseFragment() { - - private lateinit var binding: FragmentVolumePanelBinding - private var loadingDialog: LoadingDialog? = null - private var infoDialog: InfoDialog? = null - private var finalCheckedId = -1 - - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View { - binding = FragmentVolumePanelBinding.inflate(inflater, container, false) - val view: View = binding.getRoot() - - // Header - setHeader( - requireContext(), - getParentFragmentManager(), - binding.header.toolbar, - R.string.activity_title_volume_panel - ) - - binding.thinBg.isChecked = Prefs.getInt(VOLUME_PANEL_BACKGROUND_WIDTH, 0) == 1 - binding.thinBg.addOnCheckedChangeListener { button: MaterialButton, isChecked: Boolean -> - if (button.isPressed) { - if (!hasStoragePermission()) { - requestStoragePermission(requireContext()) - binding.toggleButtonGroup.uncheck(binding.thinBg.id) - } else { - if (isChecked) { - binding.toggleButtonGroup.uncheck(binding.thickBg.id) - binding.toggleButtonGroup.uncheck(binding.noBg.id) - - Prefs.putInt(VOLUME_PANEL_BACKGROUND_WIDTH, 1) - - buildOverlayWithResource( - requireContext(), - ResourceEntry( - SYSTEMUI_PACKAGE, - "dimen", - "volume_dialog_slider_width", - "42dp" - ), - ResourceEntry( - SYSTEMUI_PACKAGE, - "dimen", - "volume_dialog_track_width", - "4dp" - ), - ResourceEntry( - SYSTEMUI_PACKAGE, - "dimen", - "rounded_slider_track_inset", - "22dp" - ) - ) - } else { - Prefs.putInt(VOLUME_PANEL_BACKGROUND_WIDTH, 0) - - removeResourceFromOverlay( - requireContext(), - ResourceEntry(SYSTEMUI_PACKAGE, "dimen", "volume_dialog_slider_width"), - ResourceEntry(SYSTEMUI_PACKAGE, "dimen", "volume_dialog_track_width"), - ResourceEntry(SYSTEMUI_PACKAGE, "dimen", "rounded_slider_track_inset") - ) - } - } - } - } - - binding.thickBg.isChecked = Prefs.getInt(VOLUME_PANEL_BACKGROUND_WIDTH, 0) == 2 - binding.thickBg.addOnCheckedChangeListener { button: MaterialButton, isChecked: Boolean -> - if (button.isPressed) { - if (!hasStoragePermission()) { - requestStoragePermission(requireContext()) - binding.toggleButtonGroup.uncheck(binding.thickBg.id) - } else { - if (isChecked) { - binding.toggleButtonGroup.uncheck(binding.thinBg.id) - binding.toggleButtonGroup.uncheck(binding.noBg.id) - - Prefs.putInt(VOLUME_PANEL_BACKGROUND_WIDTH, 2) - - buildOverlayWithResource( - requireContext(), - ResourceEntry( - SYSTEMUI_PACKAGE, - "dimen", - "volume_dialog_slider_width", - "42dp" - ), - ResourceEntry( - SYSTEMUI_PACKAGE, - "dimen", - "volume_dialog_track_width", - "42dp" - ), - ResourceEntry( - SYSTEMUI_PACKAGE, - "dimen", - "rounded_slider_track_inset", - "0dp" - ) - ) - } else { - Prefs.putInt(VOLUME_PANEL_BACKGROUND_WIDTH, 0) - - removeResourceFromOverlay( - requireContext(), - ResourceEntry(SYSTEMUI_PACKAGE, "dimen", "volume_dialog_slider_width"), - ResourceEntry(SYSTEMUI_PACKAGE, "dimen", "volume_dialog_track_width"), - ResourceEntry(SYSTEMUI_PACKAGE, "dimen", "rounded_slider_track_inset") - ) - } - } - } - } - - binding.noBg.isChecked = Prefs.getInt(VOLUME_PANEL_BACKGROUND_WIDTH, 0) == 3 - binding.noBg.addOnCheckedChangeListener { button: MaterialButton, isChecked: Boolean -> - if (button.isPressed) { - if (!hasStoragePermission()) { - requestStoragePermission(requireContext()) - binding.toggleButtonGroup.uncheck(binding.noBg.id) - } else { - if (isChecked) { - binding.toggleButtonGroup.uncheck(binding.thinBg.id) - binding.toggleButtonGroup.uncheck(binding.thickBg.id) - - Prefs.putInt(VOLUME_PANEL_BACKGROUND_WIDTH, 3) - - buildOverlayWithResource( - requireContext(), - ResourceEntry( - SYSTEMUI_PACKAGE, - "dimen", - "volume_dialog_slider_width", - "42dp" - ), - ResourceEntry( - SYSTEMUI_PACKAGE, - "dimen", - "volume_dialog_track_width", - "0dp" - ), - ResourceEntry( - SYSTEMUI_PACKAGE, - "dimen", - "rounded_slider_track_inset", - "24dp" - ) - ) - } else { - Prefs.putInt(VOLUME_PANEL_BACKGROUND_WIDTH, 0) - - removeResourceFromOverlay( - requireContext(), - ResourceEntry(SYSTEMUI_PACKAGE, "dimen", "volume_dialog_slider_width"), - ResourceEntry(SYSTEMUI_PACKAGE, "dimen", "volume_dialog_track_width"), - ResourceEntry(SYSTEMUI_PACKAGE, "dimen", "rounded_slider_track_inset") - ) - } - } - } - } - - // Loading dialog while creating modules - loadingDialog = LoadingDialog(requireContext()) - - // Credits dialog for volume style modules - infoDialog = InfoDialog(requireContext()) - - // Volume style - binding.volumeStyle.volumeStyleInfo.setOnClickListener { - infoDialog!!.show( - R.string.read_carefully, - R.string.volume_module_installation_guide - ) - } - - binding.volumeStyle.volumeStyle1.clearCheck() - binding.volumeStyle.volumeStyle2.clearCheck() - - binding.volumeStyle.volumeStyle1.setOnCheckedChangeListener(listener1) - binding.volumeStyle.volumeStyle2.setOnCheckedChangeListener(listener2) - - val checkedId1 = binding.volumeStyle.volumeStyle1.checkedRadioButtonId - val checkedId2 = binding.volumeStyle.volumeStyle2.checkedRadioButtonId - finalCheckedId = if (checkedId1 == -1) checkedId2 else checkedId1 - - binding.volumeStyle.volumeStyleCreateModule.setOnClickListener { - if ((isKSUInstalled || isApatchInstalled) && !isMagiskInstalled) { - Toast.makeText( - appContext, - appContextLocale.resources.getString(R.string.toast_only_magisk_supported), - Toast.LENGTH_SHORT - ).show() - - return@setOnClickListener - } - - if (!hasStoragePermission()) { - requestStoragePermission(requireContext()) - } else { - if (finalCheckedId == -1) { - Toast.makeText( - appContext, - appContextLocale.resources.getString(R.string.toast_select_style), - Toast.LENGTH_SHORT - ).show() - } else { - installVolumeModule(finalCheckedId) - } - } - } - - return view - } - - @SuppressLint("NonConstantResourceId") - private fun installVolumeModule(volume: Int) { - loadingDialog!!.show(resources.getString(R.string.loading_dialog_wait)) - - val hasErroredOut = AtomicBoolean(false) - - val selectedStyle: String = when (volume) { - R.id.gradient_style -> "VolumeGradient" - R.id.doublelayer_style -> "VolumeDoubleLayer" - R.id.shadedlayer_style -> "VolumeShadedLayer" - R.id.neumorph_style -> "VolumeNeumorph" - R.id.outline_style -> "VolumeOutline" - R.id.neumorphoutline_style -> "VolumeNeumorphOutline" - else -> return - } - - Thread { - try { - hasErroredOut.set(buildModule(selectedStyle, SYSTEMUI_PACKAGE)) - } catch (e: Exception) { - hasErroredOut.set(true) - Log.e("VolumePanel", e.toString()) - } - - Handler(Looper.getMainLooper()).postDelayed({ - loadingDialog!!.hide() - - if (hasErroredOut.get()) { - Toast.makeText( - appContext, - appContextLocale.resources.getString(R.string.toast_error), - Toast.LENGTH_SHORT - ).show() - } else { - Toast.makeText( - appContext, - appContextLocale.resources.getString(R.string.toast_module_created), - Toast.LENGTH_SHORT - ).show() - } - }, 2000) - }.start() - } - - private fun updateVolumePreview(id: Int) { - when (id) { - R.id.gradient_style -> setVolumeDrawable( - ringerDrawable = R.drawable.volume_gradient, - progressDrawable = R.drawable.volume_gradient, - ringerInverse = false, - progressInverse = false - ) - - R.id.doublelayer_style -> setVolumeDrawable( - ringerDrawable = R.drawable.volume_double_layer, - progressDrawable = R.drawable.volume_double_layer, - ringerInverse = false, - progressInverse = false - ) - - R.id.shadedlayer_style -> setVolumeDrawable( - ringerDrawable = R.drawable.volume_shaded_layer, - progressDrawable = R.drawable.volume_shaded_layer, - ringerInverse = false, - progressInverse = false - ) - - R.id.neumorph_style -> setVolumeDrawable( - ringerDrawable = R.drawable.volume_neumorph, - progressDrawable = R.drawable.volume_neumorph, - ringerInverse = false, - progressInverse = false - ) - - R.id.outline_style -> setVolumeDrawable( - ringerDrawable = R.drawable.volume_outline_ringer, - progressDrawable = R.drawable.volume_outline, - ringerInverse = true, - progressInverse = false - ) - - R.id.neumorphoutline_style -> setVolumeDrawable( - ringerDrawable = R.drawable.volume_neumorph_outline_ringer, - progressDrawable = R.drawable.volume_neumorph_outline, - ringerInverse = true, - progressInverse = false - ) - } - } - - private fun setVolumeDrawable( - ringerDrawable: Int, - progressDrawable: Int, - ringerInverse: Boolean, - progressInverse: Boolean - ) { - binding.volumeThinBg.volumeRingerBg.background = - ContextCompat.getDrawable(appContext, ringerDrawable) - binding.volumeThinBg.volumeProgressDrawable.background = - ContextCompat.getDrawable(appContext, progressDrawable) - binding.volumeThickBg.volumeRingerBg.background = - ContextCompat.getDrawable(appContext, ringerDrawable) - binding.volumeThickBg.volumeProgressDrawable.background = - ContextCompat.getDrawable(appContext, progressDrawable) - binding.volumeNoBg.volumeRingerBg.background = - ContextCompat.getDrawable(appContext, ringerDrawable) - binding.volumeNoBg.volumeProgressDrawable.background = - ContextCompat.getDrawable(appContext, progressDrawable) - - if (ringerInverse) { - binding.volumeThinBg.volumeRingerIcon.setBackgroundTintList( - ContextCompat.getColorStateList( - appContext, R.color.textColorPrimary - ) - ) - binding.volumeThickBg.volumeRingerIcon.setBackgroundTintList( - ContextCompat.getColorStateList( - appContext, R.color.textColorPrimary - ) - ) - binding.volumeNoBg.volumeRingerIcon.setBackgroundTintList( - ContextCompat.getColorStateList( - appContext, R.color.textColorPrimary - ) - ) - } else { - binding.volumeThinBg.volumeRingerIcon.setBackgroundTintList( - ContextCompat.getColorStateList( - appContext, R.color.textColorPrimaryInverse - ) - ) - binding.volumeThickBg.volumeRingerIcon.setBackgroundTintList( - ContextCompat.getColorStateList( - appContext, R.color.textColorPrimaryInverse - ) - ) - binding.volumeNoBg.volumeRingerIcon.setBackgroundTintList( - ContextCompat.getColorStateList( - appContext, R.color.textColorPrimaryInverse - ) - ) - } - if (progressInverse) { - binding.volumeThinBg.volumeProgressIcon.setBackgroundTintList( - ContextCompat.getColorStateList( - appContext, R.color.textColorPrimary - ) - ) - binding.volumeThickBg.volumeProgressIcon.setBackgroundTintList( - ContextCompat.getColorStateList( - appContext, R.color.textColorPrimary - ) - ) - binding.volumeNoBg.volumeProgressIcon.setBackgroundTintList( - ContextCompat.getColorStateList( - appContext, R.color.textColorPrimary - ) - ) - } else { - binding.volumeThinBg.volumeProgressIcon.setBackgroundTintList( - ContextCompat.getColorStateList( - appContext, R.color.textColorPrimaryInverse - ) - ) - binding.volumeThickBg.volumeProgressIcon.setBackgroundTintList( - ContextCompat.getColorStateList( - appContext, R.color.textColorPrimaryInverse - ) - ) - binding.volumeNoBg.volumeProgressIcon.setBackgroundTintList( - ContextCompat.getColorStateList( - appContext, R.color.textColorPrimaryInverse - ) - ) - } - } - - override fun onDestroy() { - loadingDialog?.dismiss() - - super.onDestroy() - } - - private val listener1: RadioGroup.OnCheckedChangeListener = - RadioGroup.OnCheckedChangeListener { _, checkedId -> - if (checkedId != -1) { - binding.volumeStyle.volumeStyle2.setOnCheckedChangeListener(null) - binding.volumeStyle.volumeStyle2.clearCheck() - binding.volumeStyle.volumeStyle2.setOnCheckedChangeListener(listener2) - finalCheckedId = checkedId - } - - updateVolumePreview(checkedId) - } - - private val listener2: RadioGroup.OnCheckedChangeListener = - RadioGroup.OnCheckedChangeListener { _, checkedId -> - if (checkedId != -1) { - binding.volumeStyle.volumeStyle1.setOnCheckedChangeListener(null) - binding.volumeStyle.volumeStyle1.clearCheck() - binding.volumeStyle.volumeStyle1.setOnCheckedChangeListener(listener1) - finalCheckedId = checkedId - } - - updateVolumePreview(checkedId) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/XposedBackgroundChip.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/XposedBackgroundChip.kt deleted file mode 100644 index 83ffa918e..000000000 --- a/app/src/main/java/com/drdisagree/iconify/ui/fragments/XposedBackgroundChip.kt +++ /dev/null @@ -1,244 +0,0 @@ -package com.drdisagree.iconify.ui.fragments - -import android.annotation.SuppressLint -import android.graphics.Color -import android.os.Build -import android.os.Bundle -import android.os.Handler -import android.os.Looper -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.CompoundButton -import android.widget.LinearLayout -import android.widget.TextView -import androidx.core.content.ContextCompat -import com.drdisagree.iconify.Iconify.Companion.appContext -import com.drdisagree.iconify.R -import com.drdisagree.iconify.common.Const.SWITCH_ANIMATION_DELAY -import com.drdisagree.iconify.common.Preferences.CHIP_QSSTATUSICONS_STYLE -import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCKBG_STYLE -import com.drdisagree.iconify.common.Preferences.QSPANEL_STATUSICONSBG_SWITCH -import com.drdisagree.iconify.common.Preferences.STATUSBAR_CLOCKBG_SWITCH -import com.drdisagree.iconify.common.Preferences.STATUSBAR_CLOCK_COLOR_CODE -import com.drdisagree.iconify.common.Preferences.STATUSBAR_CLOCK_COLOR_OPTION -import com.drdisagree.iconify.config.RPrefs -import com.drdisagree.iconify.databinding.FragmentXposedBackgroundChipBinding -import com.drdisagree.iconify.ui.base.BaseFragment -import com.drdisagree.iconify.ui.utils.ViewHelper.setHeader -import com.drdisagree.iconify.utils.SystemUtil -import com.drdisagree.iconify.utils.overlay.OverlayUtil.enableOverlay - -class XposedBackgroundChip : BaseFragment() { - - private lateinit var binding: FragmentXposedBackgroundChipBinding - - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View { - binding = FragmentXposedBackgroundChipBinding.inflate(inflater, container, false) - val view: View = binding.getRoot() - - // Header - setHeader( - requireContext(), - getParentFragmentManager(), - binding.header.toolbar, - R.string.activity_title_background_chip - ) - - // Statusbar clock Chip - binding.clockBgChip.isSwitchChecked = RPrefs.getBoolean(STATUSBAR_CLOCKBG_SWITCH, false) - binding.clockBgChip.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> - RPrefs.putBoolean(STATUSBAR_CLOCKBG_SWITCH, isChecked) - - binding.clockTextColor.setEnabled(isChecked) - binding.clockTextColorPicker.setEnabled(isChecked) - - if (!isChecked) { - Handler(Looper.getMainLooper()).postDelayed( - { SystemUtil.handleSystemUIRestart() }, - SWITCH_ANIMATION_DELAY - ) - } - } - - // Statusbar clock chip style - addItemStatusBar(initStatusBarChipStyles()) - refreshBackgroundStatusBar() - - // Statusbar Clock Color - binding.clockTextColor.setEnabled(RPrefs.getBoolean(STATUSBAR_CLOCKBG_SWITCH, false)) - binding.clockTextColor.setSelectedIndex(RPrefs.getInt(STATUSBAR_CLOCK_COLOR_OPTION, 0)) - binding.clockTextColor.setOnItemSelectedListener { index: Int -> - RPrefs.putInt(STATUSBAR_CLOCK_COLOR_OPTION, index) - binding.clockTextColorPicker.visibility = if (index == 2) View.VISIBLE else View.GONE - } - - // Clock Color Picker - binding.clockTextColorPicker.setEnabled( - RPrefs.getBoolean( - STATUSBAR_CLOCKBG_SWITCH, - false - ) - ) - binding.clockTextColorPicker.visibility = - if (RPrefs.getInt(STATUSBAR_CLOCK_COLOR_OPTION, 0) == 2) { - View.VISIBLE - } else { - View.GONE - } - binding.clockTextColorPicker.setColorPickerListener( - activity = requireActivity(), - defaultColor = RPrefs.getInt(STATUSBAR_CLOCK_COLOR_CODE, Color.WHITE), - showPresets = true, - showAlphaSlider = true, - showColorShades = true - ) - binding.clockTextColorPicker.setOnColorSelectedListener { color: Int -> - binding.clockTextColorPicker.previewColor = color - RPrefs.putInt(STATUSBAR_CLOCK_COLOR_CODE, color) - } - - // Status icons chip - binding.statusIconsChip.isSwitchChecked = - RPrefs.getBoolean(QSPANEL_STATUSICONSBG_SWITCH, false) - binding.statusIconsChip.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> - RPrefs.putBoolean(QSPANEL_STATUSICONSBG_SWITCH, isChecked) - - Handler(Looper.getMainLooper()).postDelayed({ - enableOverlay("IconifyComponentIXCC.overlay") - - Handler(Looper.getMainLooper()).postDelayed( - { SystemUtil.handleSystemUIRestart() }, - SWITCH_ANIMATION_DELAY - ) - }, SWITCH_ANIMATION_DELAY) - } - - // Status icons chip style - addItemStatusIcons(initStatusIconsChipStyles()) - refreshBackgroundStatusIcons() - - return view - } - - private fun initStatusBarChipStyles(): ArrayList> { - val statusBarChipStyle = ArrayList>().apply { - add(arrayOf(R.drawable.chip_status_bar_1, R.string.style_1)) - add(arrayOf(R.drawable.chip_status_bar_2, R.string.style_2)) - add(arrayOf(R.drawable.chip_status_bar_3, R.string.style_3)) - add(arrayOf(R.drawable.chip_status_bar_4, R.string.style_4)) - add(arrayOf(R.drawable.chip_status_bar_5, R.string.style_5)) - add(arrayOf(R.drawable.chip_status_bar_6, R.string.style_6)) - add(arrayOf(R.drawable.chip_status_bar_7, R.string.style_7)) - } - - return statusBarChipStyle - } - - private fun initStatusIconsChipStyles(): ArrayList> { - val statusIconsChipStyle = ArrayList>().apply { - add(arrayOf(R.drawable.chip_status_icons_1, R.string.style_1)) - add(arrayOf(R.drawable.chip_status_icons_2, R.string.style_2)) - add(arrayOf(R.drawable.chip_status_icons_3, R.string.style_3)) - add(arrayOf(R.drawable.chip_status_icons_4, R.string.style_4)) - add(arrayOf(R.drawable.chip_status_icons_5, R.string.style_5)) - add(arrayOf(R.drawable.chip_status_icons_6, R.string.style_6)) - } - - return statusIconsChipStyle - } - - // Function to add new item in list - @SuppressLint("UseCompatLoadingForDrawables") - private fun addItemStatusBar(pack: ArrayList>) { - for (i in pack.indices) { - val list = LayoutInflater.from(requireContext()) - .inflate( - R.layout.view_status_bar_chip, - binding.statusBarChipContainer, - false - ) - - val clockContainer = list.findViewById(R.id.clock_container) - clockContainer.background = ContextCompat.getDrawable(appContext, pack[i][0] as Int) - - val styleName = list.findViewById(R.id.style_name) - styleName.text = resources.getString(pack[i][1] as Int) - - list.setOnClickListener { - RPrefs.putInt(CHIP_STATUSBAR_CLOCKBG_STYLE, i) - refreshBackgroundStatusBar() - } - - binding.statusBarChipContainer.addView(list) - } - } - - // Function to check for bg drawable changes - private fun refreshBackgroundStatusBar() { - for (i in 0 until binding.statusBarChipContainer.childCount) { - val child = binding.statusBarChipContainer.getChildAt(i) - .findViewById(R.id.list_item_chip) - - val title = child.findViewById(R.id.style_name) - - if (i == RPrefs.getInt(CHIP_STATUSBAR_CLOCKBG_STYLE, 0)) { - title.setTextColor(resources.getColor(R.color.colorAccent, appContext.theme)) - } else { - title.setTextColor(resources.getColor(R.color.textColorSecondary, appContext.theme)) - } - } - } - - // Function to add new item in list - private fun addItemStatusIcons(pack: ArrayList>) { - for (i in pack.indices) { - val list = LayoutInflater.from(requireContext()) - .inflate(R.layout.view_status_icons_chip, binding.statusIconsChipContainer, false) - - val iconContainer = list.findViewById(R.id.clock_container) - iconContainer.background = ContextCompat.getDrawable(appContext, pack[i][0] as Int) - - val styleName = list.findViewById(R.id.style_name) - styleName.text = resources.getString(pack[i][1] as Int) - - list.setOnClickListener { - RPrefs.putInt(CHIP_QSSTATUSICONS_STYLE, i) - - refreshBackgroundStatusIcons() - - if (RPrefs.getBoolean( - QSPANEL_STATUSICONSBG_SWITCH, - false - ) && Build.VERSION.SDK_INT < 33 - ) { - Handler(Looper.getMainLooper()).postDelayed( - { SystemUtil.doubleToggleDarkMode() }, - SWITCH_ANIMATION_DELAY - ) - } - } - binding.statusIconsChipContainer.addView(list) - } - } - - // Function to check for bg drawable changes - private fun refreshBackgroundStatusIcons() { - for (i in 0 until binding.statusIconsChipContainer.childCount) { - val child = binding.statusIconsChipContainer.getChildAt(i) - .findViewById(R.id.list_item_chip) - - val title = child.findViewById(R.id.style_name) - - if (i == RPrefs.getInt(CHIP_QSSTATUSICONS_STYLE, 0)) { - title.setTextColor(resources.getColor(R.color.colorAccent, appContext.theme)) - } else { - title.setTextColor(resources.getColor(R.color.textColorSecondary, appContext.theme)) - } - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/XposedBatteryStyle.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/XposedBatteryStyle.kt deleted file mode 100644 index f37bf0cd8..000000000 --- a/app/src/main/java/com/drdisagree/iconify/ui/fragments/XposedBatteryStyle.kt +++ /dev/null @@ -1,514 +0,0 @@ -package com.drdisagree.iconify.ui.fragments - -import android.graphics.Color -import android.os.Bundle -import android.os.Handler -import android.os.Looper -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.CompoundButton -import com.drdisagree.iconify.R -import com.drdisagree.iconify.common.Const.SWITCH_ANIMATION_DELAY -import com.drdisagree.iconify.common.Preferences.BATTERY_STYLE_CIRCLE -import com.drdisagree.iconify.common.Preferences.BATTERY_STYLE_DEFAULT -import com.drdisagree.iconify.common.Preferences.BATTERY_STYLE_DEFAULT_LANDSCAPE -import com.drdisagree.iconify.common.Preferences.BATTERY_STYLE_DEFAULT_RLANDSCAPE -import com.drdisagree.iconify.common.Preferences.BATTERY_STYLE_DOTTED_CIRCLE -import com.drdisagree.iconify.common.Preferences.BATTERY_STYLE_FILLED_CIRCLE -import com.drdisagree.iconify.common.Preferences.BATTERY_STYLE_LANDSCAPE_BATTERYL -import com.drdisagree.iconify.common.Preferences.BATTERY_STYLE_LANDSCAPE_BATTERYM -import com.drdisagree.iconify.common.Preferences.BATTERY_STYLE_LANDSCAPE_IOS_16 -import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_BLEND_COLOR -import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_CHARGING_COLOR -import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_CHARGING_ICON_MARGIN_LEFT -import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_CHARGING_ICON_MARGIN_RIGHT -import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_CHARGING_ICON_STYLE -import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_CHARGING_ICON_SWITCH -import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_CHARGING_ICON_WIDTH_HEIGHT -import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_DIMENSION -import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_FILL_ALPHA -import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_FILL_COLOR -import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_FILL_GRAD_COLOR -import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_HEIGHT -import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_HIDE_BATTERY -import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_HIDE_PERCENTAGE -import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_INSIDE_PERCENTAGE -import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_LAYOUT_REVERSE -import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_MARGIN_BOTTOM -import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_MARGIN_LEFT -import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_MARGIN_RIGHT -import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_MARGIN_TOP -import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_PERIMETER_ALPHA -import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_POWERSAVE_FILL_COLOR -import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_POWERSAVE_INDICATOR_COLOR -import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_RAINBOW_FILL_COLOR -import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_STYLE -import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_SWAP_PERCENTAGE -import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_WIDTH -import com.drdisagree.iconify.config.RPrefs.getBoolean -import com.drdisagree.iconify.config.RPrefs.getInt -import com.drdisagree.iconify.config.RPrefs.putBoolean -import com.drdisagree.iconify.config.RPrefs.putInt -import com.drdisagree.iconify.databinding.FragmentXposedBatteryStyleBinding -import com.drdisagree.iconify.databinding.ViewXposedBatteryChargingIconBinding -import com.drdisagree.iconify.databinding.ViewXposedBatteryColorBinding -import com.drdisagree.iconify.databinding.ViewXposedBatteryDimensionBinding -import com.drdisagree.iconify.databinding.ViewXposedBatteryMiscBinding -import com.drdisagree.iconify.ui.base.BaseFragment -import com.drdisagree.iconify.ui.utils.ViewHelper.getBatteryDrawables -import com.drdisagree.iconify.ui.utils.ViewHelper.getChargingIcons -import com.drdisagree.iconify.ui.utils.ViewHelper.setHeader -import com.drdisagree.iconify.utils.SystemUtil -import com.google.android.material.slider.Slider - - -class XposedBatteryStyle : BaseFragment() { - - private lateinit var binding: FragmentXposedBatteryStyleBinding - private lateinit var bindingMiscSettings: ViewXposedBatteryMiscBinding - private lateinit var bindingCustomColors: ViewXposedBatteryColorBinding - private lateinit var bindingCustomDimens: ViewXposedBatteryDimensionBinding - private lateinit var bindingChargingIcon: ViewXposedBatteryChargingIconBinding - - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View { - binding = FragmentXposedBatteryStyleBinding.inflate(inflater, container, false) - bindingMiscSettings = ViewXposedBatteryMiscBinding.bind(binding.getRoot()) - bindingCustomColors = ViewXposedBatteryColorBinding.bind(binding.getRoot()) - bindingCustomDimens = ViewXposedBatteryDimensionBinding.bind(binding.getRoot()) - bindingChargingIcon = ViewXposedBatteryChargingIconBinding.bind(binding.getRoot()) - val view: View = binding.getRoot() - - // Header - setHeader( - requireContext(), - getParentFragmentManager(), - binding.header.toolbar, - R.string.activity_title_battery_style - ) - - // Custom battery style - binding.customBatteryStyle.setSelectedIndex(getInt(CUSTOM_BATTERY_STYLE, 0)) - binding.customBatteryStyle.setDrawable(getBatteryDrawables(requireContext())) - binding.customBatteryStyle.setOnItemClickListener { index: Int -> - selectedBatteryStyle = index - binding.customBatteryStyle.setCurrentValue(index.toString()) - updateLayoutVisibility() - } - selectedBatteryStyle = getInt(CUSTOM_BATTERY_STYLE, 0) - - // Apply battery style - binding.applyBatteryStyle.setOnClickListener { - putInt(CUSTOM_BATTERY_STYLE, selectedBatteryStyle) - Handler(Looper.getMainLooper()).postDelayed( - { SystemUtil.handleSystemUIRestart() }, - SWITCH_ANIMATION_DELAY - ) - } - - miscSettings() - customColors() - customDimension() - customChargingIcon() - updateLayoutVisibility() - - return view - } - - private fun miscSettings() { - // Battery width - bindingMiscSettings.batteryWidth.sliderValue = getInt(CUSTOM_BATTERY_WIDTH, 20) - bindingMiscSettings.batteryWidth.setOnSliderChangeListener { slider: Slider, _: Float, _: Boolean -> - putInt( - CUSTOM_BATTERY_WIDTH, - slider.value.toInt() - ) - } - bindingMiscSettings.batteryWidth.setOnSliderTouchListener(object : - Slider.OnSliderTouchListener { - override fun onStartTrackingTouch(slider: Slider) {} - - override fun onStopTrackingTouch(slider: Slider) { - if (selectedBatteryStyle < 3) { - Handler(Looper.getMainLooper()).postDelayed( - { SystemUtil.handleSystemUIRestart() }, - SWITCH_ANIMATION_DELAY - ) - } - } - }) - - // Battery height - bindingMiscSettings.batteryHeight.sliderValue = getInt(CUSTOM_BATTERY_HEIGHT, 20) - bindingMiscSettings.batteryHeight.setOnSliderChangeListener { slider: Slider, _: Float, _: Boolean -> - putInt( - CUSTOM_BATTERY_HEIGHT, - slider.value.toInt() - ) - } - bindingMiscSettings.batteryHeight.setOnSliderTouchListener(object : - Slider.OnSliderTouchListener { - override fun onStartTrackingTouch(slider: Slider) {} - - override fun onStopTrackingTouch(slider: Slider) { - if (selectedBatteryStyle < 3) { - Handler(Looper.getMainLooper()).postDelayed( - { SystemUtil.handleSystemUIRestart() }, - SWITCH_ANIMATION_DELAY - ) - } - } - }) - - // Hide percentage - bindingMiscSettings.hidePercentage.isSwitchChecked = - getBoolean(CUSTOM_BATTERY_HIDE_PERCENTAGE, false) - bindingMiscSettings.hidePercentage.setSwitchChangeListener { _: CompoundButton?, isSwitchChecked: Boolean -> - putBoolean(CUSTOM_BATTERY_HIDE_PERCENTAGE, isSwitchChecked) - updateLayoutVisibility() - } - - // Inside percentage - bindingMiscSettings.insidePercentage.isSwitchChecked = - getBoolean(CUSTOM_BATTERY_INSIDE_PERCENTAGE, false) - bindingMiscSettings.insidePercentage.setSwitchChangeListener { _: CompoundButton?, isSwitchChecked: Boolean -> - putBoolean( - CUSTOM_BATTERY_INSIDE_PERCENTAGE, - isSwitchChecked - ) - } - - // Hide battery - bindingMiscSettings.hideBattery.isSwitchChecked = - getBoolean(CUSTOM_BATTERY_HIDE_BATTERY, false) - bindingMiscSettings.hideBattery.setSwitchChangeListener { _: CompoundButton?, isSwitchChecked: Boolean -> - putBoolean(CUSTOM_BATTERY_HIDE_BATTERY, isSwitchChecked) - updateLayoutVisibility() - } - - // Reverse layout - bindingMiscSettings.reverseLayout.isSwitchChecked = - getBoolean(CUSTOM_BATTERY_SWAP_PERCENTAGE, false) - bindingMiscSettings.reverseLayout.setSwitchChangeListener { _: CompoundButton?, isSwitchChecked: Boolean -> - putBoolean( - CUSTOM_BATTERY_SWAP_PERCENTAGE, - isSwitchChecked - ) - } - - // Rotate layout - bindingMiscSettings.rotateLayout.isSwitchChecked = - getBoolean(CUSTOM_BATTERY_LAYOUT_REVERSE, false) - bindingMiscSettings.rotateLayout.setSwitchChangeListener { _: CompoundButton?, isSwitchChecked: Boolean -> - putBoolean( - CUSTOM_BATTERY_LAYOUT_REVERSE, - isSwitchChecked - ) - } - } - - private fun customColors() { - // Perimeter alpha - bindingCustomColors.perimeterAlpha.isSwitchChecked = - getBoolean(CUSTOM_BATTERY_PERIMETER_ALPHA, false) - bindingCustomColors.perimeterAlpha.setSwitchChangeListener { _: CompoundButton?, isSwitchChecked: Boolean -> - putBoolean( - CUSTOM_BATTERY_PERIMETER_ALPHA, - isSwitchChecked - ) - } - - // Fill alpha - bindingCustomColors.fillAlpha.isSwitchChecked = - getBoolean(CUSTOM_BATTERY_FILL_ALPHA, false) - bindingCustomColors.fillAlpha.setSwitchChangeListener { _: CompoundButton?, isSwitchChecked: Boolean -> - putBoolean( - CUSTOM_BATTERY_FILL_ALPHA, - isSwitchChecked - ) - } - - // Rainbow color - bindingCustomColors.rainbowColor.isSwitchChecked = - getBoolean(CUSTOM_BATTERY_RAINBOW_FILL_COLOR, false) - bindingCustomColors.rainbowColor.setSwitchChangeListener { _: CompoundButton?, isSwitchChecked: Boolean -> - putBoolean( - CUSTOM_BATTERY_RAINBOW_FILL_COLOR, - isSwitchChecked - ) - } - - // Blend color - bindingCustomColors.blendColor.isSwitchChecked = - getBoolean(CUSTOM_BATTERY_BLEND_COLOR, false) - bindingCustomColors.blendColor.setSwitchChangeListener { _: CompoundButton?, isSwitchChecked: Boolean -> - putBoolean(CUSTOM_BATTERY_BLEND_COLOR, isSwitchChecked) - updateLayoutVisibility() - } - - // Fill color picker - bindingCustomColors.fillColor.setColorPickerListener( - activity = requireActivity(), - defaultColor = getInt(CUSTOM_BATTERY_FILL_COLOR, Color.BLACK), - showPresets = true, - showAlphaSlider = false, - showColorShades = true - ) - bindingCustomColors.fillColor.setOnColorSelectedListener { color: Int -> - putInt( - CUSTOM_BATTERY_FILL_COLOR, - color - ) - } - - // Fill gradient color picker - bindingCustomColors.fillGradientColor.setColorPickerListener( - activity = requireActivity(), - defaultColor = getInt(CUSTOM_BATTERY_FILL_GRAD_COLOR, Color.BLACK), - showPresets = true, - showAlphaSlider = false, - showColorShades = true - ) - bindingCustomColors.fillGradientColor.setOnColorSelectedListener { color: Int -> - putInt( - CUSTOM_BATTERY_FILL_GRAD_COLOR, - color - ) - } - - // Charging fill color picker - bindingCustomColors.chargingFillColor.setColorPickerListener( - activity = requireActivity(), - defaultColor = getInt(CUSTOM_BATTERY_CHARGING_COLOR, Color.BLACK), - showPresets = true, - showAlphaSlider = false, - showColorShades = true - ) - bindingCustomColors.chargingFillColor.setOnColorSelectedListener { color: Int -> - putInt( - CUSTOM_BATTERY_CHARGING_COLOR, - color - ) - } - - // Power save fill color picker - bindingCustomColors.powersaveFillColor.setColorPickerListener( - activity = requireActivity(), - defaultColor = getInt(CUSTOM_BATTERY_POWERSAVE_FILL_COLOR, Color.BLACK), - showPresets = true, - showAlphaSlider = false, - showColorShades = true - ) - bindingCustomColors.powersaveFillColor.setOnColorSelectedListener { color: Int -> - putInt( - CUSTOM_BATTERY_POWERSAVE_FILL_COLOR, - color - ) - } - - // Power save icon color picker - bindingCustomColors.powersaveIconColor.setColorPickerListener( - activity = requireActivity(), - defaultColor = getInt(CUSTOM_BATTERY_POWERSAVE_INDICATOR_COLOR, Color.BLACK), - showPresets = true, - showAlphaSlider = false, - showColorShades = true - ) - bindingCustomColors.powersaveIconColor.setOnColorSelectedListener { color: Int -> - putInt( - CUSTOM_BATTERY_POWERSAVE_INDICATOR_COLOR, - color - ) - } - } - - private fun customDimension() { - // Custom dimensions - bindingCustomDimens.customDimensions.isSwitchChecked = - getBoolean(CUSTOM_BATTERY_DIMENSION, false) - bindingCustomDimens.customDimensions.setSwitchChangeListener { _: CompoundButton?, isSwitchChecked: Boolean -> - putBoolean(CUSTOM_BATTERY_DIMENSION, isSwitchChecked) - updateLayoutVisibility() - } - - // Battery margin left - bindingCustomDimens.batteryMarginLeft.sliderValue = - getInt(CUSTOM_BATTERY_MARGIN_LEFT, 4) - bindingCustomDimens.batteryMarginLeft.setOnSliderChangeListener { slider: Slider, _: Float, _: Boolean -> - putInt( - CUSTOM_BATTERY_MARGIN_LEFT, - slider.value.toInt() - ) - } - - // Battery margin right - bindingCustomDimens.batteryMarginRight.sliderValue = - getInt(CUSTOM_BATTERY_MARGIN_RIGHT, 4) - bindingCustomDimens.batteryMarginRight.setOnSliderChangeListener { slider: Slider, _: Float, _: Boolean -> - putInt( - CUSTOM_BATTERY_MARGIN_RIGHT, - slider.value.toInt() - ) - } - - // Battery margin top - bindingCustomDimens.batteryMarginTop.sliderValue = - getInt(CUSTOM_BATTERY_MARGIN_TOP, 0) - bindingCustomDimens.batteryMarginTop.setOnSliderChangeListener { slider: Slider, _: Float, _: Boolean -> - putInt( - CUSTOM_BATTERY_MARGIN_TOP, - slider.value.toInt() - ) - } - - // Battery margin bottom - bindingCustomDimens.batteryMarginBottom.sliderValue = - getInt(CUSTOM_BATTERY_MARGIN_BOTTOM, 0) - bindingCustomDimens.batteryMarginBottom.setOnSliderChangeListener { slider: Slider, _: Float, _: Boolean -> - putInt( - CUSTOM_BATTERY_MARGIN_BOTTOM, - slider.value.toInt() - ) - } - } - - private fun customChargingIcon() { - // Enable charging icon - bindingChargingIcon.enableChargingIcon.isSwitchChecked = - getBoolean(CUSTOM_BATTERY_CHARGING_ICON_SWITCH, false) - bindingChargingIcon.enableChargingIcon.setSwitchChangeListener { _: CompoundButton?, isSwitchChecked: Boolean -> - putBoolean(CUSTOM_BATTERY_CHARGING_ICON_SWITCH, isSwitchChecked) - updateLayoutVisibility() - } - - // Charging icon style - bindingChargingIcon.chargingIconStyle.setSelectedIndex( - getInt( - CUSTOM_BATTERY_CHARGING_ICON_STYLE, - 0 - ) - ) - bindingChargingIcon.chargingIconStyle.setDrawable(getChargingIcons(requireContext())) - bindingChargingIcon.chargingIconStyle.setCurrentValue( - getInt( - CUSTOM_BATTERY_CHARGING_ICON_STYLE, - 0 - ).toString() - ) - bindingChargingIcon.chargingIconStyle.setOnItemClickListener { index: Int -> - bindingChargingIcon.chargingIconStyle.setCurrentValue(index.toString()) - putInt(CUSTOM_BATTERY_CHARGING_ICON_STYLE, index) - } - - // Charging icon margin left - bindingChargingIcon.chargingIconMarginLeft.sliderValue = - getInt(CUSTOM_BATTERY_CHARGING_ICON_MARGIN_LEFT, 1) - bindingChargingIcon.chargingIconMarginLeft.setOnSliderChangeListener { slider: Slider, _: Float, _: Boolean -> - putInt( - CUSTOM_BATTERY_CHARGING_ICON_MARGIN_LEFT, - slider.value.toInt() - ) - } - - // Charging icon margin right - bindingChargingIcon.chargingIconMarginRight.sliderValue = - getInt(CUSTOM_BATTERY_CHARGING_ICON_MARGIN_RIGHT, 0) - bindingChargingIcon.chargingIconMarginRight.setOnSliderChangeListener { slider: Slider, _: Float, _: Boolean -> - putInt( - CUSTOM_BATTERY_CHARGING_ICON_MARGIN_RIGHT, - slider.value.toInt() - ) - } - - // Charging icon size - bindingChargingIcon.chargingIconSize.sliderValue = - getInt(CUSTOM_BATTERY_CHARGING_ICON_WIDTH_HEIGHT, 14) - bindingChargingIcon.chargingIconSize.setOnSliderChangeListener { slider: Slider, _: Float, _: Boolean -> - putInt( - CUSTOM_BATTERY_CHARGING_ICON_WIDTH_HEIGHT, - slider.value.toInt() - ) - } - } - - private fun updateLayoutVisibility() { - val selectedIndex = selectedBatteryStyle - val batteryStyles = listOf(*resources.getStringArray(R.array.custom_battery_style)) - val showAdvancedCustomizations = - selectedIndex >= batteryStyles.indexOf(getString(R.string.battery_landscape_battery_a)) && - selectedIndex <= batteryStyles.indexOf(getString(R.string.battery_landscape_battery_o)) - val showColorPickers = bindingCustomColors.blendColor.isSwitchChecked - val showRainbowBattery = - batteryStyles.indexOf(getString(R.string.battery_landscape_battery_i)) == selectedIndex || - batteryStyles.indexOf(getString(R.string.battery_landscape_battery_j)) == selectedIndex - val showCommonCustomizations = selectedIndex != 0 - val showBatteryDimensions = - selectedIndex > 2 && bindingCustomDimens.customDimensions.isSwitchChecked - val showPercentage = - selectedIndex != BATTERY_STYLE_DEFAULT && - selectedIndex != BATTERY_STYLE_DEFAULT_LANDSCAPE && - selectedIndex != BATTERY_STYLE_DEFAULT_RLANDSCAPE && - selectedIndex != BATTERY_STYLE_LANDSCAPE_IOS_16 && - selectedIndex != BATTERY_STYLE_LANDSCAPE_BATTERYL && - selectedIndex != BATTERY_STYLE_LANDSCAPE_BATTERYM - val showInsidePercentage = - showPercentage && !bindingMiscSettings.hidePercentage.isSwitchChecked - val showChargingIconCustomization = - selectedIndex > 2 && bindingChargingIcon.enableChargingIcon.isSwitchChecked - val showReverseLayout = selectedIndex > 2 && showInsidePercentage - val circleBattery = selectedIndex == BATTERY_STYLE_CIRCLE || - selectedIndex == BATTERY_STYLE_DOTTED_CIRCLE || - selectedIndex == BATTERY_STYLE_FILLED_CIRCLE - val visibilityAdvanced = if (showAdvancedCustomizations) View.VISIBLE else View.GONE - val visibilityBlendColor = - if (showAdvancedCustomizations || circleBattery) View.VISIBLE else View.GONE - val visibilityColorPickers = - if ((showAdvancedCustomizations || circleBattery) && showColorPickers) View.VISIBLE else View.GONE - val visibilityRainbow = - if ((showAdvancedCustomizations || circleBattery) && showRainbowBattery) View.VISIBLE else View.GONE - val visibilityWh = if (selectedIndex > 2) View.VISIBLE else View.GONE - val visibilityDimensions = if (showBatteryDimensions) View.VISIBLE else View.GONE - val visibilityPercentage = if (showPercentage) View.VISIBLE else View.GONE - val visibilityInsidePercentage = if (showInsidePercentage) View.VISIBLE else View.GONE - val visibilityReverseLayout = if (showReverseLayout) View.VISIBLE else View.GONE - val visibilityChargingIconSwitch = if (selectedIndex > 2) View.VISIBLE else View.GONE - val visibilityChargingIconCustomization = - if (showChargingIconCustomization) View.VISIBLE else View.GONE - - // Misc settings - bindingMiscSettings.batteryWidth.setEnabled(showCommonCustomizations) - bindingMiscSettings.batteryHeight.setEnabled(showCommonCustomizations) - bindingMiscSettings.hidePercentage.visibility = visibilityPercentage - bindingMiscSettings.insidePercentage.visibility = visibilityInsidePercentage - bindingMiscSettings.hideBattery.visibility = visibilityChargingIconSwitch - bindingMiscSettings.reverseLayout.visibility = visibilityReverseLayout - bindingMiscSettings.rotateLayout.visibility = visibilityAdvanced - - // Custom colors - bindingCustomColors.perimeterAlpha.visibility = visibilityAdvanced - bindingCustomColors.fillAlpha.visibility = visibilityAdvanced - bindingCustomColors.rainbowColor.visibility = visibilityRainbow - bindingCustomColors.blendColor.visibility = visibilityBlendColor - bindingCustomColors.colorPickers.visibility = visibilityColorPickers - - // Custom dimensions - bindingCustomDimens.customDimensions.visibility = visibilityWh - bindingCustomDimens.batteryMarginLeft.visibility = visibilityDimensions - bindingCustomDimens.batteryMarginTop.visibility = visibilityDimensions - bindingCustomDimens.batteryMarginRight.visibility = visibilityDimensions - bindingCustomDimens.batteryMarginBottom.visibility = visibilityDimensions - - // Custom charging icon - bindingChargingIcon.enableChargingIcon.visibility = visibilityChargingIconSwitch - bindingChargingIcon.chargingIconCustContainer.visibility = - visibilityChargingIconCustomization - } - - companion object { - private var selectedBatteryStyle = 0 - } -} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/XposedDepthWallpaper.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/XposedDepthWallpaper.kt deleted file mode 100644 index 17ae285c0..000000000 --- a/app/src/main/java/com/drdisagree/iconify/ui/fragments/XposedDepthWallpaper.kt +++ /dev/null @@ -1,239 +0,0 @@ -package com.drdisagree.iconify.ui.fragments - -import android.app.Activity -import android.os.Bundle -import android.os.Handler -import android.os.Looper -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.CompoundButton -import android.widget.Toast -import androidx.activity.result.ActivityResult -import androidx.activity.result.contract.ActivityResultContracts -import com.drdisagree.iconify.Iconify.Companion.appContext -import com.drdisagree.iconify.Iconify.Companion.appContextLocale -import com.drdisagree.iconify.R -import com.drdisagree.iconify.common.Const.SWITCH_ANIMATION_DELAY -import com.drdisagree.iconify.common.Preferences.DEPTH_WALLPAPER_BACKGROUND_MOVEMENT_MULTIPLIER -import com.drdisagree.iconify.common.Preferences.DEPTH_WALLPAPER_CHANGED -import com.drdisagree.iconify.common.Preferences.DEPTH_WALLPAPER_FADE_ANIMATION -import com.drdisagree.iconify.common.Preferences.DEPTH_WALLPAPER_FOREGROUND_ALPHA -import com.drdisagree.iconify.common.Preferences.DEPTH_WALLPAPER_FOREGROUND_MOVEMENT_MULTIPLIER -import com.drdisagree.iconify.common.Preferences.DEPTH_WALLPAPER_PARALLAX_EFFECT -import com.drdisagree.iconify.common.Preferences.DEPTH_WALLPAPER_SWITCH -import com.drdisagree.iconify.common.Resources.DEPTH_WALL_BG_DIR -import com.drdisagree.iconify.common.Resources.DEPTH_WALL_FG_DIR -import com.drdisagree.iconify.config.RPrefs -import com.drdisagree.iconify.config.RPrefs.getBoolean -import com.drdisagree.iconify.config.RPrefs.getInt -import com.drdisagree.iconify.config.RPrefs.putBoolean -import com.drdisagree.iconify.config.RPrefs.putInt -import com.drdisagree.iconify.databinding.FragmentXposedDepthWallpaperBinding -import com.drdisagree.iconify.ui.base.BaseFragment -import com.drdisagree.iconify.ui.utils.ViewHelper.setHeader -import com.drdisagree.iconify.utils.FileUtil.getRealPath -import com.drdisagree.iconify.utils.FileUtil.moveToIconifyHiddenDir -import com.drdisagree.iconify.utils.SystemUtil -import com.google.android.material.slider.Slider - -class XposedDepthWallpaper : BaseFragment() { - - private lateinit var binding: FragmentXposedDepthWallpaperBinding - - private var intentForegroundImage = registerForActivityResult( - ActivityResultContracts.StartActivityForResult() - ) { result: ActivityResult -> - if (result.resultCode == Activity.RESULT_OK) { - val data = result.data - val path = getRealPath(data) - - if (path != null && moveToIconifyHiddenDir(path, DEPTH_WALL_FG_DIR)) { - putBoolean( - DEPTH_WALLPAPER_CHANGED, - !binding.depthWallpaper.isSwitchChecked - ) - putBoolean( - DEPTH_WALLPAPER_CHANGED, - binding.depthWallpaper.isSwitchChecked - ) - - Toast.makeText( - appContext, - appContextLocale.resources.getString(R.string.toast_selected_successfully), - Toast.LENGTH_SHORT - ).show() - } else { - Toast.makeText( - appContext, - appContextLocale.resources.getString(R.string.toast_rename_file), - Toast.LENGTH_SHORT - ).show() - } - } - } - - private var intentBackgroundImage = registerForActivityResult( - ActivityResultContracts.StartActivityForResult() - ) { result: ActivityResult -> - if (result.resultCode == Activity.RESULT_OK) { - val data = result.data - val path = getRealPath(data) - - if (path != null && moveToIconifyHiddenDir(path, DEPTH_WALL_BG_DIR)) { - putBoolean( - DEPTH_WALLPAPER_CHANGED, - !binding.depthWallpaper.isSwitchChecked - ) - putBoolean( - DEPTH_WALLPAPER_CHANGED, - binding.depthWallpaper.isSwitchChecked - ) - - Toast.makeText( - appContext, - appContextLocale.resources.getString(R.string.toast_selected_successfully), - Toast.LENGTH_SHORT - ).show() - } else { - Toast.makeText( - appContext, - appContextLocale.resources.getString(R.string.toast_rename_file), - Toast.LENGTH_SHORT - ).show() - } - } - } - - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View { - binding = FragmentXposedDepthWallpaperBinding.inflate(inflater, container, false) - val view: View = binding.getRoot() - - // Header - setHeader( - requireContext(), - getParentFragmentManager(), - binding.header.toolbar, - R.string.activity_title_depth_wallpaper - ) - - // Enable depth wallpaper - binding.depthWallpaper.isSwitchChecked = getBoolean(DEPTH_WALLPAPER_SWITCH, false) - binding.depthWallpaper.setSwitchChangeListener { _: CompoundButton?, isSwitchChecked: Boolean -> - putBoolean(DEPTH_WALLPAPER_SWITCH, isSwitchChecked) - updateEnabledState() - - Handler(Looper.getMainLooper()).postDelayed( - { SystemUtil.handleSystemUIRestart() }, - SWITCH_ANIMATION_DELAY - ) - } - - // Foreground image - binding.foregroundImage.setEnabled(binding.depthWallpaper.isSwitchChecked) - binding.foregroundImage.setActivityResultLauncher(intentForegroundImage) - - // Background image - binding.backgroundImage.setEnabled(binding.depthWallpaper.isSwitchChecked) - binding.backgroundImage.setActivityResultLauncher(intentBackgroundImage) - - // Foreground alpha - binding.foregroundAlpha.setEnabled(binding.depthWallpaper.isSwitchChecked) - binding.foregroundAlpha.sliderValue = getInt(DEPTH_WALLPAPER_FOREGROUND_ALPHA, 80) - binding.foregroundAlpha.setOnSliderTouchListener(object : Slider.OnSliderTouchListener { - override fun onStartTrackingTouch(slider: Slider) {} - - override fun onStopTrackingTouch(slider: Slider) { - putInt(DEPTH_WALLPAPER_FOREGROUND_ALPHA, slider.value.toInt()) - } - }) - - // Fade animation - binding.wallpaperFadeAnimation.setEnabled(binding.depthWallpaper.isSwitchChecked) - binding.wallpaperFadeAnimation.isSwitchChecked = - getBoolean(DEPTH_WALLPAPER_FADE_ANIMATION, false) - binding.wallpaperFadeAnimation.setSwitchChangeListener { _: CompoundButton?, isSwitchChecked: Boolean -> - putBoolean( - DEPTH_WALLPAPER_FADE_ANIMATION, - isSwitchChecked - ) - } - - // Parallax effect - binding.parallaxEffect.setEnabled(binding.depthWallpaper.isSwitchChecked) - binding.parallaxEffect.isSwitchChecked = getBoolean(DEPTH_WALLPAPER_PARALLAX_EFFECT, false) - binding.parallaxEffect.setSwitchChangeListener { _: CompoundButton?, isSwitchChecked: Boolean -> - putBoolean(DEPTH_WALLPAPER_PARALLAX_EFFECT, isSwitchChecked) - updateEnabledState() - } - - // Foreground sensitivity - binding.foregroundSensitivity.sliderValue = RPrefs.getFloat( - DEPTH_WALLPAPER_FOREGROUND_MOVEMENT_MULTIPLIER, - 3.0f - ).toInt() - binding.foregroundSensitivity.setOnSliderTouchListener(object : - Slider.OnSliderTouchListener { - override fun onStartTrackingTouch(slider: Slider) {} - - override fun onStopTrackingTouch(slider: Slider) { - RPrefs.putFloat(DEPTH_WALLPAPER_FOREGROUND_MOVEMENT_MULTIPLIER, slider.value) - } - }) - binding.foregroundSensitivity.setResetClickListener { - RPrefs.clearPref(DEPTH_WALLPAPER_FOREGROUND_MOVEMENT_MULTIPLIER) - true - } - - // Background sensitivity - binding.backgroundSensitivity.sliderValue = RPrefs.getFloat( - DEPTH_WALLPAPER_BACKGROUND_MOVEMENT_MULTIPLIER, - 1.0f - ).toInt() - binding.backgroundSensitivity.setOnSliderTouchListener(object : - Slider.OnSliderTouchListener { - override fun onStartTrackingTouch(slider: Slider) {} - - override fun onStopTrackingTouch(slider: Slider) { - RPrefs.putFloat(DEPTH_WALLPAPER_BACKGROUND_MOVEMENT_MULTIPLIER, slider.value) - } - }) - binding.backgroundSensitivity.setResetClickListener { - RPrefs.clearPref(DEPTH_WALLPAPER_BACKGROUND_MOVEMENT_MULTIPLIER) - true - } - - updateEnabledState() - - return view - } - - private fun updateEnabledState() { - val isDepthWallpaperEnabled = binding.depthWallpaper.isSwitchChecked - - binding.wallpaperFadeAnimation.setEnabled(isDepthWallpaperEnabled) - binding.foregroundImage.setEnabled(isDepthWallpaperEnabled) - binding.backgroundImage.setEnabled(isDepthWallpaperEnabled) - binding.foregroundAlpha.setEnabled(isDepthWallpaperEnabled) - binding.parallaxEffect.setEnabled(isDepthWallpaperEnabled) - binding.foregroundSensitivity.setEnabled(isDepthWallpaperEnabled) - binding.backgroundSensitivity.setEnabled(isDepthWallpaperEnabled) - - val isParallaxEffectEnabled = binding.parallaxEffect.isSwitchChecked - - binding.backgroundSensitivity.visibility = if (isParallaxEffectEnabled) { - View.VISIBLE - } else { - View.GONE - } - binding.foregroundSensitivity.visibility = if (isParallaxEffectEnabled) { - View.VISIBLE - } else { - View.GONE - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/XposedHeaderClock.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/XposedHeaderClock.kt deleted file mode 100644 index 20c939d37..000000000 --- a/app/src/main/java/com/drdisagree/iconify/ui/fragments/XposedHeaderClock.kt +++ /dev/null @@ -1,410 +0,0 @@ -package com.drdisagree.iconify.ui.fragments - -import android.annotation.SuppressLint -import android.app.Activity -import android.graphics.Color -import android.os.Bundle -import android.os.Handler -import android.os.Looper -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.CompoundButton -import android.widget.Toast -import androidx.activity.result.ActivityResult -import androidx.activity.result.contract.ActivityResultContracts -import androidx.core.content.ContextCompat -import androidx.recyclerview.widget.LinearSnapHelper -import androidx.recyclerview.widget.RecyclerView -import androidx.recyclerview.widget.SnapHelper -import com.drdisagree.iconify.BuildConfig -import com.drdisagree.iconify.Iconify.Companion.appContext -import com.drdisagree.iconify.Iconify.Companion.appContextLocale -import com.drdisagree.iconify.R -import com.drdisagree.iconify.common.Const.SWITCH_ANIMATION_DELAY -import com.drdisagree.iconify.common.Preferences.HEADER_CLOCK_CENTERED -import com.drdisagree.iconify.common.Preferences.HEADER_CLOCK_COLOR_CODE_ACCENT1 -import com.drdisagree.iconify.common.Preferences.HEADER_CLOCK_COLOR_CODE_ACCENT2 -import com.drdisagree.iconify.common.Preferences.HEADER_CLOCK_COLOR_CODE_ACCENT3 -import com.drdisagree.iconify.common.Preferences.HEADER_CLOCK_COLOR_CODE_TEXT1 -import com.drdisagree.iconify.common.Preferences.HEADER_CLOCK_COLOR_CODE_TEXT2 -import com.drdisagree.iconify.common.Preferences.HEADER_CLOCK_COLOR_SWITCH -import com.drdisagree.iconify.common.Preferences.HEADER_CLOCK_FONT_SWITCH -import com.drdisagree.iconify.common.Preferences.HEADER_CLOCK_FONT_TEXT_SCALING -import com.drdisagree.iconify.common.Preferences.HEADER_CLOCK_LANDSCAPE_SWITCH -import com.drdisagree.iconify.common.Preferences.HEADER_CLOCK_SIDEMARGIN -import com.drdisagree.iconify.common.Preferences.HEADER_CLOCK_STYLE -import com.drdisagree.iconify.common.Preferences.HEADER_CLOCK_SWITCH -import com.drdisagree.iconify.common.Preferences.HEADER_CLOCK_TOPMARGIN -import com.drdisagree.iconify.common.Resources.HEADER_CLOCK_FONT_DIR -import com.drdisagree.iconify.common.Resources.HEADER_CLOCK_LAYOUT -import com.drdisagree.iconify.config.RPrefs.clearPref -import com.drdisagree.iconify.config.RPrefs.clearPrefs -import com.drdisagree.iconify.config.RPrefs.getBoolean -import com.drdisagree.iconify.config.RPrefs.getInt -import com.drdisagree.iconify.config.RPrefs.putBoolean -import com.drdisagree.iconify.config.RPrefs.putInt -import com.drdisagree.iconify.databinding.FragmentXposedHeaderClockBinding -import com.drdisagree.iconify.ui.adapters.ClockPreviewAdapter -import com.drdisagree.iconify.ui.base.BaseFragment -import com.drdisagree.iconify.ui.models.ClockModel -import com.drdisagree.iconify.ui.utils.CarouselLayoutManager -import com.drdisagree.iconify.ui.utils.ViewHelper.setHeader -import com.drdisagree.iconify.utils.FileUtil.getRealPath -import com.drdisagree.iconify.utils.FileUtil.moveToIconifyHiddenDir -import com.drdisagree.iconify.utils.SystemUtil -import com.google.android.material.slider.Slider - -class XposedHeaderClock : BaseFragment() { - - private lateinit var binding: FragmentXposedHeaderClockBinding - private var totalClocks: Int = 1 - - private var startActivityIntent = registerForActivityResult( - ActivityResultContracts.StartActivityForResult() - ) { result: ActivityResult -> - if (result.resultCode == Activity.RESULT_OK) { - val data = result.data - val path = getRealPath(data) - - if (path != null && moveToIconifyHiddenDir(path, HEADER_CLOCK_FONT_DIR)) { - binding.headerClockFont.setEnableButtonVisibility(View.VISIBLE) - } else { - Toast.makeText( - appContext, - appContextLocale.resources.getString(R.string.toast_rename_file), - Toast.LENGTH_SHORT - ).show() - } - } - } - - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View { - binding = FragmentXposedHeaderClockBinding.inflate(inflater, container, false) - val view: View = binding.getRoot() - - // Header - setHeader( - requireContext(), - getParentFragmentManager(), - binding.header.toolbar, - R.string.activity_title_header_clock - ) - - // Enable header clock - binding.enableHeaderClock.isSwitchChecked = getBoolean(HEADER_CLOCK_SWITCH, false) - binding.enableHeaderClock.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> - putBoolean(HEADER_CLOCK_SWITCH, isChecked) - updateEnabled(isChecked) - - Handler(Looper.getMainLooper()).postDelayed( - { SystemUtil.handleSystemUIRestart() }, - SWITCH_ANIMATION_DELAY - ) - } - updateEnabled(getBoolean(HEADER_CLOCK_SWITCH, false)) - - // Header clock style - val snapHelper: SnapHelper = LinearSnapHelper() - val carouselLayoutManager = CarouselLayoutManager( - requireContext(), - RecyclerView.HORIZONTAL, - false - ) - carouselLayoutManager.setMinifyDistance(0.8f) - - binding.rvHeaderClockPreview.setLayoutManager(carouselLayoutManager) - binding.rvHeaderClockPreview.setAdapter(initHeaderClockStyles()) - binding.rvHeaderClockPreview.setHasFixedSize(true) - snapHelper.attachToRecyclerView(binding.rvHeaderClockPreview) - - // if index exceeds limit, set to highest available - var headerClockStyle = getInt(HEADER_CLOCK_STYLE, 0) - if (headerClockStyle >= totalClocks) { - headerClockStyle = totalClocks - 1 - putInt(HEADER_CLOCK_STYLE, headerClockStyle) - } - binding.rvHeaderClockPreview.scrollToPosition(headerClockStyle) - - // Lockscreen clock font picker - binding.headerClockFont.setActivityResultLauncher(startActivityIntent) - binding.headerClockFont.setDisableButtonVisibility( - if (getBoolean( - HEADER_CLOCK_FONT_SWITCH, - false - ) - ) View.VISIBLE else View.GONE - ) - binding.headerClockFont.setEnableButtonOnClickListener { - putBoolean(HEADER_CLOCK_FONT_SWITCH, false) - putBoolean(HEADER_CLOCK_FONT_SWITCH, true) - - binding.headerClockFont.setEnableButtonVisibility(View.GONE) - binding.headerClockFont.setDisableButtonVisibility(View.VISIBLE) - } - binding.headerClockFont.setDisableButtonOnClickListener { - putBoolean(HEADER_CLOCK_FONT_SWITCH, false) - - binding.headerClockFont.setDisableButtonVisibility(View.GONE) - } - - // Custom clock color - binding.headerClockCustomColor.isSwitchChecked = - getBoolean(HEADER_CLOCK_COLOR_SWITCH, false) - binding.headerClockCustomColor.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> - putBoolean(HEADER_CLOCK_COLOR_SWITCH, isChecked) - - clearPrefs( - HEADER_CLOCK_COLOR_CODE_ACCENT1, - HEADER_CLOCK_COLOR_CODE_ACCENT2, - HEADER_CLOCK_COLOR_CODE_ACCENT3, - HEADER_CLOCK_COLOR_CODE_TEXT1, - HEADER_CLOCK_COLOR_CODE_TEXT2 - ) - - binding.headerClockColorPicker.visibility = if (isChecked) View.VISIBLE else View.GONE - - if (!isChecked) { - binding.colorPickerAccent1.previewColor = ContextCompat.getColor( - requireContext(), - android.R.color.system_accent1_300 - ) - binding.colorPickerAccent2.previewColor = ContextCompat.getColor( - requireContext(), - android.R.color.system_accent2_300 - ) - binding.colorPickerAccent3.previewColor = ContextCompat.getColor( - requireContext(), - android.R.color.system_accent3_300 - ) - - binding.colorPickerText1.previewColor = Color.WHITE - binding.colorPickerText2.previewColor = Color.BLACK - } - } - binding.headerClockColorPicker.visibility = - if (getBoolean(HEADER_CLOCK_COLOR_SWITCH, false)) { - View.VISIBLE - } else { - View.GONE - } - - // Clock color picker accent 1 - binding.colorPickerAccent1.setColorPickerListener( - activity = requireActivity(), - defaultColor = getInt( - HEADER_CLOCK_COLOR_CODE_ACCENT1, - ContextCompat.getColor( - requireContext(), - android.R.color.system_accent1_300 - ) - ), - showPresets = true, - showAlphaSlider = true, - showColorShades = true - ) - binding.colorPickerAccent1.setOnColorSelectedListener { color: Int -> - binding.colorPickerAccent1.previewColor = color - - putInt(HEADER_CLOCK_COLOR_CODE_ACCENT1, color) - } - - // Clock color picker accent 2 - binding.colorPickerAccent2.setColorPickerListener( - activity = requireActivity(), - defaultColor = getInt( - HEADER_CLOCK_COLOR_CODE_ACCENT2, - ContextCompat.getColor( - requireContext(), - android.R.color.system_accent2_300 - ) - ), - showPresets = true, - showAlphaSlider = true, - showColorShades = true - ) - binding.colorPickerAccent2.setOnColorSelectedListener { color: Int -> - binding.colorPickerAccent2.previewColor = color - - putInt(HEADER_CLOCK_COLOR_CODE_ACCENT2, color) - } - - // Clock color picker accent 3 - binding.colorPickerAccent3.setColorPickerListener( - activity = requireActivity(), - defaultColor = getInt( - HEADER_CLOCK_COLOR_CODE_ACCENT3, - ContextCompat.getColor( - requireContext(), - android.R.color.system_accent3_300 - ) - ), - showPresets = true, - showAlphaSlider = true, - showColorShades = true - ) - binding.colorPickerAccent3.setOnColorSelectedListener { color: Int -> - binding.colorPickerAccent3.previewColor = color - - putInt(HEADER_CLOCK_COLOR_CODE_ACCENT3, color) - } - - // Clock color picker text 1 - binding.colorPickerText1.setColorPickerListener( - activity = requireActivity(), - defaultColor = getInt( - HEADER_CLOCK_COLOR_CODE_TEXT1, - Color.WHITE - ), - showPresets = true, - showAlphaSlider = true, - showColorShades = true - ) - binding.colorPickerText1.setOnColorSelectedListener { color: Int -> - binding.colorPickerText1.previewColor = color - - putInt(HEADER_CLOCK_COLOR_CODE_TEXT1, color) - } - - // Clock color picker text 2 - binding.colorPickerText2.setColorPickerListener( - activity = requireActivity(), - defaultColor = getInt( - HEADER_CLOCK_COLOR_CODE_TEXT2, - Color.BLACK - ), - showPresets = true, - showAlphaSlider = true, - showColorShades = true - ) - binding.colorPickerText2.setOnColorSelectedListener { color: Int -> - binding.colorPickerText2.previewColor = color - - putInt(HEADER_CLOCK_COLOR_CODE_TEXT2, color) - } - - // Text Scaling - binding.headerClockTextscaling.sliderValue = - getInt(HEADER_CLOCK_FONT_TEXT_SCALING, 10) - binding.headerClockTextscaling.setOnSliderTouchListener(object : - Slider.OnSliderTouchListener { - override fun onStartTrackingTouch(slider: Slider) {} - - override fun onStopTrackingTouch(slider: Slider) { - putInt(HEADER_CLOCK_FONT_TEXT_SCALING, slider.value.toInt()) - } - }) - binding.headerClockTextscaling.setResetClickListener { - clearPref(HEADER_CLOCK_FONT_TEXT_SCALING) - - true - } - - // Header clock side margin - binding.headerClockSideMargin.sliderValue = getInt(HEADER_CLOCK_SIDEMARGIN, 0) - binding.headerClockSideMargin.setOnSliderTouchListener(object : - Slider.OnSliderTouchListener { - override fun onStartTrackingTouch(slider: Slider) {} - - override fun onStopTrackingTouch(slider: Slider) { - putInt(HEADER_CLOCK_SIDEMARGIN, slider.value.toInt()) - } - }) - - // Header clock top margin - binding.headerClockTopMargin.sliderValue = getInt(HEADER_CLOCK_TOPMARGIN, 8) - binding.headerClockTopMargin.setOnSliderTouchListener(object : - Slider.OnSliderTouchListener { - override fun onStartTrackingTouch(slider: Slider) {} - - override fun onStopTrackingTouch(slider: Slider) { - putInt(HEADER_CLOCK_TOPMARGIN, slider.value.toInt()) - } - }) - - // Center clock - binding.centerClock.isSwitchChecked = getBoolean(HEADER_CLOCK_CENTERED, false) - binding.centerClock.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> - putBoolean( - HEADER_CLOCK_CENTERED, - isChecked - ) - } - - // Hide in landscape - binding.hideHeaderClockLandscape.isSwitchChecked = - getBoolean(HEADER_CLOCK_LANDSCAPE_SWITCH, true) - binding.hideHeaderClockLandscape.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> - putBoolean( - HEADER_CLOCK_LANDSCAPE_SWITCH, - isChecked - ) - } - - return view - } - - @SuppressLint("DiscouragedApi") - private fun initHeaderClockStyles(): ClockPreviewAdapter { - val headerClock = ArrayList() - var maxIndex = 0 - - while (requireContext() - .resources - .getIdentifier( - HEADER_CLOCK_LAYOUT + maxIndex, - "layout", - BuildConfig.APPLICATION_ID - ) != 0 - ) { - maxIndex++ - } - - totalClocks = maxIndex - - for (i in 0 until maxIndex) { - headerClock.add( - ClockModel( - if (i == 0) { - requireContext().getString(R.string.clock_none) - } else { - requireContext().getString(R.string.clock_style_name, i) - }, - requireContext() - .resources - .getIdentifier( - HEADER_CLOCK_LAYOUT + i, - "layout", - BuildConfig.APPLICATION_ID - ) - ) - ) - } - - return ClockPreviewAdapter( - requireContext(), - headerClock, - HEADER_CLOCK_SWITCH, - HEADER_CLOCK_STYLE - ) - } - - private fun updateEnabled(enabled: Boolean) { - binding.headerClockFont.setEnabled(enabled) - binding.headerClockCustomColor.setEnabled(enabled) - binding.colorPickerAccent1.setEnabled(enabled) - binding.colorPickerAccent2.setEnabled(enabled) - binding.colorPickerAccent3.setEnabled(enabled) - binding.colorPickerText1.setEnabled(enabled) - binding.colorPickerText2.setEnabled(enabled) - binding.headerClockTextscaling.setEnabled(enabled) - binding.headerClockSideMargin.setEnabled(enabled) - binding.headerClockTopMargin.setEnabled(enabled) - binding.centerClock.setEnabled(enabled) - binding.hideHeaderClockLandscape.setEnabled(enabled) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/XposedHeaderImage.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/XposedHeaderImage.kt deleted file mode 100644 index 0acfad928..000000000 --- a/app/src/main/java/com/drdisagree/iconify/ui/fragments/XposedHeaderImage.kt +++ /dev/null @@ -1,158 +0,0 @@ -package com.drdisagree.iconify.ui.fragments - -import android.app.Activity -import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.CompoundButton -import android.widget.Toast -import androidx.activity.result.ActivityResult -import androidx.activity.result.contract.ActivityResultContracts -import com.drdisagree.iconify.Iconify.Companion.appContext -import com.drdisagree.iconify.R -import com.drdisagree.iconify.common.Preferences.HEADER_IMAGE_ALPHA -import com.drdisagree.iconify.common.Preferences.HEADER_IMAGE_BOTTOM_FADE_AMOUNT -import com.drdisagree.iconify.common.Preferences.HEADER_IMAGE_HEIGHT -import com.drdisagree.iconify.common.Preferences.HEADER_IMAGE_LANDSCAPE_SWITCH -import com.drdisagree.iconify.common.Preferences.HEADER_IMAGE_SWITCH -import com.drdisagree.iconify.common.Preferences.HEADER_IMAGE_ZOOMTOFIT -import com.drdisagree.iconify.common.Resources.HEADER_IMAGE_DIR -import com.drdisagree.iconify.config.RPrefs.getBoolean -import com.drdisagree.iconify.config.RPrefs.getInt -import com.drdisagree.iconify.config.RPrefs.putBoolean -import com.drdisagree.iconify.config.RPrefs.putInt -import com.drdisagree.iconify.databinding.FragmentXposedHeaderImageBinding -import com.drdisagree.iconify.ui.base.BaseFragment -import com.drdisagree.iconify.ui.utils.ViewHelper.setHeader -import com.drdisagree.iconify.utils.FileUtil.getRealPath -import com.drdisagree.iconify.utils.FileUtil.moveToIconifyHiddenDir -import com.google.android.material.slider.Slider - -class XposedHeaderImage : BaseFragment() { - - private lateinit var binding: FragmentXposedHeaderImageBinding - - private var startActivityIntent = registerForActivityResult( - ActivityResultContracts.StartActivityForResult() - ) { result: ActivityResult -> - if (result.resultCode == Activity.RESULT_OK) { - val data = result.data - val path = getRealPath(data) - - if (path != null && moveToIconifyHiddenDir(path, HEADER_IMAGE_DIR)) { - binding.headerImage.setEnableButtonVisibility(View.VISIBLE) - } else { - Toast.makeText( - appContext, - resources.getString(R.string.toast_rename_file), - Toast.LENGTH_SHORT - ).show() - } - } - } - - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View { - binding = FragmentXposedHeaderImageBinding.inflate(inflater, container, false) - val view: View = binding.getRoot() - - // Header - setHeader( - requireContext(), - getParentFragmentManager(), - binding.header.toolbar, - R.string.activity_title_header_image - ) - - // Header image picker - binding.headerImage.setActivityResultLauncher(startActivityIntent) - binding.headerImage.setEnableButtonOnClickListener { - putBoolean(HEADER_IMAGE_SWITCH, false) - putBoolean(HEADER_IMAGE_SWITCH, true) - - binding.headerImage.setEnableButtonVisibility(View.GONE) - binding.headerImage.setDisableButtonVisibility(View.VISIBLE) - - updateEnabledState() - } - - binding.headerImage.setDisableButtonVisibility( - if (getBoolean(HEADER_IMAGE_SWITCH, false)) { - View.VISIBLE - } else { - View.GONE - } - ) - - binding.headerImage.setDisableButtonOnClickListener { - putBoolean(HEADER_IMAGE_SWITCH, false) - - binding.headerImage.setDisableButtonVisibility(View.GONE) - - updateEnabledState() - } - - // Image height - binding.headerImageHeight.sliderValue = getInt(HEADER_IMAGE_HEIGHT, 140) - binding.headerImageHeight.setOnSliderTouchListener(object : Slider.OnSliderTouchListener { - override fun onStartTrackingTouch(slider: Slider) {} - - override fun onStopTrackingTouch(slider: Slider) { - putInt(HEADER_IMAGE_HEIGHT, slider.value.toInt()) - } - }) - - // Image alpha - binding.headerImageAlpha.sliderValue = getInt(HEADER_IMAGE_ALPHA, 100) - binding.headerImageAlpha.setOnSliderTouchListener(object : Slider.OnSliderTouchListener { - override fun onStartTrackingTouch(slider: Slider) {} - - override fun onStopTrackingTouch(slider: Slider) { - putInt(HEADER_IMAGE_ALPHA, slider.value.toInt()) - } - }) - - // Image bottom fade amount - binding.headerImageBottomFade.sliderValue = - getInt(HEADER_IMAGE_BOTTOM_FADE_AMOUNT, 40) - binding.headerImageBottomFade.setOnSliderTouchListener(object : - Slider.OnSliderTouchListener { - override fun onStartTrackingTouch(slider: Slider) {} - - override fun onStopTrackingTouch(slider: Slider) { - putInt(HEADER_IMAGE_BOTTOM_FADE_AMOUNT, slider.value.toInt()) - } - }) - - // Header image zoom to fit - binding.zoomToFit.isSwitchChecked = getBoolean(HEADER_IMAGE_ZOOMTOFIT, false) - binding.zoomToFit.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> - putBoolean(HEADER_IMAGE_ZOOMTOFIT, isChecked) - } - - // Header image hide in landscape - binding.hideInLandscape.isSwitchChecked = - getBoolean(HEADER_IMAGE_LANDSCAPE_SWITCH, true) - binding.hideInLandscape.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> - putBoolean(HEADER_IMAGE_LANDSCAPE_SWITCH, isChecked) - } - - updateEnabledState() - - return view - } - - private fun updateEnabledState() { - val enabled = getBoolean(HEADER_IMAGE_SWITCH, false) - - binding.headerImageHeight.setEnabled(enabled) - binding.headerImageAlpha.setEnabled(enabled) - binding.headerImageBottomFade.setEnabled(enabled) - binding.zoomToFit.setEnabled(enabled) - binding.hideInLandscape.setEnabled(enabled) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/XposedLockscreenClock.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/XposedLockscreenClock.kt deleted file mode 100644 index ded345c0d..000000000 --- a/app/src/main/java/com/drdisagree/iconify/ui/fragments/XposedLockscreenClock.kt +++ /dev/null @@ -1,407 +0,0 @@ -package com.drdisagree.iconify.ui.fragments - -import android.annotation.SuppressLint -import android.app.Activity -import android.graphics.Color -import android.os.Bundle -import android.os.Handler -import android.os.Looper -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.CompoundButton -import android.widget.Toast -import androidx.activity.result.ActivityResult -import androidx.activity.result.contract.ActivityResultContracts -import androidx.core.content.ContextCompat -import androidx.recyclerview.widget.LinearSnapHelper -import androidx.recyclerview.widget.RecyclerView -import androidx.recyclerview.widget.SnapHelper -import com.drdisagree.iconify.BuildConfig -import com.drdisagree.iconify.Iconify.Companion.appContext -import com.drdisagree.iconify.Iconify.Companion.appContextLocale -import com.drdisagree.iconify.R -import com.drdisagree.iconify.common.Const.SWITCH_ANIMATION_DELAY -import com.drdisagree.iconify.common.Dynamic.isAtleastA14 -import com.drdisagree.iconify.common.Preferences.LSCLOCK_BOTTOMMARGIN -import com.drdisagree.iconify.common.Preferences.LSCLOCK_COLOR_CODE_ACCENT1 -import com.drdisagree.iconify.common.Preferences.LSCLOCK_COLOR_CODE_ACCENT2 -import com.drdisagree.iconify.common.Preferences.LSCLOCK_COLOR_CODE_ACCENT3 -import com.drdisagree.iconify.common.Preferences.LSCLOCK_COLOR_CODE_TEXT1 -import com.drdisagree.iconify.common.Preferences.LSCLOCK_COLOR_CODE_TEXT2 -import com.drdisagree.iconify.common.Preferences.LSCLOCK_COLOR_SWITCH -import com.drdisagree.iconify.common.Preferences.LSCLOCK_FONT_LINEHEIGHT -import com.drdisagree.iconify.common.Preferences.LSCLOCK_FONT_SWITCH -import com.drdisagree.iconify.common.Preferences.LSCLOCK_FONT_TEXT_SCALING -import com.drdisagree.iconify.common.Preferences.LSCLOCK_STYLE -import com.drdisagree.iconify.common.Preferences.LSCLOCK_SWITCH -import com.drdisagree.iconify.common.Preferences.LSCLOCK_TOPMARGIN -import com.drdisagree.iconify.common.Resources.LOCKSCREEN_CLOCK_LAYOUT -import com.drdisagree.iconify.common.Resources.LSCLOCK_FONT_DIR -import com.drdisagree.iconify.config.RPrefs.clearPref -import com.drdisagree.iconify.config.RPrefs.clearPrefs -import com.drdisagree.iconify.config.RPrefs.getBoolean -import com.drdisagree.iconify.config.RPrefs.getInt -import com.drdisagree.iconify.config.RPrefs.putBoolean -import com.drdisagree.iconify.config.RPrefs.putInt -import com.drdisagree.iconify.databinding.FragmentXposedLockscreenClockBinding -import com.drdisagree.iconify.ui.adapters.ClockPreviewAdapter -import com.drdisagree.iconify.ui.base.BaseFragment -import com.drdisagree.iconify.ui.models.ClockModel -import com.drdisagree.iconify.ui.utils.CarouselLayoutManager -import com.drdisagree.iconify.ui.utils.ViewHelper.setHeader -import com.drdisagree.iconify.utils.FileUtil.getRealPath -import com.drdisagree.iconify.utils.FileUtil.moveToIconifyHiddenDir -import com.drdisagree.iconify.utils.SystemUtil -import com.google.android.material.slider.Slider -import com.topjohnwu.superuser.Shell - -class XposedLockscreenClock : BaseFragment() { - - private lateinit var binding: FragmentXposedLockscreenClockBinding - private var totalClocks: Int = 1 - - private var startActivityIntent = registerForActivityResult( - ActivityResultContracts.StartActivityForResult() - ) { result: ActivityResult -> - if (result.resultCode == Activity.RESULT_OK) { - val data = result.data - val path = getRealPath(data) - - if (path != null && moveToIconifyHiddenDir(path, LSCLOCK_FONT_DIR)) { - binding.lockscreenClockFont.setEnableButtonVisibility(View.VISIBLE) - } else { - Toast.makeText( - appContext, - appContextLocale.resources.getString(R.string.toast_rename_file), - Toast.LENGTH_SHORT - ).show() - } - } - } - - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View { - binding = FragmentXposedLockscreenClockBinding.inflate(inflater, container, false) - val view: View = binding.getRoot() - - // Header - setHeader( - requireContext(), - getParentFragmentManager(), - binding.header.toolbar, - R.string.activity_title_lockscreen_clock - ) - - // Enable lockscreen clock - binding.enableLockscreenClock.isSwitchChecked = getBoolean(LSCLOCK_SWITCH, false) - binding.enableLockscreenClock.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> - if (isChecked && isAtleastA14) { - Shell.cmd( - "adb shell settings put secure lock_screen_custom_clock_face default" - ).exec() - } - - putBoolean(LSCLOCK_SWITCH, isChecked) - - updateEnabled(isChecked) - - Handler(Looper.getMainLooper()).postDelayed( - { SystemUtil.handleSystemUIRestart() }, - SWITCH_ANIMATION_DELAY - ) - } - - updateEnabled(getBoolean(LSCLOCK_SWITCH, false)) - - // Lockscreen clock style - val snapHelper: SnapHelper = LinearSnapHelper() - val carouselLayoutManager = CarouselLayoutManager( - requireContext(), - RecyclerView.HORIZONTAL, - false - ) - carouselLayoutManager.setMinifyDistance(0.8f) - - binding.rvLockscreenClockPreview.setLayoutManager(carouselLayoutManager) - binding.rvLockscreenClockPreview.setAdapter(initLockscreenClockStyles()) - binding.rvLockscreenClockPreview.setHasFixedSize(true) - snapHelper.attachToRecyclerView(binding.rvLockscreenClockPreview) - - // if index exceeds limit, set to highest available - var lsClockStyle = getInt(LSCLOCK_STYLE, 0) - if (lsClockStyle >= totalClocks) { - lsClockStyle = totalClocks - 1 - putInt(LSCLOCK_STYLE, lsClockStyle) - } - binding.rvLockscreenClockPreview.scrollToPosition(lsClockStyle) - - // Lockscreen clock font picker - binding.lockscreenClockFont.setActivityResultLauncher(startActivityIntent) - binding.lockscreenClockFont.setDisableButtonVisibility( - if (getBoolean( - LSCLOCK_FONT_SWITCH, - false - ) - ) View.VISIBLE else View.GONE - ) - binding.lockscreenClockFont.setEnableButtonOnClickListener { - putBoolean(LSCLOCK_FONT_SWITCH, false) - putBoolean(LSCLOCK_FONT_SWITCH, true) - - binding.lockscreenClockFont.setEnableButtonVisibility(View.GONE) - binding.lockscreenClockFont.setDisableButtonVisibility(View.VISIBLE) - } - binding.lockscreenClockFont.setDisableButtonOnClickListener { - putBoolean(LSCLOCK_FONT_SWITCH, false) - - binding.lockscreenClockFont.setDisableButtonVisibility(View.GONE) - } - - // Custom clock color - binding.lsClockCustomColor.isSwitchChecked = - getBoolean(LSCLOCK_COLOR_SWITCH, false) - binding.lsClockCustomColor.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> - putBoolean(LSCLOCK_COLOR_SWITCH, isChecked) - - clearPrefs( - LSCLOCK_COLOR_CODE_ACCENT1, - LSCLOCK_COLOR_CODE_ACCENT2, - LSCLOCK_COLOR_CODE_ACCENT3, - LSCLOCK_COLOR_CODE_TEXT1, - LSCLOCK_COLOR_CODE_TEXT2 - ) - - binding.lsClockColorPicker.visibility = if (isChecked) View.VISIBLE else View.GONE - - if (!isChecked) { - binding.colorPickerAccent1.previewColor = ContextCompat.getColor( - requireContext(), - android.R.color.system_accent1_300 - ) - binding.colorPickerAccent2.previewColor = ContextCompat.getColor( - requireContext(), - android.R.color.system_accent2_300 - ) - binding.colorPickerAccent3.previewColor = ContextCompat.getColor( - requireContext(), - android.R.color.system_accent3_300 - ) - - binding.colorPickerText1.previewColor = Color.WHITE - binding.colorPickerText2.previewColor = Color.BLACK - } - } - binding.lsClockColorPicker.visibility = - if (getBoolean(LSCLOCK_COLOR_SWITCH, false)) View.VISIBLE else View.GONE - - // Clock color picker accent 1 - binding.colorPickerAccent1.setColorPickerListener( - activity = requireActivity(), - defaultColor = getInt( - LSCLOCK_COLOR_CODE_ACCENT1, - ContextCompat.getColor( - requireContext(), - android.R.color.system_accent1_300 - ) - ), - showPresets = true, - showAlphaSlider = true, - showColorShades = true - ) - binding.colorPickerAccent1.setOnColorSelectedListener { color: Int -> - binding.colorPickerAccent1.previewColor = color - - putInt(LSCLOCK_COLOR_CODE_ACCENT1, color) - } - - // Clock color picker accent 2 - binding.colorPickerAccent2.setColorPickerListener( - activity = requireActivity(), - defaultColor = getInt( - LSCLOCK_COLOR_CODE_ACCENT2, - ContextCompat.getColor( - requireContext(), - android.R.color.system_accent2_300 - ) - ), - showPresets = true, - showAlphaSlider = true, - showColorShades = true - ) - binding.colorPickerAccent2.setOnColorSelectedListener { color: Int -> - binding.colorPickerAccent2.previewColor = color - - putInt(LSCLOCK_COLOR_CODE_ACCENT2, color) - } - - // Clock color picker accent 3 - binding.colorPickerAccent3.setColorPickerListener( - activity = requireActivity(), - defaultColor = getInt( - LSCLOCK_COLOR_CODE_ACCENT3, - ContextCompat.getColor( - requireContext(), - android.R.color.system_accent3_300 - ) - ), - showPresets = true, - showAlphaSlider = true, - showColorShades = true - ) - binding.colorPickerAccent3.setOnColorSelectedListener { color: Int -> - binding.colorPickerAccent3.previewColor = color - - putInt(LSCLOCK_COLOR_CODE_ACCENT3, color) - } - - // Clock color picker text 1 - binding.colorPickerText1.setColorPickerListener( - activity = requireActivity(), - defaultColor = getInt( - LSCLOCK_COLOR_CODE_TEXT1, - Color.WHITE - ), - showPresets = true, - showAlphaSlider = true, - showColorShades = true - ) - binding.colorPickerText1.setOnColorSelectedListener { color: Int -> - binding.colorPickerText1.previewColor = color - - putInt(LSCLOCK_COLOR_CODE_TEXT1, color) - } - - // Clock color picker text 2 - binding.colorPickerText2.setColorPickerListener( - activity = requireActivity(), - defaultColor = getInt( - LSCLOCK_COLOR_CODE_TEXT2, - Color.BLACK - ), - showPresets = true, - showAlphaSlider = true, - showColorShades = true - ) - binding.colorPickerText2.setOnColorSelectedListener { color: Int -> - binding.colorPickerText2.previewColor = color - - putInt(LSCLOCK_COLOR_CODE_TEXT2, color) - } - - // Line height - binding.lsclockLineHeight.sliderValue = getInt(LSCLOCK_FONT_LINEHEIGHT, 0) - binding.lsclockLineHeight.setOnSliderTouchListener(object : Slider.OnSliderTouchListener { - override fun onStartTrackingTouch(slider: Slider) {} - - override fun onStopTrackingTouch(slider: Slider) { - putInt(LSCLOCK_FONT_LINEHEIGHT, slider.value.toInt()) - } - }) - binding.lsclockLineHeight.setResetClickListener { - clearPref(LSCLOCK_FONT_LINEHEIGHT) - - true - } - - // Text Scaling - binding.lsClockTextscaling.sliderValue = getInt(LSCLOCK_FONT_TEXT_SCALING, 10) - binding.lsClockTextscaling.setOnSliderTouchListener(object : - Slider.OnSliderTouchListener { - override fun onStartTrackingTouch(slider: Slider) {} - override fun onStopTrackingTouch(slider: Slider) { - putInt(LSCLOCK_FONT_TEXT_SCALING, slider.value.toInt()) - } - }) - binding.lsClockTextscaling.setResetClickListener { - clearPref(LSCLOCK_FONT_TEXT_SCALING) - - true - } - - // Top margin - binding.lsclockTopMargin.sliderValue = getInt(LSCLOCK_TOPMARGIN, 100) - binding.lsclockTopMargin.setOnSliderTouchListener(object : Slider.OnSliderTouchListener { - override fun onStartTrackingTouch(slider: Slider) {} - - override fun onStopTrackingTouch(slider: Slider) { - putInt(LSCLOCK_TOPMARGIN, slider.value.toInt()) - } - }) - - // Bottom margin - binding.lsclockBottomMargin.sliderValue = getInt(LSCLOCK_BOTTOMMARGIN, 40) - binding.lsclockBottomMargin.setOnSliderTouchListener(object : - Slider.OnSliderTouchListener { - override fun onStartTrackingTouch(slider: Slider) {} - - override fun onStopTrackingTouch(slider: Slider) { - putInt(LSCLOCK_BOTTOMMARGIN, slider.value.toInt()) - } - }) - - return view - } - - @SuppressLint("DiscouragedApi") - private fun initLockscreenClockStyles(): ClockPreviewAdapter { - val lsClock = ArrayList() - var maxIndex = 0 - - while (requireContext() - .resources - .getIdentifier( - LOCKSCREEN_CLOCK_LAYOUT + maxIndex, - "layout", - BuildConfig.APPLICATION_ID - ) != 0 - ) { - maxIndex++ - } - - totalClocks = maxIndex - - for (i in 0 until maxIndex) { - lsClock.add( - ClockModel( - if (i == 0) { - requireContext().getString(R.string.clock_none) - } else { - requireContext().getString(R.string.clock_style_name, i) - }, - requireContext() - .resources - .getIdentifier( - LOCKSCREEN_CLOCK_LAYOUT + i, - "layout", - BuildConfig.APPLICATION_ID - ) - ) - ) - } - - return ClockPreviewAdapter( - requireContext(), - lsClock, - LSCLOCK_SWITCH, - LSCLOCK_STYLE - ) - } - - private fun updateEnabled(enabled: Boolean) { - binding.lockscreenClockFont.setEnabled(enabled) - binding.lsClockCustomColor.setEnabled(enabled) - binding.colorPickerAccent1.setEnabled(enabled) - binding.colorPickerAccent2.setEnabled(enabled) - binding.colorPickerAccent3.setEnabled(enabled) - binding.colorPickerText1.setEnabled(enabled) - binding.colorPickerText2.setEnabled(enabled) - binding.lsclockLineHeight.setEnabled(enabled) - binding.lsClockTextscaling.setEnabled(enabled) - binding.lsclockTopMargin.setEnabled(enabled) - binding.lsclockBottomMargin.setEnabled(enabled) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/XposedMenu.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/XposedMenu.kt deleted file mode 100644 index 0f5d4eaa2..000000000 --- a/app/src/main/java/com/drdisagree/iconify/ui/fragments/XposedMenu.kt +++ /dev/null @@ -1,539 +0,0 @@ -package com.drdisagree.iconify.ui.fragments - -import android.annotation.SuppressLint -import android.app.Activity -import android.content.BroadcastReceiver -import android.content.ComponentName -import android.content.Context -import android.content.DialogInterface -import android.content.Intent -import android.content.IntentFilter -import android.os.Build -import android.os.Bundle -import android.os.CountDownTimer -import android.os.Handler -import android.os.Looper -import android.util.Log -import android.view.LayoutInflater -import android.view.Menu -import android.view.MenuInflater -import android.view.MenuItem -import android.view.View -import android.view.ViewGroup -import android.widget.Toast -import androidx.activity.result.ActivityResult -import androidx.activity.result.contract.ActivityResultContracts -import androidx.appcompat.app.AppCompatActivity -import androidx.navigation.Navigation.findNavController -import com.drdisagree.iconify.Iconify.Companion.appContext -import com.drdisagree.iconify.Iconify.Companion.appContextLocale -import com.drdisagree.iconify.R -import com.drdisagree.iconify.common.Const.ACTION_HOOK_CHECK_REQUEST -import com.drdisagree.iconify.common.Const.ACTION_HOOK_CHECK_RESULT -import com.drdisagree.iconify.common.Preferences -import com.drdisagree.iconify.common.Preferences.SHOW_XPOSED_WARN -import com.drdisagree.iconify.config.Prefs -import com.drdisagree.iconify.config.RPrefs -import com.drdisagree.iconify.databinding.FragmentXposedMenuBinding -import com.drdisagree.iconify.ui.base.BaseFragment -import com.drdisagree.iconify.ui.widgets.MenuWidget -import com.drdisagree.iconify.utils.SystemUtil -import com.drdisagree.iconify.utils.SystemUtil.disableBlur -import com.drdisagree.iconify.utils.SystemUtil.hasStoragePermission -import com.drdisagree.iconify.utils.SystemUtil.requestStoragePermission -import com.drdisagree.iconify.utils.SystemUtil.restartSystemUI -import com.drdisagree.iconify.utils.extension.ObservableVariable -import com.drdisagree.iconify.utils.helper.ImportExport.exportSettings -import com.drdisagree.iconify.utils.helper.ImportExport.importSettings -import com.drdisagree.iconify.utils.overlay.FabricatedUtil.disableOverlays -import com.drdisagree.iconify.utils.overlay.OverlayUtil -import com.google.android.material.dialog.MaterialAlertDialogBuilder -import java.util.concurrent.Executors - -class XposedMenu : BaseFragment() { - - private lateinit var binding: FragmentXposedMenuBinding - - private val handler = Handler(Looper.getMainLooper()) - private var intentFilterHookedSystemUI = IntentFilter() - private var isHookSuccessful = false - - private val checkSystemUIHooked: Runnable = object : Runnable { - override fun run() { - checkXposedHooked() - handler.postDelayed(this, 1000) - } - } - - private val receiverHookedSystemui: BroadcastReceiver = object : BroadcastReceiver() { - override fun onReceive(context: Context, intent: Intent) { - if (intent.action == ACTION_HOOK_CHECK_RESULT) { - isHookSuccessful = true - isXposedHooked.setValue(true) - } - } - } - - private var startExportActivityIntent = registerForActivityResult( - ActivityResultContracts.StartActivityForResult() - ) { result1: ActivityResult -> - if (result1.resultCode == Activity.RESULT_OK) { - val data = result1.data ?: return@registerForActivityResult - - try { - exportSettings( - RPrefs.prefs, - requireContext().contentResolver.openOutputStream(data.data!!)!! - ) - - Toast.makeText( - requireContext(), - requireContext().resources.getString(R.string.toast_export_settings_successfull), - Toast.LENGTH_SHORT - ).show() - } catch (exception: Exception) { - Toast.makeText( - requireContext(), - requireContext().resources.getString(R.string.toast_error), - Toast.LENGTH_SHORT - ).show() - - Log.e("Settings", "Error exporting settings", exception) - } - } - } - - private var startImportActivityIntent = registerForActivityResult( - ActivityResultContracts.StartActivityForResult() - ) { result2: ActivityResult -> - if (result2.resultCode == Activity.RESULT_OK) { - val data = result2.data ?: return@registerForActivityResult - - MaterialAlertDialogBuilder(requireContext()) - .setTitle(requireContext().resources.getString(R.string.import_settings_confirmation_title)) - .setMessage(requireContext().resources.getString(R.string.import_settings_confirmation_desc)) - .setPositiveButton(requireContext().resources.getString(R.string.btn_positive)) { dialog: DialogInterface, _: Int -> - dialog.dismiss() - - Executors.newSingleThreadExecutor().execute { - try { - val success = importSettings( - RPrefs.prefs, - appContext.contentResolver.openInputStream(data.data!!)!!, - false - ) - - if (success) { - Handler(Looper.getMainLooper()).post { - Toast.makeText( - appContext, - appContext.resources.getString(R.string.toast_import_settings_successfull), - Toast.LENGTH_SHORT - ).show() - } - - restartSystemUI() - } else { - Handler(Looper.getMainLooper()).post { - Toast.makeText( - appContext, - appContext.resources.getString(R.string.toast_error), - Toast.LENGTH_SHORT - ).show() - } - } - } catch (exception: Exception) { - Handler(Looper.getMainLooper()).post { - Toast.makeText( - appContext, - appContext.resources.getString(R.string.toast_error), - Toast.LENGTH_SHORT - ).show() - - Log.e("Settings", "Error exporting settings", exception) - } - } - } - } - .setNegativeButton(requireContext().resources.getString(R.string.btn_negative)) { dialog: DialogInterface, _: Int -> - dialog.dismiss() - } - .show() - } - } - - @SuppressLint("UnspecifiedRegisterReceiverFlag") - @Suppress("deprecation") - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View { - binding = FragmentXposedMenuBinding.inflate(inflater, container, false) - val view: View = binding.getRoot() - - // Header - binding.header.toolbar.setTitle(resources.getString(R.string.activity_title_xposed_menu)) - (requireActivity() as AppCompatActivity).setSupportActionBar(binding.header.toolbar) - setHasOptionsMenu(true) - - if (!Preferences.isXposedOnlyMode) { - (requireActivity() as AppCompatActivity).supportActionBar - ?.setDisplayHomeAsUpEnabled(true) - (requireActivity() as AppCompatActivity).supportActionBar - ?.setDisplayShowHomeEnabled(true) - binding.header.toolbar.setNavigationOnClickListener { - findNavController(view).popBackStack() - } - } - - // Xposed hook check - intentFilterHookedSystemUI.addAction(ACTION_HOOK_CHECK_RESULT) - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - requireContext().registerReceiver( - receiverHookedSystemui, - intentFilterHookedSystemUI, - Context.RECEIVER_EXPORTED - ) - } else { - requireContext().registerReceiver( - receiverHookedSystemui, - intentFilterHookedSystemUI - ) - } - binding.xposedHookCheck.container.setOnClickListener { - try { - val intent = Intent(Intent.ACTION_MAIN) - intent.setComponent( - ComponentName( - "org.lsposed.manager", - "org.lsposed.manager.ui.activity.MainActivity" - ) - ) - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - startActivity(intent) - } catch (ignored: Exception) { - } - } - isXposedHooked.setOnChangeListener { newValue: Boolean? -> - try { - if (newValue == true) { - if (binding.xposedHookCheck.container.visibility != View.GONE) { - binding.xposedHookCheck.container.visibility = View.GONE - } - } else { - if (binding.xposedHookCheck.container.visibility != View.VISIBLE) { - binding.xposedHookCheck.container.visibility = View.VISIBLE - } - } - } catch (ignored: Exception) { - } - } - isXposedHooked.setValue(false) - handler.post(checkSystemUIHooked) - - // Xposed menu list items - addItem(initXposedMenuListItems()) - - return view - } - - private fun initXposedMenuListItems(): ArrayList> { - val xposedMenu = ArrayList>().apply { - add( - arrayOf( - R.id.action_xposedMenu2_to_xposedTransparencyBlur, - appContextLocale.resources.getString(R.string.activity_title_transparency_blur), - appContextLocale.resources.getString(R.string.activity_desc_transparency_blur), - R.drawable.ic_xposed_transparency_blur - ) - ) - add( - arrayOf( - R.id.action_xposedMenu2_to_xposedQuickSettings, - appContextLocale.resources.getString(R.string.activity_title_quick_settings), - appContextLocale.resources.getString(R.string.activity_desc_quick_settings), - R.drawable.ic_xposed_quick_settings - ) - ) - add( - arrayOf( - R.id.action_xposedMenu2_to_xposedThemes, - appContextLocale.resources.getString(R.string.activity_title_themes), - appContextLocale.resources.getString(R.string.activity_desc_themes), - R.drawable.ic_xposed_themes - ) - ) - add( - arrayOf( - R.id.action_xposedMenu2_to_xposedBatteryStyle, - appContextLocale.resources.getString(R.string.activity_title_battery_style), - appContextLocale.resources.getString(R.string.activity_desc_battery_style), - R.drawable.ic_colored_battery - ) - ) - add( - arrayOf( - R.id.action_xposedMenu_to_xposedVolumePanel, - appContextLocale.resources.getString(R.string.activity_title_volume_panel), - appContextLocale.resources.getString(R.string.activity_desc_volume_panel), - R.drawable.ic_tweaks_volume - ) - ) - add( - arrayOf( - R.id.action_xposedMenu2_to_xposedHeaderImage, - appContextLocale.resources.getString(R.string.activity_title_header_image), - appContextLocale.resources.getString(R.string.activity_desc_header_image), - R.drawable.ic_xposed_header_image - ) - ) - add( - arrayOf( - R.id.action_xposedMenu2_to_xposedHeaderClock, - appContextLocale.resources.getString(R.string.activity_title_header_clock), - appContextLocale.resources.getString(R.string.activity_desc_header_clock), - R.drawable.ic_xposed_header_clock - ) - ) - add( - arrayOf( - R.id.action_xposedMenu2_to_xposedLockscreenClock, - appContextLocale.resources.getString(R.string.activity_title_lockscreen_clock), - appContextLocale.resources.getString(R.string.activity_desc_lockscreen_clock), - R.drawable.ic_xposed_lockscreen - ) - ) - add( - arrayOf( - R.id.action_xposedMenu2_to_xposedDepthWallpaper, - appContextLocale.resources.getString(R.string.activity_title_depth_wallpaper), - appContextLocale.resources.getString(R.string.activity_desc_depth_wallpaper), - R.drawable.ic_xposed_depth_wallpaper - ) - ) - add( - arrayOf( - R.id.action_xposedMenu2_to_xposedBackgroundChip, - appContextLocale.resources.getString(R.string.activity_title_background_chip), - appContextLocale.resources.getString(R.string.activity_desc_background_chip), - R.drawable.ic_xposed_background_chip - ) - ) - add( - arrayOf( - R.id.action_xposedMenu2_to_xposedOthers, - appContextLocale.resources.getString(R.string.activity_title_xposed_others), - appContextLocale.resources.getString(R.string.activity_desc_xposed_others), - R.drawable.ic_xposed_misc - ) - ) - } - - return xposedMenu - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - if (Prefs.getBoolean(SHOW_XPOSED_WARN, true)) { - MaterialAlertDialogBuilder(requireContext()) - .setTitle(requireContext().resources.getString(R.string.attention)) - .setMessage( - buildString { - append( - (if (Preferences.isXposedOnlyMode) { - appContextLocale.resources.getString( - R.string.xposed_only_desc - ) + "\n\n" - } else { - "" - }) - ) - append(appContextLocale.resources.getString(R.string.lsposed_warn)) - } - ) - .setPositiveButton(requireContext().resources.getString(R.string.understood)) { dialog: DialogInterface, _: Int -> - dialog.dismiss() - } - .setNegativeButton(requireContext().resources.getString(R.string.dont_show_again)) { dialog: DialogInterface, _: Int -> - dialog.dismiss() - - Prefs.putBoolean(SHOW_XPOSED_WARN, false) - } - .setCancelable(true) - .show() - } - } - - @Deprecated("Deprecated in Java") - @Suppress("deprecation") - override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { - menu.clear() - inflater.inflate(R.menu.xposed_menu, menu) - - super.onCreateOptionsMenu(menu, inflater) - } - - @Deprecated("Deprecated in Java") - @SuppressLint("NonConstantResourceId") - @Suppress("deprecation") - override fun onOptionsItemSelected(item: MenuItem): Boolean { - when (item.itemId) { - android.R.id.home -> { - findNavController(binding.getRoot()).popBackStack() - return true - } - - R.id.menu_export_settings -> importExportSettings(true) - R.id.menu_import_settings -> importExportSettings(false) - R.id.menu_reset_settings -> resetSettings() - R.id.restart_systemui -> Handler(Looper.getMainLooper()).postDelayed( - { SystemUtil.restartSystemUI() }, - 300 - ) - } - - return super.onOptionsItemSelected(item) - } - - // Function to add new item in list - private fun addItem(pack: ArrayList>) { - for (i in pack.indices) { - val menu = MenuWidget(requireActivity()) - - menu.setTitle(pack[i][1] as String) - menu.setSummary(pack[i][2] as String) - menu.setIcon(pack[i][3] as Int) - menu.setEndArrowVisibility(View.VISIBLE) - menu.setOnClickListener { - findNavController(menu).navigate( - (pack[i][0] as Int) - ) - } - - binding.xposedList.addView(menu) - } - } - - private fun importExportSettings(export: Boolean) { - if (!hasStoragePermission()) { - requestStoragePermission(requireContext()) - } else { - val fileIntent = Intent() - fileIntent.setAction(if (export) Intent.ACTION_CREATE_DOCUMENT else Intent.ACTION_GET_CONTENT) - fileIntent.setType("*/*") - fileIntent.putExtra(Intent.EXTRA_TITLE, "xposed_configs" + ".iconify") - - if (export) { - startExportActivityIntent.launch(fileIntent) - } else { - startImportActivityIntent.launch(fileIntent) - } - } - } - - private fun resetSettings() { - MaterialAlertDialogBuilder(requireContext()) - .setTitle(requireContext().resources.getString(R.string.import_settings_confirmation_title)) - .setMessage(requireContext().resources.getString(R.string.import_settings_confirmation_desc)) - .setPositiveButton( - requireContext().resources.getString(R.string.btn_positive) - ) { dialog: DialogInterface, _: Int -> - dialog.dismiss() - - Handler(Looper.getMainLooper()).post { - try { - RPrefs.clearAllPrefs() - - disableBlur(false) - - disableOverlays( - "quick_qs_offset_height", - "qqs_layout_margin_top", - "qs_header_row_min_height", - "quick_qs_total_height", - "qs_panel_padding_top", - "qs_panel_padding_top_combined_headers" - ) - - OverlayUtil.disableOverlays( - "IconifyComponentQSLT.overlay", - "IconifyComponentQSDT.overlay" - ) - - restartSystemUI() - } catch (exception: Exception) { - Toast.makeText( - requireContext(), - requireContext().resources.getString(R.string.toast_error), - Toast.LENGTH_SHORT - ).show() - - Log.e("Settings", "Error importing settings", exception) - } - } - } - .setNegativeButton(requireContext().resources.getString(R.string.btn_negative)) { dialog: DialogInterface, _: Int -> - dialog.dismiss() - } - .show() - } - - private fun checkXposedHooked() { - - isHookSuccessful = false - - object : CountDownTimer(1600, 800) { - override fun onTick(millisUntilFinished: Long) { - if (isHookSuccessful) { - cancel() - } - } - - override fun onFinish() { - if (!isHookSuccessful) { - isXposedHooked.setValue(false) - } - } - }.start() - - Thread { - try { - requireContext().sendBroadcast(Intent().setAction(ACTION_HOOK_CHECK_REQUEST)) - } catch (ignored: Exception) { - } - }.start() - } - - override fun onDestroy() { - try { - handler.removeCallbacks(checkSystemUIHooked) - } catch (ignored: Exception) { - } - - super.onDestroy() - } - - override fun onResume() { - super.onResume() - - try { - isXposedHooked.notifyChanged() - handler.post(checkSystemUIHooked) - } catch (ignored: Exception) { - } - } - - override fun onPause() { - try { - handler.removeCallbacks(checkSystemUIHooked) - } catch (ignored: Exception) { - } - - super.onPause() - } - - companion object { - private val isXposedHooked = ObservableVariable() - } -} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/XposedOthers.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/XposedOthers.kt deleted file mode 100644 index af0d7be5f..000000000 --- a/app/src/main/java/com/drdisagree/iconify/ui/fragments/XposedOthers.kt +++ /dev/null @@ -1,160 +0,0 @@ -package com.drdisagree.iconify.ui.fragments - -import android.os.Build -import android.os.Bundle -import android.os.Handler -import android.os.Looper -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.CompoundButton -import com.drdisagree.iconify.R -import com.drdisagree.iconify.common.Const.SWITCH_ANIMATION_DELAY -import com.drdisagree.iconify.common.Preferences.FIXED_STATUS_ICONS_SIDEMARGIN -import com.drdisagree.iconify.common.Preferences.FIXED_STATUS_ICONS_SWITCH -import com.drdisagree.iconify.common.Preferences.FIXED_STATUS_ICONS_TOPMARGIN -import com.drdisagree.iconify.common.Preferences.HIDE_LOCKSCREEN_CARRIER -import com.drdisagree.iconify.common.Preferences.HIDE_LOCKSCREEN_LOCK_ICON -import com.drdisagree.iconify.common.Preferences.HIDE_LOCKSCREEN_STATUSBAR -import com.drdisagree.iconify.common.Preferences.HIDE_STATUS_ICONS_SWITCH -import com.drdisagree.iconify.common.Preferences.QSPANEL_HIDE_CARRIER -import com.drdisagree.iconify.common.Preferences.QSPANEL_STATUSICONSBG_SWITCH -import com.drdisagree.iconify.config.RPrefs.getBoolean -import com.drdisagree.iconify.config.RPrefs.getInt -import com.drdisagree.iconify.config.RPrefs.putBoolean -import com.drdisagree.iconify.config.RPrefs.putInt -import com.drdisagree.iconify.databinding.FragmentXposedOthersBinding -import com.drdisagree.iconify.ui.base.BaseFragment -import com.drdisagree.iconify.ui.utils.ViewHelper.setHeader -import com.drdisagree.iconify.utils.SystemUtil -import com.google.android.material.slider.Slider - -class XposedOthers : BaseFragment() { - - private lateinit var binding: FragmentXposedOthersBinding - - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View { - binding = FragmentXposedOthersBinding.inflate(inflater, container, false) - val view: View = binding.getRoot() - - // Header - setHeader( - requireContext(), - getParentFragmentManager(), - binding.header.toolbar, - R.string.activity_title_xposed_others - ) - - // Hide carrier group - binding.hideQsCarrierGroup.isSwitchChecked = getBoolean(QSPANEL_HIDE_CARRIER, false) - binding.hideQsCarrierGroup.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> - putBoolean(QSPANEL_HIDE_CARRIER, isChecked) - - Handler(Looper.getMainLooper()).postDelayed( - { SystemUtil.handleSystemUIRestart() }, - SWITCH_ANIMATION_DELAY - ) - } - - // Hide status icons - binding.hideStatusIcons.isSwitchChecked = getBoolean(HIDE_STATUS_ICONS_SWITCH, false) - binding.hideStatusIcons.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> - putBoolean(HIDE_STATUS_ICONS_SWITCH, isChecked) - - Handler(Looper.getMainLooper()).postDelayed( - { SystemUtil.handleSystemUIRestart() }, - SWITCH_ANIMATION_DELAY - ) - } - - // Hide lockscreen carrier - binding.hideLockscreenCarrier.isSwitchChecked = getBoolean(HIDE_LOCKSCREEN_CARRIER, false) - binding.hideLockscreenCarrier.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> - putBoolean(HIDE_LOCKSCREEN_CARRIER, isChecked) - - Handler(Looper.getMainLooper()).postDelayed( - { SystemUtil.handleSystemUIRestart() }, - SWITCH_ANIMATION_DELAY - ) - } - - // Hide lockscreen statusbar - binding.hideLockscreenStatusbar.isSwitchChecked = - getBoolean(HIDE_LOCKSCREEN_STATUSBAR, false) - binding.hideLockscreenStatusbar.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> - putBoolean(HIDE_LOCKSCREEN_STATUSBAR, isChecked) - - Handler(Looper.getMainLooper()).postDelayed( - { SystemUtil.handleSystemUIRestart() }, - SWITCH_ANIMATION_DELAY - ) - } - - // Hide lockscreen lock icon - binding.hideLockscreenLockIcon.isSwitchChecked = - getBoolean(HIDE_LOCKSCREEN_LOCK_ICON, false) - binding.hideLockscreenLockIcon.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> - putBoolean(HIDE_LOCKSCREEN_LOCK_ICON, isChecked) - - Handler(Looper.getMainLooper()).postDelayed( - { SystemUtil.handleSystemUIRestart() }, - SWITCH_ANIMATION_DELAY - ) - } - - // Fixed status icons - binding.fixedStatusIcons.isSwitchChecked = getBoolean(FIXED_STATUS_ICONS_SWITCH, false) - binding.fixedStatusIcons.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> - binding.statusIconsTopMargin.setEnabled(isChecked) - binding.statusIconsSideMargin.setEnabled(isChecked) - - putBoolean(FIXED_STATUS_ICONS_SWITCH, isChecked) - - Handler(Looper.getMainLooper()).postDelayed( - { SystemUtil.handleSystemUIRestart() }, - SWITCH_ANIMATION_DELAY - ) - } - - // Status icons top margin - if (Build.VERSION.SDK_INT >= 33) { - binding.statusIconsTopMargin.setSliderValueTo(250) - } - binding.statusIconsTopMargin.sliderValue = getInt(FIXED_STATUS_ICONS_TOPMARGIN, 8) - binding.statusIconsTopMargin.setEnabled( - if (Build.VERSION.SDK_INT >= 33) { - getBoolean(QSPANEL_STATUSICONSBG_SWITCH, false) || - getBoolean(FIXED_STATUS_ICONS_SWITCH, false) - } else { - getBoolean(FIXED_STATUS_ICONS_SWITCH, false) - } - ) - binding.statusIconsTopMargin.setOnSliderTouchListener(object : - Slider.OnSliderTouchListener { - override fun onStartTrackingTouch(slider: Slider) {} - - override fun onStopTrackingTouch(slider: Slider) { - putInt(FIXED_STATUS_ICONS_TOPMARGIN, slider.value.toInt()) - } - }) - - // Status icons side margin - binding.statusIconsSideMargin.sliderValue = getInt(FIXED_STATUS_ICONS_SIDEMARGIN, 0) - binding.statusIconsSideMargin.setEnabled( - getBoolean(FIXED_STATUS_ICONS_SWITCH, false) - ) - binding.statusIconsSideMargin.setOnSliderTouchListener(object : - Slider.OnSliderTouchListener { - override fun onStartTrackingTouch(slider: Slider) {} - - override fun onStopTrackingTouch(slider: Slider) { - putInt(FIXED_STATUS_ICONS_SIDEMARGIN, slider.value.toInt()) - } - }) - return view - } -} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/XposedQuickSettings.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/XposedQuickSettings.kt deleted file mode 100644 index c9c43dac4..000000000 --- a/app/src/main/java/com/drdisagree/iconify/ui/fragments/XposedQuickSettings.kt +++ /dev/null @@ -1,184 +0,0 @@ -package com.drdisagree.iconify.ui.fragments - -import android.os.Bundle -import android.os.Handler -import android.os.Looper -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.CompoundButton -import com.drdisagree.iconify.R -import com.drdisagree.iconify.common.Const.SWITCH_ANIMATION_DELAY -import com.drdisagree.iconify.common.Preferences.HIDE_QSLABEL_SWITCH -import com.drdisagree.iconify.common.Preferences.HIDE_QS_FOOTER_BUTTONS -import com.drdisagree.iconify.common.Preferences.HIDE_QS_SILENT_TEXT -import com.drdisagree.iconify.common.Preferences.QQS_TOPMARGIN -import com.drdisagree.iconify.common.Preferences.QS_TEXT_ALWAYS_WHITE -import com.drdisagree.iconify.common.Preferences.QS_TEXT_FOLLOW_ACCENT -import com.drdisagree.iconify.common.Preferences.QS_TOPMARGIN -import com.drdisagree.iconify.common.Preferences.VERTICAL_QSTILE_SWITCH -import com.drdisagree.iconify.config.RPrefs.clearPref -import com.drdisagree.iconify.config.RPrefs.getBoolean -import com.drdisagree.iconify.config.RPrefs.getInt -import com.drdisagree.iconify.config.RPrefs.putBoolean -import com.drdisagree.iconify.config.RPrefs.putInt -import com.drdisagree.iconify.databinding.FragmentXposedQuickSettingsBinding -import com.drdisagree.iconify.ui.base.BaseFragment -import com.drdisagree.iconify.ui.utils.ViewHelper.setHeader -import com.drdisagree.iconify.utils.SystemUtil -import com.google.android.material.slider.Slider - -class XposedQuickSettings : BaseFragment() { - - private lateinit var binding: FragmentXposedQuickSettingsBinding - - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View { - binding = FragmentXposedQuickSettingsBinding.inflate(inflater, container, false) - val view: View = binding.getRoot() - - // Header - setHeader( - requireContext(), - getParentFragmentManager(), - binding.header.toolbar, - R.string.activity_title_quick_settings - ) - - // Vertical QS Tile - binding.verticalTile.isSwitchChecked = getBoolean(VERTICAL_QSTILE_SWITCH, false) - binding.verticalTile.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> - putBoolean(VERTICAL_QSTILE_SWITCH, isChecked) - - binding.hideTileLabel.setEnabled(isChecked) - - Handler(Looper.getMainLooper()).postDelayed( - { SystemUtil.handleSystemUIRestart() }, - SWITCH_ANIMATION_DELAY - ) - } - - // Hide label for vertical tiles - binding.hideTileLabel.setEnabled(binding.verticalTile.isSwitchChecked) - binding.hideTileLabel.isSwitchChecked = getBoolean(HIDE_QSLABEL_SWITCH, false) - binding.hideTileLabel.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> - putBoolean(HIDE_QSLABEL_SWITCH, isChecked) - - Handler(Looper.getMainLooper()).postDelayed( - { SystemUtil.doubleToggleDarkMode() }, - SWITCH_ANIMATION_DELAY - ) - } - - // QQS panel top margin slider - binding.qqsTopMargin.sliderValue = getInt(QQS_TOPMARGIN, 100) - binding.qqsTopMargin.setOnSliderTouchListener(object : Slider.OnSliderTouchListener { - override fun onStartTrackingTouch(slider: Slider) {} - - override fun onStopTrackingTouch(slider: Slider) { - putInt(QQS_TOPMARGIN, slider.value.toInt()) - - Handler(Looper.getMainLooper()).postDelayed( - { SystemUtil.handleSystemUIRestart() }, - SWITCH_ANIMATION_DELAY - ) - } - }) - binding.qqsTopMargin.setResetClickListener { - clearPref(QQS_TOPMARGIN) - - Handler(Looper.getMainLooper()).postDelayed( - { SystemUtil.handleSystemUIRestart() }, - SWITCH_ANIMATION_DELAY - ) - - true - } - - // QS panel top margin slider - binding.qsTopMargin.sliderValue = getInt(QS_TOPMARGIN, 100) - binding.qsTopMargin.setOnSliderTouchListener(object : Slider.OnSliderTouchListener { - override fun onStartTrackingTouch(slider: Slider) {} - - override fun onStopTrackingTouch(slider: Slider) { - putInt(QS_TOPMARGIN, slider.value.toInt()) - - Handler(Looper.getMainLooper()).postDelayed( - { SystemUtil.handleSystemUIRestart() }, - SWITCH_ANIMATION_DELAY - ) - } - }) - binding.qsTopMargin.setResetClickListener { - clearPref(QS_TOPMARGIN) - - Handler(Looper.getMainLooper()).postDelayed( - { SystemUtil.handleSystemUIRestart() }, - SWITCH_ANIMATION_DELAY - ) - - true - } - - // QS text always white - binding.labelWhite.isSwitchChecked = getBoolean(QS_TEXT_ALWAYS_WHITE, false) - binding.labelWhite.setSwitchChangeListener(qsTextWhiteListener) - - // QS text follow accent - binding.labelAccent.isSwitchChecked = getBoolean(QS_TEXT_FOLLOW_ACCENT, false) - binding.labelAccent.setSwitchChangeListener(qsTextAccentListener) - - // Hide silent text - binding.hideSilentText.isSwitchChecked = getBoolean(HIDE_QS_SILENT_TEXT, false) - binding.hideSilentText.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> - putBoolean(HIDE_QS_SILENT_TEXT, isChecked) - } - - // Hide footer buttons - binding.hideFooterButtons.isSwitchChecked = getBoolean(HIDE_QS_FOOTER_BUTTONS, false) - binding.hideFooterButtons.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> - putBoolean(HIDE_QS_FOOTER_BUTTONS, isChecked) - } - - return view - } - - private var qsTextWhiteListener: CompoundButton.OnCheckedChangeListener = - CompoundButton.OnCheckedChangeListener { _, isChecked -> - if (isChecked) { - putBoolean(QS_TEXT_FOLLOW_ACCENT, false) - - binding.labelAccent.setSwitchChangeListener(null) - binding.labelAccent.isSwitchChecked = false - binding.labelAccent.setSwitchChangeListener(qsTextAccentListener) - } - - putBoolean(QS_TEXT_ALWAYS_WHITE, isChecked) - - Handler(Looper.getMainLooper()).postDelayed( - { SystemUtil.handleSystemUIRestart() }, - SWITCH_ANIMATION_DELAY - ) - } - - private var qsTextAccentListener: CompoundButton.OnCheckedChangeListener = - CompoundButton.OnCheckedChangeListener { _: CompoundButton?, isChecked: Boolean -> - if (isChecked) { - putBoolean(QS_TEXT_ALWAYS_WHITE, false) - - binding.labelWhite.setSwitchChangeListener(null) - binding.labelWhite.isSwitchChecked = false - binding.labelWhite.setSwitchChangeListener(qsTextWhiteListener) - } - - putBoolean(QS_TEXT_FOLLOW_ACCENT, isChecked) - - Handler(Looper.getMainLooper()).postDelayed( - { SystemUtil.handleSystemUIRestart() }, - SWITCH_ANIMATION_DELAY - ) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/XposedThemes.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/XposedThemes.kt deleted file mode 100644 index ae180bb6b..000000000 --- a/app/src/main/java/com/drdisagree/iconify/ui/fragments/XposedThemes.kt +++ /dev/null @@ -1,159 +0,0 @@ -package com.drdisagree.iconify.ui.fragments - -import android.os.Bundle -import android.os.Handler -import android.os.Looper -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.CompoundButton -import com.drdisagree.iconify.R -import com.drdisagree.iconify.common.Const.SWITCH_ANIMATION_DELAY -import com.drdisagree.iconify.common.Dynamic.isAtleastA14 -import com.drdisagree.iconify.common.Preferences.BLACK_QSPANEL -import com.drdisagree.iconify.common.Preferences.DUALTONE_QSPANEL -import com.drdisagree.iconify.common.Preferences.FIX_NOTIFICATION_COLOR -import com.drdisagree.iconify.common.Preferences.FIX_QS_TILE_COLOR -import com.drdisagree.iconify.common.Preferences.FLUID_NOTIF_TRANSPARENCY -import com.drdisagree.iconify.common.Preferences.FLUID_POWERMENU_TRANSPARENCY -import com.drdisagree.iconify.common.Preferences.FLUID_QSPANEL -import com.drdisagree.iconify.common.Preferences.LIGHT_QSPANEL -import com.drdisagree.iconify.config.RPrefs.getBoolean -import com.drdisagree.iconify.config.RPrefs.putBoolean -import com.drdisagree.iconify.databinding.FragmentXposedThemesBinding -import com.drdisagree.iconify.ui.base.BaseFragment -import com.drdisagree.iconify.ui.utils.ViewHelper.setHeader -import com.drdisagree.iconify.utils.SystemUtil - -class XposedThemes : BaseFragment() { - - private lateinit var binding: FragmentXposedThemesBinding - - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View { - binding = FragmentXposedThemesBinding.inflate(inflater, container, false) - val view: View = binding.getRoot() - - // Header - setHeader( - requireContext(), - getParentFragmentManager(), - binding.header.toolbar, - R.string.activity_title_themes - ) - - // Light Theme - binding.lightTheme.isSwitchChecked = getBoolean(LIGHT_QSPANEL, false) - binding.lightTheme.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> - putBoolean(LIGHT_QSPANEL, isChecked) - - binding.dualTone.setEnabled(isChecked) - - Handler(Looper.getMainLooper()).postDelayed( - { SystemUtil.handleSystemUIRestart() }, - SWITCH_ANIMATION_DELAY - ) - } - binding.dualTone.setEnabled(binding.lightTheme.isSwitchChecked) - - // Dual Tone - binding.dualTone.isSwitchChecked = getBoolean(DUALTONE_QSPANEL, false) - binding.dualTone.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> - putBoolean(DUALTONE_QSPANEL, isChecked) - } - - // Pixel Black Theme - binding.blackTheme.isSwitchChecked = getBoolean(BLACK_QSPANEL, false) - binding.blackTheme.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> - putBoolean(BLACK_QSPANEL, isChecked) - - Handler(Looper.getMainLooper()).postDelayed( - { SystemUtil.handleSystemUIRestart() }, - SWITCH_ANIMATION_DELAY - ) - } - - // Fluid QS Theme - binding.fluidQsTheme.isSwitchChecked = getBoolean(FLUID_QSPANEL, false) - binding.fluidQsTheme.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> - putBoolean(FLUID_QSPANEL, isChecked) - - binding.fluidNotifTheme.setEnabled(isChecked) - binding.fluidPowermenuTheme.setEnabled(isChecked) - - Handler(Looper.getMainLooper()).postDelayed( - { SystemUtil.handleSystemUIRestart() }, - SWITCH_ANIMATION_DELAY - ) - } - binding.fluidNotifTheme.setEnabled(binding.fluidQsTheme.isSwitchChecked) - binding.fluidPowermenuTheme.setEnabled(binding.fluidQsTheme.isSwitchChecked) - - // Fluid QS Notification Transparency - binding.fluidNotifTheme.isSwitchChecked = getBoolean(FLUID_NOTIF_TRANSPARENCY, false) - binding.fluidNotifTheme.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> - putBoolean(FLUID_NOTIF_TRANSPARENCY, isChecked) - - Handler(Looper.getMainLooper()).postDelayed( - { SystemUtil.handleSystemUIRestart() }, - SWITCH_ANIMATION_DELAY - ) - } - - // Fluid QS Power Menu Transparency - binding.fluidPowermenuTheme.isSwitchChecked = - getBoolean(FLUID_POWERMENU_TRANSPARENCY, false) - binding.fluidPowermenuTheme.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> - putBoolean(FLUID_POWERMENU_TRANSPARENCY, isChecked) - - Handler(Looper.getMainLooper()).postDelayed( - { SystemUtil.handleSystemUIRestart() }, - SWITCH_ANIMATION_DELAY - ) - } - - // Others section - binding.sectionOthers.visibility = if (isAtleastA14) { - View.VISIBLE - } else { - View.GONE - } - - // Fix qs tile color - binding.fixQsTileColor.visibility = if (isAtleastA14) { - View.VISIBLE - } else { - View.GONE - } - binding.fixQsTileColor.isSwitchChecked = getBoolean(FIX_QS_TILE_COLOR, false) - binding.fixQsTileColor.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> - putBoolean(FIX_QS_TILE_COLOR, isChecked) - - Handler(Looper.getMainLooper()).postDelayed( - { SystemUtil.handleSystemUIRestart() }, - SWITCH_ANIMATION_DELAY - ) - } - - // Fix notification color - binding.fixNotificationColor.visibility = if (isAtleastA14) { - View.VISIBLE - } else { - View.GONE - } - binding.fixNotificationColor.isSwitchChecked = getBoolean(FIX_NOTIFICATION_COLOR, false) - binding.fixNotificationColor.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> - putBoolean(FIX_NOTIFICATION_COLOR, isChecked) - - Handler(Looper.getMainLooper()).postDelayed( - { SystemUtil.handleSystemUIRestart() }, - SWITCH_ANIMATION_DELAY - ) - } - - return view - } -} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/XposedTransparencyBlur.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/XposedTransparencyBlur.kt deleted file mode 100644 index b91566648..000000000 --- a/app/src/main/java/com/drdisagree/iconify/ui/fragments/XposedTransparencyBlur.kt +++ /dev/null @@ -1,187 +0,0 @@ -package com.drdisagree.iconify.ui.fragments - -import android.os.Bundle -import android.os.Handler -import android.os.Looper -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.CompoundButton -import com.drdisagree.iconify.R -import com.drdisagree.iconify.common.Const.SWITCH_ANIMATION_DELAY -import com.drdisagree.iconify.common.Preferences.AGGRESSIVE_QSPANEL_BLUR_SWITCH -import com.drdisagree.iconify.common.Preferences.BLUR_RADIUS_VALUE -import com.drdisagree.iconify.common.Preferences.LOCKSCREEN_SHADE_SWITCH -import com.drdisagree.iconify.common.Preferences.NOTIF_TRANSPARENCY_SWITCH -import com.drdisagree.iconify.common.Preferences.QSALPHA_LEVEL -import com.drdisagree.iconify.common.Preferences.QSPANEL_BLUR_SWITCH -import com.drdisagree.iconify.common.Preferences.QS_TRANSPARENCY_SWITCH -import com.drdisagree.iconify.config.RPrefs.getBoolean -import com.drdisagree.iconify.config.RPrefs.getInt -import com.drdisagree.iconify.config.RPrefs.putBoolean -import com.drdisagree.iconify.config.RPrefs.putInt -import com.drdisagree.iconify.databinding.FragmentXposedTransparencyBlurBinding -import com.drdisagree.iconify.ui.base.BaseFragment -import com.drdisagree.iconify.ui.utils.ViewHelper.setHeader -import com.drdisagree.iconify.utils.SystemUtil -import com.drdisagree.iconify.utils.SystemUtil.disableBlur -import com.drdisagree.iconify.utils.SystemUtil.enableBlur -import com.drdisagree.iconify.utils.SystemUtil.isBlurEnabled -import com.google.android.material.slider.Slider - -class XposedTransparencyBlur : BaseFragment() { - - private lateinit var binding: FragmentXposedTransparencyBlurBinding - - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View { - binding = FragmentXposedTransparencyBlurBinding.inflate(inflater, container, false) - val view: View = binding.getRoot() - - // Header - setHeader( - requireContext(), - getParentFragmentManager(), - binding.header.toolbar, - R.string.activity_title_transparency_blur - ) - - // Qs Panel & Notification Shade Transparency - binding.transparentQsPanel.isSwitchChecked = getBoolean(QS_TRANSPARENCY_SWITCH, false) - binding.transparentQsPanel.setSwitchChangeListener(qsTransparencyListener) - binding.transparentNotifShade.isSwitchChecked = getBoolean(NOTIF_TRANSPARENCY_SWITCH, false) - binding.transparentNotifShade.setSwitchChangeListener(notifTransparencyListener) - binding.keepLockscreenShade.setEnabled(binding.transparentQsPanel.isSwitchChecked || binding.transparentNotifShade.isSwitchChecked) - binding.keepLockscreenShade.isSwitchChecked = getBoolean(LOCKSCREEN_SHADE_SWITCH, false) - binding.keepLockscreenShade.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> - putBoolean(LOCKSCREEN_SHADE_SWITCH, isChecked) - - Handler(Looper.getMainLooper()).postDelayed( - { SystemUtil.handleSystemUIRestart() }, - SWITCH_ANIMATION_DELAY - ) - } - - // Transparency Alpha - binding.transparencySlider.setEnabled(binding.transparentQsPanel.isSwitchChecked || binding.transparentNotifShade.isSwitchChecked) - binding.transparencySlider.sliderValue = getInt(QSALPHA_LEVEL, 60) - binding.transparencySlider.setOnSliderTouchListener(object : - Slider.OnSliderTouchListener { - override fun onStartTrackingTouch(slider: Slider) {} - - override fun onStopTrackingTouch(slider: Slider) { - putInt(QSALPHA_LEVEL, slider.value.toInt()) - } - }) - binding.transparencySlider.setResetClickListener { - putInt(QSALPHA_LEVEL, 60) - - true - } - - // Qs Panel Blur Enabler - putBoolean(QSPANEL_BLUR_SWITCH, isBlurEnabled(false)) - binding.blur.isSwitchChecked = getBoolean(QSPANEL_BLUR_SWITCH, false) - binding.blur.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> - putBoolean(QSPANEL_BLUR_SWITCH, isChecked) - - if (isChecked) { - enableBlur(false) - } else { - binding.aggressiveBlur.isSwitchChecked = false - disableBlur(false) - } - - binding.aggressiveBlur.visibility = if (isChecked) View.VISIBLE else View.GONE - } - - // Aggressive Qs Panel Blur Enabler - putBoolean(AGGRESSIVE_QSPANEL_BLUR_SWITCH, isBlurEnabled(true)) - binding.aggressiveBlur.visibility = - if (binding.blur.isSwitchChecked) { - View.VISIBLE - } else { - View.GONE - } - binding.aggressiveBlur.isSwitchChecked = getBoolean(AGGRESSIVE_QSPANEL_BLUR_SWITCH, false) - binding.aggressiveBlur.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> - putBoolean(AGGRESSIVE_QSPANEL_BLUR_SWITCH, isChecked) - - if (isChecked) { - enableBlur(true) - } else { - disableBlur(true) - } - } - - // Blur Intensity - binding.blurIntensity.sliderValue = getInt(BLUR_RADIUS_VALUE, 23) - binding.blurIntensity.setOnSliderTouchListener(object : Slider.OnSliderTouchListener { - override fun onStartTrackingTouch(slider: Slider) {} - - override fun onStopTrackingTouch(slider: Slider) { - putInt(BLUR_RADIUS_VALUE, slider.value.toInt()) - - Handler(Looper.getMainLooper()).postDelayed( - { SystemUtil.handleSystemUIRestart() }, - SWITCH_ANIMATION_DELAY - ) - } - }) - binding.blurIntensity.setResetClickListener { - putInt(BLUR_RADIUS_VALUE, 23) - - Handler(Looper.getMainLooper()).postDelayed( - { SystemUtil.handleSystemUIRestart() }, - SWITCH_ANIMATION_DELAY - ) - - true - } - - return view - } - - private var qsTransparencyListener: CompoundButton.OnCheckedChangeListener = - CompoundButton.OnCheckedChangeListener { _, isChecked -> - putBoolean(QS_TRANSPARENCY_SWITCH, isChecked) - - if (isChecked) { - putBoolean(NOTIF_TRANSPARENCY_SWITCH, false) - binding.transparentNotifShade.setSwitchChangeListener(null) - binding.transparentNotifShade.isSwitchChecked = false - binding.transparentNotifShade.setSwitchChangeListener(notifTransparencyListener) - } - - binding.keepLockscreenShade.setEnabled(binding.transparentQsPanel.isSwitchChecked || binding.transparentNotifShade.isSwitchChecked) - binding.transparencySlider.setEnabled(binding.transparentQsPanel.isSwitchChecked || binding.transparentNotifShade.isSwitchChecked) - - Handler(Looper.getMainLooper()).postDelayed( - { SystemUtil.handleSystemUIRestart() }, - SWITCH_ANIMATION_DELAY - ) - } - - private var notifTransparencyListener: CompoundButton.OnCheckedChangeListener = - CompoundButton.OnCheckedChangeListener { _: CompoundButton?, isChecked: Boolean -> - putBoolean(NOTIF_TRANSPARENCY_SWITCH, isChecked) - - if (isChecked) { - putBoolean(QS_TRANSPARENCY_SWITCH, false) - binding.transparentQsPanel.setSwitchChangeListener(null) - binding.transparentQsPanel.isSwitchChecked = false - binding.transparentQsPanel.setSwitchChangeListener(qsTransparencyListener) - } - - binding.keepLockscreenShade.setEnabled(binding.transparentQsPanel.isSwitchChecked || binding.transparentNotifShade.isSwitchChecked) - binding.transparencySlider.setEnabled(binding.transparentQsPanel.isSwitchChecked || binding.transparentNotifShade.isSwitchChecked) - - Handler(Looper.getMainLooper()).postDelayed( - { SystemUtil.handleSystemUIRestart() }, - SWITCH_ANIMATION_DELAY - ) - } -} diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/XposedVolumePanel.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/XposedVolumePanel.kt deleted file mode 100644 index 621a9de8b..000000000 --- a/app/src/main/java/com/drdisagree/iconify/ui/fragments/XposedVolumePanel.kt +++ /dev/null @@ -1,60 +0,0 @@ -package com.drdisagree.iconify.ui.fragments - -import android.os.Bundle -import android.os.Handler -import android.os.Looper -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.CompoundButton -import com.drdisagree.iconify.R -import com.drdisagree.iconify.common.Const.SWITCH_ANIMATION_DELAY -import com.drdisagree.iconify.common.Preferences.VOLUME_PANEL_PERCENTAGE -import com.drdisagree.iconify.common.Preferences.VOLUME_PANEL_SAFETY_WARNING -import com.drdisagree.iconify.config.RPrefs.getBoolean -import com.drdisagree.iconify.config.RPrefs.putBoolean -import com.drdisagree.iconify.databinding.FragmentXposedVolumePanelBinding -import com.drdisagree.iconify.ui.base.BaseFragment -import com.drdisagree.iconify.ui.utils.ViewHelper.setHeader -import com.drdisagree.iconify.utils.SystemUtil - -class XposedVolumePanel : BaseFragment() { - - private lateinit var binding: FragmentXposedVolumePanelBinding - - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View { - binding = FragmentXposedVolumePanelBinding.inflate(inflater, container, false) - val view: View = binding.getRoot() - - // Header - setHeader( - requireContext(), - getParentFragmentManager(), - binding.header.toolbar, - R.string.activity_title_volume_panel - ) - - // Volume percentage - binding.volumePercentage.isSwitchChecked = getBoolean(VOLUME_PANEL_PERCENTAGE, false) - binding.volumePercentage.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> - putBoolean(VOLUME_PANEL_PERCENTAGE, isChecked) - - Handler(Looper.getMainLooper()).postDelayed( - { SystemUtil.handleSystemUIRestart() }, - SWITCH_ANIMATION_DELAY - ) - } - - // Safety warning - binding.safetyWarning.isSwitchChecked = getBoolean(VOLUME_PANEL_SAFETY_WARNING, true) - binding.safetyWarning.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> - putBoolean(VOLUME_PANEL_SAFETY_WARNING, isChecked) - } - - return view - } -} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/BrightnessBar.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/home/BrightnessBar.kt similarity index 98% rename from app/src/main/java/com/drdisagree/iconify/ui/fragments/BrightnessBar.kt rename to app/src/main/java/com/drdisagree/iconify/ui/fragments/home/BrightnessBar.kt index 091372178..438c88a40 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/fragments/BrightnessBar.kt +++ b/app/src/main/java/com/drdisagree/iconify/ui/fragments/home/BrightnessBar.kt @@ -1,4 +1,4 @@ -package com.drdisagree.iconify.ui.fragments +package com.drdisagree.iconify.ui.fragments.home import android.os.Bundle import android.view.LayoutInflater @@ -64,7 +64,7 @@ class BrightnessBar : BaseFragment() { val brightnessBarActivityList = ArrayList().apply { add( MenuModel( - R.id.action_brightnessBar_to_brightnessBarPixel, + BrightnessBarPixel(), resources.getString(R.string.activity_title_pixel_variant), resources.getString(R.string.activity_desc_pixel_variant), R.drawable.ic_pixel_device @@ -73,6 +73,7 @@ class BrightnessBar : BaseFragment() { } return MenuAdapter( + parentFragmentManager, requireContext(), brightnessBarActivityList ) diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/BrightnessBarPixel.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/home/BrightnessBarPixel.kt similarity index 99% rename from app/src/main/java/com/drdisagree/iconify/ui/fragments/BrightnessBarPixel.kt rename to app/src/main/java/com/drdisagree/iconify/ui/fragments/home/BrightnessBarPixel.kt index 6c44967e8..bad96b49c 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/fragments/BrightnessBarPixel.kt +++ b/app/src/main/java/com/drdisagree/iconify/ui/fragments/home/BrightnessBarPixel.kt @@ -1,4 +1,4 @@ -package com.drdisagree.iconify.ui.fragments +package com.drdisagree.iconify.ui.fragments.home import android.os.Bundle import android.view.LayoutInflater diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/home/CellularIcons.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/home/CellularIcons.kt new file mode 100644 index 000000000..31f7c6af5 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/fragments/home/CellularIcons.kt @@ -0,0 +1,123 @@ +package com.drdisagree.iconify.ui.fragments.home + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.recyclerview.widget.LinearLayoutManager +import com.drdisagree.iconify.BuildConfig +import com.drdisagree.iconify.R +import com.drdisagree.iconify.databinding.FragmentIconPackBinding +import com.drdisagree.iconify.ui.adapters.IconPackAdapter +import com.drdisagree.iconify.ui.base.BaseFragment +import com.drdisagree.iconify.ui.dialogs.LoadingDialog +import com.drdisagree.iconify.ui.models.IconPackModel +import com.drdisagree.iconify.ui.utils.ViewHelper.setHeader +import com.drdisagree.iconify.utils.overlay.manager.SignalIconManager +import java.util.Locale + +class CellularIcons : BaseFragment() { + + private lateinit var binding: FragmentIconPackBinding + private var loadingDialog: LoadingDialog? = null + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + binding = FragmentIconPackBinding.inflate(inflater, container, false) + val view: View = binding.getRoot() + + // Header + setHeader( + requireContext(), + getParentFragmentManager(), + binding.header.toolbar, + R.string.activity_title_cellular_icons + ) + + // Loading dialog while enabling or disabling pack + loadingDialog = LoadingDialog(requireContext()) + + // RecyclerView + binding.iconPackContainer.setLayoutManager(LinearLayoutManager(requireContext())) + + binding.iconPackContainer.setAdapter(initIconPackItems()) + binding.iconPackContainer.setHasFixedSize(true) + + return view + } + + @Suppress("DiscouragedApi") + private fun initIconPackItems(): IconPackAdapter { + val iconPackList = ArrayList().apply { + val themes = listOf( + "Aquarium", "Aurora", "Bars", "Butterfly", "Circle", "Daun", + "Dec", "Deep", "Dora", "ZigZag", "Equal", "Faint UI", + "Fan", "Lorn", "Gradicon", "Huawei", "Inside", "iOS", + "Mini", "Nothing Dot", "Odin", "Pills", "Plumpy", "Rel", + "Roman", "Round", "Scroll", "Sea", "Sneaky", "Stack", + "Stroke", "Wannui", "Wavy", "Windows", "Wing", "Xperia" + ) + + val packageName = BuildConfig.APPLICATION_ID + + themes.forEachIndexed { _, themeName -> + val themeResourceName = themeName.replace(" ", "_").lowercase(Locale.ROOT) + + add( + IconPackModel( + themeName, + 0, + resources.getIdentifier( + "preview_${themeResourceName}_ic_signal_cellular_1_4_bar", + "drawable", + packageName + ), + resources.getIdentifier( + "preview_${themeResourceName}_ic_signal_cellular_2_4_bar", + "drawable", + packageName + ), + resources.getIdentifier( + "preview_${themeResourceName}_ic_signal_cellular_2_4_bar", + "drawable", + packageName + ), + resources.getIdentifier( + "preview_${themeResourceName}_ic_signal_cellular_4_4_bar", + "drawable", + packageName + ) + ) + ) + } + } + + return IconPackAdapter( + requireContext(), + iconPackList, + loadingDialog!!, + "SGIC", + onButtonClick + ) + } + + private val onButtonClick = object : IconPackAdapter.OnButtonClick { + + override fun onEnableClick(position: Int, item: IconPackModel) { + SignalIconManager.enableOverlay(n = position + 1, "SGIC") + } + + override fun onDisableClick(position: Int, item: IconPackModel) { + SignalIconManager.disableOverlay(n = position + 1, "SGIC") + } + } + + override fun onDestroy() { + loadingDialog?.dismiss() + + super.onDestroy() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/home/Home.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/home/Home.kt new file mode 100644 index 000000000..95ef31716 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/fragments/home/Home.kt @@ -0,0 +1,109 @@ +package com.drdisagree.iconify.ui.fragments.home + +import android.os.Bundle +import android.view.View +import androidx.preference.Preference +import com.drdisagree.iconify.BuildConfig +import com.drdisagree.iconify.Iconify.Companion.appContext +import com.drdisagree.iconify.R +import com.drdisagree.iconify.common.Preferences.FIRST_INSTALL +import com.drdisagree.iconify.common.Preferences.UPDATE_DETECTED +import com.drdisagree.iconify.common.Preferences.VER_CODE +import com.drdisagree.iconify.config.RPrefs.putBoolean +import com.drdisagree.iconify.config.RPrefs.putInt +import com.drdisagree.iconify.services.UpdateScheduler.scheduleUpdates +import com.drdisagree.iconify.ui.activities.MainActivity.Companion.replaceFragment +import com.drdisagree.iconify.ui.base.ControlledPreferenceFragmentCompat +import com.drdisagree.iconify.ui.fragments.settings.AppUpdates +import com.drdisagree.iconify.ui.preferences.UpdateCheckerPreference +import com.drdisagree.iconify.utils.SystemUtils.saveBootId +import com.google.android.material.appbar.AppBarLayout +import com.google.android.material.bottomnavigation.BottomNavigationView + +class Home : ControlledPreferenceFragmentCompat(), AppBarLayout.OnOffsetChangedListener { + + private lateinit var appBarLayout: AppBarLayout + + override val title: String + get() = getString(R.string.app_name) + + override val backButtonEnabled: Boolean + get() = false + + override val layoutResource: Int + get() = R.xml.home + + override val hasMenu: Boolean + get() = false + + override val themeResource: Int + get() = R.style.PrefsThemeCollapsingToolbar + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + val intent = requireActivity().intent + if (intent != null && intent.getBooleanExtra(AppUpdates.KEY_NEW_UPDATE, false)) { + (requireActivity().findViewById(R.id.bottomNavigationView) as BottomNavigationView) + .selectedItemId = R.id.settings + replaceFragment(parentFragmentManager, AppUpdates()) + intent.removeExtra(AppUpdates.KEY_NEW_UPDATE) + } else { + scheduleUpdates(appContext) + } + + appBarLayout = view.findViewById(R.id.appBarLayout) + appBarLayout.addOnOffsetChangedListener(this) + + if (isToolbarFullyExpanded) { + listView.scrollToPosition(0) + } + + putBoolean(FIRST_INSTALL, false) + putBoolean(UPDATE_DETECTED, false) + putInt(VER_CODE, BuildConfig.VERSION_CODE) + saveBootId + } + + override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { + super.onCreatePreferences(savedInstanceState, rootKey) + + findPreference("newUpdate")?.apply { + onPreferenceClickListener = + Preference.OnPreferenceClickListener { + replaceFragment(parentFragmentManager, AppUpdates()) + true + } + + checkForUpdate() + } + } + + override fun onOffsetChanged(appBarLayout: AppBarLayout?, verticalOffset: Int) { + if (verticalOffset == 0) { + if (!isToolbarFullyExpanded) { + listView.scrollToPosition(0) + isToolbarFullyExpanded = true + } + } else { + isToolbarFullyExpanded = false + } + } + + override fun onResume() { + super.onResume() + + if (isToolbarFullyExpanded) { + listView.scrollToPosition(0) + } + } + + override fun onDestroyView() { + super.onDestroyView() + appBarLayout.removeOnOffsetChangedListener(this) + } + + companion object { + private var isToolbarFullyExpanded = true + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/IconPack.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/home/IconPack.kt similarity index 79% rename from app/src/main/java/com/drdisagree/iconify/ui/fragments/IconPack.kt rename to app/src/main/java/com/drdisagree/iconify/ui/fragments/home/IconPack.kt index 48eb3b59f..9d840f588 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/fragments/IconPack.kt +++ b/app/src/main/java/com/drdisagree/iconify/ui/fragments/home/IconPack.kt @@ -1,21 +1,18 @@ -package com.drdisagree.iconify.ui.fragments +package com.drdisagree.iconify.ui.fragments.home import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import androidx.recyclerview.widget.ConcatAdapter import androidx.recyclerview.widget.LinearLayoutManager import com.drdisagree.iconify.R import com.drdisagree.iconify.databinding.FragmentIconPackBinding import com.drdisagree.iconify.ui.adapters.IconPackAdapter -import com.drdisagree.iconify.ui.adapters.MenuAdapter -import com.drdisagree.iconify.ui.adapters.SectionTitleAdapter import com.drdisagree.iconify.ui.base.BaseFragment import com.drdisagree.iconify.ui.dialogs.LoadingDialog import com.drdisagree.iconify.ui.models.IconPackModel -import com.drdisagree.iconify.ui.models.MenuModel import com.drdisagree.iconify.ui.utils.ViewHelper.setHeader +import com.drdisagree.iconify.utils.overlay.manager.IconPackManager class IconPack : BaseFragment() { @@ -44,53 +41,12 @@ class IconPack : BaseFragment() { // RecyclerView binding.iconPackContainer.setLayoutManager(LinearLayoutManager(requireContext())) - val adapter = ConcatAdapter( - initActivityItems(), - SectionTitleAdapter( - requireContext(), - R.layout.view_section_title, - R.string.icon_pack_styles - ), - initIconPackItems() - ) - - binding.iconPackContainer.setAdapter(adapter) + binding.iconPackContainer.setAdapter(initIconPackItems()) binding.iconPackContainer.setHasFixedSize(true) return view } - private fun initActivityItems(): MenuAdapter { - val iconPackActivityList = ArrayList().apply { - add( - MenuModel( - R.id.action_iconPack_to_coloredBattery, - resources.getString(R.string.activity_title_colored_battery), - resources.getString(R.string.activity_desc_colored_battery), - R.drawable.ic_colored_battery - ) - ) - add( - MenuModel( - R.id.action_iconPack_to_mediaIcons, - resources.getString(R.string.activity_title_media_icons), - resources.getString(R.string.activity_desc_media_icons), - R.drawable.ic_media_player_icon - ) - ) - add( - MenuModel( - R.id.action_iconPack_to_settingsIcons, - resources.getString(R.string.activity_title_settings_icons), - resources.getString(R.string.activity_desc_settings_icons), - R.drawable.ic_settings_icon_pack - ) - ) - } - - return MenuAdapter(requireContext(), iconPackActivityList) - } - private fun initIconPackItems(): IconPackAdapter { val iconPackList = ArrayList().apply { add( @@ -238,10 +194,23 @@ class IconPack : BaseFragment() { return IconPackAdapter( requireContext(), iconPackList, - loadingDialog!! + loadingDialog!!, + "IPSUI", + onButtonClick ) } + private val onButtonClick = object : IconPackAdapter.OnButtonClick { + + override fun onEnableClick(position: Int, item: IconPackModel) { + IconPackManager.enableOverlay(index = position + 1, "IPAS", "IPSUI") + } + + override fun onDisableClick(position: Int, item: IconPackModel) { + IconPackManager.disableOverlay(index = position + 1, "IPAS", "IPSUI") + } + } + override fun onDestroy() { loadingDialog?.dismiss() diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/home/IconShape.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/home/IconShape.kt new file mode 100644 index 000000000..091d02487 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/fragments/home/IconShape.kt @@ -0,0 +1,288 @@ +package com.drdisagree.iconify.ui.fragments.home + +import android.os.Bundle +import android.os.Handler +import android.os.Looper +import android.util.Log +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.Toast +import androidx.recyclerview.widget.GridLayoutManager +import com.drdisagree.iconify.Iconify.Companion.appContext +import com.drdisagree.iconify.Iconify.Companion.appContextLocale +import com.drdisagree.iconify.R +import com.drdisagree.iconify.common.Const.FRAMEWORK_PACKAGE +import com.drdisagree.iconify.common.Preferences.SELECTED_ICON_SHAPE +import com.drdisagree.iconify.config.RPrefs +import com.drdisagree.iconify.databinding.FragmentIconShapeBinding +import com.drdisagree.iconify.ui.adapters.IconShapeAdapter +import com.drdisagree.iconify.ui.base.BaseFragment +import com.drdisagree.iconify.ui.dialogs.LoadingDialog +import com.drdisagree.iconify.ui.models.IconShapeModel +import com.drdisagree.iconify.ui.utils.ViewHelper.setHeader +import com.drdisagree.iconify.utils.SystemUtils.hasStoragePermission +import com.drdisagree.iconify.utils.SystemUtils.requestStoragePermission +import com.drdisagree.iconify.utils.overlay.OverlayUtils +import com.drdisagree.iconify.utils.overlay.compiler.OnDemandCompiler.buildOverlay +import java.io.IOException +import java.util.concurrent.atomic.AtomicBoolean + +class IconShape : BaseFragment() { + + private lateinit var binding: FragmentIconShapeBinding + private var loadingDialog: LoadingDialog? = null + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + binding = FragmentIconShapeBinding.inflate(inflater, container, false) + val view: View = binding.getRoot() + + // Header + setHeader( + requireContext(), + getParentFragmentManager(), + binding.header.toolbar, + R.string.activity_title_icon_shape + ) + + // Loading dialog while enabling or disabling pack + loadingDialog = LoadingDialog(requireContext()) + + // Icon masking shape list + val gridLayoutManager = GridLayoutManager(appContext, 3) // 3 columns + gridLayoutManager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() { + override fun getSpanSize(position: Int): Int { + val totalItemCount = binding.iconShapeContainer.adapter?.itemCount ?: return 1 + val spanCount = gridLayoutManager.spanCount + + // Calculate the number of items in the last row + val itemsInLastRow = totalItemCount % spanCount + return if (position >= totalItemCount - itemsInLastRow) { + // Adjust span size for the last row + when (itemsInLastRow) { + 1 -> spanCount // 1 item spans all columns + 2 -> spanCount / 2 // 2 items span half of the columns each + else -> 1 // Default span size (1 column each) + } + } else { + 1 // Default span size (1 column each) + } + } + } + binding.iconShapeContainer.layoutManager = gridLayoutManager + binding.iconShapeContainer.adapter = initIconShapeList() + binding.iconShapeContainer.setHasFixedSize(true) + + return view + } + + private fun initIconShapeList(): IconShapeAdapter { + val iconShapePreviewStyles = ArrayList().apply { + add( + IconShapeModel( + R.drawable.icon_shape_none, + R.string.icon_mask_style_none + ) + ) + add( + IconShapeModel( + R.drawable.icon_shape_pebble, + R.string.icon_mask_style_pebble + ) + ) + add( + IconShapeModel( + R.drawable.icon_shape_rounded_hexagon, + R.string.icon_mask_style_hexagon + ) + ) + add( + IconShapeModel( + R.drawable.icon_shape_samsung, + R.string.icon_mask_style_samsung + ) + ) + add( + IconShapeModel( + R.drawable.icon_shape_scroll, + R.string.icon_mask_style_scroll + ) + ) + add( + IconShapeModel( + R.drawable.icon_shape_teardrops, + R.string.icon_mask_style_teardrop + ) + ) + add( + IconShapeModel( + R.drawable.icon_shape_square, + R.string.icon_mask_style_square + ) + ) + add( + IconShapeModel( + R.drawable.icon_shape_rounded_rectangle, + R.string.icon_mask_style_rounded_rectangle + ) + ) + add( + IconShapeModel( + R.drawable.icon_shape_ios, + R.string.icon_mask_style_ios + ) + ) + add( + IconShapeModel( + R.drawable.icon_shape_cloudy, + R.string.icon_mask_style_cloudy + ) + ) + add( + IconShapeModel( + R.drawable.icon_shape_cylinder, + R.string.icon_mask_style_cylinder + ) + ) + add( + IconShapeModel( + R.drawable.icon_shape_flower, + R.string.icon_mask_style_flower + ) + ) + add( + IconShapeModel( + R.drawable.icon_shape_heart, + R.string.icon_mask_style_heart + ) + ) + add( + IconShapeModel( + R.drawable.icon_shape_leaf, + R.string.icon_mask_style_leaf + ) + ) + add( + IconShapeModel( + R.drawable.icon_shape_stretched, + R.string.icon_mask_style_stretched + ) + ) + add( + IconShapeModel( + R.drawable.icon_shape_tapered_rectangle, + R.string.icon_mask_style_tapered_rectangle + ) + ) + add( + IconShapeModel( + R.drawable.icon_shape_vessel, + R.string.icon_mask_style_vessel + ) + ) + add( + IconShapeModel( + R.drawable.icon_shape_rohie_meow, + R.string.icon_mask_style_rice_rohie_meow + ) + ) + add( + IconShapeModel( + R.drawable.icon_shape_force_round, + R.string.icon_mask_style_force_round + ) + ) + } + + return IconShapeAdapter( + appContext, + iconShapePreviewStyles, + onShapeClick + ) + } + + private val onShapeClick = object : IconShapeAdapter.OnShapeClick { + override fun onShapeClick(position: Int, item: IconShapeModel) { + + if (position == 0) { + RPrefs.putInt(SELECTED_ICON_SHAPE, 0) + OverlayUtils.disableOverlay("IconifyComponentSIS.overlay") + + Toast.makeText( + appContext, + resources.getString(R.string.toast_disabled), + Toast.LENGTH_SHORT + ).show() + loadingDialog!!.hide() + return + } + + if (!hasStoragePermission()) { + requestStoragePermission( + requireContext() + ) + } else { + // Show loading dialog + loadingDialog!!.show(resources.getString(R.string.loading_dialog_wait)) + + Thread { + val hasErroredOut = AtomicBoolean(false) + + try { + hasErroredOut.set( + buildOverlay( + "SIS", + position, + FRAMEWORK_PACKAGE, + true + ) + ) + } catch (e: IOException) { + hasErroredOut.set(true) + Log.e("IconShape", e.toString()) + } + + if (!hasErroredOut.get()) { + RPrefs.putInt(SELECTED_ICON_SHAPE, position) + refreshAdapter() + } + + Handler(Looper.getMainLooper()).postDelayed({ + // Hide loading dialog + loadingDialog!!.hide() + if (!hasErroredOut.get()) { + Toast.makeText( + appContext, + appContextLocale.resources + .getString(R.string.toast_applied), + Toast.LENGTH_SHORT + ).show() + } else { + Toast.makeText( + appContext, + appContextLocale.resources + .getString(R.string.toast_error), + Toast.LENGTH_SHORT + ).show() + } + }, 3000) + }.start() + } + } + } + + private fun refreshAdapter() { + val ad = binding.iconShapeContainer.adapter as IconShapeAdapter + ad.notifyChange() + } + + override fun onDestroy() { + loadingDialog?.dismiss() + + super.onDestroy() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/MediaIcons.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/home/MediaIcons.kt similarity index 94% rename from app/src/main/java/com/drdisagree/iconify/ui/fragments/MediaIcons.kt rename to app/src/main/java/com/drdisagree/iconify/ui/fragments/home/MediaIcons.kt index 052dea5ff..d690c20f1 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/fragments/MediaIcons.kt +++ b/app/src/main/java/com/drdisagree/iconify/ui/fragments/home/MediaIcons.kt @@ -1,4 +1,4 @@ -package com.drdisagree.iconify.ui.fragments +package com.drdisagree.iconify.ui.fragments.home import android.graphics.drawable.Drawable import android.os.Build @@ -13,15 +13,15 @@ import android.widget.TextView import androidx.core.content.ContextCompat import com.drdisagree.iconify.Iconify.Companion.appContext import com.drdisagree.iconify.R -import com.drdisagree.iconify.config.Prefs.getBoolean +import com.drdisagree.iconify.config.RPrefs.getBoolean import com.drdisagree.iconify.databinding.FragmentMediaIconsBinding import com.drdisagree.iconify.ui.base.BaseFragment import com.drdisagree.iconify.ui.utils.ViewHelper.setHeader -import com.drdisagree.iconify.utils.AppUtil.getAppIcon -import com.drdisagree.iconify.utils.AppUtil.getAppName -import com.drdisagree.iconify.utils.AppUtil.isAppInstalledRoot -import com.drdisagree.iconify.utils.AppUtil.launchApp -import com.drdisagree.iconify.utils.overlay.OverlayUtil +import com.drdisagree.iconify.utils.AppUtils.getAppIcon +import com.drdisagree.iconify.utils.AppUtils.getAppName +import com.drdisagree.iconify.utils.AppUtils.isAppInstalledRoot +import com.drdisagree.iconify.utils.AppUtils.launchApp +import com.drdisagree.iconify.utils.overlay.OverlayUtils import com.drdisagree.iconify.utils.overlay.manager.MediaPlayerIconManager.enableOverlay import com.google.android.material.button.MaterialButton import com.google.android.material.button.MaterialButtonToggleGroup @@ -239,7 +239,7 @@ class MediaIcons : BaseFragment() { if (isChecked) { enableOverlay(idx, finalI) } else { - OverlayUtil.disableOverlay("IconifyComponentMPIP$idx$finalI.overlay") + OverlayUtils.disableOverlay("IconifyComponentMPIP$idx$finalI.overlay") } refreshBackground() diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/Notification.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/home/Notification.kt similarity index 93% rename from app/src/main/java/com/drdisagree/iconify/ui/fragments/Notification.kt rename to app/src/main/java/com/drdisagree/iconify/ui/fragments/home/Notification.kt index 31ef57a41..ad6e14d53 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/fragments/Notification.kt +++ b/app/src/main/java/com/drdisagree/iconify/ui/fragments/home/Notification.kt @@ -1,4 +1,4 @@ -package com.drdisagree.iconify.ui.fragments +package com.drdisagree.iconify.ui.fragments.home import android.os.Bundle import android.view.LayoutInflater @@ -51,7 +51,7 @@ class Notification : BaseFragment() { R.layout.view_section_title_notif, R.string.notification_styles ), - initNotifItems() + initNotificationItems() ) binding.notificationsContainer.setAdapter(adapter) @@ -61,10 +61,10 @@ class Notification : BaseFragment() { } private fun initActivityItems(): MenuAdapter { - val notifActivityList = ArrayList().apply { + val notificationActivityList = ArrayList().apply { add( MenuModel( - R.id.action_notification_to_notificationPixel, + NotificationPixel(), resources.getString(R.string.activity_title_pixel_variant), resources.getString(R.string.activity_desc_pixel_variant), R.drawable.ic_pixel_device @@ -73,13 +73,14 @@ class Notification : BaseFragment() { } return MenuAdapter( + parentFragmentManager, requireContext(), - notifActivityList + notificationActivityList ) } - private fun initNotifItems(): NotificationAdapter { - val notifList = ArrayList().apply { + private fun initNotificationItems(): NotificationAdapter { + val notificationList = ArrayList().apply { add( NotificationModel( "Default", @@ -204,7 +205,7 @@ class Notification : BaseFragment() { return NotificationAdapter( requireContext(), - notifList, + notificationList, loadingDialog!!, "NFN" ) diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/NotificationPixel.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/home/NotificationPixel.kt similarity index 99% rename from app/src/main/java/com/drdisagree/iconify/ui/fragments/NotificationPixel.kt rename to app/src/main/java/com/drdisagree/iconify/ui/fragments/home/NotificationPixel.kt index 418d4754a..0475809ef 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/fragments/NotificationPixel.kt +++ b/app/src/main/java/com/drdisagree/iconify/ui/fragments/home/NotificationPixel.kt @@ -1,4 +1,4 @@ -package com.drdisagree.iconify.ui.fragments +package com.drdisagree.iconify.ui.fragments.home import android.os.Bundle import android.view.LayoutInflater diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/ProgressBar.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/home/ProgressBar.kt similarity index 98% rename from app/src/main/java/com/drdisagree/iconify/ui/fragments/ProgressBar.kt rename to app/src/main/java/com/drdisagree/iconify/ui/fragments/home/ProgressBar.kt index d87dcd134..170ac1670 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/fragments/ProgressBar.kt +++ b/app/src/main/java/com/drdisagree/iconify/ui/fragments/home/ProgressBar.kt @@ -1,4 +1,4 @@ -package com.drdisagree.iconify.ui.fragments +package com.drdisagree.iconify.ui.fragments.home import android.os.Bundle import android.view.LayoutInflater diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/QsPanelTile.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/home/QsPanelTile.kt similarity index 97% rename from app/src/main/java/com/drdisagree/iconify/ui/fragments/QsPanelTile.kt rename to app/src/main/java/com/drdisagree/iconify/ui/fragments/home/QsPanelTile.kt index da31606f1..e43cae6b0 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/fragments/QsPanelTile.kt +++ b/app/src/main/java/com/drdisagree/iconify/ui/fragments/home/QsPanelTile.kt @@ -1,4 +1,4 @@ -package com.drdisagree.iconify.ui.fragments +package com.drdisagree.iconify.ui.fragments.home import android.annotation.SuppressLint import android.content.res.Configuration @@ -67,7 +67,7 @@ class QsPanelTile : BaseFragment() { val qsShapeActivityList = ArrayList().apply { add( MenuModel( - R.id.action_qsPanelTile_to_qsPanelTilePixel, + QsPanelTilePixel(), resources.getString(R.string.activity_title_pixel_variant), resources.getString(R.string.activity_desc_pixel_variant), R.drawable.ic_pixel_device @@ -75,7 +75,11 @@ class QsPanelTile : BaseFragment() { ) } - return MenuAdapter(requireContext(), qsShapeActivityList) + return MenuAdapter( + parentFragmentManager, + requireContext(), + qsShapeActivityList + ) } private fun initQsShapeItems(): QsShapeAdapter { diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/QsPanelTilePixel.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/home/QsPanelTilePixel.kt similarity index 99% rename from app/src/main/java/com/drdisagree/iconify/ui/fragments/QsPanelTilePixel.kt rename to app/src/main/java/com/drdisagree/iconify/ui/fragments/home/QsPanelTilePixel.kt index c746ec857..84f88571e 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/fragments/QsPanelTilePixel.kt +++ b/app/src/main/java/com/drdisagree/iconify/ui/fragments/home/QsPanelTilePixel.kt @@ -1,4 +1,4 @@ -package com.drdisagree.iconify.ui.fragments +package com.drdisagree.iconify.ui.fragments.home import android.annotation.SuppressLint import android.content.res.Configuration diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/SettingsIcons.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/home/SettingsIcons.kt similarity index 88% rename from app/src/main/java/com/drdisagree/iconify/ui/fragments/SettingsIcons.kt rename to app/src/main/java/com/drdisagree/iconify/ui/fragments/home/SettingsIcons.kt index 051533954..d4007f97b 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/fragments/SettingsIcons.kt +++ b/app/src/main/java/com/drdisagree/iconify/ui/fragments/home/SettingsIcons.kt @@ -1,4 +1,4 @@ -package com.drdisagree.iconify.ui.fragments +package com.drdisagree.iconify.ui.fragments.home import android.os.Bundle import android.os.Handler @@ -20,15 +20,15 @@ import com.drdisagree.iconify.common.Preferences.SELECTED_SETTINGS_ICONS_COLOR import com.drdisagree.iconify.common.Preferences.SELECTED_SETTINGS_ICONS_SET import com.drdisagree.iconify.common.Preferences.SELECTED_SETTINGS_ICONS_SHAPE import com.drdisagree.iconify.common.Preferences.SELECTED_SETTINGS_ICONS_SIZE -import com.drdisagree.iconify.config.Prefs -import com.drdisagree.iconify.config.Prefs.clearPrefs +import com.drdisagree.iconify.config.RPrefs +import com.drdisagree.iconify.config.RPrefs.clearPrefs import com.drdisagree.iconify.databinding.FragmentSettingsIconsBinding import com.drdisagree.iconify.ui.dialogs.LoadingDialog import com.drdisagree.iconify.ui.utils.ViewHelper.setHeader -import com.drdisagree.iconify.utils.SystemUtil.hasStoragePermission -import com.drdisagree.iconify.utils.SystemUtil.requestStoragePermission -import com.drdisagree.iconify.utils.overlay.OverlayUtil -import com.drdisagree.iconify.utils.overlay.OverlayUtil.enableOverlays +import com.drdisagree.iconify.utils.SystemUtils.hasStoragePermission +import com.drdisagree.iconify.utils.SystemUtils.requestStoragePermission +import com.drdisagree.iconify.utils.overlay.OverlayUtils +import com.drdisagree.iconify.utils.overlay.OverlayUtils.enableOverlays import com.drdisagree.iconify.utils.overlay.manager.SettingsIconResourceManager.buildOverlay import java.io.IOException import java.util.concurrent.atomic.AtomicBoolean @@ -58,31 +58,31 @@ class SettingsIcons : Fragment() { loadingDialog = LoadingDialog(requireContext()) // Retrieve previously saved preferences - selectedIcon = Prefs.getInt(SELECTED_SETTINGS_ICONS_SET, 1) + selectedIcon = RPrefs.getInt(SELECTED_SETTINGS_ICONS_SET, 1) // Background style - binding.bgStyle.setSelectedIndex(Prefs.getInt(SELECTED_SETTINGS_ICONS_BG, 1) - 1) + binding.bgStyle.setSelectedIndex(RPrefs.getInt(SELECTED_SETTINGS_ICONS_BG, 1) - 1) binding.bgStyle.setOnItemSelectedListener { index: Int -> selectedBackground = index + 1 } selectedBackground = binding.bgStyle.getSelectedIndex() + 1 // Background Shape - binding.bgShape.setSelectedIndex(Prefs.getInt(SELECTED_SETTINGS_ICONS_SHAPE, 1) - 1) + binding.bgShape.setSelectedIndex(RPrefs.getInt(SELECTED_SETTINGS_ICONS_SHAPE, 1) - 1) binding.bgShape.setOnItemSelectedListener { index: Int -> selectedShape = index + 1 } selectedShape = binding.bgShape.getSelectedIndex() + 1 // Icon Size - binding.iconSize.setSelectedIndex(Prefs.getInt(SELECTED_SETTINGS_ICONS_SIZE, 1) - 1) + binding.iconSize.setSelectedIndex(RPrefs.getInt(SELECTED_SETTINGS_ICONS_SIZE, 1) - 1) binding.iconSize.setOnItemSelectedListener { index: Int -> selectedSize = index + 1 } selectedSize = binding.iconSize.getSelectedIndex() + 1 // Icon color - binding.iconColor.setSelectedIndex(Prefs.getInt(SELECTED_SETTINGS_ICONS_COLOR, 1) - 1) + binding.iconColor.setSelectedIndex(RPrefs.getInt(SELECTED_SETTINGS_ICONS_COLOR, 1) - 1) binding.iconColor.setOnItemSelectedListener { index: Int -> selectedIconColor = index + 1 } @@ -115,7 +115,7 @@ class SettingsIcons : Fragment() { refreshBackground() // Enable and disable button - if (Prefs.getBoolean("IconifyComponentSIP1.overlay")) { + if (RPrefs.getBoolean("IconifyComponentSIP1.overlay")) { binding.disableSettingsIcons.visibility = View.VISIBLE } binding.enableSettingsIcons.setOnClickListener { @@ -146,11 +146,11 @@ class SettingsIcons : Fragment() { Handler(Looper.getMainLooper()).post { if (!hasErroredOut.get()) { - Prefs.putInt(SELECTED_SETTINGS_ICONS_SET, selectedIcon) - Prefs.putInt(SELECTED_SETTINGS_ICONS_BG, selectedBackground) - Prefs.putInt(SELECTED_SETTINGS_ICONS_SHAPE, selectedShape) - Prefs.putInt(SELECTED_SETTINGS_ICONS_SIZE, selectedSize) - Prefs.putInt(SELECTED_SETTINGS_ICONS_COLOR, selectedIconColor) + RPrefs.putInt(SELECTED_SETTINGS_ICONS_SET, selectedIcon) + RPrefs.putInt(SELECTED_SETTINGS_ICONS_BG, selectedBackground) + RPrefs.putInt(SELECTED_SETTINGS_ICONS_SHAPE, selectedShape) + RPrefs.putInt(SELECTED_SETTINGS_ICONS_SIZE, selectedSize) + RPrefs.putInt(SELECTED_SETTINGS_ICONS_COLOR, selectedIconColor) binding.disableSettingsIcons.visibility = View.VISIBLE binding.iconPacksList.getChildAt(selectedIcon - 1) @@ -181,7 +181,7 @@ class SettingsIcons : Fragment() { } } binding.disableSettingsIcons.setOnClickListener { - binding.iconPacksList.getChildAt(Prefs.getInt(SELECTED_SETTINGS_ICONS_SET, 1) - 1) + binding.iconPacksList.getChildAt(RPrefs.getInt(SELECTED_SETTINGS_ICONS_SET, 1) - 1) .findViewById(R.id.icon_selected).visibility = View.INVISIBLE clearPrefs( @@ -192,7 +192,7 @@ class SettingsIcons : Fragment() { binding.disableSettingsIcons.visibility = View.GONE - OverlayUtil.disableOverlays( + OverlayUtils.disableOverlays( "IconifyComponentSIP1.overlay", "IconifyComponentSIP2.overlay", "IconifyComponentSIP3.overlay" @@ -291,7 +291,7 @@ class SettingsIcons : Fragment() { itemSelected( child, - Prefs.getInt(SELECTED_SETTINGS_ICONS_SET, 1) == i + 1, + RPrefs.getInt(SELECTED_SETTINGS_ICONS_SET, 1) == i + 1, i + 1 ) } @@ -349,8 +349,8 @@ class SettingsIcons : Fragment() { ) ) parent.findViewById(R.id.icon_selected).visibility = - if (Prefs.getBoolean("IconifyComponentSIP1.overlay") && - Prefs.getInt(SELECTED_SETTINGS_ICONS_SET, 1) == selectedIndex + if (RPrefs.getBoolean("IconifyComponentSIP1.overlay") && + RPrefs.getInt(SELECTED_SETTINGS_ICONS_SET, 1) == selectedIndex ) View.VISIBLE else View.INVISIBLE parent.findViewById(R.id.iconpack_desc).setAlpha(0.8f) } else { diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/Switch.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/home/Switch.kt similarity index 98% rename from app/src/main/java/com/drdisagree/iconify/ui/fragments/Switch.kt rename to app/src/main/java/com/drdisagree/iconify/ui/fragments/home/Switch.kt index 6e4efd6ab..ec2bdbb7b 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/fragments/Switch.kt +++ b/app/src/main/java/com/drdisagree/iconify/ui/fragments/home/Switch.kt @@ -1,4 +1,4 @@ -package com.drdisagree.iconify.ui.fragments +package com.drdisagree.iconify.ui.fragments.home import android.os.Bundle import android.view.LayoutInflater diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/home/ToastFrame.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/home/ToastFrame.kt new file mode 100644 index 000000000..5360857b0 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/fragments/home/ToastFrame.kt @@ -0,0 +1,239 @@ +package com.drdisagree.iconify.ui.fragments.home + +import android.os.Bundle +import android.os.Handler +import android.os.Looper +import android.util.Log +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.Toast +import androidx.recyclerview.widget.GridLayoutManager +import androidx.recyclerview.widget.GridLayoutManager.SpanSizeLookup +import com.drdisagree.iconify.Iconify.Companion.appContext +import com.drdisagree.iconify.Iconify.Companion.appContextLocale +import com.drdisagree.iconify.R +import com.drdisagree.iconify.common.Const.FRAMEWORK_PACKAGE +import com.drdisagree.iconify.common.Preferences.SELECTED_TOAST_FRAME +import com.drdisagree.iconify.config.RPrefs +import com.drdisagree.iconify.config.RPrefs.getInt +import com.drdisagree.iconify.databinding.FragmentToastFrameBinding +import com.drdisagree.iconify.ui.adapters.ToastAdapter +import com.drdisagree.iconify.ui.base.BaseFragment +import com.drdisagree.iconify.ui.dialogs.LoadingDialog +import com.drdisagree.iconify.ui.models.ToastModel +import com.drdisagree.iconify.ui.utils.ViewHelper.setHeader +import com.drdisagree.iconify.utils.SystemUtils.hasStoragePermission +import com.drdisagree.iconify.utils.SystemUtils.requestStoragePermission +import com.drdisagree.iconify.utils.overlay.OverlayUtils +import com.drdisagree.iconify.utils.overlay.compiler.OnDemandCompiler.buildOverlay +import java.io.IOException +import java.util.concurrent.atomic.AtomicBoolean + +class ToastFrame : BaseFragment() { + + private lateinit var binding: FragmentToastFrameBinding + private var loadingDialog: LoadingDialog? = null + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + binding = FragmentToastFrameBinding.inflate(inflater, container, false) + val view: View = binding.getRoot() + + // Header + setHeader( + requireContext(), + getParentFragmentManager(), + binding.header.toolbar, + R.string.activity_title_toast_frame + ) + + // Loading dialog while enabling or disabling pack + loadingDialog = LoadingDialog(requireContext()) + + // Toast Frame style + val gridLayout = GridLayoutManager(requireContext(), 2) + gridLayout.spanSizeLookup = object : SpanSizeLookup() { + override fun getSpanSize(position: Int): Int { + val lastIndex = binding.toastStylesContainer.adapter?.itemCount?.minus(1) ?: 0 + + return if (position == lastIndex && lastIndex % gridLayout.spanCount == 0) { + 2 + } else { + 1 + } + } + } + binding.toastStylesContainer.setLayoutManager(gridLayout) + binding.toastStylesContainer.setAdapter(initToastFrameItems()) + binding.toastStylesContainer.setHasFixedSize(true) + + return view + } + + private fun initToastFrameItems(): ToastAdapter { + val selectedStyle = getInt(SELECTED_TOAST_FRAME, -1) + val toastFrameStyle = ArrayList().apply { + add( + ToastModel( + R.drawable.toast_frame_style_1, + appContextLocale.resources.getString(R.string.style_0) + ) + ) + add( + ToastModel( + R.drawable.toast_frame_style_1, + String.format(appContextLocale.resources.getString(R.string.style), 1) + ) + ) + add( + ToastModel( + R.drawable.toast_frame_style_2, + String.format(appContextLocale.resources.getString(R.string.style), 2) + ) + ) + add( + ToastModel( + R.drawable.toast_frame_style_3, + String.format(appContextLocale.resources.getString(R.string.style), 3) + ) + ) + add( + ToastModel( + R.drawable.toast_frame_style_4, + String.format(appContextLocale.resources.getString(R.string.style), 4) + ) + ) + add( + ToastModel( + R.drawable.toast_frame_style_5, + String.format(appContextLocale.resources.getString(R.string.style), 5) + ) + ) + add( + ToastModel( + R.drawable.toast_frame_style_6, + String.format(appContextLocale.resources.getString(R.string.style), 6) + ) + ) + add( + ToastModel( + R.drawable.toast_frame_style_7, + String.format(appContextLocale.resources.getString(R.string.style), 7) + ) + ) + add( + ToastModel( + R.drawable.toast_frame_style_8, + String.format(appContextLocale.resources.getString(R.string.style), 8) + ) + ) + add( + ToastModel( + R.drawable.toast_frame_style_9, + String.format(appContextLocale.resources.getString(R.string.style), 9) + ) + ) + add( + ToastModel( + R.drawable.toast_frame_style_10, + String.format(appContextLocale.resources.getString(R.string.style), 10) + ) + ) + add( + ToastModel( + R.drawable.toast_frame_style_11, + String.format(appContextLocale.resources.getString(R.string.style), 11) + ) + ) + add( + ToastModel( + R.drawable.toast_frame_style_12, + String.format(appContextLocale.resources.getString(R.string.style), 12) + ) + ) + } + + return ToastAdapter( + requireContext(), + toastFrameStyle, + onToastClick + ) + } + + private val onToastClick = object : ToastAdapter.OnToastClick { + override fun onToastClick(position: Int, item: ToastModel) { + + if (!hasStoragePermission()) { + requestStoragePermission(appContext) + return + } + + if (position == 0) { + RPrefs.putInt(SELECTED_TOAST_FRAME, -1) + OverlayUtils.disableOverlay("IconifyComponentTSTFRM.overlay") + Toast.makeText( + appContext, + appContextLocale.resources.getString(R.string.toast_disabled), + Toast.LENGTH_SHORT + ).show() + return + } + + // Show loading dialog + loadingDialog!!.show(appContextLocale.resources.getString(R.string.loading_dialog_wait)) + + Thread { + val hasErroredOut = AtomicBoolean(false) + + try { + hasErroredOut.set( + buildOverlay( + "TSTFRM", + position, + FRAMEWORK_PACKAGE, + true + ) + ) + } catch (e: IOException) { + hasErroredOut.set(true) + Log.e("ToastFrame", e.toString()) + } + + if (!hasErroredOut.get()) { + RPrefs.putInt(SELECTED_TOAST_FRAME, position) + val ad = binding.toastStylesContainer.adapter as ToastAdapter + ad.notifyChange() + } + + Handler(Looper.getMainLooper()).postDelayed({ + // Hide loading dialog + loadingDialog!!.hide() + + if (!hasErroredOut.get()) { + Toast.makeText( + appContext, + appContextLocale.resources.getString(R.string.toast_applied), + Toast.LENGTH_SHORT + ).show() + } else { + Toast.makeText( + appContext, + appContextLocale.resources.getString(R.string.toast_error), + Toast.LENGTH_SHORT + ).show() + } + }, 3000) + }.start() + } + } + + override fun onDestroy() { + loadingDialog?.dismiss() + + super.onDestroy() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/home/WiFiIcons.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/home/WiFiIcons.kt new file mode 100644 index 000000000..5cefd0db4 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/fragments/home/WiFiIcons.kt @@ -0,0 +1,119 @@ +package com.drdisagree.iconify.ui.fragments.home + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.recyclerview.widget.LinearLayoutManager +import com.drdisagree.iconify.BuildConfig +import com.drdisagree.iconify.R +import com.drdisagree.iconify.databinding.FragmentIconPackBinding +import com.drdisagree.iconify.ui.adapters.IconPackAdapter +import com.drdisagree.iconify.ui.base.BaseFragment +import com.drdisagree.iconify.ui.dialogs.LoadingDialog +import com.drdisagree.iconify.ui.models.IconPackModel +import com.drdisagree.iconify.ui.utils.ViewHelper.setHeader +import com.drdisagree.iconify.utils.overlay.manager.SignalIconManager +import java.util.Locale + +class WiFiIcons : BaseFragment() { + + private lateinit var binding: FragmentIconPackBinding + private var loadingDialog: LoadingDialog? = null + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + binding = FragmentIconPackBinding.inflate(inflater, container, false) + + // Header + setHeader( + requireContext(), + getParentFragmentManager(), + binding.header.toolbar, + R.string.activity_title_wifi_icons + ) + + // Loading dialog while enabling or disabling pack + loadingDialog = LoadingDialog(requireContext()) + + // RecyclerView + binding.iconPackContainer.setLayoutManager(LinearLayoutManager(requireContext())) + + binding.iconPackContainer.setAdapter(initIconPackItems()) + binding.iconPackContainer.setHasFixedSize(true) + + return binding.getRoot() + } + + @Suppress("DiscouragedApi") + private fun initIconPackItems(): IconPackAdapter { + val iconPackList = ArrayList().apply { + val themes = listOf( + "Aurora", "Bars", "Dora", "Faint UI", "Lorn", "Gradicon", + "Inside", "Nothing Dot", "Plumpy", "Round", "Sneaky", "Stroke", + "Wavy", "Weed", "Xperia", "ZigZag" + ) + + val packageName = BuildConfig.APPLICATION_ID + + themes.forEachIndexed { _, themeName -> + val themeResourceName = themeName.replace(" ", "_").lowercase(Locale.ROOT) + + add( + IconPackModel( + themeName, + 0, + resources.getIdentifier( + "preview_${themeResourceName}_ic_wifi_signal_1", + "drawable", + packageName + ), + resources.getIdentifier( + "preview_${themeResourceName}_ic_wifi_signal_2", + "drawable", + packageName + ), + resources.getIdentifier( + "preview_${themeResourceName}_ic_wifi_signal_3", + "drawable", + packageName + ), + resources.getIdentifier( + "preview_${themeResourceName}_ic_wifi_signal_4", + "drawable", + packageName + ) + ) + ) + } + } + + return IconPackAdapter( + requireContext(), + iconPackList, + loadingDialog!!, + "WIFI", + onButtonClick + ) + } + + private val onButtonClick = object : IconPackAdapter.OnButtonClick { + + override fun onEnableClick(position: Int, item: IconPackModel) { + SignalIconManager.enableOverlay(n = position + 1, "WIFI") + } + + override fun onDisableClick(position: Int, item: IconPackModel) { + SignalIconManager.disableOverlay(n = position + 1, "WIFI") + } + } + + override fun onDestroy() { + loadingDialog?.dismiss() + + super.onDestroy() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/AppUpdates.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/settings/AppUpdates.kt similarity index 97% rename from app/src/main/java/com/drdisagree/iconify/ui/fragments/AppUpdates.kt rename to app/src/main/java/com/drdisagree/iconify/ui/fragments/settings/AppUpdates.kt index 434f444ea..53e43dbb2 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/fragments/AppUpdates.kt +++ b/app/src/main/java/com/drdisagree/iconify/ui/fragments/settings/AppUpdates.kt @@ -1,4 +1,4 @@ -package com.drdisagree.iconify.ui.fragments +package com.drdisagree.iconify.ui.fragments.settings import android.content.Intent import android.net.Uri @@ -23,8 +23,8 @@ import com.drdisagree.iconify.common.Const.LATEST_VERSION_URL import com.drdisagree.iconify.common.Preferences.UPDATE_CHECK_TIME import com.drdisagree.iconify.common.Preferences.UPDATE_SCHEDULE import com.drdisagree.iconify.common.Preferences.VER_CODE -import com.drdisagree.iconify.config.Prefs -import com.drdisagree.iconify.config.Prefs.putLong +import com.drdisagree.iconify.config.RPrefs +import com.drdisagree.iconify.config.RPrefs.putLong import com.drdisagree.iconify.databinding.FragmentAppUpdatesBinding import com.drdisagree.iconify.ui.base.BaseFragment import com.drdisagree.iconify.ui.utils.ViewHelper.dp2px @@ -60,9 +60,9 @@ class AppUpdates : BaseFragment() { ) // Update Schedule - binding.updateSchedule.setSelectedIndex(Prefs.getInt(UPDATE_SCHEDULE, 1)) + binding.updateSchedule.setSelectedIndex(RPrefs.getInt(UPDATE_SCHEDULE, 1)) binding.updateSchedule.setOnItemSelectedListener { index: Int -> - Prefs.putInt(UPDATE_SCHEDULE, index) + RPrefs.putInt(UPDATE_SCHEDULE, index) when (index) { 0 -> putLong(UPDATE_CHECK_TIME, 6) 1 -> putLong(UPDATE_CHECK_TIME, 12) diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/Changelog.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/settings/Changelog.kt similarity index 99% rename from app/src/main/java/com/drdisagree/iconify/ui/fragments/Changelog.kt rename to app/src/main/java/com/drdisagree/iconify/ui/fragments/settings/Changelog.kt index 86674bdc7..815e42de0 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/fragments/Changelog.kt +++ b/app/src/main/java/com/drdisagree/iconify/ui/fragments/settings/Changelog.kt @@ -1,4 +1,4 @@ -package com.drdisagree.iconify.ui.fragments +package com.drdisagree.iconify.ui.fragments.settings import android.content.Intent import android.net.Uri diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/Credits.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/settings/Credits.kt similarity index 97% rename from app/src/main/java/com/drdisagree/iconify/ui/fragments/Credits.kt rename to app/src/main/java/com/drdisagree/iconify/ui/fragments/settings/Credits.kt index fc05d2f2f..f563fcecc 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/fragments/Credits.kt +++ b/app/src/main/java/com/drdisagree/iconify/ui/fragments/settings/Credits.kt @@ -1,4 +1,4 @@ -package com.drdisagree.iconify.ui.fragments +package com.drdisagree.iconify.ui.fragments.settings import android.os.Bundle import android.view.LayoutInflater @@ -155,6 +155,15 @@ class Credits : BaseFragment() { val contributorsList = ArrayList().apply { add(InfoModel(resources.getString(R.string.section_title_contributors))) + add( + InfoModel( + requireContext(), + "Luigi", + appContextLocale.resources.getString(R.string.info_contributor_desc), + "https://github.com/DHD2280", + R.drawable.ic_user + ) + ) add( InfoModel( requireContext(), diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/settings/Experimental.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/settings/Experimental.kt new file mode 100644 index 000000000..fb246e210 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/fragments/settings/Experimental.kt @@ -0,0 +1,217 @@ +package com.drdisagree.iconify.ui.fragments.settings + +import android.Manifest +import android.annotation.SuppressLint +import android.app.NotificationChannel +import android.app.NotificationManager +import android.app.PendingIntent +import android.content.Context +import android.content.Intent +import android.content.pm.PackageManager +import android.os.Build +import android.os.Bundle +import android.os.Handler +import android.os.Looper +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.CompoundButton +import android.widget.Toast +import androidx.activity.result.contract.ActivityResultContracts +import androidx.core.app.NotificationCompat +import androidx.core.content.ContextCompat +import com.drdisagree.iconify.R +import com.drdisagree.iconify.common.Const.SWITCH_ANIMATION_DELAY +import com.drdisagree.iconify.common.Preferences.HEADER_IMAGE_OVERLAP +import com.drdisagree.iconify.common.Preferences.HIDE_DATA_DISABLED_ICON +import com.drdisagree.iconify.common.Preferences.OP_QS_HEADER_GAP_EXPANDED +import com.drdisagree.iconify.config.RPrefs.getBoolean +import com.drdisagree.iconify.config.RPrefs.getInt +import com.drdisagree.iconify.config.RPrefs.putBoolean +import com.drdisagree.iconify.config.RPrefs.putInt +import com.drdisagree.iconify.databinding.FragmentExperimentalBinding +import com.drdisagree.iconify.ui.activities.MainActivity +import com.drdisagree.iconify.ui.base.BaseFragment +import com.drdisagree.iconify.ui.dialogs.EditTextDialog +import com.drdisagree.iconify.ui.utils.ViewHelper.setHeader +import com.drdisagree.iconify.utils.SystemUtils +import com.google.android.material.slider.Slider +import kotlin.random.Random + +class Experimental : BaseFragment() { + + private lateinit var binding: FragmentExperimentalBinding + private lateinit var notificationManager: NotificationManager + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + notificationManager = + requireContext().getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager + } + + @SuppressLint("InlinedApi") + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + binding = FragmentExperimentalBinding.inflate(inflater, container, false) + val root: View = binding.getRoot() + + // Header + setHeader( + requireContext(), + getParentFragmentManager(), + binding.header.toolbar, + R.string.activity_title_experimental + ) + + // Header image overlap + binding.headerImageOverlap.isSwitchChecked = getBoolean(HEADER_IMAGE_OVERLAP, false) + binding.headerImageOverlap.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> + putBoolean(HEADER_IMAGE_OVERLAP, isChecked) + + Handler(Looper.getMainLooper()).postDelayed( + { SystemUtils.restartSystemUI() }, + SWITCH_ANIMATION_DELAY + ) + } + + // Hide data disabled icon + binding.hideDataDisabledIcon.isSwitchChecked = getBoolean(HIDE_DATA_DISABLED_ICON, false) + binding.hideDataDisabledIcon.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> + putBoolean(HIDE_DATA_DISABLED_ICON, isChecked) + } + + // OP QS Header Gap Expanded + binding.opQsGapExpanded.apply { + visibility = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { + View.VISIBLE + } else { + View.GONE + } + sliderValue = getInt(OP_QS_HEADER_GAP_EXPANDED, 0) + setResetClickListener { + putInt(OP_QS_HEADER_GAP_EXPANDED, 0) + + MainActivity.showOrHidePendingActionButton( + activityBinding = (requireActivity() as MainActivity).binding, + requiresSystemUiRestart = true + ) + + true + } + setOnSliderTouchListener(object : Slider.OnSliderTouchListener { + override fun onStartTrackingTouch(slider: Slider) {} + + override fun onStopTrackingTouch(slider: Slider) { + putInt(OP_QS_HEADER_GAP_EXPANDED, slider.value.toInt()) + + MainActivity.showOrHidePendingActionButton( + activityBinding = (requireActivity() as MainActivity).binding, + requiresSystemUiRestart = true + ) + } + }) + } + + // Send notification + binding.sendNotification.setOnClickListener { + val permissionGranted = hasNotificationPermission() + + if (!permissionGranted) { + requestNotificationPermission.launch(Manifest.permission.POST_NOTIFICATIONS) + return@setOnClickListener + } + + showCustomNotificationDialog() + } + + return root + } + + private fun showCustomNotificationDialog() { + EditTextDialog(requireContext(), View.generateViewId()).apply { + setDialogListener(object : EditTextDialog.EditTextDialogListener { + override fun onOkPressed(dialogId: Int, newText: String) { + if (newText.isNotEmpty()) { + sendCustomNotification(requireContext(), newText, notificationManager) + } else { + Toast.makeText( + requireContext(), + "Please enter a message", + Toast.LENGTH_SHORT + ).show() + } + } + }) + + show("Notification Body", "Enter notification message", "Enter message", "") + } + } + + private val requestNotificationPermission = registerForActivityResult( + ActivityResultContracts.RequestPermission() + ) { result: Boolean -> + if (result) { + showCustomNotificationDialog() + } else { + Toast.makeText( + requireContext(), + "Permission not granted", + Toast.LENGTH_SHORT + ).show() + } + } + + private fun createChannel(notificationManager: NotificationManager) { + val channel = NotificationChannel( + "TEST_NOTIFICATION_CHANNEL", + "Test Notification", + NotificationManager.IMPORTANCE_DEFAULT + ) + channel.description = "This channel is for testing purposes" + + notificationManager.createNotificationChannel(channel) + } + + private fun sendCustomNotification( + context: Context, + message: String, + notificationManager: NotificationManager + ) { + createChannel(notificationManager) + + val intent = Intent(context, MainActivity::class.java).apply { + flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK + } + val pendingIntent = PendingIntent.getActivity( + context, + 0, + intent, + PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE + ) + + val notification = NotificationCompat.Builder(context, "TEST_NOTIFICATION_CHANNEL") + .setSmallIcon(R.drawable.ic_launcher_fg) + .setContentTitle(getString(R.string.derived_app_name)) + .setContentText(message) + .setPriority(NotificationCompat.PRIORITY_DEFAULT) + .setContentIntent(pendingIntent) + .setAutoCancel(true) + .build() + + notificationManager.notify(Random.nextInt(), notification) + } + + private fun hasNotificationPermission(): Boolean { + return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + ContextCompat.checkSelfPermission( + requireContext(), Manifest.permission.POST_NOTIFICATIONS + ) == PackageManager.PERMISSION_GRANTED + } else { + true + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/settings/Settings.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/settings/Settings.kt new file mode 100644 index 000000000..b51db4c19 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/fragments/settings/Settings.kt @@ -0,0 +1,209 @@ +package com.drdisagree.iconify.ui.fragments.settings + +import android.content.ComponentName +import android.content.DialogInterface +import android.content.Intent +import android.content.pm.PackageManager +import android.net.Uri +import android.os.Bundle +import android.os.Handler +import android.os.Looper +import android.widget.Toast +import com.drdisagree.iconify.Iconify.Companion.appContext +import com.drdisagree.iconify.Iconify.Companion.appContextLocale +import com.drdisagree.iconify.R +import com.drdisagree.iconify.common.Const +import com.drdisagree.iconify.common.Preferences.APP_ICON +import com.drdisagree.iconify.common.Preferences.APP_LANGUAGE +import com.drdisagree.iconify.common.Preferences.APP_THEME +import com.drdisagree.iconify.common.Preferences.FIRST_INSTALL +import com.drdisagree.iconify.common.Preferences.ON_HOME_PAGE +import com.drdisagree.iconify.common.Preferences.RESTART_SYSUI_AFTER_BOOT +import com.drdisagree.iconify.common.Resources.MODULE_DIR +import com.drdisagree.iconify.config.RPrefs +import com.drdisagree.iconify.ui.base.ControlledPreferenceFragmentCompat +import com.drdisagree.iconify.ui.dialogs.LoadingDialog +import com.drdisagree.iconify.ui.preferences.PreferenceMenu +import com.drdisagree.iconify.utils.AppUtils.restartApplication +import com.drdisagree.iconify.utils.CacheUtils.clearCache +import com.drdisagree.iconify.utils.SystemUtils.disableBlur +import com.drdisagree.iconify.utils.SystemUtils.disableRestartSystemuiAfterBoot +import com.drdisagree.iconify.utils.SystemUtils.enableRestartSystemuiAfterBoot +import com.drdisagree.iconify.utils.SystemUtils.restartSystemUI +import com.drdisagree.iconify.utils.SystemUtils.saveBootId +import com.drdisagree.iconify.utils.SystemUtils.saveVersionCode +import com.drdisagree.iconify.utils.weather.WeatherConfig +import com.google.android.material.dialog.MaterialAlertDialogBuilder +import com.topjohnwu.superuser.Shell +import java.util.concurrent.Executors + +class Settings : ControlledPreferenceFragmentCompat() { + + private var loadingDialog: LoadingDialog? = null + + override val title: String + get() = getString(R.string.settings_title) + + override val backButtonEnabled: Boolean + get() = true + + override val layoutResource: Int + get() = R.xml.settings + + override val hasMenu: Boolean + get() = true + + override val menuResource: Int + get() = R.menu.settings_menu + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + // Initialize loading dialog + loadingDialog = LoadingDialog(requireActivity()) + } + + override fun updateScreen(key: String?) { + super.updateScreen(key) + + when (key) { + APP_LANGUAGE -> { + restartApplication(requireActivity()) + } + + APP_ICON -> { + val splashActivities = appContextLocale.resources + .getStringArray(R.array.app_icon_identifier) + changeIcon(RPrefs.getString(key, splashActivities[0])!!) + } + + APP_THEME -> { + restartApplication(requireActivity()) + } + + RESTART_SYSUI_AFTER_BOOT -> { + if (RPrefs.getBoolean(key, false)) { + enableRestartSystemuiAfterBoot() + } else { + disableRestartSystemuiAfterBoot() + } + } + } + } + + override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { + super.onCreatePreferences(savedInstanceState, rootKey) + + findPreference("clearAppCache")?.setOnPreferenceClickListener { + clearCache(appContext) + Toast.makeText( + appContext, + appContextLocale.resources.getString(R.string.toast_clear_cache), + Toast.LENGTH_SHORT + ).show() + true + } + + findPreference("disableEverything")?.setOnPreferenceClickListener { + MaterialAlertDialogBuilder(requireActivity()) + .setCancelable(true) + .setTitle(requireContext().resources.getString(R.string.import_settings_confirmation_title)) + .setMessage(requireContext().resources.getString(R.string.import_settings_confirmation_desc)) + .setPositiveButton(getString(R.string.positive)) { dialog: DialogInterface, _: Int -> + dialog.dismiss() + + // Show loading dialog + loadingDialog?.show(resources.getString(R.string.loading_dialog_wait)) + + Executors.newSingleThreadExecutor().execute { + Settings.disableEverything() + Handler(Looper.getMainLooper()).postDelayed({ + + // Hide loading dialog + loadingDialog?.hide() + + // Restart SystemUI + restartSystemUI() + }, 3000) + } + } + .setNegativeButton(getString(R.string.negative)) { dialog: DialogInterface, _: Int -> + dialog.dismiss() + } + .show() + true + } + + findPreference("iconifyGitHub")?.setOnPreferenceClickListener { + startActivity( + Intent(Intent.ACTION_VIEW).apply { + data = Uri.parse(Const.GITHUB_REPO) + } + ) + true + } + + findPreference("iconifyTelegram")?.setOnPreferenceClickListener { + startActivity( + Intent(Intent.ACTION_VIEW).apply { + data = Uri.parse(Const.TELEGRAM_GROUP) + } + ) + true + } + + findPreference("iconifyTranslate")?.setOnPreferenceClickListener { + startActivity( + Intent(Intent.ACTION_VIEW).apply { + data = Uri.parse(Const.ICONIFY_CROWDIN) + } + ) + true + } + } + + private fun changeIcon(splash: String) { + val manager = requireActivity().packageManager + val splashActivities = appContextLocale.resources + .getStringArray(R.array.app_icon_identifier) + + for (splashActivity in splashActivities) { + manager.setComponentEnabledSetting( + ComponentName( + requireActivity(), + "com.drdisagree.iconify.$splashActivity" + ), + if (splash == splashActivity) { + PackageManager.COMPONENT_ENABLED_STATE_ENABLED + } else { + PackageManager.COMPONENT_ENABLED_STATE_DISABLED + }, + PackageManager.DONT_KILL_APP + ) + } + } + + override fun onDestroy() { + loadingDialog?.hide() + + super.onDestroy() + } + + companion object { + fun disableEverything() { + WeatherConfig.clear(appContext) + RPrefs.clearAllPrefs() + + saveBootId + disableBlur(false) + saveVersionCode() + + RPrefs.putBoolean(ON_HOME_PAGE, true) + RPrefs.putBoolean(FIRST_INSTALL, false) + + Shell.cmd( + "> $MODULE_DIR/system.prop; > $MODULE_DIR/post-exec.sh; for ol in $(cmd overlay list | grep -E '.x.*IconifyComponent' | sed -E 's/^.x..//'); do cmd overlay disable \$ol; done; killall com.android.systemui" + ).submit() + } + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/BasicColors.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/tweaks/BasicColors.kt similarity index 94% rename from app/src/main/java/com/drdisagree/iconify/ui/fragments/BasicColors.kt rename to app/src/main/java/com/drdisagree/iconify/ui/fragments/tweaks/BasicColors.kt index d1aa659f3..c24dc7eb8 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/fragments/BasicColors.kt +++ b/app/src/main/java/com/drdisagree/iconify/ui/fragments/tweaks/BasicColors.kt @@ -1,4 +1,4 @@ -package com.drdisagree.iconify.ui.fragments +package com.drdisagree.iconify.ui.fragments.tweaks import android.graphics.drawable.GradientDrawable import android.os.Bundle @@ -21,18 +21,18 @@ import com.drdisagree.iconify.common.Preferences.CUSTOM_PRIMARY_COLOR_SWITCH import com.drdisagree.iconify.common.Preferences.CUSTOM_SECONDARY_COLOR_SWITCH import com.drdisagree.iconify.common.References.ICONIFY_COLOR_ACCENT_PRIMARY import com.drdisagree.iconify.common.References.ICONIFY_COLOR_ACCENT_SECONDARY -import com.drdisagree.iconify.config.Prefs.clearPrefs -import com.drdisagree.iconify.config.Prefs.getBoolean -import com.drdisagree.iconify.config.Prefs.getString -import com.drdisagree.iconify.config.Prefs.putBoolean -import com.drdisagree.iconify.config.Prefs.putString +import com.drdisagree.iconify.config.RPrefs.clearPrefs +import com.drdisagree.iconify.config.RPrefs.getBoolean +import com.drdisagree.iconify.config.RPrefs.getString +import com.drdisagree.iconify.config.RPrefs.putBoolean +import com.drdisagree.iconify.config.RPrefs.putString import com.drdisagree.iconify.databinding.FragmentBasicColorsBinding import com.drdisagree.iconify.ui.base.BaseFragment import com.drdisagree.iconify.ui.utils.ViewHelper.setHeader -import com.drdisagree.iconify.utils.color.ColorUtil.colorToSpecialHex -import com.drdisagree.iconify.utils.overlay.FabricatedUtil.buildAndEnableOverlays -import com.drdisagree.iconify.utils.overlay.FabricatedUtil.disableOverlays -import com.drdisagree.iconify.utils.overlay.OverlayUtil.isOverlayDisabled +import com.drdisagree.iconify.utils.color.ColorUtils.colorToSpecialHex +import com.drdisagree.iconify.utils.overlay.FabricatedUtils.buildAndEnableOverlays +import com.drdisagree.iconify.utils.overlay.FabricatedUtils.disableOverlays +import com.drdisagree.iconify.utils.overlay.OverlayUtils.isOverlayDisabled class BasicColors : BaseFragment() { diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/ColorEngine.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/tweaks/ColorEngine.kt similarity index 83% rename from app/src/main/java/com/drdisagree/iconify/ui/fragments/ColorEngine.kt rename to app/src/main/java/com/drdisagree/iconify/ui/fragments/tweaks/ColorEngine.kt index d48609b20..255d2c6fa 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/fragments/ColorEngine.kt +++ b/app/src/main/java/com/drdisagree/iconify/ui/fragments/tweaks/ColorEngine.kt @@ -1,4 +1,4 @@ -package com.drdisagree.iconify.ui.fragments +package com.drdisagree.iconify.ui.fragments.tweaks import android.os.Bundle import android.os.Handler @@ -7,21 +7,21 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.CompoundButton -import androidx.navigation.Navigation.findNavController import com.drdisagree.iconify.R import com.drdisagree.iconify.common.Const.SWITCH_ANIMATION_DELAY import com.drdisagree.iconify.common.Preferences.COLOR_ACCENT_PRIMARY import com.drdisagree.iconify.common.Preferences.COLOR_ACCENT_SECONDARY -import com.drdisagree.iconify.common.Preferences.STR_NULL -import com.drdisagree.iconify.config.Prefs.getBoolean -import com.drdisagree.iconify.config.Prefs.getString +import com.drdisagree.iconify.config.RPrefs.getBoolean +import com.drdisagree.iconify.config.RPrefs.getString import com.drdisagree.iconify.databinding.FragmentColorEngineBinding +import com.drdisagree.iconify.ui.activities.MainActivity.Companion.replaceFragment import com.drdisagree.iconify.ui.base.BaseFragment import com.drdisagree.iconify.ui.utils.ViewHelper.setHeader -import com.drdisagree.iconify.utils.overlay.OverlayUtil -import com.drdisagree.iconify.utils.overlay.OverlayUtil.changeOverlayState -import com.drdisagree.iconify.utils.overlay.OverlayUtil.enableOverlay -import com.drdisagree.iconify.utils.overlay.OverlayUtil.isOverlayDisabled +import com.drdisagree.iconify.utils.overlay.OverlayUtils.changeOverlayState +import com.drdisagree.iconify.utils.overlay.OverlayUtils.disableOverlay +import com.drdisagree.iconify.utils.overlay.OverlayUtils.disableOverlays +import com.drdisagree.iconify.utils.overlay.OverlayUtils.enableOverlay +import com.drdisagree.iconify.utils.overlay.OverlayUtils.isOverlayDisabled class ColorEngine : BaseFragment() { @@ -46,12 +46,12 @@ class ColorEngine : BaseFragment() { // Basic colors binding.basicColors.setOnClickListener { - findNavController(view).navigate(R.id.action_colorEngine_to_basicColors) + replaceFragment(parentFragmentManager, BasicColors()) } // Monet engine binding.monetEngine.setOnClickListener { - findNavController(view).navigate(R.id.action_colorEngine_to_monetEngine) + replaceFragment(parentFragmentManager, MonetEngine()) } // Apply monet accent and gradient @@ -77,19 +77,17 @@ class ColorEngine : BaseFragment() { binding.minimalQspanel.setSwitchChangeListener(minimalQsListener) // Disable Monet - binding.disableMonet.isSwitchChecked = getBoolean("IconifyComponentDM.overlay") - binding.disableMonet.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> - Handler(Looper.getMainLooper()).postDelayed( - { - if (isChecked) { - enableOverlay("IconifyComponentDM.overlay") - } else { - OverlayUtil.disableOverlay("IconifyComponentDM.overlay") - } - }, SWITCH_ANIMATION_DELAY - ) + binding.systemMonet.isSwitchChecked = !getBoolean("IconifyComponentDM.overlay") + binding.systemMonet.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> + Handler(Looper.getMainLooper()).postDelayed({ + if (!isChecked) { + enableOverlay("IconifyComponentDM.overlay") + } else { + disableOverlay("IconifyComponentDM.overlay") + } + }, SWITCH_ANIMATION_DELAY) } - + return view } @@ -99,7 +97,7 @@ class ColorEngine : BaseFragment() { } private fun disableMonetAccent() { - OverlayUtil.disableOverlays("IconifyComponentAMAC.overlay") + disableOverlays("IconifyComponentAMAC.overlay") } private fun enableMonetGradient() { @@ -108,7 +106,7 @@ class ColorEngine : BaseFragment() { } private fun disableMonetGradient() { - OverlayUtil.disableOverlay("IconifyComponentAMGC.overlay") + disableOverlay("IconifyComponentAMGC.overlay") } private fun shouldUseDefaultColors(): Boolean { @@ -117,13 +115,13 @@ class ColorEngine : BaseFragment() { private fun applyDefaultColors() { if (shouldUseDefaultColors()) { - if (getString(COLOR_ACCENT_PRIMARY) == STR_NULL) { + if (getString(COLOR_ACCENT_PRIMARY) == null) { BasicColors.applyDefaultPrimaryColors() } else { BasicColors.applyPrimaryColors() } - if (getString(COLOR_ACCENT_SECONDARY) == STR_NULL) { + if (getString(COLOR_ACCENT_SECONDARY) == null) { BasicColors.applyDefaultSecondaryColors() } else { BasicColors.applySecondaryColors() @@ -154,7 +152,7 @@ class ColorEngine : BaseFragment() { true ) } else { - OverlayUtil.disableOverlay("IconifyComponentQSST.overlay") + disableOverlay("IconifyComponentQSST.overlay") } }, SWITCH_ANIMATION_DELAY) } @@ -223,7 +221,7 @@ class ColorEngine : BaseFragment() { true ) } else { - OverlayUtil.disableOverlay("IconifyComponentQSPBD.overlay") + disableOverlay("IconifyComponentQSPBD.overlay") } }, SWITCH_ANIMATION_DELAY) } @@ -254,7 +252,7 @@ class ColorEngine : BaseFragment() { true ) } else { - OverlayUtil.disableOverlay("IconifyComponentQSPBA.overlay") + disableOverlay("IconifyComponentQSPBA.overlay") } }, SWITCH_ANIMATION_DELAY) } diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/ColoredBattery.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/tweaks/ColoredBattery.kt similarity index 80% rename from app/src/main/java/com/drdisagree/iconify/ui/fragments/ColoredBattery.kt rename to app/src/main/java/com/drdisagree/iconify/ui/fragments/tweaks/ColoredBattery.kt index f18bbda8c..a1ba88909 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/fragments/ColoredBattery.kt +++ b/app/src/main/java/com/drdisagree/iconify/ui/fragments/tweaks/ColoredBattery.kt @@ -1,4 +1,4 @@ -package com.drdisagree.iconify.ui.fragments +package com.drdisagree.iconify.ui.fragments.tweaks import android.os.Bundle import android.os.Handler @@ -16,19 +16,18 @@ import com.drdisagree.iconify.common.Const.SWITCH_ANIMATION_DELAY import com.drdisagree.iconify.common.Const.SYSTEMUI_PACKAGE import com.drdisagree.iconify.common.Preferences.COLORED_BATTERY_CHECK import com.drdisagree.iconify.common.Preferences.COLORED_BATTERY_SWITCH -import com.drdisagree.iconify.common.Preferences.STR_NULL import com.drdisagree.iconify.common.References.FABRICATED_BATTERY_COLOR_BG import com.drdisagree.iconify.common.References.FABRICATED_BATTERY_COLOR_FG import com.drdisagree.iconify.common.References.FABRICATED_COLORED_BATTERY -import com.drdisagree.iconify.config.Prefs -import com.drdisagree.iconify.config.Prefs.putString +import com.drdisagree.iconify.config.RPrefs +import com.drdisagree.iconify.config.RPrefs.putString import com.drdisagree.iconify.databinding.FragmentColoredBatteryBinding import com.drdisagree.iconify.ui.base.BaseFragment import com.drdisagree.iconify.ui.utils.ViewHelper.setHeader -import com.drdisagree.iconify.utils.color.ColorUtil.colorToSpecialHex -import com.drdisagree.iconify.utils.overlay.FabricatedUtil -import com.drdisagree.iconify.utils.overlay.FabricatedUtil.buildAndEnableOverlay -import com.drdisagree.iconify.utils.overlay.OverlayUtil.isOverlayEnabled +import com.drdisagree.iconify.utils.color.ColorUtils.colorToSpecialHex +import com.drdisagree.iconify.utils.overlay.FabricatedUtils +import com.drdisagree.iconify.utils.overlay.FabricatedUtils.buildAndEnableOverlay +import com.drdisagree.iconify.utils.overlay.OverlayUtils.isOverlayEnabled class ColoredBattery : BaseFragment() { @@ -52,11 +51,11 @@ class ColoredBattery : BaseFragment() { // Enable colored battery binding.enableColoredBattery.isSwitchChecked = - if (Prefs.getString(COLORED_BATTERY_CHECK, STR_NULL) == STR_NULL) { + if (RPrefs.getString(COLORED_BATTERY_CHECK) == null) { isOverlayEnabled("IconifyComponentIPSUI2.overlay") || isOverlayEnabled("IconifyComponentIPSUI4.overlay") } else { - Prefs.getBoolean(COLORED_BATTERY_SWITCH) + RPrefs.getBoolean(COLORED_BATTERY_SWITCH) } binding.enableColoredBattery.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> @@ -73,7 +72,7 @@ class ColoredBattery : BaseFragment() { ) } else { putString(COLORED_BATTERY_CHECK, "Off") - FabricatedUtil.disableOverlay(FABRICATED_COLORED_BATTERY) + FabricatedUtils.disableOverlay(FABRICATED_COLORED_BATTERY) buildAndEnableOverlay( FRAMEWORK_PACKAGE, FABRICATED_COLORED_BATTERY, @@ -82,11 +81,11 @@ class ColoredBattery : BaseFragment() { "0" ) - if (Prefs.getString(FABRICATED_BATTERY_COLOR_BG) != STR_NULL) FabricatedUtil.disableOverlay( + if (RPrefs.getString(FABRICATED_BATTERY_COLOR_BG) != null) FabricatedUtils.disableOverlay( FABRICATED_BATTERY_COLOR_BG ) - if (Prefs.getString(FABRICATED_BATTERY_COLOR_FG) != STR_NULL) FabricatedUtil.disableOverlay( + if (RPrefs.getString(FABRICATED_BATTERY_COLOR_FG) != null) FabricatedUtils.disableOverlay( FABRICATED_BATTERY_COLOR_FG ) } @@ -105,25 +104,26 @@ class ColoredBattery : BaseFragment() { ).show() } - Prefs.putBoolean(COLORED_BATTERY_SWITCH, isChecked) + RPrefs.putBoolean(COLORED_BATTERY_SWITCH, isChecked) }, SWITCH_ANIMATION_DELAY ) } - colorBackground = if (Prefs.getString(FABRICATED_BATTERY_COLOR_BG) != STR_NULL) { - Prefs.getString(FABRICATED_BATTERY_COLOR_BG) + colorBackground = if (RPrefs.getString(FABRICATED_BATTERY_COLOR_BG) != null) { + RPrefs.getString(FABRICATED_BATTERY_COLOR_BG) } else { (-0xf0f10).toString() } - colorFilled = if (Prefs.getString(FABRICATED_BATTERY_COLOR_FG) != STR_NULL) { - Prefs.getString(FABRICATED_BATTERY_COLOR_FG) + colorFilled = if (RPrefs.getString(FABRICATED_BATTERY_COLOR_FG) != null) { + RPrefs.getString(FABRICATED_BATTERY_COLOR_FG) } else { (-0xf0f10).toString() } // Battery background color binding.batteryBackgroundColor.setColorPickerListener( - activity = requireActivity(), defaultColor = colorBackground!!.toInt(), + activity = requireActivity(), + defaultColor = colorBackground!!.toInt(), showPresets = true, showAlphaSlider = false, showColorShades = true diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/MediaPlayer.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/tweaks/MediaPlayer.kt similarity index 79% rename from app/src/main/java/com/drdisagree/iconify/ui/fragments/MediaPlayer.kt rename to app/src/main/java/com/drdisagree/iconify/ui/fragments/tweaks/MediaPlayer.kt index 2d62eac75..27101b4a3 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/fragments/MediaPlayer.kt +++ b/app/src/main/java/com/drdisagree/iconify/ui/fragments/tweaks/MediaPlayer.kt @@ -1,4 +1,4 @@ -package com.drdisagree.iconify.ui.fragments +package com.drdisagree.iconify.ui.fragments.tweaks import android.os.Bundle import android.view.LayoutInflater @@ -6,12 +6,12 @@ import android.view.View import android.view.ViewGroup import android.widget.CompoundButton import com.drdisagree.iconify.R -import com.drdisagree.iconify.config.Prefs +import com.drdisagree.iconify.config.RPrefs import com.drdisagree.iconify.databinding.FragmentMediaPlayerBinding import com.drdisagree.iconify.ui.base.BaseFragment import com.drdisagree.iconify.ui.utils.ViewHelper.setHeader -import com.drdisagree.iconify.utils.overlay.OverlayUtil -import com.drdisagree.iconify.utils.overlay.OverlayUtil.changeOverlayState +import com.drdisagree.iconify.utils.overlay.OverlayUtils +import com.drdisagree.iconify.utils.overlay.OverlayUtils.changeOverlayState class MediaPlayer : BaseFragment() { @@ -35,7 +35,7 @@ class MediaPlayer : BaseFragment() { refreshPreview() - binding.mpAccent.isSwitchChecked = Prefs.getBoolean("IconifyComponentMPA.overlay") + binding.mpAccent.isSwitchChecked = RPrefs.getBoolean("IconifyComponentMPA.overlay") binding.mpAccent.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> if (isChecked) { binding.mpSystem.isSwitchChecked = false @@ -50,13 +50,13 @@ class MediaPlayer : BaseFragment() { true ) } else { - OverlayUtil.disableOverlay("IconifyComponentMPA.overlay") + OverlayUtils.disableOverlay("IconifyComponentMPA.overlay") } refreshPreview() } - binding.mpSystem.isSwitchChecked = Prefs.getBoolean("IconifyComponentMPS.overlay") + binding.mpSystem.isSwitchChecked = RPrefs.getBoolean("IconifyComponentMPS.overlay") binding.mpSystem.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> if (isChecked) { binding.mpAccent.isSwitchChecked = false @@ -71,13 +71,13 @@ class MediaPlayer : BaseFragment() { true ) } else { - OverlayUtil.disableOverlay("IconifyComponentMPS.overlay") + OverlayUtils.disableOverlay("IconifyComponentMPS.overlay") } refreshPreview() } - binding.mpPitchBlack.isSwitchChecked = Prefs.getBoolean("IconifyComponentMPB.overlay") + binding.mpPitchBlack.isSwitchChecked = RPrefs.getBoolean("IconifyComponentMPB.overlay") binding.mpPitchBlack.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> if (isChecked) { binding.mpAccent.isSwitchChecked = false @@ -92,7 +92,7 @@ class MediaPlayer : BaseFragment() { true ) } else { - OverlayUtil.disableOverlay("IconifyComponentMPB.overlay") + OverlayUtils.disableOverlay("IconifyComponentMPB.overlay") } refreshPreview() @@ -107,11 +107,11 @@ class MediaPlayer : BaseFragment() { binding.mpSystemPreview.previewMpSystem.visibility = View.GONE when { - Prefs.getBoolean("IconifyComponentMPA.overlay") -> { + RPrefs.getBoolean("IconifyComponentMPA.overlay") -> { binding.mpAccentPreview.previewMpAccent.visibility = View.VISIBLE } - Prefs.getBoolean("IconifyComponentMPB.overlay") -> { + RPrefs.getBoolean("IconifyComponentMPB.overlay") -> { binding.mpPitchBlackPreview.previewMpBlack.visibility = View.VISIBLE } diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/Miscellaneous.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/tweaks/Miscellaneous.kt similarity index 92% rename from app/src/main/java/com/drdisagree/iconify/ui/fragments/Miscellaneous.kt rename to app/src/main/java/com/drdisagree/iconify/ui/fragments/tweaks/Miscellaneous.kt index 1452b34bc..f8ae14ce8 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/fragments/Miscellaneous.kt +++ b/app/src/main/java/com/drdisagree/iconify/ui/fragments/tweaks/Miscellaneous.kt @@ -1,4 +1,4 @@ -package com.drdisagree.iconify.ui.fragments +package com.drdisagree.iconify.ui.fragments.tweaks import android.os.Build import android.os.Bundle @@ -16,19 +16,18 @@ import com.drdisagree.iconify.common.Preferences.NOTCH_BAR_KILLER_SWITCH import com.drdisagree.iconify.common.Preferences.PROGRESS_WAVE_ANIMATION_SWITCH import com.drdisagree.iconify.common.Preferences.TABLET_LANDSCAPE_SWITCH import com.drdisagree.iconify.common.References.FABRICATED_TABLET_HEADER -import com.drdisagree.iconify.config.Prefs -import com.drdisagree.iconify.config.Prefs.getBoolean +import com.drdisagree.iconify.config.RPrefs +import com.drdisagree.iconify.config.RPrefs.getBoolean import com.drdisagree.iconify.databinding.FragmentMiscellaneousBinding import com.drdisagree.iconify.ui.base.BaseFragment import com.drdisagree.iconify.ui.utils.ViewHelper.setHeader -import com.drdisagree.iconify.utils.SystemUtil -import com.drdisagree.iconify.utils.SystemUtil.hasStoragePermission -import com.drdisagree.iconify.utils.SystemUtil.requestStoragePermission -import com.drdisagree.iconify.utils.SystemUtil.restartSystemUI -import com.drdisagree.iconify.utils.overlay.FabricatedUtil -import com.drdisagree.iconify.utils.overlay.FabricatedUtil.buildAndEnableOverlay -import com.drdisagree.iconify.utils.overlay.OverlayUtil -import com.drdisagree.iconify.utils.overlay.OverlayUtil.enableOverlay +import com.drdisagree.iconify.utils.SystemUtils.hasStoragePermission +import com.drdisagree.iconify.utils.SystemUtils.requestStoragePermission +import com.drdisagree.iconify.utils.SystemUtils.restartSystemUI +import com.drdisagree.iconify.utils.overlay.FabricatedUtils +import com.drdisagree.iconify.utils.overlay.FabricatedUtils.buildAndEnableOverlay +import com.drdisagree.iconify.utils.overlay.OverlayUtils +import com.drdisagree.iconify.utils.overlay.OverlayUtils.enableOverlay import com.drdisagree.iconify.utils.overlay.manager.resource.ResourceEntry import com.drdisagree.iconify.utils.overlay.manager.resource.ResourceManager.buildOverlayWithResource import com.drdisagree.iconify.utils.overlay.manager.resource.ResourceManager.removeResourceFromOverlay @@ -69,7 +68,7 @@ class Miscellaneous : BaseFragment() { return@setSwitchChangeListener } - Prefs.putBoolean(TABLET_LANDSCAPE_SWITCH, isChecked) + RPrefs.putBoolean(TABLET_LANDSCAPE_SWITCH, isChecked) val resourceEntry1 = ResourceEntry( SYSTEMUI_PACKAGE, @@ -220,7 +219,7 @@ class Miscellaneous : BaseFragment() { return@setSwitchChangeListener } - Prefs.putBoolean(NOTCH_BAR_KILLER_SWITCH, isChecked) + RPrefs.putBoolean(NOTCH_BAR_KILLER_SWITCH, isChecked) if (isChecked) { buildOverlayWithResource( @@ -275,7 +274,7 @@ class Miscellaneous : BaseFragment() { binding.tabletHeader.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> Handler(Looper.getMainLooper()).postDelayed( { - Prefs.putBoolean(FABRICATED_TABLET_HEADER, isChecked) + RPrefs.putBoolean(FABRICATED_TABLET_HEADER, isChecked) if (isChecked) { buildAndEnableOverlay( @@ -286,7 +285,7 @@ class Miscellaneous : BaseFragment() { "1" ) } else { - FabricatedUtil.disableOverlay(FABRICATED_TABLET_HEADER) + FabricatedUtils.disableOverlay(FABRICATED_TABLET_HEADER) } }, SWITCH_ANIMATION_DELAY ) @@ -300,7 +299,7 @@ class Miscellaneous : BaseFragment() { if (isChecked) { enableOverlay("IconifyComponentPCBG.overlay") } else { - OverlayUtil.disableOverlay("IconifyComponentPCBG.overlay") + OverlayUtils.disableOverlay("IconifyComponentPCBG.overlay") } restartSystemUI() @@ -328,7 +327,7 @@ class Miscellaneous : BaseFragment() { return@setSwitchChangeListener } - Prefs.putBoolean(PROGRESS_WAVE_ANIMATION_SWITCH, isChecked) + RPrefs.putBoolean(PROGRESS_WAVE_ANIMATION_SWITCH, isChecked) if (isChecked) { buildOverlayWithResource( diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/MonetEngine.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/tweaks/MonetEngine.kt similarity index 95% rename from app/src/main/java/com/drdisagree/iconify/ui/fragments/MonetEngine.kt rename to app/src/main/java/com/drdisagree/iconify/ui/fragments/tweaks/MonetEngine.kt index f66e8b8bb..92c79dd96 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/fragments/MonetEngine.kt +++ b/app/src/main/java/com/drdisagree/iconify/ui/fragments/tweaks/MonetEngine.kt @@ -1,5 +1,6 @@ -package com.drdisagree.iconify.ui.fragments +package com.drdisagree.iconify.ui.fragments.tweaks +import android.annotation.SuppressLint import android.app.Activity import android.content.DialogInterface import android.content.Intent @@ -12,8 +13,6 @@ import android.util.Log import android.util.TypedValue import android.view.Gravity import android.view.LayoutInflater -import android.view.Menu -import android.view.MenuInflater import android.view.MenuItem import android.view.View import android.view.ViewGroup @@ -43,32 +42,31 @@ import com.drdisagree.iconify.common.Preferences.MONET_PRIMARY_COLOR import com.drdisagree.iconify.common.Preferences.MONET_SECONDARY_ACCENT_SATURATION import com.drdisagree.iconify.common.Preferences.MONET_SECONDARY_COLOR import com.drdisagree.iconify.common.Preferences.MONET_STYLE -import com.drdisagree.iconify.common.Preferences.STR_NULL -import com.drdisagree.iconify.config.Prefs.clearPrefs -import com.drdisagree.iconify.config.Prefs.getBoolean -import com.drdisagree.iconify.config.Prefs.getInt -import com.drdisagree.iconify.config.Prefs.getString -import com.drdisagree.iconify.config.Prefs.prefs -import com.drdisagree.iconify.config.Prefs.putBoolean -import com.drdisagree.iconify.config.Prefs.putInt -import com.drdisagree.iconify.config.Prefs.putString +import com.drdisagree.iconify.config.RPrefs +import com.drdisagree.iconify.config.RPrefs.clearPrefs +import com.drdisagree.iconify.config.RPrefs.getBoolean +import com.drdisagree.iconify.config.RPrefs.getInt +import com.drdisagree.iconify.config.RPrefs.getString +import com.drdisagree.iconify.config.RPrefs.putBoolean +import com.drdisagree.iconify.config.RPrefs.putInt +import com.drdisagree.iconify.config.RPrefs.putString import com.drdisagree.iconify.databinding.FragmentMonetEngineBinding import com.drdisagree.iconify.ui.activities.MainActivity import com.drdisagree.iconify.ui.base.BaseFragment import com.drdisagree.iconify.ui.events.ColorSelectedEvent import com.drdisagree.iconify.ui.utils.ViewHelper.setHeader -import com.drdisagree.iconify.utils.SystemUtil -import com.drdisagree.iconify.utils.SystemUtil.hasStoragePermission -import com.drdisagree.iconify.utils.SystemUtil.requestStoragePermission -import com.drdisagree.iconify.utils.color.ColorSchemeUtil.generateColorPalette -import com.drdisagree.iconify.utils.color.ColorUtil.colorNames -import com.drdisagree.iconify.utils.color.ColorUtil.getSystemColors -import com.drdisagree.iconify.utils.color.ColorUtil.setLightness -import com.drdisagree.iconify.utils.color.ColorUtil.setSaturation +import com.drdisagree.iconify.utils.SystemUtils +import com.drdisagree.iconify.utils.SystemUtils.hasStoragePermission +import com.drdisagree.iconify.utils.SystemUtils.requestStoragePermission +import com.drdisagree.iconify.utils.color.ColorSchemeUtils.generateColorPalette +import com.drdisagree.iconify.utils.color.ColorUtils.colorNames +import com.drdisagree.iconify.utils.color.ColorUtils.getSystemColors +import com.drdisagree.iconify.utils.color.ColorUtils.setLightness +import com.drdisagree.iconify.utils.color.ColorUtils.setSaturation import com.drdisagree.iconify.utils.helper.ImportExport.exportSettings -import com.drdisagree.iconify.utils.overlay.FabricatedUtil.disableOverlays -import com.drdisagree.iconify.utils.overlay.OverlayUtil -import com.drdisagree.iconify.utils.overlay.OverlayUtil.changeOverlayState +import com.drdisagree.iconify.utils.overlay.FabricatedUtils.disableOverlays +import com.drdisagree.iconify.utils.overlay.OverlayUtils +import com.drdisagree.iconify.utils.overlay.OverlayUtils.changeOverlayState import com.drdisagree.iconify.utils.overlay.manager.MonetEngineManager.buildOverlay import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.slider.Slider @@ -88,7 +86,7 @@ class MonetEngine : BaseFragment() { private lateinit var binding: FragmentMonetEngineBinding private lateinit var colorTableRows: Array - private var isDarkMode = SystemUtil.isDarkMode + private var isDarkMode = SystemUtils.isDarkMode private var showApplyButton = false private var showDisableButton = false @@ -108,7 +106,7 @@ class MonetEngine : BaseFragment() { try { exportSettings( - prefs, + RPrefs.getPrefs, requireContext().contentResolver.openOutputStream(data.data!!)!! ) @@ -144,7 +142,7 @@ class MonetEngine : BaseFragment() { Handler(Looper.getMainLooper()).post { try { val success = importMonetSettings( - prefs, + RPrefs.getPrefs, requireContext().contentResolver.openInputStream(data.data!!)!! ) @@ -204,7 +202,7 @@ class MonetEngine : BaseFragment() { binding.monetEngine.systemNeutral2 ) - isDarkMode = SystemUtil.isDarkMode + isDarkMode = SystemUtils.isDarkMode selectedStyle = getString( MONET_STYLE, appContextLocale.resources.getString(R.string.monet_tonalspot) @@ -417,7 +415,7 @@ class MonetEngine : BaseFragment() { binding.enableCustomMonet.setOnClickListener { if (!hasStoragePermission()) { requestStoragePermission(requireContext()) - } else if (selectedStyle == STR_NULL) { + } else if (selectedStyle == null) { Toast.makeText( appContext, appContextLocale.resources.getString(R.string.toast_select_style), @@ -510,7 +508,7 @@ class MonetEngine : BaseFragment() { putBoolean(MONET_ENGINE_SWITCH, false) clearPrefs(MONET_PRIMARY_COLOR, MONET_SECONDARY_COLOR) - OverlayUtil.disableOverlays( + OverlayUtils.disableOverlays( "IconifyComponentDM.overlay", "IconifyComponentME.overlay" ) @@ -560,19 +558,19 @@ class MonetEngine : BaseFragment() { } } - if (!binding.floatingActionMenu.isShown()) { + if (!binding.floatingActionMenu.isShown) { binding.enableCustomMonet.hide() binding.disableCustomMonet.hide() } binding.floatingActionMenu.setOnClickListener { - if (showApplyButton && !binding.enableCustomMonet.isShown()) { + if (showApplyButton && !binding.enableCustomMonet.isShown) { binding.enableCustomMonet.show() } else { binding.enableCustomMonet.hide() } - if (showDisableButton && !binding.disableCustomMonet.isShown()) { + if (showDisableButton && !binding.disableCustomMonet.isShown) { binding.disableCustomMonet.show() } else { binding.disableCustomMonet.hide() @@ -582,6 +580,7 @@ class MonetEngine : BaseFragment() { return view } + @SuppressLint("SetTextI18n") private fun assignStockColorsToPalette() { val systemColors = getSystemColors(requireContext()) val temp: MutableList> = ArrayList() @@ -608,9 +607,9 @@ class MonetEngine : BaseFragment() { textView.rotation = 270f textView.setTextColor(calculateTextColor(systemColors[i][j])) textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 10f) - textView.setAlpha(0.8f) - textView.setMaxLines(1) - textView.setSingleLine(true) + textView.alpha = 0.8f + textView.maxLines = 1 + textView.isSingleLine = true textView.setAutoSizeTextTypeUniformWithConfiguration( 1, 20, @@ -984,14 +983,6 @@ class MonetEngine : BaseFragment() { return status } - @Deprecated("Deprecated in Java") - override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { - menu.clear() - inflater.inflate(R.menu.monet_menu, menu) - - super.onCreateOptionsMenu(menu, inflater) - } - @Deprecated("Deprecated in Java") override fun onOptionsItemSelected(item: MenuItem): Boolean { val itemID = item.itemId diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/NavigationBar.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/tweaks/NavigationBar.kt similarity index 96% rename from app/src/main/java/com/drdisagree/iconify/ui/fragments/NavigationBar.kt rename to app/src/main/java/com/drdisagree/iconify/ui/fragments/tweaks/NavigationBar.kt index cd53a2e9f..d9b589aa6 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/fragments/NavigationBar.kt +++ b/app/src/main/java/com/drdisagree/iconify/ui/fragments/tweaks/NavigationBar.kt @@ -1,4 +1,4 @@ -package com.drdisagree.iconify.ui.fragments +package com.drdisagree.iconify.ui.fragments.tweaks import android.os.Bundle import android.os.Handler @@ -23,19 +23,19 @@ import com.drdisagree.iconify.common.Preferences.PILL_SHAPE_SWITCH import com.drdisagree.iconify.common.References.FABRICATED_PILL_BOTTOM_SPACE import com.drdisagree.iconify.common.References.FABRICATED_PILL_THICKNESS import com.drdisagree.iconify.common.References.FABRICATED_PILL_WIDTH -import com.drdisagree.iconify.config.Prefs.getBoolean -import com.drdisagree.iconify.config.Prefs.getInt -import com.drdisagree.iconify.config.Prefs.putBoolean -import com.drdisagree.iconify.config.Prefs.putInt +import com.drdisagree.iconify.config.RPrefs.getBoolean +import com.drdisagree.iconify.config.RPrefs.getInt +import com.drdisagree.iconify.config.RPrefs.putBoolean +import com.drdisagree.iconify.config.RPrefs.putInt import com.drdisagree.iconify.databinding.FragmentNavigationBarBinding import com.drdisagree.iconify.ui.base.BaseFragment import com.drdisagree.iconify.ui.utils.ViewHelper.setHeader -import com.drdisagree.iconify.utils.SystemUtil -import com.drdisagree.iconify.utils.SystemUtil.hasStoragePermission -import com.drdisagree.iconify.utils.SystemUtil.requestStoragePermission -import com.drdisagree.iconify.utils.SystemUtil.restartSystemUI -import com.drdisagree.iconify.utils.overlay.OverlayUtil -import com.drdisagree.iconify.utils.overlay.OverlayUtil.enableOverlay +import com.drdisagree.iconify.utils.SystemUtils +import com.drdisagree.iconify.utils.SystemUtils.hasStoragePermission +import com.drdisagree.iconify.utils.SystemUtils.requestStoragePermission +import com.drdisagree.iconify.utils.SystemUtils.restartSystemUI +import com.drdisagree.iconify.utils.overlay.OverlayUtils +import com.drdisagree.iconify.utils.overlay.OverlayUtils.enableOverlay import com.drdisagree.iconify.utils.overlay.manager.resource.ResourceEntry import com.drdisagree.iconify.utils.overlay.manager.resource.ResourceManager.buildOverlayWithResource import com.drdisagree.iconify.utils.overlay.manager.resource.ResourceManager.removeResourceFromOverlay @@ -283,7 +283,7 @@ class NavigationBar : BaseFragment() { handleHidePill(isSwitchChecked) Handler(Looper.getMainLooper()).postDelayed( - { SystemUtil.handleSystemUIRestart() }, + { SystemUtils.handleSystemUIRestart() }, 2000 ) }, SWITCH_ANIMATION_DELAY) @@ -303,7 +303,7 @@ class NavigationBar : BaseFragment() { enableOverlay("IconifyComponentNBMonetPill.overlay") restartSystemUI() } else { - OverlayUtil.disableOverlay("IconifyComponentNBMonetPill.overlay") + OverlayUtils.disableOverlay("IconifyComponentNBMonetPill.overlay") restartSystemUI() } }, SWITCH_ANIMATION_DELAY @@ -317,7 +317,7 @@ class NavigationBar : BaseFragment() { if (isSwitchChecked) { enableOverlay("IconifyComponentNBHideKBButton.overlay") } else { - OverlayUtil.disableOverlay("IconifyComponentNBHideKBButton.overlay") + OverlayUtils.disableOverlay("IconifyComponentNBHideKBButton.overlay") } }, SWITCH_ANIMATION_DELAY ) diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/QsIconLabel.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/tweaks/QsIconLabel.kt similarity index 93% rename from app/src/main/java/com/drdisagree/iconify/ui/fragments/QsIconLabel.kt rename to app/src/main/java/com/drdisagree/iconify/ui/fragments/tweaks/QsIconLabel.kt index 470d9f0eb..eede0031f 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/fragments/QsIconLabel.kt +++ b/app/src/main/java/com/drdisagree/iconify/ui/fragments/tweaks/QsIconLabel.kt @@ -1,4 +1,4 @@ -package com.drdisagree.iconify.ui.fragments +package com.drdisagree.iconify.ui.fragments.tweaks import android.os.Bundle import android.os.Handler @@ -16,23 +16,22 @@ import com.drdisagree.iconify.common.Preferences.QS_HIDE_LABEL_SWITCH import com.drdisagree.iconify.common.Preferences.QS_TEXT_COLOR_VARIANT import com.drdisagree.iconify.common.Preferences.QS_TEXT_COLOR_VARIANT_NORMAL import com.drdisagree.iconify.common.Preferences.QS_TEXT_COLOR_VARIANT_PIXEL -import com.drdisagree.iconify.common.Preferences.STR_NULL import com.drdisagree.iconify.common.References.FABRICATED_QS_ICON_SIZE import com.drdisagree.iconify.common.References.FABRICATED_QS_MOVE_ICON import com.drdisagree.iconify.common.References.FABRICATED_QS_TEXT_SIZE -import com.drdisagree.iconify.config.Prefs.getBoolean -import com.drdisagree.iconify.config.Prefs.getString -import com.drdisagree.iconify.config.Prefs.putBoolean -import com.drdisagree.iconify.config.Prefs.putString +import com.drdisagree.iconify.config.RPrefs.getBoolean +import com.drdisagree.iconify.config.RPrefs.getString +import com.drdisagree.iconify.config.RPrefs.putBoolean +import com.drdisagree.iconify.config.RPrefs.putString import com.drdisagree.iconify.databinding.FragmentQsIconLabelBinding import com.drdisagree.iconify.ui.base.BaseFragment import com.drdisagree.iconify.ui.utils.ViewHelper.setHeader -import com.drdisagree.iconify.utils.SystemUtil.hasStoragePermission -import com.drdisagree.iconify.utils.SystemUtil.requestStoragePermission -import com.drdisagree.iconify.utils.overlay.OverlayUtil -import com.drdisagree.iconify.utils.overlay.OverlayUtil.changeOverlayState -import com.drdisagree.iconify.utils.overlay.OverlayUtil.disableOverlays -import com.drdisagree.iconify.utils.overlay.OverlayUtil.enableOverlay +import com.drdisagree.iconify.utils.SystemUtils.hasStoragePermission +import com.drdisagree.iconify.utils.SystemUtils.requestStoragePermission +import com.drdisagree.iconify.utils.overlay.OverlayUtils +import com.drdisagree.iconify.utils.overlay.OverlayUtils.changeOverlayState +import com.drdisagree.iconify.utils.overlay.OverlayUtils.disableOverlays +import com.drdisagree.iconify.utils.overlay.OverlayUtils.enableOverlay import com.drdisagree.iconify.utils.overlay.manager.resource.ResourceEntry import com.drdisagree.iconify.utils.overlay.manager.resource.ResourceManager.buildOverlayWithResource import com.drdisagree.iconify.utils.overlay.manager.resource.ResourceManager.removeResourceFromOverlay @@ -62,7 +61,7 @@ class QsIconLabel : BaseFragment() { // Text Size val finalTextSize = intArrayOf(14) - if (getString(FABRICATED_QS_TEXT_SIZE) != STR_NULL) { + if (getString(FABRICATED_QS_TEXT_SIZE) != null) { finalTextSize[0] = getString(FABRICATED_QS_TEXT_SIZE)!!.toInt() binding.textSize.sliderValue = finalTextSize[0] } @@ -100,7 +99,7 @@ class QsIconLabel : BaseFragment() { // Icon Size val finalIconSize = intArrayOf(20) - if (getString(FABRICATED_QS_ICON_SIZE) != STR_NULL) { + if (getString(FABRICATED_QS_ICON_SIZE) != null) { finalIconSize[0] = getString(FABRICATED_QS_ICON_SIZE)!!.toInt() binding.iconSize.sliderValue = finalIconSize[0] } @@ -260,7 +259,7 @@ class QsIconLabel : BaseFragment() { enableOverlay(replaceVariant("IconifyComponentQST1.overlay")) } else { - OverlayUtil.disableOverlay(replaceVariant("IconifyComponentQST1.overlay")) + OverlayUtils.disableOverlay(replaceVariant("IconifyComponentQST1.overlay")) } handleCommonOverlay() @@ -298,7 +297,7 @@ class QsIconLabel : BaseFragment() { enableOverlay(replaceVariant("IconifyComponentQST2.overlay")) } else { - OverlayUtil.disableOverlay(replaceVariant("IconifyComponentQST2.overlay")) + OverlayUtils.disableOverlay(replaceVariant("IconifyComponentQST2.overlay")) } handleCommonOverlay() @@ -336,7 +335,7 @@ class QsIconLabel : BaseFragment() { enableOverlay(replaceVariant("IconifyComponentQST3.overlay")) } else { - OverlayUtil.disableOverlay(replaceVariant("IconifyComponentQST3.overlay")) + OverlayUtils.disableOverlay(replaceVariant("IconifyComponentQST3.overlay")) } handleCommonOverlay() @@ -373,7 +372,7 @@ class QsIconLabel : BaseFragment() { enableOverlay(replaceVariant("IconifyComponentQST4.overlay")) } else { - OverlayUtil.disableOverlay(replaceVariant("IconifyComponentQST4.overlay")) + OverlayUtils.disableOverlay(replaceVariant("IconifyComponentQST4.overlay")) } handleCommonOverlay() @@ -411,7 +410,7 @@ class QsIconLabel : BaseFragment() { enableOverlay(replaceVariant("IconifyComponentQST5.overlay")) } else { - OverlayUtil.disableOverlay(replaceVariant("IconifyComponentQST5.overlay")) + OverlayUtils.disableOverlay(replaceVariant("IconifyComponentQST5.overlay")) } handleCommonOverlay() @@ -456,12 +455,12 @@ class QsIconLabel : BaseFragment() { } } binding.hideLabel.setBeforeSwitchChangeListener { - isHideLabelContainerClicked.set( true ) + isHideLabelContainerClicked.set(true) } // Move Icon val finalMoveIcon = intArrayOf(16) - if (getString(FABRICATED_QS_MOVE_ICON) != STR_NULL) { + if (getString(FABRICATED_QS_MOVE_ICON) != null) { finalMoveIcon[0] = getString(FABRICATED_QS_MOVE_ICON)!!.toInt() binding.moveIcon.sliderValue = finalMoveIcon[0] } diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/QsPanelMargin.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/tweaks/QsPanelMargin.kt similarity index 97% rename from app/src/main/java/com/drdisagree/iconify/ui/fragments/QsPanelMargin.kt rename to app/src/main/java/com/drdisagree/iconify/ui/fragments/tweaks/QsPanelMargin.kt index c11fccac4..ecebb123b 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/fragments/QsPanelMargin.kt +++ b/app/src/main/java/com/drdisagree/iconify/ui/fragments/tweaks/QsPanelMargin.kt @@ -1,4 +1,4 @@ -package com.drdisagree.iconify.ui.fragments +package com.drdisagree.iconify.ui.fragments.tweaks import android.os.Bundle import android.os.Handler @@ -13,15 +13,15 @@ import com.drdisagree.iconify.common.Preferences.LAND_QQS_TOP_MARGIN import com.drdisagree.iconify.common.Preferences.LAND_QS_TOP_MARGIN import com.drdisagree.iconify.common.Preferences.PORT_QQS_TOP_MARGIN import com.drdisagree.iconify.common.Preferences.PORT_QS_TOP_MARGIN -import com.drdisagree.iconify.config.Prefs.clearPrefs -import com.drdisagree.iconify.config.Prefs.getInt -import com.drdisagree.iconify.config.Prefs.putInt +import com.drdisagree.iconify.config.RPrefs.clearPrefs +import com.drdisagree.iconify.config.RPrefs.getInt +import com.drdisagree.iconify.config.RPrefs.putInt import com.drdisagree.iconify.databinding.FragmentQsPanelMarginBinding import com.drdisagree.iconify.ui.base.BaseFragment import com.drdisagree.iconify.ui.dialogs.LoadingDialog import com.drdisagree.iconify.ui.utils.ViewHelper.setHeader -import com.drdisagree.iconify.utils.SystemUtil.hasStoragePermission -import com.drdisagree.iconify.utils.SystemUtil.requestStoragePermission +import com.drdisagree.iconify.utils.SystemUtils.hasStoragePermission +import com.drdisagree.iconify.utils.SystemUtils.requestStoragePermission import com.drdisagree.iconify.utils.overlay.manager.resource.ResourceEntry import com.drdisagree.iconify.utils.overlay.manager.resource.ResourceManager.buildOverlayWithResource import com.drdisagree.iconify.utils.overlay.manager.resource.ResourceManager.removeResourceFromOverlay diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/QsRowColumn.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/tweaks/QsRowColumn.kt similarity index 83% rename from app/src/main/java/com/drdisagree/iconify/ui/fragments/QsRowColumn.kt rename to app/src/main/java/com/drdisagree/iconify/ui/fragments/tweaks/QsRowColumn.kt index 3b3367cf3..2678f5ad8 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/fragments/QsRowColumn.kt +++ b/app/src/main/java/com/drdisagree/iconify/ui/fragments/tweaks/QsRowColumn.kt @@ -1,4 +1,4 @@ -package com.drdisagree.iconify.ui.fragments +package com.drdisagree.iconify.ui.fragments.tweaks import android.content.DialogInterface import android.os.Bundle @@ -19,13 +19,13 @@ import com.drdisagree.iconify.common.References.FABRICATED_QQS_TILE import com.drdisagree.iconify.common.References.FABRICATED_QS_COLUMN import com.drdisagree.iconify.common.References.FABRICATED_QS_ROW import com.drdisagree.iconify.common.References.FABRICATED_QS_TILE -import com.drdisagree.iconify.config.Prefs +import com.drdisagree.iconify.config.RPrefs import com.drdisagree.iconify.databinding.FragmentQsRowColumnBinding import com.drdisagree.iconify.ui.base.BaseFragment import com.drdisagree.iconify.ui.dialogs.LoadingDialog import com.drdisagree.iconify.ui.utils.ViewHelper.setHeader -import com.drdisagree.iconify.utils.overlay.FabricatedUtil.buildAndEnableOverlays -import com.drdisagree.iconify.utils.overlay.FabricatedUtil.disableOverlays +import com.drdisagree.iconify.utils.overlay.FabricatedUtils.buildAndEnableOverlays +import com.drdisagree.iconify.utils.overlay.FabricatedUtils.disableOverlays import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.slider.Slider @@ -54,7 +54,7 @@ class QsRowColumn : BaseFragment() { loadingDialog = LoadingDialog(requireContext()) // Quick QsPanel Row - val finalQqsRow = intArrayOf(Prefs.getInt(FABRICATED_QQS_ROW, 2)) + val finalQqsRow = intArrayOf(RPrefs.getInt(FABRICATED_QQS_ROW, 2)) binding.qqsRow.sliderValue = finalQqsRow[0] binding.qqsRow.setOnSliderTouchListener(object : Slider.OnSliderTouchListener { override fun onStartTrackingTouch(slider: Slider) {} @@ -65,7 +65,7 @@ class QsRowColumn : BaseFragment() { }) // QsPanel Row - val finalQsRow = intArrayOf(Prefs.getInt(FABRICATED_QS_ROW, 4)) + val finalQsRow = intArrayOf(RPrefs.getInt(FABRICATED_QS_ROW, 4)) binding.qsRow.sliderValue = finalQsRow[0] binding.qsRow.setOnSliderTouchListener(object : Slider.OnSliderTouchListener { override fun onStartTrackingTouch(slider: Slider) {} @@ -76,7 +76,7 @@ class QsRowColumn : BaseFragment() { }) // QsPanel Column - val finalQsColumn = intArrayOf(Prefs.getInt(FABRICATED_QS_COLUMN, 2)) + val finalQsColumn = intArrayOf(RPrefs.getInt(FABRICATED_QS_COLUMN, 2)) binding.qsColumn.sliderValue = finalQsColumn[0] binding.qsColumn.setOnSliderTouchListener(object : Slider.OnSliderTouchListener { override fun onStartTrackingTouch(slider: Slider) {} @@ -91,12 +91,12 @@ class QsRowColumn : BaseFragment() { // Show loading dialog loadingDialog!!.show(resources.getString(R.string.loading_dialog_wait)) Thread { - Prefs.putBoolean(QS_ROW_COLUMN_SWITCH, true) - Prefs.putInt(FABRICATED_QQS_ROW, finalQqsRow[0]) - Prefs.putInt(FABRICATED_QS_ROW, finalQsRow[0]) - Prefs.putInt(FABRICATED_QS_COLUMN, finalQsColumn[0]) - Prefs.putInt(FABRICATED_QQS_TILE, finalQqsRow[0] * finalQsColumn[0]) - Prefs.putInt(FABRICATED_QS_TILE, finalQsColumn[0] * finalQsRow[0]) + RPrefs.putBoolean(QS_ROW_COLUMN_SWITCH, true) + RPrefs.putInt(FABRICATED_QQS_ROW, finalQqsRow[0]) + RPrefs.putInt(FABRICATED_QS_ROW, finalQsRow[0]) + RPrefs.putInt(FABRICATED_QS_COLUMN, finalQsColumn[0]) + RPrefs.putInt(FABRICATED_QQS_TILE, finalQqsRow[0] * finalQsColumn[0]) + RPrefs.putInt(FABRICATED_QS_TILE, finalQsColumn[0] * finalQsRow[0]) applyRowColumn() @@ -122,7 +122,7 @@ class QsRowColumn : BaseFragment() { // Reset button binding.qsRowColumnReset.visibility = - if (Prefs.getBoolean(QS_ROW_COLUMN_SWITCH)) { + if (RPrefs.getBoolean(QS_ROW_COLUMN_SWITCH)) { View.VISIBLE } else { View.GONE @@ -135,7 +135,7 @@ class QsRowColumn : BaseFragment() { resetRowColumn() Handler(Looper.getMainLooper()).post { - Prefs.putBoolean(QS_ROW_COLUMN_SWITCH, false) + RPrefs.putBoolean(QS_ROW_COLUMN_SWITCH, false) Handler(Looper.getMainLooper()).postDelayed({ // Hide loading dialog loadingDialog!!.hide() @@ -153,7 +153,7 @@ class QsRowColumn : BaseFragment() { }.start() } - if (Prefs.getBoolean(ALERT_DIALOG_QSROWCOL, true)) { + if (RPrefs.getBoolean(ALERT_DIALOG_QSROWCOL, true)) { MaterialAlertDialogBuilder(requireContext()) .setTitle(resources.getString(R.string.hey_there)) .setMessage(resources.getString(R.string.qs_row_column_warn_desc)) @@ -162,7 +162,7 @@ class QsRowColumn : BaseFragment() { } .setNegativeButton(getString(R.string.dont_show_again)) { dialog: DialogInterface, _: Int -> dialog.dismiss() - Prefs.putBoolean(ALERT_DIALOG_QSROWCOL, false) + RPrefs.putBoolean(ALERT_DIALOG_QSROWCOL, false) } .setCancelable(true) .show() @@ -185,28 +185,28 @@ class QsRowColumn : BaseFragment() { FABRICATED_QQS_ROW, "integer", "quick_qs_panel_max_rows", - Prefs.getInt(FABRICATED_QQS_ROW, 2).toString() + RPrefs.getInt(FABRICATED_QQS_ROW, 2).toString() ), arrayOf( SYSTEMUI_PACKAGE, FABRICATED_QS_ROW, "integer", "quick_settings_max_rows", - Prefs.getInt(FABRICATED_QS_ROW, 4).toString() + RPrefs.getInt(FABRICATED_QS_ROW, 4).toString() ), arrayOf( SYSTEMUI_PACKAGE, FABRICATED_QS_COLUMN, "integer", "quick_settings_num_columns", - Prefs.getInt(FABRICATED_QS_COLUMN, 2).toString() + RPrefs.getInt(FABRICATED_QS_COLUMN, 2).toString() ), arrayOf( SYSTEMUI_PACKAGE, FABRICATED_QQS_TILE, "integer", "quick_qs_panel_max_tiles", - (Prefs.getInt(FABRICATED_QQS_ROW, 2) * Prefs.getInt( + (RPrefs.getInt(FABRICATED_QQS_ROW, 2) * RPrefs.getInt( FABRICATED_QS_COLUMN, 2 )).toString() @@ -216,7 +216,7 @@ class QsRowColumn : BaseFragment() { FABRICATED_QS_TILE, "integer", "quick_settings_min_num_tiles", - (Prefs.getInt(FABRICATED_QS_COLUMN, 2) * Prefs.getInt( + (RPrefs.getInt(FABRICATED_QS_COLUMN, 2) * RPrefs.getInt( FABRICATED_QS_ROW, 4 )).toString() diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/QsTileSize.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/tweaks/QsTileSize.kt similarity index 88% rename from app/src/main/java/com/drdisagree/iconify/ui/fragments/QsTileSize.kt rename to app/src/main/java/com/drdisagree/iconify/ui/fragments/tweaks/QsTileSize.kt index e2b7fe644..7bb417c97 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/fragments/QsTileSize.kt +++ b/app/src/main/java/com/drdisagree/iconify/ui/fragments/tweaks/QsTileSize.kt @@ -1,4 +1,4 @@ -package com.drdisagree.iconify.ui.fragments +package com.drdisagree.iconify.ui.fragments.tweaks import android.os.Bundle import android.os.Handler @@ -12,14 +12,14 @@ import com.drdisagree.iconify.common.Preferences.LAND_QSTILE_EXPANDED_HEIGHT import com.drdisagree.iconify.common.Preferences.LAND_QSTILE_NONEXPANDED_HEIGHT import com.drdisagree.iconify.common.Preferences.PORT_QSTILE_EXPANDED_HEIGHT import com.drdisagree.iconify.common.Preferences.PORT_QSTILE_NONEXPANDED_HEIGHT -import com.drdisagree.iconify.config.Prefs -import com.drdisagree.iconify.config.Prefs.clearPrefs +import com.drdisagree.iconify.config.RPrefs +import com.drdisagree.iconify.config.RPrefs.clearPrefs import com.drdisagree.iconify.databinding.FragmentQsTileSizeBinding import com.drdisagree.iconify.ui.base.BaseFragment import com.drdisagree.iconify.ui.dialogs.LoadingDialog import com.drdisagree.iconify.ui.utils.ViewHelper.setHeader -import com.drdisagree.iconify.utils.SystemUtil.hasStoragePermission -import com.drdisagree.iconify.utils.SystemUtil.requestStoragePermission +import com.drdisagree.iconify.utils.SystemUtils.hasStoragePermission +import com.drdisagree.iconify.utils.SystemUtils.requestStoragePermission import com.drdisagree.iconify.utils.overlay.manager.resource.ResourceEntry import com.drdisagree.iconify.utils.overlay.manager.resource.ResourceManager.buildOverlayWithResource import com.drdisagree.iconify.utils.overlay.manager.resource.ResourceManager.removeResourceFromOverlay @@ -51,7 +51,7 @@ class QsTileSize : BaseFragment() { loadingDialog = LoadingDialog(requireContext()) // Portrait non expanded height - val portNonExpandedHeight = intArrayOf(Prefs.getInt(PORT_QSTILE_NONEXPANDED_HEIGHT, 60)) + val portNonExpandedHeight = intArrayOf(RPrefs.getInt(PORT_QSTILE_NONEXPANDED_HEIGHT, 60)) binding.portNonexpandedHeight.sliderValue = portNonExpandedHeight[0] binding.portNonexpandedHeight.setOnSliderTouchListener(object : Slider.OnSliderTouchListener { @@ -69,7 +69,7 @@ class QsTileSize : BaseFragment() { } // Portrait Expanded height - val portExpandedHeight = intArrayOf(Prefs.getInt(PORT_QSTILE_EXPANDED_HEIGHT, 80)) + val portExpandedHeight = intArrayOf(RPrefs.getInt(PORT_QSTILE_EXPANDED_HEIGHT, 80)) binding.portExpandedHeight.sliderValue = portExpandedHeight[0] binding.portExpandedHeight.setOnSliderTouchListener(object : Slider.OnSliderTouchListener { @@ -87,7 +87,7 @@ class QsTileSize : BaseFragment() { } // Landscape non expanded height - val landNonExpandedHeight = intArrayOf(Prefs.getInt(LAND_QSTILE_NONEXPANDED_HEIGHT, 60)) + val landNonExpandedHeight = intArrayOf(RPrefs.getInt(LAND_QSTILE_NONEXPANDED_HEIGHT, 60)) binding.landNonexpandedHeight.sliderValue = landNonExpandedHeight[0] binding.landNonexpandedHeight.setOnSliderTouchListener(object : Slider.OnSliderTouchListener { @@ -105,7 +105,7 @@ class QsTileSize : BaseFragment() { } // Landscape Expanded height - val landExpandedHeight = intArrayOf(Prefs.getInt(LAND_QSTILE_EXPANDED_HEIGHT, 80)) + val landExpandedHeight = intArrayOf(RPrefs.getInt(LAND_QSTILE_EXPANDED_HEIGHT, 80)) binding.landExpandedHeight.sliderValue = landExpandedHeight[0] binding.landExpandedHeight.setOnSliderTouchListener(object : Slider.OnSliderTouchListener { @@ -176,10 +176,10 @@ class QsTileSize : BaseFragment() { ) if (!hasErroredOut.get()) { - Prefs.putInt(PORT_QSTILE_NONEXPANDED_HEIGHT, portNonExpandedHeight[0]) - Prefs.putInt(PORT_QSTILE_EXPANDED_HEIGHT, portExpandedHeight[0]) - Prefs.putInt(LAND_QSTILE_NONEXPANDED_HEIGHT, landNonExpandedHeight[0]) - Prefs.putInt(LAND_QSTILE_EXPANDED_HEIGHT, landExpandedHeight[0]) + RPrefs.putInt(PORT_QSTILE_NONEXPANDED_HEIGHT, portNonExpandedHeight[0]) + RPrefs.putInt(PORT_QSTILE_EXPANDED_HEIGHT, portExpandedHeight[0]) + RPrefs.putInt(LAND_QSTILE_NONEXPANDED_HEIGHT, landNonExpandedHeight[0]) + RPrefs.putInt(LAND_QSTILE_EXPANDED_HEIGHT, landExpandedHeight[0]) } Handler(Looper.getMainLooper()).postDelayed({ @@ -273,10 +273,10 @@ class QsTileSize : BaseFragment() { } private val isQsTileHeightEnabled: Boolean - get() = Prefs.getInt(PORT_QSTILE_NONEXPANDED_HEIGHT, 60) != 60 || - Prefs.getInt(PORT_QSTILE_EXPANDED_HEIGHT, 80) != 80 || - Prefs.getInt(LAND_QSTILE_NONEXPANDED_HEIGHT, 60) != 60 || - Prefs.getInt(LAND_QSTILE_EXPANDED_HEIGHT, 80) != 80 + get() = RPrefs.getInt(PORT_QSTILE_NONEXPANDED_HEIGHT, 60) != 60 || + RPrefs.getInt(PORT_QSTILE_EXPANDED_HEIGHT, 80) != 80 || + RPrefs.getInt(LAND_QSTILE_NONEXPANDED_HEIGHT, 60) != 60 || + RPrefs.getInt(LAND_QSTILE_EXPANDED_HEIGHT, 80) != 80 override fun onDestroy() { loadingDialog?.dismiss() diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/tweaks/Statusbar.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/tweaks/Statusbar.kt new file mode 100644 index 000000000..7e21b364d --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/fragments/tweaks/Statusbar.kt @@ -0,0 +1,366 @@ +package com.drdisagree.iconify.ui.fragments.tweaks + +import android.os.Bundle +import android.os.Handler +import android.os.Looper +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.RadioGroup +import com.drdisagree.iconify.Iconify.Companion.appContext +import com.drdisagree.iconify.R +import com.drdisagree.iconify.common.Const.FRAMEWORK_PACKAGE +import com.drdisagree.iconify.common.Const.SWITCH_ANIMATION_DELAY +import com.drdisagree.iconify.common.Const.SYSTEMUI_PACKAGE +import com.drdisagree.iconify.common.References.FABRICATED_SB_COLOR_SOURCE +import com.drdisagree.iconify.common.References.FABRICATED_SB_COLOR_TINT +import com.drdisagree.iconify.common.References.FABRICATED_SB_HEIGHT +import com.drdisagree.iconify.common.References.FABRICATED_SB_LEFT_PADDING +import com.drdisagree.iconify.common.References.FABRICATED_SB_RIGHT_PADDING +import com.drdisagree.iconify.config.RPrefs +import com.drdisagree.iconify.config.RPrefs.putString +import com.drdisagree.iconify.databinding.FragmentStatusbarBinding +import com.drdisagree.iconify.ui.activities.MainActivity +import com.drdisagree.iconify.ui.base.BaseFragment +import com.drdisagree.iconify.ui.events.ColorDismissedEvent +import com.drdisagree.iconify.ui.events.ColorSelectedEvent +import com.drdisagree.iconify.ui.utils.ViewHelper.setHeader +import com.drdisagree.iconify.utils.SystemUtils +import com.drdisagree.iconify.utils.color.ColorUtils.colorToSpecialHex +import com.drdisagree.iconify.utils.overlay.FabricatedUtils.buildAndEnableOverlays +import com.drdisagree.iconify.utils.overlay.FabricatedUtils.disableOverlays +import com.drdisagree.iconify.utils.overlay.OverlayUtils +import com.drdisagree.iconify.utils.overlay.OverlayUtils.enableOverlay +import com.drdisagree.iconify.utils.overlay.manager.resource.ResourceEntry +import com.drdisagree.iconify.utils.overlay.manager.resource.ResourceManager.buildOverlayWithResource +import com.drdisagree.iconify.utils.overlay.manager.resource.ResourceManager.removeResourceFromOverlay +import com.google.android.material.slider.Slider +import org.greenrobot.eventbus.EventBus +import org.greenrobot.eventbus.Subscribe + + +class Statusbar : BaseFragment() { + + private lateinit var binding: FragmentStatusbarBinding + private val finalSBLeftPadding = intArrayOf(RPrefs.getInt(FABRICATED_SB_LEFT_PADDING, 8)) + private val finalSBRightPadding = intArrayOf(RPrefs.getInt(FABRICATED_SB_RIGHT_PADDING, 8)) + private val finalSBHeight = intArrayOf(RPrefs.getInt(FABRICATED_SB_HEIGHT, 28)) + + private val sbLeftPaddingListener: Slider.OnSliderTouchListener = + object : Slider.OnSliderTouchListener { + override fun onStartTrackingTouch(slider: Slider) {} + + override fun onStopTrackingTouch(slider: Slider) { + finalSBLeftPadding[0] = slider.value.toInt() + RPrefs.putInt(FABRICATED_SB_LEFT_PADDING, finalSBLeftPadding[0]) + + buildOverlayWithResource( + requireContext(), + ResourceEntry( + SYSTEMUI_PACKAGE, + "dimen", + "status_bar_padding_start", + finalSBLeftPadding[0].toString() + "dp" + ) + ) + } + } + + private val sbRightPaddingListener: Slider.OnSliderTouchListener = + object : Slider.OnSliderTouchListener { + override fun onStartTrackingTouch(slider: Slider) {} + + override fun onStopTrackingTouch(slider: Slider) { + finalSBRightPadding[0] = slider.value.toInt() + RPrefs.putInt(FABRICATED_SB_RIGHT_PADDING, finalSBRightPadding[0]) + + buildOverlayWithResource( + requireContext(), + ResourceEntry( + SYSTEMUI_PACKAGE, + "dimen", + "status_bar_padding_end", + finalSBRightPadding[0].toString() + "dp" + ) + ) + } + } + + private val sbHeightListener: Slider.OnSliderTouchListener = + object : Slider.OnSliderTouchListener { + override fun onStartTrackingTouch(slider: Slider) {} + + override fun onStopTrackingTouch(slider: Slider) { + finalSBHeight[0] = slider.value.toInt() + RPrefs.putInt(FABRICATED_SB_HEIGHT, finalSBHeight[0]) + + buildOverlayWithResource( + requireContext(), + ResourceEntry( + FRAMEWORK_PACKAGE, + "dimen", + "status_bar_height", + finalSBHeight[0].toString() + "dp" + ), + ResourceEntry( + FRAMEWORK_PACKAGE, + "dimen", + "status_bar_height_default", + finalSBHeight[0].toString() + "dp" + ), + ResourceEntry( + FRAMEWORK_PACKAGE, + "dimen", + "status_bar_height_portrait", + finalSBHeight[0].toString() + "dp" + ), + ResourceEntry( + FRAMEWORK_PACKAGE, + "dimen", + "status_bar_height_landscape", + finalSBHeight[0].toString() + "dp" + ) + ) + } + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + binding = FragmentStatusbarBinding.inflate(inflater, container, false) + val view: View = binding.getRoot() + + // Header + setHeader( + requireContext(), + getParentFragmentManager(), + binding.header.toolbar, + R.string.activity_title_statusbar + ) + + // Statusbar left padding + binding.sbLeftPadding.sliderValue = finalSBLeftPadding[0] + binding.sbLeftPadding.setOnSliderTouchListener(sbLeftPaddingListener) + + // Reset left padding + binding.sbLeftPadding.setResetClickListener { + RPrefs.putInt(FABRICATED_SB_LEFT_PADDING, 8) + + removeResourceFromOverlay( + requireContext(), + ResourceEntry(SYSTEMUI_PACKAGE, "dimen", "status_bar_padding_start") + ) + + true + } + + // Statusbar right padding + binding.sbRightPadding.sliderValue = finalSBRightPadding[0] + binding.sbRightPadding.setOnSliderTouchListener(sbRightPaddingListener) + + // Reset right padding + binding.sbRightPadding.setResetClickListener { + RPrefs.putInt(FABRICATED_SB_RIGHT_PADDING, 8) + + removeResourceFromOverlay( + requireContext(), + ResourceEntry(SYSTEMUI_PACKAGE, "dimen", "status_bar_padding_end") + ) + + true + } + + // Statusbar height + binding.sbHeight.sliderValue = finalSBHeight[0] + binding.sbHeight.setOnSliderTouchListener(sbHeightListener) + + // Reset height + binding.sbHeight.setResetClickListener { + RPrefs.putInt(FABRICATED_SB_HEIGHT, 28) + + removeResourceFromOverlay( + requireContext(), + ResourceEntry(FRAMEWORK_PACKAGE, "dimen", "status_bar_height"), + ResourceEntry(FRAMEWORK_PACKAGE, "dimen", "status_bar_height_default"), + ResourceEntry(FRAMEWORK_PACKAGE, "dimen", "status_bar_height_portrait"), + ResourceEntry(FRAMEWORK_PACKAGE, "dimen", "status_bar_height_landscape") + ) + + true + } + colorSBTint = resources.getColor(R.color.colorAccent, appContext.theme).toString() + + //set current chosen style + selectedStyle = RPrefs.getString(FABRICATED_SB_COLOR_SOURCE) + when { + selectedStyle == "Monet" || RPrefs.getBoolean("IconifyComponentSBTint.overlay") -> { + binding.sbTintMonet.setChecked(true) + putString(FABRICATED_SB_COLOR_SOURCE, "Monet") + } + + selectedStyle == "System" -> { + binding.sbTintSystem.setChecked(true) + } + + selectedStyle == "Custom" -> { + binding.sbTintCustom.setChecked( + true + ) + } + } + + // Statusbar color source select + binding.sbTintSourceSelector.setOnCheckedChangeListener { _: RadioGroup?, checkedId: Int -> + when (checkedId) { + R.id.sb_tint_system -> { + if (selectedStyle != "System") { + putString(FABRICATED_SB_COLOR_SOURCE, "System") + resetSBColor() + } + } + + R.id.sb_tint_monet -> { + if (selectedStyle != "Monet") { + enableOverlay("IconifyComponentSBTint.overlay") + putString(FABRICATED_SB_COLOR_SOURCE, "Monet") + Handler(Looper.getMainLooper()).postDelayed( + { SystemUtils.restartSystemUI() }, + SWITCH_ANIMATION_DELAY + ) + } + } + + R.id.sb_tint_custom -> { + (requireActivity() as MainActivity).showColorPickerDialog( + dialogId = 1, + defaultColor = colorSBTint!!.toInt(), + showPresets = true, + showAlphaSlider = false, + showColorShades = true + ) + } + } + } + + return view + } + + @Suppress("unused") + @Subscribe + fun onColorSelected(event: ColorSelectedEvent) { + if (event.dialogId == 1) { + colorSBTint = event.selectedColor.toString() + putString(FABRICATED_SB_COLOR_TINT, colorSBTint) + + applySBColor() + + putString(FABRICATED_SB_COLOR_SOURCE, "Custom") + + OverlayUtils.disableOverlay("IconifyComponentSBTint.overlay") + } + } + + @Suppress("unused") + @Subscribe + fun onDialogDismissed(event: ColorDismissedEvent) { + if (event.dialogId == 1) { + selectedStyle = RPrefs.getString(FABRICATED_SB_COLOR_SOURCE) + when (selectedStyle) { + "System" -> binding.sbTintSystem.setChecked(true) + "Monet" -> binding.sbTintMonet.setChecked(true) + "Custom" -> binding.sbTintCustom.setChecked(true) + } + } + } + + private fun applySBColor() { + buildAndEnableOverlays( + arrayOf( + SYSTEMUI_PACKAGE, + "colorSBTint1", + "color", + "dark_mode_icon_color_dual_tone_fill", + colorToSpecialHex(colorSBTint!!.toInt()) + ), arrayOf( + SYSTEMUI_PACKAGE, + "colorSBTint2", + "color", + "dark_mode_icon_color_single_tone", + colorToSpecialHex(colorSBTint!!.toInt()) + ), arrayOf( + SYSTEMUI_PACKAGE, + "colorSBTint3", + "color", + "dark_mode_qs_icon_color_dual_tone_fill", + colorToSpecialHex(colorSBTint!!.toInt()) + ), arrayOf( + SYSTEMUI_PACKAGE, + "colorSBTint4", + "color", + "dark_mode_qs_icon_color_single_tone", + colorToSpecialHex(colorSBTint!!.toInt()) + ), arrayOf( + SYSTEMUI_PACKAGE, + "colorSBTint5", + "color", + "light_mode_icon_color_dual_tone_fill", + colorToSpecialHex(colorSBTint!!.toInt()) + ), arrayOf( + SYSTEMUI_PACKAGE, + "colorSBTint6", + "color", + "light_mode_icon_color_single_tone", + colorToSpecialHex(colorSBTint!!.toInt()) + ), arrayOf( + SYSTEMUI_PACKAGE, + "colorSBTint7", + "color", + "status_bar_clock_color", + colorToSpecialHex(colorSBTint!!.toInt()) + ) + ) + + Handler(Looper.getMainLooper()).postDelayed( + { SystemUtils.restartSystemUI() }, + 1000 + ) + } + + private fun resetSBColor() { + disableOverlays( + "colorSBTint1", + "colorSBTint2", + "colorSBTint3", + "colorSBTint4", + "colorSBTint5", + "colorSBTint6", + "colorSBTint7" + ) + + OverlayUtils.disableOverlay("IconifyComponentSBTint.overlay") + + Handler(Looper.getMainLooper()).postDelayed( + { SystemUtils.restartSystemUI() }, + 1000 + ) + } + + override fun onStart() { + super.onStart() + + EventBus.getDefault().register(this) + } + + override fun onStop() { + super.onStop() + + EventBus.getDefault().unregister(this) + } + + companion object { + private var colorSBTint: String? = null + private var selectedStyle: String? = null + } +} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/tweaks/Tweaks.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/tweaks/Tweaks.kt new file mode 100644 index 000000000..ea03bccf2 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/fragments/tweaks/Tweaks.kt @@ -0,0 +1,19 @@ +package com.drdisagree.iconify.ui.fragments.tweaks + +import com.drdisagree.iconify.R +import com.drdisagree.iconify.ui.base.ControlledPreferenceFragmentCompat + +class Tweaks : ControlledPreferenceFragmentCompat() { + + override val title: String + get() = getString(R.string.navbar_tweaks) + + override val backButtonEnabled: Boolean + get() = true + + override val layoutResource: Int + get() = R.xml.tweaks + + override val hasMenu: Boolean + get() = true +} diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/UiRoundness.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/tweaks/UiRoundness.kt similarity index 94% rename from app/src/main/java/com/drdisagree/iconify/ui/fragments/UiRoundness.kt rename to app/src/main/java/com/drdisagree/iconify/ui/fragments/tweaks/UiRoundness.kt index 11873a5d4..8d23d8512 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/fragments/UiRoundness.kt +++ b/app/src/main/java/com/drdisagree/iconify/ui/fragments/tweaks/UiRoundness.kt @@ -1,4 +1,4 @@ -package com.drdisagree.iconify.ui.fragments +package com.drdisagree.iconify.ui.fragments.tweaks import android.content.res.Configuration import android.graphics.drawable.GradientDrawable @@ -15,14 +15,13 @@ import com.drdisagree.iconify.Iconify.Companion.appContext import com.drdisagree.iconify.Iconify.Companion.appContextLocale import com.drdisagree.iconify.R import com.drdisagree.iconify.common.Preferences.UI_CORNER_RADIUS -import com.drdisagree.iconify.config.Prefs import com.drdisagree.iconify.config.RPrefs import com.drdisagree.iconify.databinding.FragmentUiRoundnessBinding import com.drdisagree.iconify.ui.base.BaseFragment import com.drdisagree.iconify.ui.dialogs.LoadingDialog import com.drdisagree.iconify.ui.utils.ViewHelper.setHeader -import com.drdisagree.iconify.utils.SystemUtil.hasStoragePermission -import com.drdisagree.iconify.utils.SystemUtil.requestStoragePermission +import com.drdisagree.iconify.utils.SystemUtils.hasStoragePermission +import com.drdisagree.iconify.utils.SystemUtils.requestStoragePermission import com.drdisagree.iconify.utils.overlay.manager.RoundnessManager.buildOverlay import com.google.android.material.slider.Slider import java.io.IOException @@ -70,7 +69,7 @@ class UiRoundness : BaseFragment() { binding.autoBrightness.background as GradientDrawable ) - val finalUiCornerRadius = intArrayOf(Prefs.getInt(UI_CORNER_RADIUS, 28)) + val finalUiCornerRadius = intArrayOf(RPrefs.getInt(UI_CORNER_RADIUS, 28)) if (finalUiCornerRadius[0] == 28) { binding.cornerRadiusOutput.text = @@ -146,7 +145,7 @@ class UiRoundness : BaseFragment() { Handler(Looper.getMainLooper()).post { if (!hasErroredOut.get()) { - Prefs.putInt(UI_CORNER_RADIUS, finalUiCornerRadius[0]) + RPrefs.putInt(UI_CORNER_RADIUS, finalUiCornerRadius[0]) RPrefs.putInt(UI_CORNER_RADIUS, finalUiCornerRadius[0]) } diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/tweaks/VolumePanel.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/tweaks/VolumePanel.kt new file mode 100644 index 000000000..43906b7fa --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/fragments/tweaks/VolumePanel.kt @@ -0,0 +1,463 @@ +package com.drdisagree.iconify.ui.fragments.tweaks + +import android.annotation.SuppressLint +import android.os.Bundle +import android.os.Handler +import android.os.Looper +import android.util.Log +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.RadioGroup +import android.widget.Toast +import androidx.core.content.ContextCompat +import com.drdisagree.iconify.Iconify.Companion.appContext +import com.drdisagree.iconify.Iconify.Companion.appContextLocale +import com.drdisagree.iconify.R +import com.drdisagree.iconify.common.Const.SYSTEMUI_PACKAGE +import com.drdisagree.iconify.common.Preferences.VOLUME_PANEL_BACKGROUND_WIDTH +import com.drdisagree.iconify.config.RPrefs +import com.drdisagree.iconify.databinding.FragmentVolumePanelBinding +import com.drdisagree.iconify.ui.base.BaseFragment +import com.drdisagree.iconify.ui.dialogs.InfoDialog +import com.drdisagree.iconify.ui.dialogs.LoadingDialog +import com.drdisagree.iconify.ui.utils.ViewHelper.setHeader +import com.drdisagree.iconify.utils.RootUtils.isApatchInstalled +import com.drdisagree.iconify.utils.RootUtils.isKSUInstalled +import com.drdisagree.iconify.utils.RootUtils.isMagiskInstalled +import com.drdisagree.iconify.utils.SystemUtils.hasStoragePermission +import com.drdisagree.iconify.utils.SystemUtils.requestStoragePermission +import com.drdisagree.iconify.utils.overlay.compiler.VolumeCompiler.buildModule +import com.drdisagree.iconify.utils.overlay.manager.resource.ResourceEntry +import com.drdisagree.iconify.utils.overlay.manager.resource.ResourceManager.buildOverlayWithResource +import com.drdisagree.iconify.utils.overlay.manager.resource.ResourceManager.removeResourceFromOverlay +import com.google.android.material.button.MaterialButton +import java.util.concurrent.atomic.AtomicBoolean + +class VolumePanel : BaseFragment() { + + private lateinit var binding: FragmentVolumePanelBinding + private var loadingDialog: LoadingDialog? = null + private var infoDialog: InfoDialog? = null + private var finalCheckedId = -1 + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + binding = FragmentVolumePanelBinding.inflate(inflater, container, false) + val view: View = binding.getRoot() + + // Header + setHeader( + requireContext(), + getParentFragmentManager(), + binding.header.toolbar, + R.string.activity_title_volume_panel + ) + + binding.thinBg.isChecked = RPrefs.getInt(VOLUME_PANEL_BACKGROUND_WIDTH, 0) == 1 + binding.thinBg.addOnCheckedChangeListener { button: MaterialButton, isChecked: Boolean -> + if (button.isPressed) { + if (!hasStoragePermission()) { + requestStoragePermission(requireContext()) + binding.toggleButtonGroup.uncheck(binding.thinBg.id) + } else { + if (isChecked) { + binding.toggleButtonGroup.uncheck(binding.thickBg.id) + binding.toggleButtonGroup.uncheck(binding.noBg.id) + + RPrefs.putInt(VOLUME_PANEL_BACKGROUND_WIDTH, 1) + + buildOverlayWithResource( + requireContext(), + ResourceEntry( + SYSTEMUI_PACKAGE, + "dimen", + "volume_dialog_slider_width", + "42dp" + ), + ResourceEntry( + SYSTEMUI_PACKAGE, + "dimen", + "volume_dialog_track_width", + "4dp" + ), + ResourceEntry( + SYSTEMUI_PACKAGE, + "dimen", + "rounded_slider_track_inset", + "22dp" + ) + ) + } else { + RPrefs.putInt(VOLUME_PANEL_BACKGROUND_WIDTH, 0) + + removeResourceFromOverlay( + requireContext(), + ResourceEntry(SYSTEMUI_PACKAGE, "dimen", "volume_dialog_slider_width"), + ResourceEntry(SYSTEMUI_PACKAGE, "dimen", "volume_dialog_track_width"), + ResourceEntry(SYSTEMUI_PACKAGE, "dimen", "rounded_slider_track_inset") + ) + } + } + } + } + + binding.thickBg.isChecked = RPrefs.getInt(VOLUME_PANEL_BACKGROUND_WIDTH, 0) == 2 + binding.thickBg.addOnCheckedChangeListener { button: MaterialButton, isChecked: Boolean -> + if (button.isPressed) { + if (!hasStoragePermission()) { + requestStoragePermission(requireContext()) + binding.toggleButtonGroup.uncheck(binding.thickBg.id) + } else { + if (isChecked) { + binding.toggleButtonGroup.uncheck(binding.thinBg.id) + binding.toggleButtonGroup.uncheck(binding.noBg.id) + + RPrefs.putInt(VOLUME_PANEL_BACKGROUND_WIDTH, 2) + + buildOverlayWithResource( + requireContext(), + ResourceEntry( + SYSTEMUI_PACKAGE, + "dimen", + "volume_dialog_slider_width", + "42dp" + ), + ResourceEntry( + SYSTEMUI_PACKAGE, + "dimen", + "volume_dialog_track_width", + "42dp" + ), + ResourceEntry( + SYSTEMUI_PACKAGE, + "dimen", + "rounded_slider_track_inset", + "0dp" + ) + ) + } else { + RPrefs.putInt(VOLUME_PANEL_BACKGROUND_WIDTH, 0) + + removeResourceFromOverlay( + requireContext(), + ResourceEntry(SYSTEMUI_PACKAGE, "dimen", "volume_dialog_slider_width"), + ResourceEntry(SYSTEMUI_PACKAGE, "dimen", "volume_dialog_track_width"), + ResourceEntry(SYSTEMUI_PACKAGE, "dimen", "rounded_slider_track_inset") + ) + } + } + } + } + + binding.noBg.isChecked = RPrefs.getInt(VOLUME_PANEL_BACKGROUND_WIDTH, 0) == 3 + binding.noBg.addOnCheckedChangeListener { button: MaterialButton, isChecked: Boolean -> + if (button.isPressed) { + if (!hasStoragePermission()) { + requestStoragePermission(requireContext()) + binding.toggleButtonGroup.uncheck(binding.noBg.id) + } else { + if (isChecked) { + binding.toggleButtonGroup.uncheck(binding.thinBg.id) + binding.toggleButtonGroup.uncheck(binding.thickBg.id) + + RPrefs.putInt(VOLUME_PANEL_BACKGROUND_WIDTH, 3) + + buildOverlayWithResource( + requireContext(), + ResourceEntry( + SYSTEMUI_PACKAGE, + "dimen", + "volume_dialog_slider_width", + "42dp" + ), + ResourceEntry( + SYSTEMUI_PACKAGE, + "dimen", + "volume_dialog_track_width", + "0dp" + ), + ResourceEntry( + SYSTEMUI_PACKAGE, + "dimen", + "rounded_slider_track_inset", + "24dp" + ) + ) + } else { + RPrefs.putInt(VOLUME_PANEL_BACKGROUND_WIDTH, 0) + + removeResourceFromOverlay( + requireContext(), + ResourceEntry(SYSTEMUI_PACKAGE, "dimen", "volume_dialog_slider_width"), + ResourceEntry(SYSTEMUI_PACKAGE, "dimen", "volume_dialog_track_width"), + ResourceEntry(SYSTEMUI_PACKAGE, "dimen", "rounded_slider_track_inset") + ) + } + } + } + } + + // Loading dialog while creating modules + loadingDialog = LoadingDialog(requireContext()) + + // Credits dialog for volume style modules + infoDialog = InfoDialog(requireContext()) + + // Volume style + binding.volumeStyle.volumeStyleInfo.setOnClickListener { + infoDialog!!.show( + R.string.read_carefully, + R.string.volume_module_installation_guide + ) + } + + binding.volumeStyle.volumeStyle1.clearCheck() + binding.volumeStyle.volumeStyle2.clearCheck() + + binding.volumeStyle.volumeStyle1.setOnCheckedChangeListener(listener1) + binding.volumeStyle.volumeStyle2.setOnCheckedChangeListener(listener2) + + val checkedId1 = binding.volumeStyle.volumeStyle1.checkedRadioButtonId + val checkedId2 = binding.volumeStyle.volumeStyle2.checkedRadioButtonId + finalCheckedId = if (checkedId1 == -1) checkedId2 else checkedId1 + + binding.volumeStyle.volumeStyleCreateModule.setOnClickListener { + if ((isKSUInstalled || isApatchInstalled) && !isMagiskInstalled) { + Toast.makeText( + appContext, + appContextLocale.resources.getString(R.string.toast_only_magisk_supported), + Toast.LENGTH_SHORT + ).show() + + return@setOnClickListener + } + + if (!hasStoragePermission()) { + requestStoragePermission(requireContext()) + } else { + if (finalCheckedId == -1) { + Toast.makeText( + appContext, + appContextLocale.resources.getString(R.string.toast_select_style), + Toast.LENGTH_SHORT + ).show() + } else { + installVolumeModule(finalCheckedId) + } + } + } + + return view + } + + @SuppressLint("NonConstantResourceId") + private fun installVolumeModule(volume: Int) { + loadingDialog!!.show(resources.getString(R.string.loading_dialog_wait)) + + val hasErroredOut = AtomicBoolean(false) + + val selectedStyle: String = when (volume) { + R.id.gradient_style -> "VolumeGradient" + R.id.doublelayer_style -> "VolumeDoubleLayer" + R.id.shadedlayer_style -> "VolumeShadedLayer" + R.id.neumorph_style -> "VolumeNeumorph" + R.id.outline_style -> "VolumeOutline" + R.id.neumorphoutline_style -> "VolumeNeumorphOutline" + else -> return + } + + Thread { + try { + hasErroredOut.set(buildModule(selectedStyle, SYSTEMUI_PACKAGE)) + } catch (e: Exception) { + hasErroredOut.set(true) + Log.e("VolumePanel", e.toString()) + } + + Handler(Looper.getMainLooper()).postDelayed({ + loadingDialog!!.hide() + + if (hasErroredOut.get()) { + Toast.makeText( + appContext, + appContextLocale.resources.getString(R.string.toast_error), + Toast.LENGTH_SHORT + ).show() + } else { + Toast.makeText( + appContext, + appContextLocale.resources.getString(R.string.toast_module_created), + Toast.LENGTH_SHORT + ).show() + } + }, 2000) + }.start() + } + + private fun updateVolumePreview(id: Int) { + when (id) { + R.id.gradient_style -> setVolumeDrawable( + ringerDrawable = R.drawable.volume_gradient, + progressDrawable = R.drawable.volume_gradient, + ringerInverse = false, + progressInverse = false + ) + + R.id.doublelayer_style -> setVolumeDrawable( + ringerDrawable = R.drawable.volume_double_layer, + progressDrawable = R.drawable.volume_double_layer, + ringerInverse = false, + progressInverse = false + ) + + R.id.shadedlayer_style -> setVolumeDrawable( + ringerDrawable = R.drawable.volume_shaded_layer, + progressDrawable = R.drawable.volume_shaded_layer, + ringerInverse = false, + progressInverse = false + ) + + R.id.neumorph_style -> setVolumeDrawable( + ringerDrawable = R.drawable.volume_neumorph, + progressDrawable = R.drawable.volume_neumorph, + ringerInverse = false, + progressInverse = false + ) + + R.id.outline_style -> setVolumeDrawable( + ringerDrawable = R.drawable.volume_outline_ringer, + progressDrawable = R.drawable.volume_outline, + ringerInverse = true, + progressInverse = false + ) + + R.id.neumorphoutline_style -> setVolumeDrawable( + ringerDrawable = R.drawable.volume_neumorph_outline_ringer, + progressDrawable = R.drawable.volume_neumorph_outline, + ringerInverse = true, + progressInverse = false + ) + } + } + + private fun setVolumeDrawable( + ringerDrawable: Int, + progressDrawable: Int, + ringerInverse: Boolean, + progressInverse: Boolean + ) { + binding.volumeThinBg.volumeRingerBg.background = + ContextCompat.getDrawable(appContext, ringerDrawable) + binding.volumeThinBg.volumeProgressDrawable.background = + ContextCompat.getDrawable(appContext, progressDrawable) + binding.volumeThickBg.volumeRingerBg.background = + ContextCompat.getDrawable(appContext, ringerDrawable) + binding.volumeThickBg.volumeProgressDrawable.background = + ContextCompat.getDrawable(appContext, progressDrawable) + binding.volumeNoBg.volumeRingerBg.background = + ContextCompat.getDrawable(appContext, ringerDrawable) + binding.volumeNoBg.volumeProgressDrawable.background = + ContextCompat.getDrawable(appContext, progressDrawable) + + if (ringerInverse) { + binding.volumeThinBg.volumeRingerIcon.setBackgroundTintList( + ContextCompat.getColorStateList( + appContext, R.color.textColorPrimary + ) + ) + binding.volumeThickBg.volumeRingerIcon.setBackgroundTintList( + ContextCompat.getColorStateList( + appContext, R.color.textColorPrimary + ) + ) + binding.volumeNoBg.volumeRingerIcon.setBackgroundTintList( + ContextCompat.getColorStateList( + appContext, R.color.textColorPrimary + ) + ) + } else { + binding.volumeThinBg.volumeRingerIcon.setBackgroundTintList( + ContextCompat.getColorStateList( + appContext, R.color.textColorPrimaryInverse + ) + ) + binding.volumeThickBg.volumeRingerIcon.setBackgroundTintList( + ContextCompat.getColorStateList( + appContext, R.color.textColorPrimaryInverse + ) + ) + binding.volumeNoBg.volumeRingerIcon.setBackgroundTintList( + ContextCompat.getColorStateList( + appContext, R.color.textColorPrimaryInverse + ) + ) + } + if (progressInverse) { + binding.volumeThinBg.volumeProgressIcon.setBackgroundTintList( + ContextCompat.getColorStateList( + appContext, R.color.textColorPrimary + ) + ) + binding.volumeThickBg.volumeProgressIcon.setBackgroundTintList( + ContextCompat.getColorStateList( + appContext, R.color.textColorPrimary + ) + ) + binding.volumeNoBg.volumeProgressIcon.setBackgroundTintList( + ContextCompat.getColorStateList( + appContext, R.color.textColorPrimary + ) + ) + } else { + binding.volumeThinBg.volumeProgressIcon.setBackgroundTintList( + ContextCompat.getColorStateList( + appContext, R.color.textColorPrimaryInverse + ) + ) + binding.volumeThickBg.volumeProgressIcon.setBackgroundTintList( + ContextCompat.getColorStateList( + appContext, R.color.textColorPrimaryInverse + ) + ) + binding.volumeNoBg.volumeProgressIcon.setBackgroundTintList( + ContextCompat.getColorStateList( + appContext, R.color.textColorPrimaryInverse + ) + ) + } + } + + override fun onDestroy() { + loadingDialog?.dismiss() + + super.onDestroy() + } + + private val listener1: RadioGroup.OnCheckedChangeListener = + RadioGroup.OnCheckedChangeListener { _, checkedId -> + if (checkedId != -1) { + binding.volumeStyle.volumeStyle2.setOnCheckedChangeListener(null) + binding.volumeStyle.volumeStyle2.clearCheck() + binding.volumeStyle.volumeStyle2.setOnCheckedChangeListener(listener2) + finalCheckedId = checkedId + } + + updateVolumePreview(checkedId) + } + + private val listener2: RadioGroup.OnCheckedChangeListener = + RadioGroup.OnCheckedChangeListener { _, checkedId -> + if (checkedId != -1) { + binding.volumeStyle.volumeStyle1.setOnCheckedChangeListener(null) + binding.volumeStyle.volumeStyle1.clearCheck() + binding.volumeStyle.volumeStyle1.setOnCheckedChangeListener(listener1) + finalCheckedId = checkedId + } + + updateVolumePreview(checkedId) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/BackgroundChip.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/BackgroundChip.kt new file mode 100644 index 000000000..7d1dac154 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/BackgroundChip.kt @@ -0,0 +1,45 @@ +package com.drdisagree.iconify.ui.fragments.xposed + +import com.drdisagree.iconify.R +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_SWITCH +import com.drdisagree.iconify.common.Preferences.CHIP_STATUS_ICONS_SWITCH +import com.drdisagree.iconify.config.RPrefs.getBoolean +import com.drdisagree.iconify.ui.activities.MainActivity +import com.drdisagree.iconify.ui.base.ControlledPreferenceFragmentCompat + +class BackgroundChip : ControlledPreferenceFragmentCompat() { + + override val title: String + get() = getString(R.string.activity_title_background_chip) + + override val backButtonEnabled: Boolean + get() = true + + override val layoutResource: Int + get() = R.xml.xposed_background_chip + + override val hasMenu: Boolean + get() = true + + override fun updateScreen(key: String?) { + super.updateScreen(key) + + when (key) { + CHIP_STATUSBAR_CLOCK_SWITCH -> { + if (!getBoolean(key)) { + MainActivity.showOrHidePendingActionButton( + activityBinding = (requireActivity() as MainActivity).binding, + requiresSystemUiRestart = true + ) + } + } + + CHIP_STATUS_ICONS_SWITCH -> { + MainActivity.showOrHidePendingActionButton( + activityBinding = (requireActivity() as MainActivity).binding, + requiresSystemUiRestart = true + ) + } + } + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/BatteryStyle.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/BatteryStyle.kt new file mode 100644 index 000000000..44e16cc2b --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/BatteryStyle.kt @@ -0,0 +1,67 @@ +package com.drdisagree.iconify.ui.fragments.xposed + +import android.os.Bundle +import com.drdisagree.iconify.R +import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_CHARGING_ICON_STYLE +import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_HEIGHT +import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_STYLE +import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_WIDTH +import com.drdisagree.iconify.config.RPrefs +import com.drdisagree.iconify.ui.activities.MainActivity +import com.drdisagree.iconify.ui.adapters.ListPreferenceAdapter +import com.drdisagree.iconify.ui.base.ControlledPreferenceFragmentCompat +import com.drdisagree.iconify.ui.preferences.BottomSheetListPreference +import com.drdisagree.iconify.ui.utils.ViewHelper.getBatteryDrawables +import com.drdisagree.iconify.ui.utils.ViewHelper.getChargingIcons + +class BatteryStyle : ControlledPreferenceFragmentCompat() { + + override val title: String + get() = getString(R.string.activity_title_battery_style) + + override val backButtonEnabled: Boolean + get() = true + + override val layoutResource: Int + get() = R.xml.xposed_battery_style + + override val hasMenu: Boolean + get() = true + + override fun updateScreen(key: String?) { + super.updateScreen(key) + + when (key) { + CUSTOM_BATTERY_STYLE -> { + MainActivity.showOrHidePendingActionButton( + activityBinding = (requireActivity() as MainActivity).binding, + requiresSystemUiRestart = true + ) + } + + CUSTOM_BATTERY_WIDTH, + CUSTOM_BATTERY_HEIGHT -> { + if (RPrefs.getString(CUSTOM_BATTERY_STYLE, "0")!!.toInt() < 3) { + MainActivity.showOrHidePendingActionButton( + activityBinding = (requireActivity() as MainActivity).binding, + requiresSystemUiRestart = true + ) + } + } + } + } + + override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { + super.onCreatePreferences(savedInstanceState, rootKey) + + findPreference(CUSTOM_BATTERY_STYLE)?.apply { + createDefaultAdapter(getBatteryDrawables(requireContext())) + setAdapterType(ListPreferenceAdapter.TYPE_BATTERY_ICONS) + } + + findPreference(CUSTOM_BATTERY_CHARGING_ICON_STYLE)?.apply { + createDefaultAdapter(getChargingIcons(requireContext())) + setAdapterType(ListPreferenceAdapter.TYPE_BATTERY_ICONS) + } + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/ClockChip.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/ClockChip.kt new file mode 100644 index 000000000..ff8ebda04 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/ClockChip.kt @@ -0,0 +1,426 @@ +package com.drdisagree.iconify.ui.fragments.xposed + +import android.content.res.Configuration +import android.graphics.Color +import android.graphics.PorterDuff +import android.graphics.PorterDuffXfermode +import android.graphics.drawable.Drawable +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.view.ViewTreeObserver +import android.widget.CompoundButton +import androidx.coordinatorlayout.widget.CoordinatorLayout +import androidx.core.content.ContextCompat +import androidx.core.view.ViewCompat +import androidx.core.view.WindowInsetsCompat +import com.drdisagree.iconify.R +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_ACCENT +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_END_COLOR +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_GRADIENT_DIRECTION +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_PADDING_BOTTOM +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_PADDING_LEFT +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_PADDING_RIGHT +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_PADDING_TOP +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_RADIUS_BOTTOM_LEFT +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_RADIUS_BOTTOM_RIGHT +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_RADIUS_TOP_LEFT +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_RADIUS_TOP_RIGHT +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_START_COLOR +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_STROKE_ACCENT +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_STROKE_COLOR +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_STROKE_DASH +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_STROKE_DASH_GAP +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_STROKE_DASH_WIDTH +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_STROKE_SWITCH +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_STROKE_WIDTH +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_STYLE_CHANGED +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_TEXT_COLOR_CODE +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_TEXT_COLOR_OPTION +import com.drdisagree.iconify.config.RPrefs +import com.drdisagree.iconify.config.RPrefs.getBoolean +import com.drdisagree.iconify.config.RPrefs.getInt +import com.drdisagree.iconify.databinding.FragmentXposedClockChipBinding +import com.drdisagree.iconify.ui.base.BaseFragment +import com.drdisagree.iconify.ui.utils.ViewHelper.setHeader +import com.drdisagree.iconify.xposed.modules.utils.ViewHelper.toPx +import com.drdisagree.iconify.xposed.modules.views.ChipDrawable +import com.drdisagree.iconify.xposed.modules.views.ChipDrawable.GradientDirection.Companion.toIndex +import com.google.android.material.slider.Slider +import eightbitlab.com.blurview.RenderEffectBlur + +class ClockChip : BaseFragment() { + + private lateinit var binding: FragmentXposedClockChipBinding + + private var customTextColorIndex: Int = getInt(CHIP_STATUSBAR_CLOCK_TEXT_COLOR_OPTION, 0) + private var customTextColor: Int = getInt(CHIP_STATUSBAR_CLOCK_TEXT_COLOR_CODE, Color.WHITE) + private var accentFillEnabled: Boolean = getBoolean(CHIP_STATUSBAR_CLOCK_ACCENT, true) + private var startColor: Int = getInt(CHIP_STATUSBAR_CLOCK_START_COLOR, Color.RED) + private var endColor: Int = getInt(CHIP_STATUSBAR_CLOCK_END_COLOR, Color.BLUE) + private var gradientDirection: ChipDrawable.GradientDirection = + ChipDrawable.GradientDirection.fromIndex( + getInt( + CHIP_STATUSBAR_CLOCK_GRADIENT_DIRECTION, + ChipDrawable.GradientDirection.LEFT_RIGHT.toIndex() + ) + ) + private var padding: IntArray = intArrayOf( + getInt(CHIP_STATUSBAR_CLOCK_PADDING_LEFT, 8), + getInt(CHIP_STATUSBAR_CLOCK_PADDING_TOP, 4), + getInt(CHIP_STATUSBAR_CLOCK_PADDING_RIGHT, 8), + getInt(CHIP_STATUSBAR_CLOCK_PADDING_BOTTOM, 4) + ) + private var strokeEnabled: Boolean = getBoolean(CHIP_STATUSBAR_CLOCK_STROKE_SWITCH) + private var strokeWidth: Int = getInt(CHIP_STATUSBAR_CLOCK_STROKE_WIDTH, 2) + private var accentBorderEnabled: Boolean = getBoolean(CHIP_STATUSBAR_CLOCK_STROKE_ACCENT, true) + private var strokeColor: Int = getInt(CHIP_STATUSBAR_CLOCK_STROKE_COLOR, Color.GREEN) + private var dashedBorderEnabled: Boolean = getBoolean(CHIP_STATUSBAR_CLOCK_STROKE_DASH) + private var dashWidth: Int = getInt(CHIP_STATUSBAR_CLOCK_STROKE_DASH_WIDTH, 4) + private var dashGap: Int = getInt(CHIP_STATUSBAR_CLOCK_STROKE_DASH_GAP, 4) + private var cornerRadii = floatArrayOf( + getInt(CHIP_STATUSBAR_CLOCK_RADIUS_TOP_LEFT, 28).toFloat(), + getInt(CHIP_STATUSBAR_CLOCK_RADIUS_TOP_LEFT, 28).toFloat(), + getInt(CHIP_STATUSBAR_CLOCK_RADIUS_TOP_RIGHT, 28).toFloat(), + getInt(CHIP_STATUSBAR_CLOCK_RADIUS_TOP_RIGHT, 28).toFloat(), + getInt(CHIP_STATUSBAR_CLOCK_RADIUS_BOTTOM_RIGHT, 28).toFloat(), + getInt(CHIP_STATUSBAR_CLOCK_RADIUS_BOTTOM_RIGHT, 28).toFloat(), + getInt(CHIP_STATUSBAR_CLOCK_RADIUS_BOTTOM_LEFT, 28).toFloat(), + getInt(CHIP_STATUSBAR_CLOCK_RADIUS_BOTTOM_LEFT, 28).toFloat(), + ) + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + binding = FragmentXposedClockChipBinding.inflate(inflater, container, false) + + // Header + setHeader( + requireContext(), + getParentFragmentManager(), + binding.header.toolbar, + R.string.activity_title_clock_chip + ) + + binding.header.appBarLayout.viewTreeObserver.addOnGlobalLayoutListener(object : + ViewTreeObserver.OnGlobalLayoutListener { + override fun onGlobalLayout() { + binding.header.appBarLayout.viewTreeObserver.removeOnGlobalLayoutListener(this) + + val windowInsetsCompat = ViewCompat.getRootWindowInsets(binding.root) + val statusBarHeight = + windowInsetsCompat?.isVisible(WindowInsetsCompat.Type.statusBars())?.let { + windowInsetsCompat.getInsets(WindowInsetsCompat.Type.statusBars()).top + } ?: 0 + + val headerHeight = binding.header.appBarLayout.height + + val params = binding.blurView.layoutParams as CoordinatorLayout.LayoutParams + params.topMargin = headerHeight + binding.blurView.layoutParams = params + + val blurViewHeight = binding.header.appBarLayout.height + + binding.linearLayout.setPadding( + binding.linearLayout.paddingLeft, + blurViewHeight - statusBarHeight, + binding.linearLayout.paddingRight, + binding.linearLayout.paddingBottom + ) + } + }) + + val windowBackground: Drawable? = requireActivity().window.decorView.background + binding.blurView.setupWith(binding.root, RenderEffectBlur()) + .setFrameClearDrawable(windowBackground) + .setBlurRadius(8f) + + binding.clockTextColor.setSelectedIndex(getInt(CHIP_STATUSBAR_CLOCK_TEXT_COLOR_OPTION, 0)) + binding.clockTextColor.setOnItemSelectedListener { index: Int -> + customTextColorIndex = index + updateVisibility() + } + + binding.clockTextColorPicker.apply { + setColorPickerListener( + activity = requireActivity(), + defaultColor = customTextColor, + showPresets = true, + showAlphaSlider = true, + showColorShades = true + ) + setOnColorSelectedListener { color: Int -> + customTextColor = color + updateVisibility() + } + } + + binding.accentFillColor.isSwitchChecked = accentFillEnabled + binding.accentFillColor.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> + accentFillEnabled = isChecked + updateVisibility() + } + + binding.gradientDirection.setSelectedIndex(gradientDirection.toIndex()) + binding.gradientDirection.setOnItemSelectedListener { index: Int -> + gradientDirection = ChipDrawable.GradientDirection.entries.toTypedArray()[index] + updateVisibility() + } + + binding.fillStartColor.apply { + setColorPickerListener( + activity = requireActivity(), + defaultColor = startColor, + showPresets = true, + showAlphaSlider = true, + showColorShades = true + ) + setOnColorSelectedListener { color: Int -> + startColor = color + updateVisibility() + } + } + + binding.fillEndColor.apply { + setColorPickerListener( + activity = requireActivity(), + defaultColor = endColor, + showPresets = true, + showAlphaSlider = true, + showColorShades = true + ) + setOnColorSelectedListener { color: Int -> + endColor = color + updateVisibility() + } + } + + binding.enableBorder.isSwitchChecked = strokeEnabled + binding.enableBorder.setSwitchChangeListener { _: CompoundButton?, enabled: Boolean -> + strokeEnabled = enabled + updateVisibility() + } + + binding.accentBorderColor.isSwitchChecked = accentBorderEnabled + binding.accentBorderColor.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> + accentBorderEnabled = isChecked + updateVisibility() + } + + binding.borderColor.apply { + setColorPickerListener( + activity = requireActivity(), + defaultColor = strokeColor, + showPresets = true, + showAlphaSlider = true, + showColorShades = true + ) + setOnColorSelectedListener { color: Int -> + strokeColor = color + updateVisibility() + } + } + + binding.borderThickness.sliderValue = strokeWidth + binding.borderThickness.setOnSliderChangeListener { _: Slider?, value: Float, _: Boolean -> + strokeWidth = value.toInt() + updateVisibility() + } + + binding.dashedBorder.isSwitchChecked = dashedBorderEnabled + binding.dashedBorder.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> + dashedBorderEnabled = isChecked + updateVisibility() + } + + binding.dashWidth.sliderValue = dashWidth + binding.dashWidth.setOnSliderChangeListener { _: Slider?, value: Float, _: Boolean -> + dashWidth = value.toInt() + updateVisibility() + } + + binding.dashGap.sliderValue = dashGap + binding.dashGap.setOnSliderChangeListener { _: Slider?, value: Float, _: Boolean -> + dashGap = value.toInt() + updateVisibility() + } + + binding.paddingLeft.sliderValue = padding[0] + binding.paddingLeft.setOnSliderChangeListener { _: Slider?, value: Float, _: Boolean -> + padding[0] = value.toInt() + updateVisibility() + } + + binding.paddingRight.sliderValue = padding[2] + binding.paddingRight.setOnSliderChangeListener { _: Slider?, value: Float, _: Boolean -> + padding[2] = value.toInt() + updateVisibility() + } + + binding.paddingTop.sliderValue = padding[1] + binding.paddingTop.setOnSliderChangeListener { _: Slider?, value: Float, _: Boolean -> + padding[1] = value.toInt() + updateVisibility() + } + + binding.paddingBottom.sliderValue = padding[3] + binding.paddingBottom.setOnSliderChangeListener { _: Slider?, value: Float, _: Boolean -> + padding[3] = value.toInt() + updateVisibility() + } + + binding.cornerRadiusTopLeft.sliderValue = cornerRadii[0].toInt() + binding.cornerRadiusTopLeft.setOnSliderChangeListener { _: Slider?, value: Float, _: Boolean -> + cornerRadii[0] = value + cornerRadii[1] = value + updateVisibility() + } + + binding.cornerRadiusTopRight.sliderValue = cornerRadii[2].toInt() + binding.cornerRadiusTopRight.setOnSliderChangeListener { _: Slider?, value: Float, _: Boolean -> + cornerRadii[2] = value + cornerRadii[3] = value + updateVisibility() + } + + binding.cornerRadiusBottomLeft.sliderValue = cornerRadii[6].toInt() + binding.cornerRadiusBottomLeft.setOnSliderChangeListener { _: Slider?, value: Float, _: Boolean -> + cornerRadii[6] = value + cornerRadii[7] = value + updateVisibility() + } + + binding.cornerRadiusBottomRight.sliderValue = cornerRadii[4].toInt() + binding.cornerRadiusBottomRight.setOnSliderChangeListener { _: Slider?, value: Float, _: Boolean -> + cornerRadii[4] = value + cornerRadii[5] = value + updateVisibility() + } + + binding.btnApply.setOnClickListener { + RPrefs.apply { + putInt(CHIP_STATUSBAR_CLOCK_TEXT_COLOR_OPTION, customTextColorIndex) + putInt(CHIP_STATUSBAR_CLOCK_TEXT_COLOR_CODE, customTextColor) + putBoolean(CHIP_STATUSBAR_CLOCK_ACCENT, accentFillEnabled) + putInt(CHIP_STATUSBAR_CLOCK_START_COLOR, startColor) + putInt(CHIP_STATUSBAR_CLOCK_END_COLOR, endColor) + putInt(CHIP_STATUSBAR_CLOCK_GRADIENT_DIRECTION, gradientDirection.toIndex()) + putInt(CHIP_STATUSBAR_CLOCK_PADDING_LEFT, padding[0]) + putInt(CHIP_STATUSBAR_CLOCK_PADDING_TOP, padding[1]) + putInt(CHIP_STATUSBAR_CLOCK_PADDING_RIGHT, padding[2]) + putInt(CHIP_STATUSBAR_CLOCK_PADDING_BOTTOM, padding[3]) + putBoolean(CHIP_STATUSBAR_CLOCK_STROKE_SWITCH, strokeEnabled) + putInt(CHIP_STATUSBAR_CLOCK_STROKE_WIDTH, strokeWidth) + putBoolean(CHIP_STATUSBAR_CLOCK_STROKE_ACCENT, accentBorderEnabled) + putInt(CHIP_STATUSBAR_CLOCK_STROKE_COLOR, strokeColor) + putBoolean(CHIP_STATUSBAR_CLOCK_STROKE_DASH, dashedBorderEnabled) + putInt(CHIP_STATUSBAR_CLOCK_STROKE_DASH_WIDTH, dashWidth) + putInt(CHIP_STATUSBAR_CLOCK_STROKE_DASH_GAP, dashGap) + putInt(CHIP_STATUSBAR_CLOCK_RADIUS_TOP_LEFT, cornerRadii[0].toInt()) + putInt(CHIP_STATUSBAR_CLOCK_RADIUS_TOP_LEFT, cornerRadii[0].toInt()) + putInt(CHIP_STATUSBAR_CLOCK_RADIUS_TOP_RIGHT, cornerRadii[2].toInt()) + putInt(CHIP_STATUSBAR_CLOCK_RADIUS_TOP_RIGHT, cornerRadii[2].toInt()) + putInt(CHIP_STATUSBAR_CLOCK_RADIUS_BOTTOM_RIGHT, cornerRadii[4].toInt()) + putInt(CHIP_STATUSBAR_CLOCK_RADIUS_BOTTOM_RIGHT, cornerRadii[4].toInt()) + putInt(CHIP_STATUSBAR_CLOCK_RADIUS_BOTTOM_LEFT, cornerRadii[6].toInt()) + putInt(CHIP_STATUSBAR_CLOCK_RADIUS_BOTTOM_LEFT, cornerRadii[6].toInt()) + + putBoolean( + CHIP_STATUSBAR_CLOCK_STYLE_CHANGED, + !getBoolean(CHIP_STATUSBAR_CLOCK_STYLE_CHANGED) + ) + } + } + + updateVisibility() + + return binding.getRoot() + } + + private fun updateVisibility() { + val textColorPicker = if (customTextColorIndex == 2) View.VISIBLE else View.GONE + + binding.clockTextColorPicker.visibility = textColorPicker + + val accentFillEnabled = + if (binding.accentFillColor.isSwitchChecked) View.GONE else View.VISIBLE + + binding.gradientDirection.visibility = accentFillEnabled + binding.fillStartColor.visibility = accentFillEnabled + binding.fillEndColor.visibility = accentFillEnabled + + val borderEnabled = if (binding.enableBorder.isSwitchChecked) View.VISIBLE else View.GONE + + binding.accentBorderColor.visibility = borderEnabled + binding.borderThickness.visibility = borderEnabled + binding.dashedBorder.visibility = borderEnabled + + val accentBorderColor = + if (binding.accentBorderColor.isSwitchChecked || !binding.enableBorder.isSwitchChecked) View.GONE else View.VISIBLE + + binding.borderColor.visibility = accentBorderColor + + val dashedBorderEnabled = if (binding.dashedBorder.isSwitchChecked) { + if (!binding.enableBorder.isSwitchChecked) View.GONE else View.VISIBLE + } else View.GONE + + binding.dashWidth.visibility = dashedBorderEnabled + binding.dashGap.visibility = dashedBorderEnabled + + val isDarkMode = + requireContext().resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_YES == + Configuration.UI_MODE_NIGHT_YES + + when (customTextColorIndex) { + 0 -> { + binding.previewClock.paint.xfermode = null + binding.previewClock.setTextColor( + ContextCompat.getColor( + requireContext(), + if (isDarkMode) { + R.color.white + } else { + R.color.black + } + ) + ) + } + + 1 -> { + binding.previewClock.paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.DST_OUT) + } + + 2 -> { + binding.previewClock.paint.xfermode = null + binding.previewClock.setTextColor(customTextColor) + } + } + + binding.previewClock.setPadding( + requireContext().toPx(padding[0]), + requireContext().toPx(padding[1]), + requireContext().toPx(padding[2]), + requireContext().toPx(padding[3]) + ) + + binding.previewClock.background = ChipDrawable.createChipDrawable( + context = requireContext(), + accentFill = this.accentFillEnabled, + startColor = startColor, + endColor = endColor, + gradientDirection = gradientDirection, + padding = intArrayOf(0, 0, 0, 0), + strokeEnabled = strokeEnabled, + accentStroke = accentBorderEnabled, + strokeWidth = strokeWidth, + strokeColor = strokeColor, + dashedBorderEnabled = this.dashedBorderEnabled, + dashWidth = dashWidth, + dashGap = dashGap, + cornerRadii = cornerRadii + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/DepthWallpaper.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/DepthWallpaper.kt new file mode 100644 index 000000000..684f7344f --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/DepthWallpaper.kt @@ -0,0 +1,148 @@ +package com.drdisagree.iconify.ui.fragments.xposed + +import android.app.Activity +import android.os.Build +import android.os.Bundle +import android.widget.Toast +import androidx.activity.result.ActivityResult +import androidx.activity.result.contract.ActivityResultContracts +import com.drdisagree.iconify.Iconify.Companion.appContext +import com.drdisagree.iconify.Iconify.Companion.appContextLocale +import com.drdisagree.iconify.R +import com.drdisagree.iconify.common.Preferences.DEPTH_WALLPAPER_CHANGED +import com.drdisagree.iconify.common.Preferences.DEPTH_WALLPAPER_SWITCH +import com.drdisagree.iconify.common.Resources.DEPTH_WALL_BG_DIR +import com.drdisagree.iconify.common.Resources.DEPTH_WALL_FG_DIR +import com.drdisagree.iconify.config.RPrefs.putBoolean +import com.drdisagree.iconify.ui.activities.MainActivity +import com.drdisagree.iconify.ui.base.ControlledPreferenceFragmentCompat +import com.drdisagree.iconify.ui.preferences.FilePickerPreference +import com.drdisagree.iconify.ui.preferences.SwitchPreference +import com.drdisagree.iconify.utils.FileUtils.getRealPath +import com.drdisagree.iconify.utils.FileUtils.launchFilePicker +import com.drdisagree.iconify.utils.FileUtils.moveToIconifyHiddenDir +import com.drdisagree.iconify.xposed.modules.utils.BitmapSubjectSegmenter +import com.google.android.gms.common.moduleinstall.ModuleAvailabilityResponse + +class DepthWallpaper : ControlledPreferenceFragmentCompat() { + + override val title: String + get() = getString(R.string.activity_title_depth_wallpaper) + + override val backButtonEnabled: Boolean + get() = true + + override val layoutResource: Int + get() = R.xml.xposed_depth_wallpaper + + override val hasMenu: Boolean + get() = true + + private var startActivityIntentForBackgroundImage = registerForActivityResult( + ActivityResultContracts.StartActivityForResult() + ) { result: ActivityResult -> + if (result.resultCode == Activity.RESULT_OK) { + val data = result.data + val path = getRealPath(data) + + if (path != null && moveToIconifyHiddenDir(path, DEPTH_WALL_BG_DIR)) { + putBoolean(DEPTH_WALLPAPER_CHANGED, false) + putBoolean(DEPTH_WALLPAPER_CHANGED, true) + + Toast.makeText( + appContext, + appContextLocale.resources.getString(R.string.toast_applied), + Toast.LENGTH_SHORT + ).show() + } else { + Toast.makeText( + appContext, + appContextLocale.resources.getString(R.string.toast_rename_file), + Toast.LENGTH_SHORT + ).show() + } + } + } + + private var startActivityIntentForForegroundImage = registerForActivityResult( + ActivityResultContracts.StartActivityForResult() + ) { result: ActivityResult -> + if (result.resultCode == Activity.RESULT_OK) { + val data = result.data + val path = getRealPath(data) + + if (path != null && moveToIconifyHiddenDir(path, DEPTH_WALL_FG_DIR)) { + putBoolean(DEPTH_WALLPAPER_CHANGED, false) + putBoolean(DEPTH_WALLPAPER_CHANGED, true) + + Toast.makeText( + appContext, + appContextLocale.resources.getString(R.string.toast_applied), + Toast.LENGTH_SHORT + ).show() + } else { + Toast.makeText( + appContext, + appContextLocale.resources.getString(R.string.toast_rename_file), + Toast.LENGTH_SHORT + ).show() + } + } + } + + override fun updateScreen(key: String?) { + super.updateScreen(key) + + when (key) { + DEPTH_WALLPAPER_SWITCH -> { + MainActivity.showOrHidePendingActionButton( + activityBinding = (requireActivity() as MainActivity).binding, + requiresSystemUiRestart = true + ) + } + } + } + + override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { + super.onCreatePreferences(savedInstanceState, rootKey) + + findPreference(DEPTH_WALLPAPER_SWITCH)?.apply { + if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.TIRAMISU) { + setSummary( + getString( + R.string.enable_depth_wallpaper_desc, + getString(R.string.use_custom_lockscreen_clock) + ) + ) + } else { + BitmapSubjectSegmenter(requireContext()) + .checkModelAvailability { moduleAvailabilityResponse: ModuleAvailabilityResponse? -> + setSummary( + getString( + R.string.enable_depth_wallpaper_desc, + getString( + if (moduleAvailabilityResponse?.areModulesAvailable() == true) { + R.string.depth_wallpaper_model_ready + } else { + R.string.depth_wallpaper_model_not_available + } + ) + ) + ) + } + } + } + + findPreference("xposed_depthwallpaperbgimagepicker")?.apply { + setOnButtonClick { + launchFilePicker(context, "image", startActivityIntentForBackgroundImage) + } + } + + findPreference("xposed_depthwallpaperfgimagepicker")?.apply { + setOnButtonClick { + launchFilePicker(context, "image", startActivityIntentForForegroundImage) + } + } + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/HeaderClock.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/HeaderClock.kt new file mode 100644 index 000000000..073c93380 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/HeaderClock.kt @@ -0,0 +1,139 @@ +package com.drdisagree.iconify.ui.fragments.xposed + +import android.annotation.SuppressLint +import android.app.Activity +import android.os.Bundle +import android.widget.Toast +import androidx.activity.result.ActivityResult +import androidx.activity.result.contract.ActivityResultContracts +import com.drdisagree.iconify.BuildConfig +import com.drdisagree.iconify.Iconify.Companion.appContext +import com.drdisagree.iconify.Iconify.Companion.appContextLocale +import com.drdisagree.iconify.R +import com.drdisagree.iconify.common.Preferences.HEADER_CLOCK_FONT_SWITCH +import com.drdisagree.iconify.common.Preferences.HEADER_CLOCK_STYLE +import com.drdisagree.iconify.common.Preferences.HEADER_CLOCK_SWITCH +import com.drdisagree.iconify.common.Resources.HEADER_CLOCK_FONT_DIR +import com.drdisagree.iconify.common.Resources.HEADER_CLOCK_LAYOUT +import com.drdisagree.iconify.config.RPrefs.putBoolean +import com.drdisagree.iconify.ui.activities.MainActivity +import com.drdisagree.iconify.ui.adapters.ClockPreviewAdapter +import com.drdisagree.iconify.ui.base.ControlledPreferenceFragmentCompat +import com.drdisagree.iconify.ui.models.ClockModel +import com.drdisagree.iconify.ui.preferences.FilePickerPreference +import com.drdisagree.iconify.ui.preferences.RecyclerPreference +import com.drdisagree.iconify.utils.FileUtils.getRealPath +import com.drdisagree.iconify.utils.FileUtils.launchFilePicker +import com.drdisagree.iconify.utils.FileUtils.moveToIconifyHiddenDir + +class HeaderClock : ControlledPreferenceFragmentCompat() { + + override val title: String + get() = getString(R.string.activity_title_header_clock) + + override val backButtonEnabled: Boolean + get() = true + + override val layoutResource: Int + get() = R.xml.xposed_header_clock + + override val hasMenu: Boolean + get() = true + + private var startActivityIntent = registerForActivityResult( + ActivityResultContracts.StartActivityForResult() + ) { result: ActivityResult -> + if (result.resultCode == Activity.RESULT_OK) { + val data = result.data + val path = getRealPath(data) + + if (path != null && moveToIconifyHiddenDir(path, HEADER_CLOCK_FONT_DIR)) { + putBoolean(HEADER_CLOCK_FONT_SWITCH, false) + putBoolean(HEADER_CLOCK_FONT_SWITCH, true) + + Toast.makeText( + appContext, + appContextLocale.resources.getString(R.string.toast_applied), + Toast.LENGTH_SHORT + ).show() + } else { + Toast.makeText( + appContext, + appContextLocale.resources.getString(R.string.toast_rename_file), + Toast.LENGTH_SHORT + ).show() + } + } + } + + override fun updateScreen(key: String?) { + super.updateScreen(key) + + when (key) { + HEADER_CLOCK_SWITCH -> { + MainActivity.showOrHidePendingActionButton( + activityBinding = (requireActivity() as MainActivity).binding, + requiresSystemUiRestart = true + ) + } + } + } + + override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { + super.onCreatePreferences(savedInstanceState, rootKey) + + findPreference(HEADER_CLOCK_STYLE)?.apply { + setAdapter(initHeaderClockStyles()) + setPreference(HEADER_CLOCK_STYLE, 0) + } + + findPreference("xposed_headerclockfontpicker")?.apply { + setOnButtonClick { + launchFilePicker(context, "font", startActivityIntent) + } + } + } + + @SuppressLint("DiscouragedApi") + private fun initHeaderClockStyles(): ClockPreviewAdapter { + val headerClock = ArrayList() + var maxIndex = 0 + + while (requireContext() + .resources + .getIdentifier( + HEADER_CLOCK_LAYOUT + maxIndex, + "layout", + BuildConfig.APPLICATION_ID + ) != 0 + ) { + maxIndex++ + } + + for (i in 0 until maxIndex) { + headerClock.add( + ClockModel( + if (i == 0) { + requireContext().getString(R.string.clock_none) + } else { + requireContext().getString(R.string.clock_style_name, i) + }, + requireContext() + .resources + .getIdentifier( + HEADER_CLOCK_LAYOUT + i, + "layout", + BuildConfig.APPLICATION_ID + ) + ) + ) + } + + return ClockPreviewAdapter( + requireContext(), + headerClock, + HEADER_CLOCK_SWITCH, + HEADER_CLOCK_STYLE + ) + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/HeaderImage.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/HeaderImage.kt new file mode 100644 index 000000000..f224e76be --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/HeaderImage.kt @@ -0,0 +1,69 @@ +package com.drdisagree.iconify.ui.fragments.xposed + +import android.app.Activity +import android.os.Bundle +import android.widget.Toast +import androidx.activity.result.ActivityResult +import androidx.activity.result.contract.ActivityResultContracts +import com.drdisagree.iconify.Iconify.Companion.appContext +import com.drdisagree.iconify.Iconify.Companion.appContextLocale +import com.drdisagree.iconify.R +import com.drdisagree.iconify.common.Preferences.HEADER_IMAGE_SWITCH +import com.drdisagree.iconify.common.Resources.HEADER_IMAGE_DIR +import com.drdisagree.iconify.config.RPrefs.putBoolean +import com.drdisagree.iconify.ui.base.ControlledPreferenceFragmentCompat +import com.drdisagree.iconify.ui.preferences.FilePickerPreference +import com.drdisagree.iconify.utils.FileUtils.getRealPath +import com.drdisagree.iconify.utils.FileUtils.launchFilePicker +import com.drdisagree.iconify.utils.FileUtils.moveToIconifyHiddenDir + +class HeaderImage : ControlledPreferenceFragmentCompat() { + + override val title: String + get() = getString(R.string.activity_title_header_image) + + override val backButtonEnabled: Boolean + get() = true + + override val layoutResource: Int + get() = R.xml.xposed_header_image + + override val hasMenu: Boolean + get() = true + + private var startActivityIntent = registerForActivityResult( + ActivityResultContracts.StartActivityForResult() + ) { result: ActivityResult -> + if (result.resultCode == Activity.RESULT_OK) { + val data = result.data + val path = getRealPath(data) + + if (path != null && moveToIconifyHiddenDir(path, HEADER_IMAGE_DIR)) { + putBoolean(HEADER_IMAGE_SWITCH, false) + putBoolean(HEADER_IMAGE_SWITCH, true) + + Toast.makeText( + appContext, + appContextLocale.resources.getString(R.string.toast_applied), + Toast.LENGTH_SHORT + ).show() + } else { + Toast.makeText( + appContext, + appContextLocale.resources.getString(R.string.toast_rename_file), + Toast.LENGTH_SHORT + ).show() + } + } + } + + override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { + super.onCreatePreferences(savedInstanceState, rootKey) + + findPreference("xposed_headerimagepicker")?.apply { + setOnButtonClick { + launchFilePicker(context, "image", startActivityIntent) + } + } + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/LocationBrowse.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/LocationBrowse.kt new file mode 100644 index 000000000..d7be85936 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/LocationBrowse.kt @@ -0,0 +1,245 @@ +package com.drdisagree.iconify.ui.fragments.xposed + +import android.annotation.SuppressLint +import android.content.Context +import android.net.Uri +import android.os.Bundle +import android.os.Handler +import android.os.Looper +import android.text.Editable +import android.text.Spannable +import android.text.SpannableString +import android.text.TextWatcher +import android.util.Log +import android.view.LayoutInflater +import android.view.MenuItem +import android.view.View +import android.view.ViewGroup +import android.widget.EditText +import android.widget.FrameLayout +import android.widget.TextView +import androidx.appcompat.app.AppCompatActivity +import androidx.fragment.app.setFragmentResult +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import com.drdisagree.iconify.R +import com.drdisagree.iconify.ui.activities.MainActivity.Companion.popCurrentFragment +import com.drdisagree.iconify.ui.base.BaseFragment +import com.drdisagree.iconify.ui.drawables.TintedDrawableSpan +import com.drdisagree.iconify.utils.NetworkUtils +import com.drdisagree.iconify.utils.weather.WeatherConfig +import com.google.android.material.appbar.MaterialToolbar +import org.json.JSONObject +import java.util.Locale +import java.util.concurrent.ExecutorService +import java.util.concurrent.Executors + +open class LocationBrowse : BaseFragment() { + + private val mLocationBrowseList: MutableList = ArrayList() + private var mAdapter: LocationListAdapter? = null + private val mExecutorService: ExecutorService = Executors.newSingleThreadExecutor() + private val mHandler = Handler(Looper.getMainLooper()) + private var mQueryString: String? = null + private var mProgressBar: FrameLayout? = null + + private val mQueryRunnable = Runnable { + mExecutorService.submit { + getLocations(mQueryString) + } + } + + private open class LocationBrowseItem( + val cityExt: String, + private val mCountryId: String, + val city: String, + val lat: Double, + val lon: Double + ) { + protected val id: String + get() = "$city,$mCountryId" + + override fun equals(other: Any?): Boolean { + return (other is LocationBrowseItem) && this.id == other.id + } + + override fun hashCode(): Int { + var result = cityExt.hashCode() + result = 31 * result + mCountryId.hashCode() + result = 31 * result + city.hashCode() + result = 31 * result + lat.hashCode() + result = 31 * result + lon.hashCode() + return result + } + } + + inner class LocationListAdapter : RecyclerView.Adapter() { + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + val inflater = LayoutInflater.from(parent.context) + return ViewHolder( + inflater.inflate( + R.layout.view_list_item_location_browse, + parent, + false + ) + ) + } + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + val city = mLocationBrowseList[position] + + holder.itemView.findViewById(R.id.location_city).text = city.city + holder.itemView.findViewById(R.id.location_city_ext).text = city.cityExt + + holder.itemView.setOnClickListener { + WeatherConfig.apply { + setLocationId(requireContext(), city.lat.toString(), city.lon.toString()) + setLocationName(requireContext(), city.city) + } + val resultBundle = Bundle().apply { + putString(DATA_LOCATION_NAME, city.city) + putDouble(DATA_LOCATION_LAT, city.lat) + putDouble(DATA_LOCATION_LON, city.lon) + } + setFragmentResult(DATA_LOCATION_KEY, resultBundle) + popCurrentFragment(parentFragmentManager) + } + } + + override fun getItemCount(): Int = mLocationBrowseList.size + + inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) + } + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + return inflater.inflate(R.layout.fragment_xposed_location_browse, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + val toolbar: MaterialToolbar = view.findViewById(R.id.toolbar) + toolbar.setTitle(R.string.custom_location_title) + (activity as AppCompatActivity).setSupportActionBar(toolbar) + (activity as AppCompatActivity).supportActionBar?.setDisplayHomeAsUpEnabled(true) + + mProgressBar = view.findViewById(R.id.query_progressbar) + + val queryPattern: EditText = view.findViewById(R.id.query_pattern_text) + queryPattern.addTextChangedListener(object : TextWatcher { + override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {} + + @SuppressLint("NotifyDataSetChanged") + override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) { + mHandler.removeCallbacks(mQueryRunnable) + mQueryString = s.toString() + if (mQueryString.isNullOrEmpty()) { + hideProgress() + mLocationBrowseList.clear() + mAdapter?.notifyDataSetChanged() + } else { + showProgress() + mHandler.postDelayed(mQueryRunnable, 750) + } + } + + override fun afterTextChanged(s: Editable) {} + }) + + mAdapter = LocationListAdapter() + val queryList: RecyclerView = view.findViewById(R.id.query_result) + queryList.adapter = mAdapter + queryList.layoutManager = LinearLayoutManager(requireContext()) + } + + @Deprecated("Deprecated in Java") + @Suppress("deprecation") + override fun onOptionsItemSelected(item: MenuItem): Boolean { + when (item.itemId) { + android.R.id.home -> { + activity?.finish() + return true + } + + else -> return super.onOptionsItemSelected(item) + } + } + + @SuppressLint("NotifyDataSetChanged") + protected fun getLocations(input: String?) { + mLocationBrowseList.clear() + + try { + val lang = Locale.getDefault().language.replaceFirst("_".toRegex(), "-") + val url = String.format(URL_PLACES, Uri.encode(input?.trim { it <= ' ' }), lang) + val response: String = NetworkUtils.downloadUrlMemoryAsString(url) + val jsonResults = JSONObject(response).getJSONArray("geonames") + val count = jsonResults.length() + Log.d(TAG, "URL = $url returning a response of count = $count") + + for (i in 0 until count) { + val result = jsonResults.getJSONObject(i) + + val population = if (result.has("population")) result.getInt("population") else 0 + if (population == 0) continue + + val city = result.getString("name") + val country = result.getString("countryName") + val countryId = result.getString("countryId") + val adminName = if (result.has("adminName1")) result.getString("adminName1") else "" + val cityExt = (if (adminName.isNullOrEmpty()) "" else "$adminName, ") + country + val lat = result.getDouble("lat") + val lon = result.getDouble("lng") + + val locationItem = LocationBrowseItem(cityExt, countryId, city, lat, lon) + if (!mLocationBrowseList.contains(locationItem)) { + mLocationBrowseList.add(locationItem) + if (mLocationBrowseList.size == 5) break + } + } + } catch (e: Exception) { + Log.e(TAG, "Received malformed location data input=$input", e) + } finally { + mHandler.post { + hideProgress() + mAdapter?.notifyDataSetChanged() + } + } + } + + private fun showProgress() { + mProgressBar?.visibility = View.VISIBLE + } + + private fun hideProgress() { + mProgressBar?.visibility = View.GONE + } + + companion object { + private val TAG = LocationBrowse::class.java.simpleName + + const val DATA_LOCATION_KEY = "locationRequestKey" + const val DATA_LOCATION_NAME = "location_name" + const val DATA_LOCATION_LAT = "location_lat" + const val DATA_LOCATION_LON = "location_lon" + + private const val URL_PLACES = + "https://secure.geonames.org/searchJSON?name_startsWith=%s&lang=%s&username=omnijaws&maxRows=20" + + fun prefixTextWithIcon(context: Context, iconRes: Int, msg: CharSequence): CharSequence { + // Update the hint to contain the icon. + // Prefix the original hint with two spaces. The first space gets replaced by the icon + // using span. The second space is used for a singe space character between the hint + // and the icon. + val spanned = SpannableString(" $msg") + spanned.setSpan( + TintedDrawableSpan(context, iconRes), + 0, 1, Spannable.SPAN_EXCLUSIVE_INCLUSIVE + ) + return spanned + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/LockscreenClock.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/LockscreenClock.kt new file mode 100644 index 000000000..10e499c83 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/LockscreenClock.kt @@ -0,0 +1,148 @@ +package com.drdisagree.iconify.ui.fragments.xposed + +import android.annotation.SuppressLint +import android.app.Activity +import android.os.Bundle +import android.widget.Toast +import androidx.activity.result.ActivityResult +import androidx.activity.result.contract.ActivityResultContracts +import com.drdisagree.iconify.BuildConfig +import com.drdisagree.iconify.Iconify.Companion.appContext +import com.drdisagree.iconify.Iconify.Companion.appContextLocale +import com.drdisagree.iconify.R +import com.drdisagree.iconify.common.Dynamic.isAtleastA14 +import com.drdisagree.iconify.common.Preferences.LSCLOCK_FONT_SWITCH +import com.drdisagree.iconify.common.Preferences.LSCLOCK_STYLE +import com.drdisagree.iconify.common.Preferences.LSCLOCK_SWITCH +import com.drdisagree.iconify.common.Resources.LOCKSCREEN_CLOCK_LAYOUT +import com.drdisagree.iconify.common.Resources.LSCLOCK_FONT_DIR +import com.drdisagree.iconify.config.RPrefs.getBoolean +import com.drdisagree.iconify.config.RPrefs.putBoolean +import com.drdisagree.iconify.ui.activities.MainActivity +import com.drdisagree.iconify.ui.adapters.ClockPreviewAdapter +import com.drdisagree.iconify.ui.base.ControlledPreferenceFragmentCompat +import com.drdisagree.iconify.ui.models.ClockModel +import com.drdisagree.iconify.ui.preferences.FilePickerPreference +import com.drdisagree.iconify.ui.preferences.RecyclerPreference +import com.drdisagree.iconify.utils.FileUtils.getRealPath +import com.drdisagree.iconify.utils.FileUtils.launchFilePicker +import com.drdisagree.iconify.utils.FileUtils.moveToIconifyHiddenDir +import com.topjohnwu.superuser.Shell + +class LockscreenClock : ControlledPreferenceFragmentCompat() { + + override val title: String + get() = getString(R.string.activity_title_lockscreen_clock) + + override val backButtonEnabled: Boolean + get() = true + + override val layoutResource: Int + get() = R.xml.xposed_lockscreen_clock + + override val hasMenu: Boolean + get() = true + + private var startActivityIntent = registerForActivityResult( + ActivityResultContracts.StartActivityForResult() + ) { result: ActivityResult -> + if (result.resultCode == Activity.RESULT_OK) { + val data = result.data + val path = getRealPath(data) + + if (path != null && moveToIconifyHiddenDir(path, LSCLOCK_FONT_DIR)) { + putBoolean(LSCLOCK_FONT_SWITCH, false) + putBoolean(LSCLOCK_FONT_SWITCH, true) + + Toast.makeText( + appContext, + appContextLocale.resources.getString(R.string.toast_applied), + Toast.LENGTH_SHORT + ).show() + } else { + Toast.makeText( + appContext, + appContextLocale.resources.getString(R.string.toast_rename_file), + Toast.LENGTH_SHORT + ).show() + } + } + } + + override fun updateScreen(key: String?) { + super.updateScreen(key) + + when (key) { + LSCLOCK_SWITCH -> { + if (getBoolean(key) && isAtleastA14) { + Shell.cmd( + "settings put secure lock_screen_custom_clock_face default" + ).exec() + } + + MainActivity.showOrHidePendingActionButton( + activityBinding = (requireActivity() as MainActivity).binding, + requiresSystemUiRestart = true + ) + } + } + } + + override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { + super.onCreatePreferences(savedInstanceState, rootKey) + + findPreference(LSCLOCK_STYLE)?.apply { + setAdapter(initLockscreenClockStyles()) + setPreference(LSCLOCK_STYLE, 0) + } + + findPreference("xposed_lockscreenclockfontpicker")?.apply { + setOnButtonClick { + launchFilePicker(context, "font", startActivityIntent) + } + } + } + + @SuppressLint("DiscouragedApi") + private fun initLockscreenClockStyles(): ClockPreviewAdapter { + val lsClock = ArrayList() + var maxIndex = 0 + + while (requireContext() + .resources + .getIdentifier( + LOCKSCREEN_CLOCK_LAYOUT + maxIndex, + "layout", + BuildConfig.APPLICATION_ID + ) != 0 + ) { + maxIndex++ + } + + for (i in 0 until maxIndex) { + lsClock.add( + ClockModel( + if (i == 0) { + requireContext().getString(R.string.clock_none) + } else { + requireContext().getString(R.string.clock_style_name, i) + }, + requireContext() + .resources + .getIdentifier( + LOCKSCREEN_CLOCK_LAYOUT + i, + "layout", + BuildConfig.APPLICATION_ID + ) + ) + ) + } + + return ClockPreviewAdapter( + requireContext(), + lsClock, + LSCLOCK_SWITCH, + LSCLOCK_STYLE + ) + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/LockscreenWeather.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/LockscreenWeather.kt new file mode 100644 index 000000000..39a9159da --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/LockscreenWeather.kt @@ -0,0 +1,61 @@ +package com.drdisagree.iconify.ui.fragments.xposed + +import com.drdisagree.iconify.Iconify.Companion.appContextLocale +import com.drdisagree.iconify.R +import com.drdisagree.iconify.common.Preferences.WEATHER_OWM_KEY +import com.drdisagree.iconify.common.Preferences.WEATHER_PROVIDER +import com.drdisagree.iconify.common.Preferences.WEATHER_SWITCH +import com.drdisagree.iconify.config.RPrefs +import com.drdisagree.iconify.ui.activities.MainActivity +import com.drdisagree.iconify.ui.base.WeatherPreferenceFragment +import com.google.android.material.dialog.MaterialAlertDialogBuilder + +class LockscreenWeather : WeatherPreferenceFragment() { + + override val title: String + get() = getString(R.string.activity_title_lockscreen_weather) + + override val backButtonEnabled: Boolean + get() = true + + override val layoutResource: Int + get() = R.xml.xposed_lockscreen_weather + + override val hasMenu: Boolean + get() = true + + override fun getMainSwitchKey(): String { + return WEATHER_SWITCH + } + + private fun showOwnKeyDialog() { + MaterialAlertDialogBuilder(requireContext()) + .setTitle(appContextLocale.getString(R.string.weather_provider_owm_key_title)) + .setMessage(appContextLocale.getString(R.string.weather_provider_owm_key_message)) + .setCancelable(false) + .setPositiveButton(appContextLocale.getString(R.string.understood), null) + .create() + .show() + } + + override fun updateScreen(key: String?) { + super.updateScreen(key) + + when (key) { + WEATHER_SWITCH -> { + MainActivity.showOrHidePendingActionButton( + activityBinding = (requireActivity() as MainActivity).binding, + requiresSystemUiRestart = true + ) + } + + WEATHER_PROVIDER -> { + if (RPrefs.getString(WEATHER_PROVIDER) == "1" && RPrefs.getString(WEATHER_OWM_KEY) + .isNullOrEmpty() + ) { + showOwnKeyDialog() + } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/LockscreenWidget.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/LockscreenWidget.kt new file mode 100644 index 000000000..a4a3be7fd --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/LockscreenWidget.kt @@ -0,0 +1,143 @@ +package com.drdisagree.iconify.ui.fragments.xposed + +import android.os.Bundle +import android.text.TextUtils +import androidx.preference.Preference +import com.drdisagree.iconify.R +import com.drdisagree.iconify.common.Preferences.EXTRA_WIDGET_1_KEY +import com.drdisagree.iconify.common.Preferences.EXTRA_WIDGET_2_KEY +import com.drdisagree.iconify.common.Preferences.EXTRA_WIDGET_3_KEY +import com.drdisagree.iconify.common.Preferences.EXTRA_WIDGET_4_KEY +import com.drdisagree.iconify.common.Preferences.LOCKSCREEN_WIDGETS +import com.drdisagree.iconify.common.Preferences.LOCKSCREEN_WIDGETS_DEVICE_WIDGET +import com.drdisagree.iconify.common.Preferences.LOCKSCREEN_WIDGETS_ENABLED +import com.drdisagree.iconify.common.Preferences.LOCKSCREEN_WIDGETS_EXTRAS +import com.drdisagree.iconify.common.Preferences.MAIN_WIDGET_1_KEY +import com.drdisagree.iconify.common.Preferences.MAIN_WIDGET_2_KEY +import com.drdisagree.iconify.config.RPrefs +import com.drdisagree.iconify.services.WeatherScheduler +import com.drdisagree.iconify.ui.activities.MainActivity +import com.drdisagree.iconify.ui.base.ControlledPreferenceFragmentCompat +import com.drdisagree.iconify.utils.OmniJawsClient +import com.drdisagree.iconify.utils.weather.WeatherConfig +import java.util.stream.Collectors + +class LockscreenWidget : ControlledPreferenceFragmentCompat() { + + private lateinit var mWeatherClient: OmniJawsClient + + private val widgetKeysMap: MutableMap = HashMap() + private val initialWidgetKeysMap: MutableMap = HashMap() + + private lateinit var mMainWidget1: Preference + private lateinit var mMainWidget2: Preference + private lateinit var mExtraWidget1: Preference + private lateinit var mExtraWidget2: Preference + private lateinit var mExtraWidget3: Preference + private lateinit var mExtraWidget4: Preference + private lateinit var mDeviceInfoWidgetPref: Preference + + private var mWidgetPreferences: List? = null + + override val title: String + get() = getString(R.string.activity_title_lockscreen_widget) + + override val backButtonEnabled: Boolean + get() = true + + override val layoutResource: Int + get() = R.xml.xposed_lockscreen_widget + + override val hasMenu: Boolean + get() = true + + override fun updateScreen(key: String?) { + super.updateScreen(key) + + if (key == null) return + + saveInitialPreferences() + + var mainWidgetsList: List = listOf( + RPrefs.getString(MAIN_WIDGET_1_KEY, "none")!!, + RPrefs.getString(MAIN_WIDGET_2_KEY, "none")!! + ) + var extraWidgetsList: List = listOf( + RPrefs.getString(EXTRA_WIDGET_1_KEY, "none")!!, + RPrefs.getString(EXTRA_WIDGET_2_KEY, "none")!!, + RPrefs.getString(EXTRA_WIDGET_3_KEY, "none")!!, + RPrefs.getString(EXTRA_WIDGET_4_KEY, "none")!! + ) + + mainWidgetsList = replaceEmptyWithNone(mainWidgetsList) + extraWidgetsList = replaceEmptyWithNone(extraWidgetsList) + + val mainWidgets = TextUtils.join(",", mainWidgetsList) + val extraWidgets = TextUtils.join(",", extraWidgetsList) + + val wasWeatherEnabled: Boolean = WeatherConfig.isEnabled(requireContext()) + + RPrefs.putString(LOCKSCREEN_WIDGETS, mainWidgets) + RPrefs.putString(LOCKSCREEN_WIDGETS_EXTRAS, extraWidgets) + + val weatherEnabled = + mainWidgets.contains("weather") || extraWidgets.contains("weather") + + if (weatherEnabled && wasWeatherEnabled && mWeatherClient.weatherInfo != null) { + if (System.currentTimeMillis() - mWeatherClient.weatherInfo!!.timeStamp > 3600000) { + WeatherScheduler.scheduleUpdateNow(requireContext()) + } + } else if (weatherEnabled) { + WeatherScheduler.scheduleUpdates(requireContext()) + WeatherScheduler.scheduleUpdateNow(requireContext()) + } + + when (key) { + LOCKSCREEN_WIDGETS_ENABLED -> { + MainActivity.showOrHidePendingActionButton( + activityBinding = (requireActivity() as MainActivity).binding, + requiresSystemUiRestart = true + ) + } + } + } + + override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { + super.onCreatePreferences(savedInstanceState, rootKey) + + mWeatherClient = OmniJawsClient(requireContext()) + mWeatherClient.queryWeather() + + mMainWidget1 = findPreference(MAIN_WIDGET_1_KEY)!! + mMainWidget2 = findPreference(MAIN_WIDGET_2_KEY)!! + mExtraWidget1 = findPreference(EXTRA_WIDGET_1_KEY)!! + mExtraWidget2 = findPreference(EXTRA_WIDGET_2_KEY)!! + mExtraWidget3 = findPreference(EXTRA_WIDGET_3_KEY)!! + mExtraWidget4 = findPreference(EXTRA_WIDGET_4_KEY)!! + mDeviceInfoWidgetPref = findPreference(LOCKSCREEN_WIDGETS_DEVICE_WIDGET)!! + + mWidgetPreferences = listOf( + mMainWidget1, + mMainWidget2, + mExtraWidget1, + mExtraWidget2, + mExtraWidget3, + mExtraWidget4, + mDeviceInfoWidgetPref + ) + } + + private fun replaceEmptyWithNone(inputList: List): MutableList { + return inputList.stream() + .map { s: String? -> if (TextUtils.isEmpty(s)) "none" else s } + .collect(Collectors.toList()) + } + + private fun saveInitialPreferences() { + initialWidgetKeysMap.clear() + + for (widgetPref in mWidgetPreferences!!) { + initialWidgetKeysMap[widgetPref] = widgetKeysMap[widgetPref] + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/OpQsHeader.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/OpQsHeader.kt new file mode 100644 index 000000000..2516bc889 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/OpQsHeader.kt @@ -0,0 +1,40 @@ +package com.drdisagree.iconify.ui.fragments.xposed + +import com.drdisagree.iconify.R +import com.drdisagree.iconify.common.Preferences.OP_QS_HEADER_EXPANSION_Y +import com.drdisagree.iconify.common.Preferences.OP_QS_HEADER_HIDE_STOCK_MEDIA +import com.drdisagree.iconify.common.Preferences.OP_QS_HEADER_SWITCH +import com.drdisagree.iconify.common.Preferences.OP_QS_HEADER_TOP_MARGIN +import com.drdisagree.iconify.ui.activities.MainActivity +import com.drdisagree.iconify.ui.base.ControlledPreferenceFragmentCompat + +class OpQsHeader : ControlledPreferenceFragmentCompat() { + + override val title: String + get() = getString(R.string.activity_title_op_qs_header) + + override val backButtonEnabled: Boolean + get() = true + + override val layoutResource: Int + get() = R.xml.xposed_op_qs_header + + override val hasMenu: Boolean + get() = true + + override fun updateScreen(key: String?) { + super.updateScreen(key) + + when (key) { + OP_QS_HEADER_SWITCH, + OP_QS_HEADER_HIDE_STOCK_MEDIA, + OP_QS_HEADER_TOP_MARGIN, + OP_QS_HEADER_EXPANSION_Y -> { + MainActivity.showOrHidePendingActionButton( + activityBinding = (requireActivity() as MainActivity).binding, + requiresSystemUiRestart = true + ) + } + } + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/Others.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/Others.kt new file mode 100644 index 000000000..3887042cf --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/Others.kt @@ -0,0 +1,52 @@ +package com.drdisagree.iconify.ui.fragments.xposed + +import android.os.Build +import android.os.Bundle +import com.drdisagree.iconify.R +import com.drdisagree.iconify.common.Preferences.FIXED_STATUS_ICONS_SWITCH +import com.drdisagree.iconify.common.Preferences.FIXED_STATUS_ICONS_TOPMARGIN +import com.drdisagree.iconify.common.Preferences.HIDE_LOCKSCREEN_LOCK_ICON +import com.drdisagree.iconify.common.Preferences.HIDE_STATUS_ICONS_SWITCH +import com.drdisagree.iconify.common.Preferences.QSPANEL_HIDE_CARRIER +import com.drdisagree.iconify.ui.activities.MainActivity +import com.drdisagree.iconify.ui.base.ControlledPreferenceFragmentCompat +import com.drdisagree.iconify.ui.preferences.SliderPreference + +class Others : ControlledPreferenceFragmentCompat() { + + override val title: String + get() = getString(R.string.activity_title_xposed_others) + + override val backButtonEnabled: Boolean + get() = true + + override val layoutResource: Int + get() = R.xml.xposed_others + + override val hasMenu: Boolean + get() = true + + override fun updateScreen(key: String?) { + super.updateScreen(key) + + when (key) { + QSPANEL_HIDE_CARRIER, + HIDE_STATUS_ICONS_SWITCH, + HIDE_LOCKSCREEN_LOCK_ICON, + FIXED_STATUS_ICONS_SWITCH -> { + MainActivity.showOrHidePendingActionButton( + activityBinding = (requireActivity() as MainActivity).binding, + requiresSystemUiRestart = true + ) + } + } + } + + override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { + super.onCreatePreferences(savedInstanceState, rootKey) + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + findPreference(FIXED_STATUS_ICONS_TOPMARGIN)?.setMax(250f) + } + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/QuickSettings.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/QuickSettings.kt new file mode 100644 index 000000000..e2e6e17ac --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/QuickSettings.kt @@ -0,0 +1,84 @@ +package com.drdisagree.iconify.ui.fragments.xposed + +import android.os.Bundle +import com.drdisagree.iconify.R +import com.drdisagree.iconify.common.Preferences.CUSTOM_QS_MARGIN +import com.drdisagree.iconify.common.Preferences.HIDE_QSLABEL_SWITCH +import com.drdisagree.iconify.common.Preferences.HIDE_QS_ON_LOCKSCREEN +import com.drdisagree.iconify.common.Preferences.HIDE_QS_SILENT_TEXT +import com.drdisagree.iconify.common.Preferences.QQS_TOPMARGIN +import com.drdisagree.iconify.common.Preferences.QS_TEXT_ALWAYS_WHITE +import com.drdisagree.iconify.common.Preferences.QS_TEXT_FOLLOW_ACCENT +import com.drdisagree.iconify.common.Preferences.QS_TOPMARGIN +import com.drdisagree.iconify.common.Preferences.VERTICAL_QSTILE_SWITCH +import com.drdisagree.iconify.config.RPrefs.getBoolean +import com.drdisagree.iconify.config.RPrefs.putBoolean +import com.drdisagree.iconify.ui.activities.MainActivity +import com.drdisagree.iconify.ui.base.ControlledPreferenceFragmentCompat +import com.drdisagree.iconify.ui.preferences.SwitchPreference + +class QuickSettings : ControlledPreferenceFragmentCompat() { + + private var alwaysWhitePreference: SwitchPreference? = null + private var followAccentPreference: SwitchPreference? = null + + override val title: String + get() = getString(R.string.activity_title_quick_settings) + + override val backButtonEnabled: Boolean + get() = true + + override val layoutResource: Int + get() = R.xml.xposed_quick_settings + + override val hasMenu: Boolean + get() = true + + override fun updateScreen(key: String?) { + super.updateScreen(key) + + when (key) { + VERTICAL_QSTILE_SWITCH, + HIDE_QSLABEL_SWITCH, + CUSTOM_QS_MARGIN, + QQS_TOPMARGIN, + QS_TOPMARGIN, + HIDE_QS_ON_LOCKSCREEN, + HIDE_QS_SILENT_TEXT -> { + MainActivity.showOrHidePendingActionButton( + activityBinding = (requireActivity() as MainActivity).binding, + requiresSystemUiRestart = true + ) + } + + QS_TEXT_ALWAYS_WHITE -> { + if (getBoolean(key)) { + putBoolean(QS_TEXT_FOLLOW_ACCENT, false) + followAccentPreference?.isChecked = false + } + MainActivity.showOrHidePendingActionButton( + activityBinding = (requireActivity() as MainActivity).binding, + requiresSystemUiRestart = true + ) + } + + QS_TEXT_FOLLOW_ACCENT -> { + if (getBoolean(key)) { + putBoolean(QS_TEXT_ALWAYS_WHITE, false) + alwaysWhitePreference?.isChecked = false + } + MainActivity.showOrHidePendingActionButton( + activityBinding = (requireActivity() as MainActivity).binding, + requiresSystemUiRestart = true + ) + } + } + } + + override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { + super.onCreatePreferences(savedInstanceState, rootKey) + + alwaysWhitePreference = findPreference(QS_TEXT_ALWAYS_WHITE) + followAccentPreference = findPreference(QS_TEXT_FOLLOW_ACCENT) + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/StatusIconsChip.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/StatusIconsChip.kt new file mode 100644 index 000000000..de79b5e26 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/StatusIconsChip.kt @@ -0,0 +1,382 @@ +package com.drdisagree.iconify.ui.fragments.xposed + +import android.graphics.Color +import android.graphics.drawable.Drawable +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.view.ViewTreeObserver +import android.widget.CompoundButton +import androidx.coordinatorlayout.widget.CoordinatorLayout +import androidx.core.view.ViewCompat +import androidx.core.view.WindowInsetsCompat +import com.drdisagree.iconify.R +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_ACCENT +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_END_COLOR +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_GRADIENT_DIRECTION +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_PADDING_BOTTOM +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_PADDING_LEFT +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_PADDING_RIGHT +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_PADDING_TOP +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_RADIUS_BOTTOM_LEFT +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_RADIUS_BOTTOM_RIGHT +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_RADIUS_TOP_LEFT +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_RADIUS_TOP_RIGHT +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_START_COLOR +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_STROKE_ACCENT +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_STROKE_COLOR +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_STROKE_DASH +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_STROKE_DASH_GAP +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_STROKE_DASH_WIDTH +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_STROKE_SWITCH +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_STROKE_WIDTH +import com.drdisagree.iconify.common.Preferences.CHIP_STATUS_ICONS_ACCENT +import com.drdisagree.iconify.common.Preferences.CHIP_STATUS_ICONS_END_COLOR +import com.drdisagree.iconify.common.Preferences.CHIP_STATUS_ICONS_GRADIENT_DIRECTION +import com.drdisagree.iconify.common.Preferences.CHIP_STATUS_ICONS_PADDING_BOTTOM +import com.drdisagree.iconify.common.Preferences.CHIP_STATUS_ICONS_PADDING_LEFT +import com.drdisagree.iconify.common.Preferences.CHIP_STATUS_ICONS_PADDING_RIGHT +import com.drdisagree.iconify.common.Preferences.CHIP_STATUS_ICONS_PADDING_TOP +import com.drdisagree.iconify.common.Preferences.CHIP_STATUS_ICONS_RADIUS_BOTTOM_LEFT +import com.drdisagree.iconify.common.Preferences.CHIP_STATUS_ICONS_RADIUS_BOTTOM_RIGHT +import com.drdisagree.iconify.common.Preferences.CHIP_STATUS_ICONS_RADIUS_TOP_LEFT +import com.drdisagree.iconify.common.Preferences.CHIP_STATUS_ICONS_RADIUS_TOP_RIGHT +import com.drdisagree.iconify.common.Preferences.CHIP_STATUS_ICONS_START_COLOR +import com.drdisagree.iconify.common.Preferences.CHIP_STATUS_ICONS_STROKE_ACCENT +import com.drdisagree.iconify.common.Preferences.CHIP_STATUS_ICONS_STROKE_COLOR +import com.drdisagree.iconify.common.Preferences.CHIP_STATUS_ICONS_STROKE_DASH +import com.drdisagree.iconify.common.Preferences.CHIP_STATUS_ICONS_STROKE_DASH_GAP +import com.drdisagree.iconify.common.Preferences.CHIP_STATUS_ICONS_STROKE_DASH_WIDTH +import com.drdisagree.iconify.common.Preferences.CHIP_STATUS_ICONS_STROKE_SWITCH +import com.drdisagree.iconify.common.Preferences.CHIP_STATUS_ICONS_STROKE_WIDTH +import com.drdisagree.iconify.common.Preferences.CHIP_STATUS_ICONS_STYLE_CHANGED +import com.drdisagree.iconify.config.RPrefs +import com.drdisagree.iconify.config.RPrefs.getBoolean +import com.drdisagree.iconify.config.RPrefs.getInt +import com.drdisagree.iconify.databinding.FragmentXposedStatusIconsChipBinding +import com.drdisagree.iconify.ui.base.BaseFragment +import com.drdisagree.iconify.ui.utils.ViewHelper.setHeader +import com.drdisagree.iconify.xposed.modules.utils.ViewHelper.toPx +import com.drdisagree.iconify.xposed.modules.views.ChipDrawable +import com.drdisagree.iconify.xposed.modules.views.ChipDrawable.GradientDirection.Companion.toIndex +import com.google.android.material.slider.Slider +import eightbitlab.com.blurview.RenderEffectBlur + +class StatusIconsChip : BaseFragment() { + + private lateinit var binding: FragmentXposedStatusIconsChipBinding + + private var accentFillEnabled: Boolean = getBoolean(CHIP_STATUSBAR_CLOCK_ACCENT, true) + private var startColor: Int = getInt(CHIP_STATUSBAR_CLOCK_START_COLOR, Color.RED) + private var endColor: Int = getInt(CHIP_STATUSBAR_CLOCK_END_COLOR, Color.BLUE) + private var gradientDirection: ChipDrawable.GradientDirection = + ChipDrawable.GradientDirection.fromIndex( + getInt( + CHIP_STATUSBAR_CLOCK_GRADIENT_DIRECTION, + ChipDrawable.GradientDirection.LEFT_RIGHT.toIndex() + ) + ) + private var padding: IntArray = intArrayOf( + getInt(CHIP_STATUSBAR_CLOCK_PADDING_LEFT, 8), + getInt(CHIP_STATUSBAR_CLOCK_PADDING_TOP, 4), + getInt(CHIP_STATUSBAR_CLOCK_PADDING_RIGHT, 8), + getInt(CHIP_STATUSBAR_CLOCK_PADDING_BOTTOM, 4) + ) + private var strokeEnabled: Boolean = getBoolean(CHIP_STATUSBAR_CLOCK_STROKE_SWITCH) + private var strokeWidth: Int = getInt(CHIP_STATUSBAR_CLOCK_STROKE_WIDTH, 2) + private var accentBorderEnabled: Boolean = getBoolean(CHIP_STATUSBAR_CLOCK_STROKE_ACCENT, true) + private var strokeColor: Int = getInt(CHIP_STATUSBAR_CLOCK_STROKE_COLOR, Color.GREEN) + private var dashedBorderEnabled: Boolean = getBoolean(CHIP_STATUSBAR_CLOCK_STROKE_DASH) + private var dashWidth: Int = getInt(CHIP_STATUSBAR_CLOCK_STROKE_DASH_WIDTH, 4) + private var dashGap: Int = getInt(CHIP_STATUSBAR_CLOCK_STROKE_DASH_GAP, 4) + private var cornerRadii = floatArrayOf( + getInt(CHIP_STATUSBAR_CLOCK_RADIUS_TOP_LEFT, 28).toFloat(), + getInt(CHIP_STATUSBAR_CLOCK_RADIUS_TOP_LEFT, 28).toFloat(), + getInt(CHIP_STATUSBAR_CLOCK_RADIUS_TOP_RIGHT, 28).toFloat(), + getInt(CHIP_STATUSBAR_CLOCK_RADIUS_TOP_RIGHT, 28).toFloat(), + getInt(CHIP_STATUSBAR_CLOCK_RADIUS_BOTTOM_RIGHT, 28).toFloat(), + getInt(CHIP_STATUSBAR_CLOCK_RADIUS_BOTTOM_RIGHT, 28).toFloat(), + getInt(CHIP_STATUSBAR_CLOCK_RADIUS_BOTTOM_LEFT, 28).toFloat(), + getInt(CHIP_STATUSBAR_CLOCK_RADIUS_BOTTOM_LEFT, 28).toFloat(), + ) + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + binding = FragmentXposedStatusIconsChipBinding.inflate(inflater, container, false) + + // Header + setHeader( + requireContext(), + getParentFragmentManager(), + binding.header.toolbar, + R.string.activity_title_clock_chip + ) + + binding.header.appBarLayout.viewTreeObserver.addOnGlobalLayoutListener(object : + ViewTreeObserver.OnGlobalLayoutListener { + override fun onGlobalLayout() { + binding.header.appBarLayout.viewTreeObserver.removeOnGlobalLayoutListener(this) + + val windowInsetsCompat = ViewCompat.getRootWindowInsets(binding.root) + val statusBarHeight = + windowInsetsCompat?.isVisible(WindowInsetsCompat.Type.statusBars())?.let { + windowInsetsCompat.getInsets(WindowInsetsCompat.Type.statusBars()).top + } ?: 0 + + val headerHeight = binding.header.appBarLayout.height + + val params = binding.blurView.layoutParams as CoordinatorLayout.LayoutParams + params.topMargin = headerHeight + binding.blurView.layoutParams = params + + val blurViewHeight = binding.header.appBarLayout.height + + binding.linearLayout.setPadding( + binding.linearLayout.paddingLeft, + blurViewHeight - statusBarHeight, + binding.linearLayout.paddingRight, + binding.linearLayout.paddingBottom + ) + } + }) + + val windowBackground: Drawable? = requireActivity().window.decorView.background + binding.blurView.setupWith(binding.root, RenderEffectBlur()) + .setFrameClearDrawable(windowBackground) + .setBlurRadius(8f) + + binding.accentFillColor.isSwitchChecked = accentFillEnabled + binding.accentFillColor.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> + accentFillEnabled = isChecked + updateVisibility() + } + + binding.gradientDirection.setSelectedIndex(gradientDirection.toIndex()) + binding.gradientDirection.setOnItemSelectedListener { index: Int -> + gradientDirection = ChipDrawable.GradientDirection.entries.toTypedArray()[index] + updateVisibility() + } + + binding.fillStartColor.apply { + setColorPickerListener( + activity = requireActivity(), + defaultColor = startColor, + showPresets = true, + showAlphaSlider = true, + showColorShades = true + ) + setOnColorSelectedListener { color: Int -> + startColor = color + updateVisibility() + } + } + + binding.fillEndColor.apply { + setColorPickerListener( + activity = requireActivity(), + defaultColor = endColor, + showPresets = true, + showAlphaSlider = true, + showColorShades = true + ) + setOnColorSelectedListener { color: Int -> + endColor = color + updateVisibility() + } + } + + binding.enableBorder.isSwitchChecked = strokeEnabled + binding.enableBorder.setSwitchChangeListener { _: CompoundButton?, enabled: Boolean -> + strokeEnabled = enabled + updateVisibility() + } + + binding.accentBorderColor.isSwitchChecked = accentBorderEnabled + binding.accentBorderColor.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> + accentBorderEnabled = isChecked + updateVisibility() + } + + binding.borderColor.apply { + setColorPickerListener( + activity = requireActivity(), + defaultColor = strokeColor, + showPresets = true, + showAlphaSlider = true, + showColorShades = true + ) + setOnColorSelectedListener { color: Int -> + strokeColor = color + updateVisibility() + } + } + + binding.borderThickness.sliderValue = strokeWidth + binding.borderThickness.setOnSliderChangeListener { _: Slider?, value: Float, _: Boolean -> + strokeWidth = value.toInt() + updateVisibility() + } + + binding.dashedBorder.isSwitchChecked = dashedBorderEnabled + binding.dashedBorder.setSwitchChangeListener { _: CompoundButton?, isChecked: Boolean -> + dashedBorderEnabled = isChecked + updateVisibility() + } + + binding.dashWidth.sliderValue = dashWidth + binding.dashWidth.setOnSliderChangeListener { _: Slider?, value: Float, _: Boolean -> + dashWidth = value.toInt() + updateVisibility() + } + + binding.dashGap.sliderValue = dashGap + binding.dashGap.setOnSliderChangeListener { _: Slider?, value: Float, _: Boolean -> + dashGap = value.toInt() + updateVisibility() + } + + binding.paddingLeft.sliderValue = padding[0] + binding.paddingLeft.setOnSliderChangeListener { _: Slider?, value: Float, _: Boolean -> + padding[0] = value.toInt() + updateVisibility() + } + + binding.paddingRight.sliderValue = padding[2] + binding.paddingRight.setOnSliderChangeListener { _: Slider?, value: Float, _: Boolean -> + padding[2] = value.toInt() + updateVisibility() + } + + binding.paddingTop.sliderValue = padding[1] + binding.paddingTop.setOnSliderChangeListener { _: Slider?, value: Float, _: Boolean -> + padding[1] = value.toInt() + updateVisibility() + } + + binding.paddingBottom.sliderValue = padding[3] + binding.paddingBottom.setOnSliderChangeListener { _: Slider?, value: Float, _: Boolean -> + padding[3] = value.toInt() + updateVisibility() + } + + binding.cornerRadiusTopLeft.sliderValue = cornerRadii[0].toInt() + binding.cornerRadiusTopLeft.setOnSliderChangeListener { _: Slider?, value: Float, _: Boolean -> + cornerRadii[0] = value + cornerRadii[1] = value + updateVisibility() + } + + binding.cornerRadiusTopRight.sliderValue = cornerRadii[2].toInt() + binding.cornerRadiusTopRight.setOnSliderChangeListener { _: Slider?, value: Float, _: Boolean -> + cornerRadii[2] = value + cornerRadii[3] = value + updateVisibility() + } + + binding.cornerRadiusBottomLeft.sliderValue = cornerRadii[6].toInt() + binding.cornerRadiusBottomLeft.setOnSliderChangeListener { _: Slider?, value: Float, _: Boolean -> + cornerRadii[6] = value + cornerRadii[7] = value + updateVisibility() + } + + binding.cornerRadiusBottomRight.sliderValue = cornerRadii[4].toInt() + binding.cornerRadiusBottomRight.setOnSliderChangeListener { _: Slider?, value: Float, _: Boolean -> + cornerRadii[4] = value + cornerRadii[5] = value + updateVisibility() + } + + binding.btnApply.setOnClickListener { + RPrefs.apply { + putBoolean(CHIP_STATUS_ICONS_ACCENT, accentFillEnabled) + putInt(CHIP_STATUS_ICONS_START_COLOR, startColor) + putInt(CHIP_STATUS_ICONS_END_COLOR, endColor) + putInt(CHIP_STATUS_ICONS_GRADIENT_DIRECTION, gradientDirection.toIndex()) + putInt(CHIP_STATUS_ICONS_PADDING_LEFT, padding[0]) + putInt(CHIP_STATUS_ICONS_PADDING_TOP, padding[1]) + putInt(CHIP_STATUS_ICONS_PADDING_RIGHT, padding[2]) + putInt(CHIP_STATUS_ICONS_PADDING_BOTTOM, padding[3]) + putBoolean(CHIP_STATUS_ICONS_STROKE_SWITCH, strokeEnabled) + putInt(CHIP_STATUS_ICONS_STROKE_WIDTH, strokeWidth) + putBoolean(CHIP_STATUS_ICONS_STROKE_ACCENT, accentBorderEnabled) + putInt(CHIP_STATUS_ICONS_STROKE_COLOR, strokeColor) + putBoolean(CHIP_STATUS_ICONS_STROKE_DASH, dashedBorderEnabled) + putInt(CHIP_STATUS_ICONS_STROKE_DASH_WIDTH, dashWidth) + putInt(CHIP_STATUS_ICONS_STROKE_DASH_GAP, dashGap) + putInt(CHIP_STATUS_ICONS_RADIUS_TOP_LEFT, cornerRadii[0].toInt()) + putInt(CHIP_STATUS_ICONS_RADIUS_TOP_LEFT, cornerRadii[0].toInt()) + putInt(CHIP_STATUS_ICONS_RADIUS_TOP_RIGHT, cornerRadii[2].toInt()) + putInt(CHIP_STATUS_ICONS_RADIUS_TOP_RIGHT, cornerRadii[2].toInt()) + putInt(CHIP_STATUS_ICONS_RADIUS_BOTTOM_RIGHT, cornerRadii[4].toInt()) + putInt(CHIP_STATUS_ICONS_RADIUS_BOTTOM_RIGHT, cornerRadii[4].toInt()) + putInt(CHIP_STATUS_ICONS_RADIUS_BOTTOM_LEFT, cornerRadii[6].toInt()) + putInt(CHIP_STATUS_ICONS_RADIUS_BOTTOM_LEFT, cornerRadii[6].toInt()) + + putBoolean( + CHIP_STATUS_ICONS_STYLE_CHANGED, + !getBoolean(CHIP_STATUS_ICONS_STYLE_CHANGED) + ) + } + } + + updateVisibility() + + return binding.getRoot() + } + + private fun updateVisibility() { + val accentFillEnabled = + if (binding.accentFillColor.isSwitchChecked) View.GONE else View.VISIBLE + + binding.gradientDirection.visibility = accentFillEnabled + binding.fillStartColor.visibility = accentFillEnabled + binding.fillEndColor.visibility = accentFillEnabled + + val borderEnabled = if (binding.enableBorder.isSwitchChecked) View.VISIBLE else View.GONE + + binding.accentBorderColor.visibility = borderEnabled + binding.borderThickness.visibility = borderEnabled + binding.dashedBorder.visibility = borderEnabled + + val accentBorderColor = + if (binding.accentBorderColor.isSwitchChecked || !binding.enableBorder.isSwitchChecked) View.GONE else View.VISIBLE + + binding.borderColor.visibility = accentBorderColor + + val dashedBorderEnabled = if (binding.dashedBorder.isSwitchChecked) { + if (!binding.enableBorder.isSwitchChecked) View.GONE else View.VISIBLE + } else View.GONE + + binding.dashWidth.visibility = dashedBorderEnabled + binding.dashGap.visibility = dashedBorderEnabled + + binding.previewClock.setPadding( + requireContext().toPx(padding[0]), + requireContext().toPx(padding[1]), + requireContext().toPx(padding[2]), + requireContext().toPx(padding[3]) + ) + + binding.previewClock.background = ChipDrawable.createChipDrawable( + context = requireContext(), + accentFill = this.accentFillEnabled, + startColor = startColor, + endColor = endColor, + gradientDirection = gradientDirection, + padding = intArrayOf(0, 0, 0, 0), + strokeEnabled = strokeEnabled, + accentStroke = accentBorderEnabled, + strokeWidth = strokeWidth, + strokeColor = strokeColor, + dashedBorderEnabled = this.dashedBorderEnabled, + dashWidth = dashWidth, + dashGap = dashGap, + cornerRadii = cornerRadii + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/Statusbar.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/Statusbar.kt new file mode 100644 index 000000000..46cea7d02 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/Statusbar.kt @@ -0,0 +1,38 @@ +package com.drdisagree.iconify.ui.fragments.xposed + +import com.drdisagree.iconify.R +import com.drdisagree.iconify.common.Preferences.COLORED_STATUSBAR_ICON +import com.drdisagree.iconify.common.Preferences.HIDE_LOCKSCREEN_CARRIER +import com.drdisagree.iconify.common.Preferences.HIDE_LOCKSCREEN_STATUSBAR +import com.drdisagree.iconify.ui.activities.MainActivity +import com.drdisagree.iconify.ui.base.ControlledPreferenceFragmentCompat + +class Statusbar : ControlledPreferenceFragmentCompat() { + + override val title: String + get() = getString(R.string.activity_title_statusbar) + + override val backButtonEnabled: Boolean + get() = true + + override val layoutResource: Int + get() = R.xml.xposed_statusbar + + override val hasMenu: Boolean + get() = true + + override fun updateScreen(key: String?) { + super.updateScreen(key) + + when (key) { + COLORED_STATUSBAR_ICON, + HIDE_LOCKSCREEN_CARRIER, + HIDE_LOCKSCREEN_STATUSBAR -> { + MainActivity.showOrHidePendingActionButton( + activityBinding = (requireActivity() as MainActivity).binding, + requiresSystemUiRestart = true + ) + } + } + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/Themes.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/Themes.kt new file mode 100644 index 000000000..32657963d --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/Themes.kt @@ -0,0 +1,48 @@ +package com.drdisagree.iconify.ui.fragments.xposed + +import com.drdisagree.iconify.R +import com.drdisagree.iconify.common.Preferences.BLACK_QSPANEL +import com.drdisagree.iconify.common.Preferences.FIX_NOTIFICATION_COLOR +import com.drdisagree.iconify.common.Preferences.FIX_NOTIFICATION_FOOTER_BUTTON_COLOR +import com.drdisagree.iconify.common.Preferences.FIX_QS_TILE_COLOR +import com.drdisagree.iconify.common.Preferences.FLUID_NOTIF_TRANSPARENCY +import com.drdisagree.iconify.common.Preferences.FLUID_POWERMENU_TRANSPARENCY +import com.drdisagree.iconify.common.Preferences.FLUID_QSPANEL +import com.drdisagree.iconify.common.Preferences.LIGHT_QSPANEL +import com.drdisagree.iconify.ui.activities.MainActivity +import com.drdisagree.iconify.ui.base.ControlledPreferenceFragmentCompat + +class Themes : ControlledPreferenceFragmentCompat() { + + override val title: String + get() = getString(R.string.activity_title_themes) + + override val backButtonEnabled: Boolean + get() = true + + override val layoutResource: Int + get() = R.xml.xposed_themes + + override val hasMenu: Boolean + get() = true + + override fun updateScreen(key: String?) { + super.updateScreen(key) + + when (key) { + LIGHT_QSPANEL, + BLACK_QSPANEL, + FLUID_QSPANEL, + FLUID_NOTIF_TRANSPARENCY, + FLUID_POWERMENU_TRANSPARENCY, + FIX_QS_TILE_COLOR, + FIX_NOTIFICATION_COLOR, + FIX_NOTIFICATION_FOOTER_BUTTON_COLOR -> { + MainActivity.showOrHidePendingActionButton( + activityBinding = (requireActivity() as MainActivity).binding, + requiresSystemUiRestart = true + ) + } + } + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/TransparencyBlur.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/TransparencyBlur.kt new file mode 100644 index 000000000..11bee5aae --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/TransparencyBlur.kt @@ -0,0 +1,116 @@ +package com.drdisagree.iconify.ui.fragments.xposed + +import android.os.Bundle +import com.drdisagree.iconify.R +import com.drdisagree.iconify.common.Preferences.AGGRESSIVE_QSPANEL_BLUR_SWITCH +import com.drdisagree.iconify.common.Preferences.BLUR_RADIUS_VALUE +import com.drdisagree.iconify.common.Preferences.LOCKSCREEN_SHADE_SWITCH +import com.drdisagree.iconify.common.Preferences.NOTIF_TRANSPARENCY_SWITCH +import com.drdisagree.iconify.common.Preferences.QSPANEL_BLUR_SWITCH +import com.drdisagree.iconify.common.Preferences.QS_TRANSPARENCY_SWITCH +import com.drdisagree.iconify.config.RPrefs.getBoolean +import com.drdisagree.iconify.config.RPrefs.putBoolean +import com.drdisagree.iconify.ui.activities.MainActivity +import com.drdisagree.iconify.ui.base.ControlledPreferenceFragmentCompat +import com.drdisagree.iconify.ui.preferences.SwitchPreference +import com.drdisagree.iconify.utils.SystemUtils.disableBlur +import com.drdisagree.iconify.utils.SystemUtils.enableBlur +import com.drdisagree.iconify.utils.SystemUtils.isBlurEnabled + +class TransparencyBlur : ControlledPreferenceFragmentCompat() { + + private var transparentQsPreference: SwitchPreference? = null + private var transparentNotificationPreference: SwitchPreference? = null + + override val title: String + get() = getString(R.string.activity_title_transparency_blur) + + override val backButtonEnabled: Boolean + get() = true + + override val layoutResource: Int + get() = R.xml.xposed_transparency_blur + + override val hasMenu: Boolean + get() = true + + override fun updateScreen(key: String?) { + super.updateScreen(key) + + when (key) { + QS_TRANSPARENCY_SWITCH -> { + if (getBoolean(key)) { + putBoolean(NOTIF_TRANSPARENCY_SWITCH, false) + transparentNotificationPreference?.isChecked = false + } + MainActivity.showOrHidePendingActionButton( + activityBinding = (requireActivity() as MainActivity).binding, + requiresSystemUiRestart = true + ) + } + + NOTIF_TRANSPARENCY_SWITCH -> { + if (getBoolean(key)) { + putBoolean(QS_TRANSPARENCY_SWITCH, false) + transparentQsPreference?.isChecked = false + } + MainActivity.showOrHidePendingActionButton( + activityBinding = (requireActivity() as MainActivity).binding, + requiresSystemUiRestart = true + ) + } + + LOCKSCREEN_SHADE_SWITCH -> { + MainActivity.showOrHidePendingActionButton( + activityBinding = (requireActivity() as MainActivity).binding, + requiresSystemUiRestart = true + ) + } + + QSPANEL_BLUR_SWITCH -> { + if (getBoolean(key)) { + enableBlur(force = false) + } else { + putBoolean(AGGRESSIVE_QSPANEL_BLUR_SWITCH, false) + disableBlur(force = false) + } + MainActivity.showOrHidePendingActionButton( + activityBinding = (requireActivity() as MainActivity).binding, + requiresDeviceRestart = true + ) + } + + AGGRESSIVE_QSPANEL_BLUR_SWITCH -> { + if (getBoolean(key)) { + enableBlur(force = true) + } else { + disableBlur(force = true) + } + MainActivity.showOrHidePendingActionButton( + activityBinding = (requireActivity() as MainActivity).binding, + requiresDeviceRestart = true + ) + } + + BLUR_RADIUS_VALUE -> { + MainActivity.showOrHidePendingActionButton( + activityBinding = (requireActivity() as MainActivity).binding, + requiresSystemUiRestart = true + ) + } + } + } + + override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { + super.onCreatePreferences(savedInstanceState, rootKey) + + transparentQsPreference = findPreference(QS_TRANSPARENCY_SWITCH) + transparentNotificationPreference = findPreference(NOTIF_TRANSPARENCY_SWITCH) + + findPreference(QSPANEL_BLUR_SWITCH)?.isChecked = + isBlurEnabled(force = false) + + findPreference(AGGRESSIVE_QSPANEL_BLUR_SWITCH)?.isChecked = + isBlurEnabled(force = true) + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/VolumePanel.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/VolumePanel.kt new file mode 100644 index 000000000..d2aa01614 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/VolumePanel.kt @@ -0,0 +1,39 @@ +package com.drdisagree.iconify.ui.fragments.xposed + +import android.os.Bundle +import com.drdisagree.iconify.R +import com.drdisagree.iconify.common.Preferences.VOLUME_PANEL_PERCENTAGE +import com.drdisagree.iconify.ui.activities.MainActivity +import com.drdisagree.iconify.ui.base.ControlledPreferenceFragmentCompat + +class VolumePanel : ControlledPreferenceFragmentCompat() { + + override val title: String + get() = getString(R.string.activity_title_volume_panel) + + override val backButtonEnabled: Boolean + get() = true + + override val layoutResource: Int + get() = R.xml.xposed_volume_panel + + override val hasMenu: Boolean + get() = true + + override fun updateScreen(key: String?) { + super.updateScreen(key) + + when (key) { + VOLUME_PANEL_PERCENTAGE -> { + MainActivity.showOrHidePendingActionButton( + activityBinding = (requireActivity() as MainActivity).binding, + requiresSystemUiRestart = true + ) + } + } + } + + override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { + super.onCreatePreferences(savedInstanceState, rootKey) + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/WeatherSettings.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/WeatherSettings.kt new file mode 100644 index 000000000..5e97c2c4e --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/WeatherSettings.kt @@ -0,0 +1,52 @@ +package com.drdisagree.iconify.ui.fragments.xposed + +import com.drdisagree.iconify.Iconify.Companion.appContextLocale +import com.drdisagree.iconify.R +import com.drdisagree.iconify.common.Preferences.WEATHER_OWM_KEY +import com.drdisagree.iconify.common.Preferences.WEATHER_PROVIDER +import com.drdisagree.iconify.config.RPrefs +import com.drdisagree.iconify.ui.base.WeatherPreferenceFragment +import com.google.android.material.dialog.MaterialAlertDialogBuilder + +class WeatherSettings : WeatherPreferenceFragment() { + + override fun getMainSwitchKey(): String { + return "" + } + + override val title: String + get() = getString(R.string.activity_title_xposed_weather_settings) + + override val backButtonEnabled: Boolean + get() = true + + override val layoutResource: Int + get() = R.xml.xposed_weather_settings + + override val hasMenu: Boolean + get() = true + + private fun showOwnKeyDialog() { + MaterialAlertDialogBuilder(requireContext()) + .setTitle(appContextLocale.getString(R.string.weather_provider_owm_key_title)) + .setMessage(appContextLocale.getString(R.string.weather_provider_owm_key_message)) + .setCancelable(false) + .setPositiveButton(appContextLocale.getString(R.string.understood), null) + .create() + .show() + } + + override fun updateScreen(key: String?) { + super.updateScreen(key) + + when (key) { + WEATHER_PROVIDER -> { + if (RPrefs.getString(WEATHER_PROVIDER) == "1" && RPrefs.getString(WEATHER_OWM_KEY) + .isNullOrEmpty() + ) { + showOwnKeyDialog() + } + } + } + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/Xposed.kt b/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/Xposed.kt new file mode 100644 index 000000000..73fd6b740 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/fragments/xposed/Xposed.kt @@ -0,0 +1,60 @@ +package com.drdisagree.iconify.ui.fragments.xposed + +import android.content.ComponentName +import android.content.Intent +import android.os.Bundle +import com.drdisagree.iconify.R +import com.drdisagree.iconify.common.Preferences +import com.drdisagree.iconify.common.Preferences.XPOSED_HOOK_CHECK +import com.drdisagree.iconify.ui.base.ControlledPreferenceFragmentCompat +import com.drdisagree.iconify.ui.preferences.HookCheckPreference + +class Xposed : ControlledPreferenceFragmentCompat() { + + private var hookCheckPreference: HookCheckPreference? = null + + override val title: String + get() = getString(R.string.navbar_xposed) + + override val backButtonEnabled: Boolean + get() = !Preferences.isXposedOnlyMode + + override val layoutResource: Int + get() = R.xml.xposed + + override val hasMenu: Boolean + get() = true + + override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { + super.onCreatePreferences(savedInstanceState, rootKey) + + findPreference(XPOSED_HOOK_CHECK)?.apply { + hookCheckPreference = this + + setOnPreferenceClickListener { + try { + val intent = Intent(Intent.ACTION_MAIN) + intent.setComponent( + ComponentName( + "org.lsposed.manager", + "org.lsposed.manager.ui.activities.MainActivity" + ) + ) + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + startActivity(intent) + } catch (ignored: Exception) { + } + true + } + + initializeHookCheck() + } + } + + override fun onResume() { + super.onResume() + + hookCheckPreference?.isHooked = false + hookCheckPreference?.initializeHookCheck() + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/ui/models/IconPackModel.kt b/app/src/main/java/com/drdisagree/iconify/ui/models/IconPackModel.kt index 11031a53b..3a058b728 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/models/IconPackModel.kt +++ b/app/src/main/java/com/drdisagree/iconify/ui/models/IconPackModel.kt @@ -1,10 +1,38 @@ package com.drdisagree.iconify.ui.models -class IconPackModel( - var name: String, - var desc: Int, - var icon1: Int, - var icon2: Int, - var icon3: Int, - var icon4: Int -) +import android.graphics.drawable.Drawable + +data class IconPackModel( + var name: String? = null, + var desc: Int = 0, + var icon1: Int = 0, + var icon2: Int = 0, + var icon3: Int = 0, + var icon4: Int = 0, + var drawableIcon1: Drawable? = null, + var drawableIcon2: Drawable? = null, + var drawableIcon3: Drawable? = null, + var drawableIcon4: Drawable? = null, + var isEnabled: Boolean = false +) { + var packageName: String? = null + + constructor( + packName: String?, + pkgName: String, + icon1: Drawable?, + icon2: Drawable?, + icon3: Drawable?, + icon4: Drawable?, + isEnabled: Boolean + ) : this( + name = packName, + drawableIcon1 = icon1, + drawableIcon2 = icon2, + drawableIcon3 = icon3, + drawableIcon4 = icon4, + isEnabled = isEnabled + ) { + this.packageName = pkgName + } +} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/ui/models/IconShapeModel.kt b/app/src/main/java/com/drdisagree/iconify/ui/models/IconShapeModel.kt new file mode 100644 index 000000000..2a19f1aa4 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/models/IconShapeModel.kt @@ -0,0 +1,7 @@ +package com.drdisagree.iconify.ui.models + +class IconShapeModel ( + var style: Int, + var title: Int, + var selected: Boolean = false +) \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/ui/models/InfoModel.kt b/app/src/main/java/com/drdisagree/iconify/ui/models/InfoModel.kt index c17e7fdd4..c909ae865 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/models/InfoModel.kt +++ b/app/src/main/java/com/drdisagree/iconify/ui/models/InfoModel.kt @@ -8,19 +8,11 @@ import android.view.View class InfoModel { var context: Context? = null - - @JvmField var icon = 0 - - @JvmField var layout = 0 - - @JvmField var title: String? = null - - @JvmField var desc: String? = null - private var onClickListener: View.OnClickListener? = null + var onClickListener: View.OnClickListener? = null constructor(title: String?) { this.title = title @@ -48,44 +40,4 @@ class InfoModel { this.icon = icon this.onClickListener = onClickListener } - - fun getIcon(): Int { - return icon - } - - fun setIcon(icon: Int) { - this.icon = icon - } - - fun getTitle(): String? { - return title - } - - fun setTitle(title: String?) { - this.title = title - } - - fun getDesc(): String? { - return desc - } - - fun setDesc(desc: String?) { - this.desc = desc - } - - fun getOnClickListener(): View.OnClickListener? { - return onClickListener - } - - fun setOnClickListener(onClickListener: View.OnClickListener?) { - this.onClickListener = onClickListener - } - - fun getLayout(): Int { - return layout - } - - fun setLayout(layout: Int) { - this.layout = layout - } } diff --git a/app/src/main/java/com/drdisagree/iconify/ui/models/MenuModel.kt b/app/src/main/java/com/drdisagree/iconify/ui/models/MenuModel.kt index fc0d7ff22..996f49fe8 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/models/MenuModel.kt +++ b/app/src/main/java/com/drdisagree/iconify/ui/models/MenuModel.kt @@ -1,7 +1,9 @@ package com.drdisagree.iconify.ui.models +import androidx.fragment.app.Fragment + class MenuModel( - var id: Int, + var fragment: Fragment, var title: String, var desc: String, var icon: Int diff --git a/app/src/main/java/com/drdisagree/iconify/ui/models/SearchPreferenceItem.kt b/app/src/main/java/com/drdisagree/iconify/ui/models/SearchPreferenceItem.kt new file mode 100644 index 000000000..c0abb1dc0 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/models/SearchPreferenceItem.kt @@ -0,0 +1,12 @@ +package com.drdisagree.iconify.ui.models + +import androidx.annotation.StringRes +import androidx.annotation.XmlRes +import com.drdisagree.iconify.ui.base.ControlledPreferenceFragmentCompat + +class SearchPreferenceItem( + @field:XmlRes val xml: Int, + @field:StringRes val title: Int, + val fragment: ControlledPreferenceFragmentCompat, + val shouldAdd: Boolean = true +) diff --git a/app/src/main/java/com/drdisagree/iconify/ui/models/ToastModel.kt b/app/src/main/java/com/drdisagree/iconify/ui/models/ToastModel.kt new file mode 100644 index 000000000..45b1669a0 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/models/ToastModel.kt @@ -0,0 +1,7 @@ +package com.drdisagree.iconify.ui.models + +class ToastModel ( + var style: Int, + var title: String, + var selected: Boolean = false +) diff --git a/app/src/main/java/com/drdisagree/iconify/ui/preferences/BottomSheetListPreference.kt b/app/src/main/java/com/drdisagree/iconify/ui/preferences/BottomSheetListPreference.kt new file mode 100644 index 000000000..bd1d6d77c --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/preferences/BottomSheetListPreference.kt @@ -0,0 +1,199 @@ +package com.drdisagree.iconify.ui.preferences + +import android.content.Context +import android.graphics.drawable.Drawable +import android.util.AttributeSet +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.annotation.DrawableRes +import androidx.recyclerview.widget.GridLayoutManager +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import androidx.preference.ListPreference +import com.drdisagree.iconify.R +import com.drdisagree.iconify.ui.adapters.ListPreferenceAdapter +import com.google.android.material.appbar.MaterialToolbar +import com.google.android.material.bottomsheet.BottomSheetDialog + +class BottomSheetListPreference : ListPreference { + + private var mEntryIcons: IntArray? = null + private var mEntryDrawables: Array? = null + private var mHasImages = false + private var mAdapter: ListPreferenceAdapter? = null + private var bottomSheetDialog: BottomSheetDialog? = null + private var recyclerView: RecyclerView? = null + + constructor( + context: Context, + attrs: AttributeSet?, + defStyleAttr: Int, + defStyleRes: Int + ) : super(context, attrs, defStyleAttr, defStyleRes) { + initResource() + } + + constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super( + context, + attrs, + defStyleAttr + ) { + initResource() + } + + constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) { + initResource() + } + + constructor(context: Context) : super(context) { + initResource() + } + + private fun initResource() { + layoutResource = R.layout.custom_preference_list + } + + fun setDrawables(@DrawableRes drawables: IntArray) { + mHasImages = true + mEntryIcons = drawables + } + + fun setDrawables(drawables: Array) { + mHasImages = true + mEntryDrawables = drawables + } + + fun setHasImages(hasImages: Boolean) { + mHasImages = hasImages + } + + fun setAdapter(adapter: ListPreferenceAdapter?) { + mAdapter = adapter + } + + fun setAdapterType(type: Int) { + if (mAdapter != null) mAdapter!!.type = type + } + + fun setImages(images: List) { + if (mAdapter != null) { + mAdapter!!.setImages(images) + } + } + + fun setDefaultAdapterListener() { + mAdapter!!.setListener(object : ListPreferenceAdapter.OnItemClickListener { + + override fun onItemClick(view: View?, position: Int) { + if (callChangeListener(entryValues[position].toString())) { + setValueIndex(position) + } + if (bottomSheetDialog != null) bottomSheetDialog!!.dismiss() + } + }) + } + + protected override fun onClick() { + bottomSheetDialog = BottomSheetDialog(context) + + val view: View = LayoutInflater.from(context) + .inflate(R.layout.view_bottom_sheet_dialog_layout, null as ViewGroup?) + recyclerView = view.findViewById(R.id.select_dialog_listview) + val toolbarPref = view.findViewById(R.id.toolbar_preference) + toolbarPref.setTitle(title) + toolbarPref.isTitleCentered = true + if (mAdapter != null && mAdapter!!.type == ListPreferenceAdapter.TYPE_BATTERY_ICONS) { + recyclerView!!.setLayoutManager(GridLayoutManager(context, 3)) + } else { + recyclerView!!.setLayoutManager(LinearLayoutManager(context)) + } + if (mAdapter == null) { + mAdapter = ListPreferenceAdapter( + entries, + entryValues, + mEntryIcons, + key, + mHasImages, + object : ListPreferenceAdapter.OnItemClickListener { + override fun onItemClick(view: View?, position: Int) { + if (callChangeListener(entryValues[position].toString())) { + setValueIndex(position) + } + } + } + ) + } + recyclerView!!.setAdapter(mAdapter) + bottomSheetDialog!!.setContentView(view) + bottomSheetDialog!!.show() + } + + private fun getValueIndex(): Int { + return findIndexOfValue(value) + } + + override fun setValueIndex(index: Int) { + setValue(entryValues[index].toString()) + } + + fun createDefaultAdapter() { + mAdapter = ListPreferenceAdapter( + entries, + entryValues, + mEntryIcons, + key, + mHasImages, + object : ListPreferenceAdapter.OnItemClickListener { + override fun onItemClick(view: View?, position: Int) { + if (callChangeListener(entryValues[position].toString())) { + setValueIndex(position) + } + } + } + ) + } + + fun createDefaultAdapter(drawables: Array) { + mHasImages = true + mEntryDrawables = drawables + mAdapter = ListPreferenceAdapter( + entries, + entryValues, + drawables, + key, + mHasImages, + object : ListPreferenceAdapter.OnItemClickListener { + override fun onItemClick(view: View?, position: Int) { + if (callChangeListener(entryValues[position].toString())) { + setValueIndex(position) + } + } + } + ) + } + + fun createDefaultAdapter(drawables: Array, listener: OnItemClickListener?) { + mHasImages = true + mEntryDrawables = drawables + mAdapter = ListPreferenceAdapter( + entries, + entryValues, + drawables, + key, + mHasImages, + object : ListPreferenceAdapter.OnItemClickListener { + override fun onItemClick(view: View?, position: Int) { + if (callChangeListener(entryValues[position].toString())) { + setValueIndex(position) + } + listener?.onItemClick(position) + } + } + ) + } + + interface OnItemClickListener { + fun onItemClick(position: Int) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/ui/preferences/ColorPreference.java b/app/src/main/java/com/drdisagree/iconify/ui/preferences/ColorPreference.java new file mode 100644 index 000000000..3c1f47d3c --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/preferences/ColorPreference.java @@ -0,0 +1,225 @@ +package com.drdisagree.iconify.ui.preferences; + +import android.content.Context; +import android.content.ContextWrapper; +import android.content.res.TypedArray; +import android.graphics.Color; +import android.util.AttributeSet; + +import androidx.annotation.ColorInt; +import androidx.annotation.NonNull; +import androidx.fragment.app.FragmentActivity; +import androidx.preference.Preference; +import androidx.preference.PreferenceViewHolder; + +import com.jaredrummler.android.colorpicker.R; +import com.jaredrummler.android.colorpicker.ColorPanelView; +import com.jaredrummler.android.colorpicker.ColorPickerDialog; +import com.jaredrummler.android.colorpicker.ColorPickerDialogListener; +import com.jaredrummler.android.colorpicker.ColorShape; + +public class ColorPreference extends Preference implements ColorPickerDialogListener { + + private static final int SIZE_NORMAL = 0; + private static final int SIZE_LARGE = 1; + + private OnShowDialogListener onShowDialogListener; + private int color = Color.BLACK; + private boolean showDialog; + private int dialogType; + private int colorShape; + private boolean allowPresets; + private boolean allowCustom; + private boolean showAlphaSlider; + private boolean showColorShades; + private int previewSize; + private int[] presets; + private int dialogTitle; + + public ColorPreference(Context context, AttributeSet attrs) { + super(context, attrs); + init(attrs); + } + + public ColorPreference(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + init(attrs); + } + + private void init(AttributeSet attrs) { + setPersistent(true); + + TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.ColorPreference); + showDialog = a.getBoolean(R.styleable.ColorPreference_cpv_showDialog, true); + dialogType = a.getInt(R.styleable.ColorPreference_cpv_dialogType, ColorPickerDialog.TYPE_PRESETS); + colorShape = a.getInt(R.styleable.ColorPreference_cpv_colorShape, ColorShape.CIRCLE); + allowPresets = a.getBoolean(R.styleable.ColorPreference_cpv_allowPresets, true); + allowCustom = a.getBoolean(R.styleable.ColorPreference_cpv_allowCustom, true); + showAlphaSlider = a.getBoolean(R.styleable.ColorPreference_cpv_showAlphaSlider, false); + showColorShades = a.getBoolean(R.styleable.ColorPreference_cpv_showColorShades, true); + previewSize = a.getInt(R.styleable.ColorPreference_cpv_previewSize, SIZE_NORMAL); + final int presetsResId = a.getResourceId(R.styleable.ColorPreference_cpv_colorPresets, 0); + dialogTitle = a.getResourceId(R.styleable.ColorPreference_cpv_dialogTitle, R.string.cpv_default_title); + if (presetsResId != 0) { + presets = getContext().getResources().getIntArray(presetsResId); + } else { + presets = ColorPickerDialog.MATERIAL_COLORS; + } + if (colorShape == ColorShape.CIRCLE) { + setWidgetLayoutResource( + previewSize == SIZE_LARGE ? R.layout.cpv_preference_circle_large : R.layout.cpv_preference_circle); + } else { + setWidgetLayoutResource( + previewSize == SIZE_LARGE ? R.layout.cpv_preference_square_large : R.layout.cpv_preference_square); + } + a.recycle(); + + initResource(); + } + + private void initResource() { + setLayoutResource(com.drdisagree.iconify.R.layout.custom_preference_color); + } + + @Override + protected void onClick() { + super.onClick(); + if (onShowDialogListener != null) { + onShowDialogListener.onShowColorPickerDialog((String) getTitle(), color); + } else if (showDialog) { + ColorPickerDialog dialog = ColorPickerDialog.newBuilder() + .setDialogType(dialogType) + .setDialogTitle(dialogTitle) + .setColorShape(colorShape) + .setPresets(presets) + .setAllowPresets(allowPresets) + .setAllowCustom(allowCustom) + .setShowAlphaSlider(showAlphaSlider) + .setShowColorShades(showColorShades) + .setColor(color) + .create(); + dialog.setColorPickerDialogListener(this); + getActivity().getSupportFragmentManager() + .beginTransaction() + .add(dialog, getFragmentTag()) + .commitAllowingStateLoss(); + } + } + + public FragmentActivity getActivity() { + Context context = getContext(); + if (context instanceof FragmentActivity) { + return (FragmentActivity) context; + } else if (context instanceof ContextWrapper) { + Context baseContext = ((ContextWrapper) context).getBaseContext(); + if (baseContext instanceof FragmentActivity) { + return (FragmentActivity) baseContext; + } + } + throw new IllegalStateException("Error getting activity from context"); + } + + @Override + public void onAttached() { + super.onAttached(); + if (showDialog) { + ColorPickerDialog fragment = + (ColorPickerDialog) getActivity().getSupportFragmentManager().findFragmentByTag(getFragmentTag()); + if (fragment != null) { + // re-bind preference to fragment + fragment.setColorPickerDialogListener(this); + } + } + } + + @Override + public void onBindViewHolder(@NonNull PreferenceViewHolder holder) { + super.onBindViewHolder(holder); + + ColorPanelView preview = holder.itemView.findViewById(R.id.cpv_preference_preview_color_panel); + if (preview != null) { + preview.setColor(color); + } + } + + @Override + protected void onSetInitialValue(Object defaultValue) { + super.onSetInitialValue(defaultValue); + if (defaultValue instanceof Integer) { + color = (Integer) defaultValue; + persistInt(color); + } else { + color = getPersistedInt(0xFF000000); + } + } + + @Override + protected Object onGetDefaultValue(TypedArray a, int index) { + return a.getInteger(index, Color.BLACK); + } + + @Override + public void onColorSelected(int dialogId, @ColorInt int color) { + saveValue(color); + } + + @Override + public void onDialogDismissed(int dialogId) { + // no-op + } + + /** + * Set the new color + * + * @param color The newly selected color + */ + public void saveValue(@ColorInt int color) { + this.color = color; + persistInt(this.color); + notifyChanged(); + callChangeListener(color); + } + + /** + * Get the colors that will be shown in the {@link ColorPickerDialog}. + * + * @return An array of color ints + */ + public int[] getPresets() { + return presets; + } + + /** + * Set the colors shown in the {@link ColorPickerDialog}. + * + * @param presets An array of color ints + */ + public void setPresets(@NonNull int[] presets) { + this.presets = presets; + } + + /** + * The listener used for showing the {@link ColorPickerDialog}. + * Call {@link #saveValue(int)} after the user chooses a color. + * If this is set then it is up to you to show the dialog. + * + * @param listener The listener to show the dialog + */ + public void setOnShowDialogListener(OnShowDialogListener listener) { + onShowDialogListener = listener; + } + + /** + * The tag used for the {@link ColorPickerDialog}. + * + * @return The tag + */ + public String getFragmentTag() { + return "color_" + getKey(); + } + + public interface OnShowDialogListener { + + void onShowColorPickerDialog(String title, int currentColor); + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/ui/preferences/EditTextPreference.kt b/app/src/main/java/com/drdisagree/iconify/ui/preferences/EditTextPreference.kt new file mode 100644 index 000000000..23a2e91b0 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/preferences/EditTextPreference.kt @@ -0,0 +1,38 @@ +package com.drdisagree.iconify.ui.preferences + +import android.content.Context +import android.util.AttributeSet +import androidx.preference.EditTextPreference +import com.drdisagree.iconify.R + +class EditTextPreference : EditTextPreference { + + constructor( + context: Context, + attrs: AttributeSet?, + defStyleAttr: Int, + defStyleRes: Int + ) : super(context, attrs, defStyleAttr, defStyleRes) { + initResource() + } + + constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super( + context, + attrs, + defStyleAttr + ) { + initResource() + } + + constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) { + initResource() + } + + constructor(context: Context) : super(context) { + initResource() + } + + private fun initResource() { + layoutResource = R.layout.custom_preference_edit_text + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/ui/preferences/FilePickerPreference.kt b/app/src/main/java/com/drdisagree/iconify/ui/preferences/FilePickerPreference.kt new file mode 100644 index 000000000..3681b9ff4 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/preferences/FilePickerPreference.kt @@ -0,0 +1,76 @@ +package com.drdisagree.iconify.ui.preferences + +import android.content.Context +import android.util.AttributeSet +import android.widget.TextView +import androidx.core.content.ContextCompat +import androidx.preference.Preference +import androidx.preference.PreferenceViewHolder +import com.drdisagree.iconify.R +import com.google.android.material.button.MaterialButton + +class FilePickerPreference : Preference { + + private var mOnClick: () -> Unit? = {} + private var mButtonText = "" + + constructor( + context: Context, + attrs: AttributeSet?, + defStyleAttr: Int, + defStyleRes: Int + ) : super(context, attrs, defStyleAttr, defStyleRes) { + init(attrs) + } + + constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super( + context, + attrs, + defStyleAttr + ) { + init(attrs) + } + + constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) { + init(attrs) + } + + constructor(context: Context) : super(context) { + init(null) + } + + private fun init(attrs: AttributeSet?) { + isSelectable = false + layoutResource = R.layout.custom_preference_filepicker + + attrs?.let { it -> + val a = context.obtainStyledAttributes(it, R.styleable.FilePickerPreference) + val customText: String? = a.getString(R.styleable.FilePickerPreference_buttonText) + mButtonText = + customText ?: a.getResourceId(R.styleable.FilePickerPreference_buttonText, 0) + .takeIf { it != 0 } + ?.let { context.getString(it) } ?: context.getString(R.string.btn_pick_image) + a.recycle() + } + } + + override fun onBindViewHolder(holder: PreferenceViewHolder) { + super.onBindViewHolder(holder) + + if (isEnabled) { + holder.itemView.findViewById(android.R.id.title)?.apply { + setTextColor(ContextCompat.getColor(context, R.color.textColorPrimary)) + } + } + + holder.itemView.findViewById(R.id.btn_picker)?.apply { + text = mButtonText + this.isEnabled = isEnabled + setOnClickListener { mOnClick.invoke() } + } + } + + fun setOnButtonClick(onClick: () -> Unit) { + mOnClick = onClick + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/ui/preferences/FooterPreference.java b/app/src/main/java/com/drdisagree/iconify/ui/preferences/FooterPreference.java new file mode 100644 index 000000000..0850005fc --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/preferences/FooterPreference.java @@ -0,0 +1,296 @@ +package com.drdisagree.iconify.ui.preferences; + +import android.content.Context; +import android.text.SpannableString; +import android.text.TextUtils; +import android.text.style.URLSpan; +import android.util.AttributeSet; +import android.view.View; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.StringRes; +import androidx.annotation.VisibleForTesting; +import androidx.preference.Preference; +import androidx.preference.PreferenceViewHolder; + +import com.drdisagree.iconify.R; + +/** + * A custom preference acting as "footer" of a page. It has a field for icon and text. It is added + * to screen as the last preference. + */ +public class FooterPreference extends Preference { + + public static final String KEY_FOOTER = "footer_preference"; + static final int ORDER_FOOTER = Integer.MAX_VALUE - 1; + @VisibleForTesting + View.OnClickListener mLearnMoreListener; + @VisibleForTesting + int mIconVisibility = View.VISIBLE; + private CharSequence mContentDescription; + private CharSequence mLearnMoreText; + private FooterLearnMoreSpan mLearnMoreSpan; + + public FooterPreference(Context context, AttributeSet attrs) { + super(context, attrs, R.attr.footerPreferenceStyle); + init(); + } + + public FooterPreference(Context context) { + this(context, null); + } + + @Override + public void onBindViewHolder(@NonNull PreferenceViewHolder holder) { + super.onBindViewHolder(holder); + TextView title = holder.itemView.findViewById(android.R.id.title); + if (title != null && !TextUtils.isEmpty(mContentDescription)) { + title.setContentDescription(mContentDescription); + } + + TextView learnMore = holder.itemView.findViewById(R.id.settingslib_learn_more); + if (learnMore != null) { + if (mLearnMoreListener != null) { + learnMore.setVisibility(View.VISIBLE); + if (TextUtils.isEmpty(mLearnMoreText)) { + mLearnMoreText = learnMore.getText(); + } else { + learnMore.setText(mLearnMoreText); + } + SpannableString learnMoreText = new SpannableString(mLearnMoreText); + if (mLearnMoreSpan != null) { + learnMoreText.removeSpan(mLearnMoreSpan); + } + mLearnMoreSpan = new FooterLearnMoreSpan(mLearnMoreListener); + learnMoreText.setSpan(mLearnMoreSpan, 0, + learnMoreText.length(), 0); + learnMore.setText(learnMoreText); + } else { + learnMore.setVisibility(View.GONE); + } + } + + View icon = holder.itemView.findViewById(R.id.icon_frame); + if (icon != null) { + icon.setVisibility(mIconVisibility); + } + } + + @Override + public void setSummary(CharSequence summary) { + setTitle(summary); + } + + @Override + public void setSummary(int summaryResId) { + setTitle(summaryResId); + } + + @Override + public CharSequence getSummary() { + return getTitle(); + } + + /** + * To set content description of the {@link FooterPreference}. This can use for talkback + * environment if developer wants to have a customization content. + * + * @param contentDescription The resource id of the content description. + */ + public void setContentDescription(CharSequence contentDescription) { + if (!TextUtils.equals(mContentDescription, contentDescription)) { + mContentDescription = contentDescription; + notifyChanged(); + } + } + + /** + * Return the content description of footer preference. + */ + @VisibleForTesting + CharSequence getContentDescription() { + return mContentDescription; + } + + /** + * Sets the learn more text. + * + * @param learnMoreText The string of the learn more text. + */ + public void setLearnMoreText(CharSequence learnMoreText) { + if (!TextUtils.equals(mLearnMoreText, learnMoreText)) { + mLearnMoreText = learnMoreText; + notifyChanged(); + } + } + + /** + * Assign an action for the learn more link. + */ + public void setLearnMoreAction(View.OnClickListener listener) { + if (mLearnMoreListener != listener) { + mLearnMoreListener = listener; + notifyChanged(); + } + } + + /** + * Set visibility of footer icon. + */ + public void setIconVisibility(int iconVisibility) { + if (mIconVisibility == iconVisibility) { + return; + } + mIconVisibility = iconVisibility; + notifyChanged(); + } + + private void init() { + setLayoutResource(R.layout.preference_footer); + if (getIcon() == null) { + setIcon(R.drawable.ic_info); + } + setOrder(ORDER_FOOTER); + if (TextUtils.isEmpty(getKey())) { + setKey(KEY_FOOTER); + } + setSelectable(false); + } + + /** + * The builder is convenient to creat a dynamic FooterPreference. + */ + public static class Builder { + private Context mContext; + private String mKey; + private CharSequence mTitle; + private CharSequence mContentDescription; + private CharSequence mLearnMoreText; + + public Builder(@NonNull Context context) { + mContext = context; + } + + /** + * To set the key value of the {@link FooterPreference}. + * + * @param key The key value. + */ + public Builder setKey(@NonNull String key) { + mKey = key; + return this; + } + + /** + * To set the title of the {@link FooterPreference}. + * + * @param title The title. + */ + public Builder setTitle(CharSequence title) { + mTitle = title; + return this; + } + + /** + * To set the title of the {@link FooterPreference}. + * + * @param titleResId The resource id of the title. + */ + public Builder setTitle(@StringRes int titleResId) { + mTitle = mContext.getText(titleResId); + return this; + } + + /** + * To set content description of the {@link FooterPreference}. This can use for talkback + * environment if developer wants to have a customization content. + * + * @param contentDescription The resource id of the content description. + */ + public Builder setContentDescription(CharSequence contentDescription) { + mContentDescription = contentDescription; + return this; + } + + /** + * To set content description of the {@link FooterPreference}. This can use for talkback + * environment if developer wants to have a customization content. + * + * @param contentDescriptionResId The resource id of the content description. + */ + public Builder setContentDescription(@StringRes int contentDescriptionResId) { + mContentDescription = mContext.getText(contentDescriptionResId); + return this; + } + + /** + * To set learn more string of the learn more text. This can use for talkback + * environment if developer wants to have a customization content. + * + * @param learnMoreText The resource id of the learn more string. + */ + public Builder setLearnMoreText(CharSequence learnMoreText) { + mLearnMoreText = learnMoreText; + return this; + } + + /** + * To set learn more string of the {@link FooterPreference}. This can use for talkback + * environment if developer wants to have a customization content. + * + * @param learnMoreTextResId The resource id of the learn more string. + */ + public Builder setLearnMoreText(@StringRes int learnMoreTextResId) { + mLearnMoreText = mContext.getText(learnMoreTextResId); + return this; + } + + + /** + * To generate the {@link FooterPreference}. + */ + public FooterPreference build() { + final FooterPreference footerPreference = new FooterPreference(mContext); + footerPreference.setSelectable(false); + if (TextUtils.isEmpty(mTitle)) { + throw new IllegalArgumentException("Footer title cannot be empty!"); + } + footerPreference.setTitle(mTitle); + if (!TextUtils.isEmpty(mKey)) { + footerPreference.setKey(mKey); + } + + if (!TextUtils.isEmpty(mContentDescription)) { + footerPreference.setContentDescription(mContentDescription); + } + + if (!TextUtils.isEmpty(mLearnMoreText)) { + footerPreference.setLearnMoreText(mLearnMoreText); + } + return footerPreference; + } + } + + /** + * A {@link URLSpan} that opens a support page when clicked + */ + static class FooterLearnMoreSpan extends URLSpan { + + private final View.OnClickListener mClickListener; + + FooterLearnMoreSpan(View.OnClickListener clickListener) { + // sets the url to empty string so we can prevent any other span processing from + // clearing things we need in this string. + super(""); + mClickListener = clickListener; + } + + @Override + public void onClick(View widget) { + if (mClickListener != null) { + mClickListener.onClick(widget); + } + } + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/ui/preferences/HomeCardPreference.kt b/app/src/main/java/com/drdisagree/iconify/ui/preferences/HomeCardPreference.kt new file mode 100644 index 000000000..e8624d791 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/preferences/HomeCardPreference.kt @@ -0,0 +1,29 @@ +package com.drdisagree.iconify.ui.preferences + +import android.content.Context +import android.util.AttributeSet +import androidx.preference.Preference +import androidx.preference.PreferenceViewHolder +import com.drdisagree.iconify.R +import com.drdisagree.iconify.common.Preferences.SHOW_HOME_CARD +import com.drdisagree.iconify.config.RPrefs +import com.google.android.material.button.MaterialButton + +class HomeCardPreference(context: Context, attrs: AttributeSet?) : Preference(context, attrs) { + + override fun onBindViewHolder(holder: PreferenceViewHolder) { + super.onBindViewHolder(holder) + + holder.itemView.findViewById(R.id.button).setOnClickListener { + holder.itemView + .animate() + .setDuration(400) + .translationX(holder.itemView.width * 2f) + .alpha(0f) + .withEndAction { + RPrefs.putBoolean(SHOW_HOME_CARD, false) + } + .start() + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/ui/preferences/HookCheckPreference.kt b/app/src/main/java/com/drdisagree/iconify/ui/preferences/HookCheckPreference.kt new file mode 100644 index 000000000..3aaf2dcdf --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/preferences/HookCheckPreference.kt @@ -0,0 +1,175 @@ +package com.drdisagree.iconify.ui.preferences + +import android.annotation.SuppressLint +import android.content.BroadcastReceiver +import android.content.ComponentName +import android.content.Context +import android.content.DialogInterface +import android.content.Intent +import android.content.IntentFilter +import android.os.Build +import android.os.CountDownTimer +import android.os.Handler +import android.os.Looper +import android.util.AttributeSet +import android.widget.ImageView +import androidx.preference.Preference +import androidx.preference.PreferenceViewHolder +import com.drdisagree.iconify.Iconify.Companion.appContextLocale +import com.drdisagree.iconify.R +import com.drdisagree.iconify.common.Const.ACTION_HOOK_CHECK_REQUEST +import com.drdisagree.iconify.common.Const.ACTION_HOOK_CHECK_RESULT +import com.drdisagree.iconify.common.Preferences +import com.drdisagree.iconify.common.Preferences.XPOSED_HOOK_CHECK +import com.drdisagree.iconify.config.RPrefs +import com.google.android.material.dialog.MaterialAlertDialogBuilder + +class HookCheckPreference(context: Context, attrs: AttributeSet?) : Preference(context, attrs) { + + private val handler = Handler(Looper.getMainLooper()) + private val delayedHandler = Handler(Looper.getMainLooper()) + private val intentFilterHookedSystemUI = IntentFilter() + private var isHookSuccessful = false + var isHooked: Boolean = false + + init { + intentFilterHookedSystemUI.addAction(ACTION_HOOK_CHECK_RESULT) + } + + override fun onBindViewHolder(holder: PreferenceViewHolder) { + super.onBindViewHolder(holder) + + holder.itemView.setOnClickListener { + try { + context.startActivity( + Intent(Intent.ACTION_MAIN).apply { + setComponent( + ComponentName( + "org.lsposed.manager", + "org.lsposed.manager.ui.activity.MainActivity" + ) + ) + addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + } + ) + } catch (ignored: Exception) { + } + } + + holder.itemView.findViewById(R.id.info_icon).setOnClickListener { + MaterialAlertDialogBuilder(context) + .setTitle(context.resources.getString(R.string.attention)) + .setMessage( + buildString { + append( + (if (Preferences.isXposedOnlyMode) { + appContextLocale.resources.getString( + R.string.xposed_only_desc + ) + "\n\n" + } else { + "" + }) + ) + append(appContextLocale.resources.getString(R.string.lsposed_warn)) + } + ) + .setPositiveButton(context.resources.getString(R.string.understood)) { dialog: DialogInterface, _: Int -> + dialog.dismiss() + } + .setCancelable(true) + .show() + } + } + + @SuppressLint("UnspecifiedRegisterReceiverFlag") + fun initializeHookCheck() { + delayedHandler.postDelayed(delayedHookCheck, 1000) + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + context.registerReceiver( + receiverHookedSystemUI, + intentFilterHookedSystemUI, + Context.RECEIVER_EXPORTED + ) + } else { + context.registerReceiver( + receiverHookedSystemUI, + intentFilterHookedSystemUI + ) + } + + handler.post(checkSystemUIHooked) + } + + private val delayedHookCheck: Runnable = Runnable { + if (!isHooked) { + RPrefs.putBoolean(XPOSED_HOOK_CHECK, false) + } + } + + private val checkSystemUIHooked: Runnable = object : Runnable { + override fun run() { + checkXposedHooked() +// handler.postDelayed(this, 1000) // repeat check every 1 second + } + } + + private val receiverHookedSystemUI: BroadcastReceiver = object : BroadcastReceiver() { + override fun onReceive(context: Context, intent: Intent) { + if (intent.action == ACTION_HOOK_CHECK_RESULT) { + isHookSuccessful = true + + try { + delayedHandler.removeCallbacks(delayedHookCheck) + } catch (ignored: Exception) { + } + + isHooked = true + + RPrefs.putBoolean(XPOSED_HOOK_CHECK, true) + } + } + } + + private fun checkXposedHooked() { + isHookSuccessful = false + + object : CountDownTimer(1600, 800) { + override fun onTick(millisUntilFinished: Long) { + if (isHookSuccessful) { + cancel() + } + } + + override fun onFinish() { + if (!isHookSuccessful) { + try { + delayedHandler.removeCallbacks(delayedHookCheck) + } catch (ignored: Exception) { + } + + isHooked = false + + RPrefs.putBoolean(XPOSED_HOOK_CHECK, false) + } + } + }.start() + + Thread { + try { + context.sendBroadcast(Intent().setAction(ACTION_HOOK_CHECK_REQUEST)) + } catch (ignored: Exception) { + } + }.start() + } + + override fun onDetached() { + super.onDetached() + try { + handler.removeCallbacks(checkSystemUIHooked) + delayedHandler.removeCallbacks(delayedHookCheck) + context.unregisterReceiver(receiverHookedSystemUI) + } catch (ignored: Exception) { + } + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/ui/preferences/LinkTextView.java b/app/src/main/java/com/drdisagree/iconify/ui/preferences/LinkTextView.java new file mode 100644 index 000000000..ffc6917cc --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/preferences/LinkTextView.java @@ -0,0 +1,35 @@ +package com.drdisagree.iconify.ui.preferences; + +import android.content.Context; +import android.text.Spanned; +import android.text.method.LinkMovementMethod; +import android.text.style.ClickableSpan; +import android.util.AttributeSet; + +/** + * Copied from setup wizard. This TextView performed two functions. The first is to make it so the + * link behaves properly and becomes clickable. The second was that it made the link visible to + * accessibility services, but from O forward support for links is provided natively. + */ +public class LinkTextView extends androidx.appcompat.widget.AppCompatTextView { + + public LinkTextView(Context context) { + this(context, null); + } + + public LinkTextView(Context context, AttributeSet attrs) { + super(context, attrs); + } + + @Override + public void setText(CharSequence text, BufferType type) { + super.setText(text, type); + if (text instanceof Spanned) { + final ClickableSpan[] spans = + ((Spanned) text).getSpans(0, text.length(), ClickableSpan.class); + if (spans.length > 0) { + setMovementMethod(LinkMovementMethod.getInstance()); + } + } + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/ui/preferences/ListPreference.kt b/app/src/main/java/com/drdisagree/iconify/ui/preferences/ListPreference.kt new file mode 100644 index 000000000..76edb34ae --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/preferences/ListPreference.kt @@ -0,0 +1,38 @@ +package com.drdisagree.iconify.ui.preferences + +import android.content.Context +import android.util.AttributeSet +import androidx.preference.ListPreference +import com.drdisagree.iconify.R + +class ListPreference : ListPreference { + + constructor( + context: Context, + attrs: AttributeSet?, + defStyleAttr: Int, + defStyleRes: Int + ) : super(context, attrs, defStyleAttr, defStyleRes) { + initResource() + } + + constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super( + context, + attrs, + defStyleAttr + ) { + initResource() + } + + constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) { + initResource() + } + + constructor(context: Context) : super(context) { + initResource() + } + + private fun initResource() { + layoutResource = R.layout.custom_preference_list + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/ui/preferences/PreferenceCategory.kt b/app/src/main/java/com/drdisagree/iconify/ui/preferences/PreferenceCategory.kt new file mode 100644 index 000000000..2e0499e2e --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/preferences/PreferenceCategory.kt @@ -0,0 +1,38 @@ +package com.drdisagree.iconify.ui.preferences + +import android.content.Context +import android.util.AttributeSet +import androidx.preference.PreferenceCategory +import com.drdisagree.iconify.R + +class PreferenceCategory : PreferenceCategory { + + constructor( + context: Context, + attrs: AttributeSet?, + defStyleAttr: Int, + defStyleRes: Int + ) : super(context, attrs, defStyleAttr, defStyleRes) { + initResource() + } + + constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super( + context, + attrs, + defStyleAttr + ) { + initResource() + } + + constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) { + initResource() + } + + constructor(context: Context) : super(context) { + initResource() + } + + private fun initResource() { + layoutResource = R.layout.custom_preference_category + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/ui/preferences/PreferenceMenu.kt b/app/src/main/java/com/drdisagree/iconify/ui/preferences/PreferenceMenu.kt new file mode 100644 index 000000000..1809ccaa4 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/preferences/PreferenceMenu.kt @@ -0,0 +1,53 @@ +package com.drdisagree.iconify.ui.preferences + +import android.content.Context +import android.util.AttributeSet +import android.view.View +import androidx.preference.Preference +import androidx.preference.PreferenceViewHolder +import com.drdisagree.iconify.R + +class PreferenceMenu : Preference { + + private var showArrow = true + + constructor( + context: Context, + attrs: AttributeSet?, + defStyleAttr: Int, + defStyleRes: Int + ) : super(context, attrs, defStyleAttr, defStyleRes) { + init(attrs) + } + + constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super( + context, + attrs, + defStyleAttr + ) { + init(attrs) + } + + constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) { + init(attrs) + } + + constructor(context: Context) : super(context) { + init(null) + } + + private fun init(attrs: AttributeSet?) { + if (attrs != null) { + val a = context.obtainStyledAttributes(attrs, R.styleable.PreferenceMenu) + showArrow = a.getBoolean(R.styleable.PreferenceMenu_showArrow, true) + a.recycle() + } + layoutResource = R.layout.custom_preference_menu + } + + override fun onBindViewHolder(holder: PreferenceViewHolder) { + super.onBindViewHolder(holder) + + holder.findViewById(R.id.end_arrow)?.visibility = if (showArrow) View.VISIBLE else View.GONE + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/ui/preferences/RebootReminderPreference.kt b/app/src/main/java/com/drdisagree/iconify/ui/preferences/RebootReminderPreference.kt new file mode 100644 index 000000000..f003c8ca1 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/preferences/RebootReminderPreference.kt @@ -0,0 +1,30 @@ +package com.drdisagree.iconify.ui.preferences + +import android.content.Context +import android.os.Handler +import android.os.Looper +import android.util.AttributeSet +import androidx.preference.Preference +import androidx.preference.PreferenceViewHolder +import com.drdisagree.iconify.R +import com.drdisagree.iconify.ui.dialogs.LoadingDialog +import com.drdisagree.iconify.utils.SystemUtils.restartDevice + +class RebootReminderPreference(context: Context, attrs: AttributeSet?) : + Preference(context, attrs) { + + override fun onBindViewHolder(holder: PreferenceViewHolder) { + super.onBindViewHolder(holder) + + holder.findViewById(R.id.btn_reboot).setOnClickListener { + val rebootingDialog = LoadingDialog(context) + + rebootingDialog.show(context.resources.getString(R.string.rebooting_desc)) + + Handler(Looper.getMainLooper()).postDelayed({ + rebootingDialog.hide() + restartDevice() + }, 5000) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/ui/preferences/RecyclerPreference.kt b/app/src/main/java/com/drdisagree/iconify/ui/preferences/RecyclerPreference.kt new file mode 100644 index 000000000..8ab7708c2 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/preferences/RecyclerPreference.kt @@ -0,0 +1,84 @@ +package com.drdisagree.iconify.ui.preferences + +import android.content.Context +import android.util.AttributeSet +import android.widget.TextView +import androidx.core.content.ContextCompat +import androidx.preference.Preference +import androidx.preference.PreferenceViewHolder +import androidx.recyclerview.widget.LinearSnapHelper +import androidx.recyclerview.widget.RecyclerView +import com.drdisagree.iconify.R +import com.drdisagree.iconify.config.RPrefs +import com.drdisagree.iconify.ui.utils.CarouselLayoutManager + +class RecyclerPreference : Preference { + + private var mRecyclerView: RecyclerView? = null + private var mAdapter: RecyclerView.Adapter<*>? = null + private var mKey: String? = null + private var mDefaultValue = 0 + + constructor( + context: Context, + attrs: AttributeSet?, + defStyleAttr: Int, + defStyleRes: Int + ) : super(context, attrs, defStyleAttr, defStyleRes) { + init() + } + + constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super( + context, + attrs, + defStyleAttr + ) { + init() + } + + constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) { + init() + } + + constructor(context: Context) : super(context) { + init() + } + + private fun init() { + isSelectable = false + layoutResource = R.layout.custom_preference_recyclerview + } + + override fun onBindViewHolder(holder: PreferenceViewHolder) { + super.onBindViewHolder(holder) + + mRecyclerView = (holder.findViewById(R.id.recycler_view) as RecyclerView).apply { + layoutManager = CarouselLayoutManager( + context, RecyclerView.HORIZONTAL, false + ).also { + it.setMinifyDistance(0.8f) + } + adapter = mAdapter + setHasFixedSize(true); + scrollToPosition(RPrefs.getInt(mKey, mDefaultValue)) + if (onFlingListener == null) { + LinearSnapHelper().attachToRecyclerView(this) + } + suppressLayout(!isEnabled) + } + + if (isEnabled) { + val title = holder.itemView.findViewById(android.R.id.title) + title.setTextColor(ContextCompat.getColor(context, R.color.textColorPrimary)) + } + } + + fun setPreference(key: String?, defaultValue: Int) { + mKey = key + mDefaultValue = defaultValue + } + + fun setAdapter(adapter: RecyclerView.Adapter<*>?) { + mAdapter = adapter + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/ui/preferences/SelectorWithWidgetPreference.java b/app/src/main/java/com/drdisagree/iconify/ui/preferences/SelectorWithWidgetPreference.java new file mode 100644 index 000000000..eb0506fef --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/preferences/SelectorWithWidgetPreference.java @@ -0,0 +1,186 @@ +package com.drdisagree.iconify.ui.preferences; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.text.TextUtils; +import android.util.AttributeSet; +import android.view.View; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.preference.CheckBoxPreference; +import androidx.preference.PreferenceViewHolder; + +import com.drdisagree.iconify.R; + +public class SelectorWithWidgetPreference extends CheckBoxPreference { + + /** + * Interface definition for a callback to be invoked when the preference is clicked. + */ + public interface OnClickListener { + /** + * Called when a preference has been clicked. + * + * @param emiter The clicked preference + */ + void onRadioButtonClicked(SelectorWithWidgetPreference emiter); + } + + private OnClickListener mListener = null; + private View mAppendix; + private int mAppendixVisibility = -1; + + private View mExtraWidgetContainer; + private ImageView mExtraWidget; + private boolean mIsCheckBox = false; // whether to display this button as a checkbox + + private View.OnClickListener mExtraWidgetOnClickListener; + + /** + * Perform inflation from XML and apply a class-specific base style. + * + * @param context The {@link Context} this is associated with, through which it can + * access the current theme, resources, etc. + * @param attrs The attributes of the XML tag that is inflating the preference + * @param defStyle An attribute in the current theme that contains a reference to a style + * resource that supplies default values for the view. Can be 0 to not + * look for defaults. + */ + public SelectorWithWidgetPreference(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + init(); + } + + /** + * Perform inflation from XML and apply a class-specific base style. + * + * @param context The {@link Context} this is associated with, through which it can + * access the current theme, resources, etc. + * @param attrs The attributes of the XML tag that is inflating the preference + */ + public SelectorWithWidgetPreference(Context context, AttributeSet attrs) { + super(context, attrs); + init(); + } + + /** + * Constructor to create a preference, which will display with a checkbox style. + * + * @param context The {@link Context} this is associated with. + * @param isCheckbox Whether this preference should display as a checkbox. + */ + public SelectorWithWidgetPreference(Context context, boolean isCheckbox) { + super(context, null); + mIsCheckBox = isCheckbox; + init(); + } + + /** + * Constructor to create a preference. + * + * @param context The Context this is associated with. + */ + public SelectorWithWidgetPreference(Context context) { + this(context, null); + } + + /** + * Sets the callback to be invoked when this preference is clicked by the user. + * + * @param listener The callback to be invoked + */ + public void setOnClickListener(OnClickListener listener) { + mListener = listener; + } + + /** + * Processes a click on the preference. + */ + @Override + public void onClick() { + if (mListener != null) { + mListener.onRadioButtonClicked(this); + } + } + + /** + * Binds the created View to the data for this preference. + * + *

This is a good place to grab references to custom Views in the layout and set + * properties on them. + * + *

Make sure to call through to the superclass's implementation. + * + * @param holder The ViewHolder that provides references to the views to fill in. These views + * will be recycled, so you should not hold a reference to them after this method + * returns. + */ + @SuppressLint("WrongConstant") + @Override + public void onBindViewHolder(@NonNull PreferenceViewHolder holder) { + super.onBindViewHolder(holder); + + View summaryContainer = holder.findViewById(R.id.summary_container); + if (summaryContainer != null) { + summaryContainer.setVisibility( + TextUtils.isEmpty(getSummary()) ? View.GONE : View.VISIBLE); + mAppendix = holder.findViewById(R.id.appendix); + if (mAppendix != null && mAppendixVisibility != -1) { + mAppendix.setVisibility(mAppendixVisibility); + } + } + + mExtraWidget = (ImageView) holder.findViewById(R.id.selector_extra_widget); + mExtraWidgetContainer = holder.findViewById(R.id.selector_extra_widget_container); + + setExtraWidgetOnClickListener(mExtraWidgetOnClickListener); + } + + /** + * Set the visibility state of appendix view. + * + * @param visibility One of {@link View#VISIBLE}, {@link View#INVISIBLE}, or {@link View#GONE}. + */ + public void setAppendixVisibility(int visibility) { + if (mAppendix != null) { + mAppendix.setVisibility(visibility); + } + mAppendixVisibility = visibility; + } + + /** + * Sets the callback to be invoked when extra widget is clicked by the user. + * + * @param listener The callback to be invoked + */ + public void setExtraWidgetOnClickListener(View.OnClickListener listener) { + mExtraWidgetOnClickListener = listener; + + if (mExtraWidget == null || mExtraWidgetContainer == null) { + return; + } + + mExtraWidget.setOnClickListener(mExtraWidgetOnClickListener); + + mExtraWidgetContainer.setVisibility((mExtraWidgetOnClickListener != null) + ? View.VISIBLE : View.GONE); + } + + /** + * Returns whether this preference is a checkbox. + */ + public boolean isCheckBox() { + return mIsCheckBox; + } + + private void init() { + if (mIsCheckBox) { + setWidgetLayoutResource(R.layout.preference_widget_checkbox); + } else { + setWidgetLayoutResource(R.layout.preference_widget_radiobutton); + } + setLayoutResource(R.layout.preference_selector_with_widget); + setIconSpaceReserved(false); + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/ui/preferences/SliderPreference.java b/app/src/main/java/com/drdisagree/iconify/ui/preferences/SliderPreference.java new file mode 100644 index 000000000..cebbff3e6 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/preferences/SliderPreference.java @@ -0,0 +1,343 @@ +package com.drdisagree.iconify.ui.preferences; + +/* + * From Siavash79/rangesliderpreference + * https://github.com/siavash79/rangesliderpreference + */ + +import android.content.Context; +import android.content.SharedPreferences; +import android.content.res.TypedArray; +import android.text.TextUtils; +import android.util.AttributeSet; +import android.util.JsonReader; +import android.util.JsonWriter; +import android.util.Log; +import android.view.View; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; +import androidx.preference.Preference; +import androidx.preference.PreferenceViewHolder; + +import com.drdisagree.iconify.utils.HapticUtils; +import com.google.android.material.button.MaterialButton; +import com.google.android.material.slider.LabelFormatter; +import com.google.android.material.slider.RangeSlider; + +import java.io.StringReader; +import java.io.StringWriter; +import java.math.BigDecimal; +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Locale; +import java.util.Objects; +import java.util.Scanner; + +import com.drdisagree.iconify.R; + +public class SliderPreference extends Preference { + + private static final String TAG = SliderPreference.class.getSimpleName(); + private float valueFrom; + private float valueTo; + private final float tickInterval; + private final boolean showResetButton; + public final List defaultValue = new ArrayList<>(); + public RangeSlider slider; + private MaterialButton mResetButton; + @SuppressWarnings("unused") + private TextView sliderValue; + int valueCount; + private String valueFormat; + private final float outputScale; + private final boolean isDecimalFormat; + private String decimalFormat = "#.#"; + + boolean updateConstantly, showValueLabel; + + @SuppressWarnings("unused") + public SliderPreference(Context context, AttributeSet attrs) { + this(context, attrs, 0); + setSelectable(false); + } + + public SliderPreference(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + setSelectable(false); + setLayoutResource(R.layout.custom_preference_slider); + + TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SliderPreference); + updateConstantly = a.getBoolean(R.styleable.SliderPreference_updatesContinuously, false); + valueCount = a.getInteger(R.styleable.SliderPreference_valueCount, 1); + valueFrom = a.getFloat(R.styleable.SliderPreference_minVal, 0f); + valueTo = a.getFloat(R.styleable.SliderPreference_maxVal, 100f); + tickInterval = a.getFloat(R.styleable.SliderPreference_tickInterval, 1f); + showResetButton = a.getBoolean(R.styleable.SliderPreference_showResetButton, false); + showValueLabel = a.getBoolean(R.styleable.SliderPreference_showValueLabel, true); + valueFormat = a.getString(R.styleable.SliderPreference_valueFormat); + isDecimalFormat = a.getBoolean(R.styleable.SliderPreference_isDecimalFormat, false); + if (a.hasValue(R.styleable.SliderPreference_decimalFormat)) { + decimalFormat = a.getString(R.styleable.SliderPreference_decimalFormat); + } else { + decimalFormat = "#.#"; // Default decimal format + } + outputScale = a.getFloat(R.styleable.SliderPreference_outputScale, 1f); + String defaultValStr = a.getString(androidx.preference.R.styleable.Preference_defaultValue); + + if (valueFormat == null) valueFormat = ""; + + try { + Scanner scanner = new Scanner(defaultValStr); + scanner.useDelimiter(","); + scanner.useLocale(Locale.ENGLISH); + + while (scanner.hasNext()) { + defaultValue.add(scanner.nextFloat()); + } + } catch (Exception ignored) { + Log.e(TAG, String.format("SliderPreference: Error parsing default values for key: %s", getKey())); + } + + a.recycle(); + } + + public void savePrefs() { + setValues(getSharedPreferences(), getKey(), slider.getValues()); + } + + @SuppressWarnings("UnusedReturnValue") + public static boolean setValues(SharedPreferences sharedPreferences, String key, List values) { + try { + StringWriter writer = new StringWriter(); + JsonWriter jsonWriter = new JsonWriter(writer); + jsonWriter.beginObject(); + jsonWriter.name(""); + jsonWriter.beginArray(); + + for (float value : values) { + jsonWriter.value(value); + } + jsonWriter.endArray(); + jsonWriter.endObject(); + jsonWriter.close(); + String jsonString = writer.toString(); + + sharedPreferences.edit().putString(key, jsonString).apply(); + + return true; + + } catch (Exception ignored) { + return false; + } + } + + public void syncState() { + boolean needsCommit = false; + + List values = getValues(getSharedPreferences(), getKey(), valueFrom); + BigDecimal step = new BigDecimal(String.valueOf(slider.getStepSize())); //float and double are not accurate when it comes to decimal points + + for (int i = 0; i < values.size(); i++) { + BigDecimal round = new BigDecimal(Math.round(values.get(i) / slider.getStepSize())); + double v = Math.min(Math.max(step.multiply(round).doubleValue(), slider.getValueFrom()), slider.getValueTo()); + if (v != values.get(i)) { + values.set(i, (float) v); + needsCommit = true; + } + } + if (values.size() < valueCount) { + needsCommit = true; + values = defaultValue; + while (values.size() < valueCount) { + values.add(valueFrom); + } + } else if (values.size() > valueCount) { + needsCommit = true; + while (values.size() > valueCount) { + values.remove(values.size() - 1); + } + } + + try { + slider.setValues(values); + if (needsCommit) savePrefs(); + } catch (Throwable t) { + values.clear(); + } + } + + RangeSlider.OnChangeListener changeListener = (slider, value, fromUser) -> { + if (!getKey().equals(slider.getTag())) return; + + if (updateConstantly && fromUser) { + savePrefs(); + } + }; + + RangeSlider.OnSliderTouchListener sliderTouchListener = new RangeSlider.OnSliderTouchListener() { + @Override + public void onStartTrackingTouch(@NonNull RangeSlider slider) { + slider.setLabelFormatter(labelFormatter); + } + + @Override + public void onStopTrackingTouch(@NonNull RangeSlider slider) { + if (!getKey().equals(slider.getTag())) return; + + handleResetButton(); + + if (!updateConstantly) { + savePrefs(); + } + } + }; + + LabelFormatter labelFormatter = new LabelFormatter() { + @NonNull + @Override + public String getFormattedValue(float value) { + String result; + if (valueFormat != null && (valueFormat.isBlank() || valueFormat.isEmpty())) { + result = !isDecimalFormat + ? Integer.toString((int) (slider.getValues().get(0) / outputScale)) + : new DecimalFormat(decimalFormat).format(slider.getValues().get(0) / outputScale); + } else { + result = !isDecimalFormat + ? Integer.toString((int) (slider.getValues().get(0) / 1f)) + : new DecimalFormat(decimalFormat).format(slider.getValues().get(0) / outputScale); + } + result += valueFormat; + + return result; + } + }; + + @Override + public void onBindViewHolder(@NonNull PreferenceViewHolder holder) { + super.onBindViewHolder(holder); + + if (isEnabled()) { + TextView title = holder.itemView.findViewById(android.R.id.title); + title.setTextColor(ContextCompat.getColor(getContext(), R.color.textColorPrimary)); + } + + slider = holder.itemView.findViewById(R.id.slider); + slider.setTag(getKey()); + + slider.addOnSliderTouchListener(sliderTouchListener); + slider.addOnChangeListener(changeListener); + + slider.setLabelFormatter(labelFormatter); + + mResetButton = holder.itemView.findViewById(R.id.reset_button); + if (showResetButton) { + mResetButton.setVisibility(View.VISIBLE); + mResetButton.setOnClickListener(v -> { + handleResetButton(); + HapticUtils.weakVibrate(v); + + slider.setValues(defaultValue); + savePrefs(); + }); + } else { + mResetButton.setVisibility(View.GONE); + } + + sliderValue = holder.itemView.findViewById(androidx.preference.R.id.seekbar_value); + + slider.setValueFrom(valueFrom); + slider.setValueTo(valueTo); + slider.setStepSize(tickInterval); + + syncState(); + + handleResetButton(); + } + + public void setMin(float value) { + valueFrom = value; + if (slider != null) slider.setValueFrom(value); + } + + public void setMax(float value) { + valueTo = value; + if (slider != null) slider.setValueTo(value); + } + + public static List getValues(SharedPreferences prefs, String key, float defaultValue) { + List values; + + try { + String JSONString = prefs.getString(key, ""); + values = getValues(JSONString); + } catch (Exception ignored) { + try { + float value = prefs.getFloat(key, defaultValue); + values = Collections.singletonList(value); + } catch (Exception ignored2) { + try { + int value = prefs.getInt(key, Math.round(defaultValue)); + values = Collections.singletonList((float) value); + } catch (Exception ignored3) { + values = Collections.singletonList(defaultValue); + } + } + } + return values; + } + + public static List getValues(String JSONString) throws Exception { + List values = new ArrayList<>(); + + if (JSONString.trim().isEmpty()) return values; + + JsonReader jsonReader = new JsonReader(new StringReader(JSONString)); + + jsonReader.beginObject(); + try { + jsonReader.nextName(); + jsonReader.beginArray(); + } catch (Exception ignored) { + } + + while (jsonReader.hasNext()) { + try { + jsonReader.nextName(); + } catch (Exception ignored) { + } + values.add((float) jsonReader.nextDouble()); + } + + return values; + } + + private void handleResetButton() { + if (mResetButton == null) return; + + if (showResetButton) { + mResetButton.setVisibility(View.VISIBLE); + mResetButton.setEnabled(isEnabled() && !Objects.equals(slider.getValues().get(0), defaultValue.get(0))); + } else { + mResetButton.setVisibility(View.GONE); + } + } + + public static float getSingleFloatValue(SharedPreferences prefs, String key, float defaultValue) { + float result = defaultValue; + + try { + result = getValues(prefs, key, defaultValue).get(0); + } catch (Throwable ignored) { + } + + return result; + } + + public static int getSingleIntValue(SharedPreferences prefs, String key, int defaultValue) { + return Math.round(getSingleFloatValue(prefs, key, defaultValue)); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/ui/preferences/SwitchPreference.kt b/app/src/main/java/com/drdisagree/iconify/ui/preferences/SwitchPreference.kt new file mode 100644 index 000000000..9121bb20e --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/preferences/SwitchPreference.kt @@ -0,0 +1,39 @@ +package com.drdisagree.iconify.ui.preferences + +import android.content.Context +import android.util.AttributeSet +import androidx.preference.SwitchPreferenceCompat +import com.drdisagree.iconify.R + +class SwitchPreference : SwitchPreferenceCompat { + + constructor( + context: Context, + attrs: AttributeSet?, + defStyleAttr: Int, + defStyleRes: Int + ) : super(context, attrs, defStyleAttr, defStyleRes) { + initResource() + } + + constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super( + context, + attrs, + defStyleAttr + ) { + initResource() + } + + constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) { + initResource() + } + + constructor(context: Context) : super(context) { + initResource() + } + + private fun initResource() { + layoutResource = R.layout.custom_preference_switch + widgetLayoutResource = R.layout.preference_material_switch + } +} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/ui/preferences/TimePickerPreference.java b/app/src/main/java/com/drdisagree/iconify/ui/preferences/TimePickerPreference.java new file mode 100644 index 000000000..877c34f7f --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/preferences/TimePickerPreference.java @@ -0,0 +1,113 @@ +package com.drdisagree.iconify.ui.preferences; + +/* + * Modified from https://github.com/etidoUP/Material-Time-picker-preference- + * Credits: etidoUP + */ + +import android.content.Context; +import android.content.res.TypedArray; +import android.text.format.DateFormat; +import android.util.AttributeSet; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; +import androidx.preference.Preference; +import androidx.preference.PreferenceViewHolder; + +import com.google.android.material.timepicker.MaterialTimePicker; +import com.google.android.material.timepicker.TimeFormat; + +import java.util.Locale; +import java.util.concurrent.atomic.AtomicInteger; + +import com.drdisagree.iconify.R; + +public class TimePickerPreference extends Preference { + + private String timeValue = "00:00"; + + public TimePickerPreference(Context context) { + super(context); + } + + public TimePickerPreference(Context context, AttributeSet attrs) { + super(context, attrs); + init(context, attrs); + } + + public TimePickerPreference(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + init(context, attrs); + } + + private void init(Context context, AttributeSet attrs) { + setLayoutResource(R.layout.custom_preference_time_picker); + if (attrs != null) { + TypedArray a = + context.getTheme().obtainStyledAttributes(attrs, R.styleable.MaterialTimePickerPreference, 0, 0); + try { + timeValue = a.getString(R.styleable.MaterialTimePickerPreference_presetValue); + } catch (Exception e) { + timeValue = "00:00"; + } finally { + a.recycle(); + } + } + } + + @Override + public void onBindViewHolder(@NonNull PreferenceViewHolder holder) { + super.onBindViewHolder(holder); + TextView timeTextView = (TextView) holder.findViewById(R.id.time_stamp); + timeTextView.setText(timeValue); + } + + @Override + protected void onClick() { + super.onClick(); + + // parse hour and minute from timeValue + AtomicInteger hour = new AtomicInteger(Integer.parseInt(timeValue.split(":")[0])); + AtomicInteger minute = new AtomicInteger(Integer.parseInt(timeValue.split(":")[1])); + + MaterialTimePicker timePicker = + new MaterialTimePicker.Builder().setTimeFormat(DateFormat.is24HourFormat(getContext()) ? TimeFormat.CLOCK_24H : TimeFormat.CLOCK_12H).setHour(hour.get()).setMinute(minute.get()).build(); + + timePicker.addOnPositiveButtonClickListener( + v -> { + hour.set(timePicker.getHour()); + minute.set(timePicker.getMinute()); + String selectedTime = String.format(Locale.getDefault(), "%02d:%02d", hour.get(), minute.get()); + + timeValue = selectedTime; + persistString(selectedTime); + + notifyChanged(); + }); + + timePicker.show(((AppCompatActivity) getContext()).getSupportFragmentManager(), "timePicker"); + } + + @Override + protected Object onGetDefaultValue(TypedArray a, int index) { + return a.getString(index); + } + + @Override + protected void onSetInitialValue(Object defaultValue) { + timeValue = getPersistedString((String) defaultValue); + persistString(timeValue); + } + + public String getTimeValue() { + return this.timeValue; + } + + public void setTimeValue(String timeValue) { + this.timeValue = timeValue; + persistString(timeValue); + notifyChanged(); + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/ui/preferences/UpdateCheckerPreference.kt b/app/src/main/java/com/drdisagree/iconify/ui/preferences/UpdateCheckerPreference.kt new file mode 100644 index 000000000..8c5b3412d --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/preferences/UpdateCheckerPreference.kt @@ -0,0 +1,146 @@ +package com.drdisagree.iconify.ui.preferences + +import android.content.Context +import android.util.AttributeSet +import android.view.View +import android.widget.TextView +import androidx.preference.Preference +import androidx.preference.PreferenceViewHolder +import com.drdisagree.iconify.BuildConfig +import com.drdisagree.iconify.R +import com.drdisagree.iconify.common.Const.LATEST_VERSION_URL +import com.drdisagree.iconify.common.Preferences.AUTO_UPDATE +import com.drdisagree.iconify.common.Preferences.LAST_UPDATE_CHECK_TIME +import com.drdisagree.iconify.common.Preferences.NEW_UPDATE_FOUND +import com.drdisagree.iconify.common.Preferences.NEW_UPDATE_VERSION_CODE +import com.drdisagree.iconify.common.Preferences.UPDATE_CHECK_TIME +import com.drdisagree.iconify.common.Preferences.VER_CODE +import com.drdisagree.iconify.config.RPrefs.getBoolean +import com.drdisagree.iconify.config.RPrefs.getLong +import com.drdisagree.iconify.config.RPrefs.getString +import com.drdisagree.iconify.config.RPrefs.putBoolean +import com.drdisagree.iconify.config.RPrefs.putLong +import com.drdisagree.iconify.config.RPrefs.putString +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.cancel +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import org.json.JSONObject +import java.io.BufferedReader +import java.io.InputStreamReader +import java.net.HttpURLConnection +import java.net.URL + +class UpdateCheckerPreference(context: Context, attrs: AttributeSet?) : Preference(context, attrs) { + + private val scope = CoroutineScope(Dispatchers.Main + SupervisorJob()) + private var mView: View? = null + + override fun onBindViewHolder(holder: PreferenceViewHolder) { + super.onBindViewHolder(holder) + + mView = holder.itemView + + if (newUpdateVersionCode != BuildConfig.VERSION_CODE.toString()) { + mView?.findViewById(R.id.update_desc)?.text = context.getString( + R.string.update_dialog_desc, + newUpdateVersionCode + ) + } + } + + fun checkForUpdate() { + if (shouldCheckForUpdate()) { + putLong(LAST_UPDATE_CHECK_TIME, System.currentTimeMillis()) + + scope.launch { + val result = fetchLatestVersion() + + if (result != null) { + handleUpdateResult(result) + } + } + } else { + if (getString(NEW_UPDATE_VERSION_CODE, null) == null || getString( + NEW_UPDATE_VERSION_CODE, + BuildConfig.VERSION_CODE.toString() + )!!.toInt() <= BuildConfig.VERSION_CODE + ) { + putString(NEW_UPDATE_VERSION_CODE, BuildConfig.VERSION_CODE.toString()) + putBoolean(NEW_UPDATE_FOUND, false) + } + } + } + + private fun shouldCheckForUpdate(): Boolean { + val lastChecked = getLong(LAST_UPDATE_CHECK_TIME, -1) + + return getBoolean(AUTO_UPDATE, true) && (lastChecked == -1L || + (System.currentTimeMillis() - lastChecked >= getLong(UPDATE_CHECK_TIME, 0))) + } + + private suspend fun fetchLatestVersion(): String? = withContext(Dispatchers.IO) { + var urlConnection: HttpURLConnection? = null + var bufferedReader: BufferedReader? = null + + return@withContext try { + val url = URL(LATEST_VERSION_URL) + urlConnection = url.openConnection() as HttpURLConnection + urlConnection.connect() + + val inputStream = urlConnection.inputStream + bufferedReader = BufferedReader(InputStreamReader(inputStream)) + + val stringBuffer = StringBuilder() + var line: String? + + while (bufferedReader.readLine().also { line = it } != null) { + stringBuffer.append(line).append("\n") + } + + if (stringBuffer.isEmpty()) { + null + } else { + stringBuffer.toString() + } + } catch (e: Exception) { + null + } finally { + urlConnection?.disconnect() + bufferedReader?.close() + } + } + + private fun handleUpdateResult(result: String) { + try { + val latestVersion = JSONObject(result) + + if (latestVersion.getString(VER_CODE).toInt() > BuildConfig.VERSION_CODE) { + newUpdateVersionCode = latestVersion.getString("versionName") + + mView?.findViewById(R.id.update_desc)?.text = context.getString( + R.string.update_dialog_desc, + newUpdateVersionCode + ) + + putString(NEW_UPDATE_VERSION_CODE, newUpdateVersionCode) + putBoolean(NEW_UPDATE_FOUND, true) + } else { + putString(NEW_UPDATE_VERSION_CODE, BuildConfig.VERSION_CODE.toString()) + putBoolean(NEW_UPDATE_FOUND, false) + } + } catch (_: Exception) { + } + } + + override fun onDetached() { + scope.cancel() + super.onDetached() + } + + companion object { + private var newUpdateVersionCode = BuildConfig.VERSION_CODE.toString() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/ui/preferences/preferencesearch/AnimationUtils.java b/app/src/main/java/com/drdisagree/iconify/ui/preferences/preferencesearch/AnimationUtils.java new file mode 100644 index 000000000..9442bcdcb --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/preferences/preferencesearch/AnimationUtils.java @@ -0,0 +1,89 @@ +package com.drdisagree.iconify.ui.preferences.preferencesearch; + +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.ArgbEvaluator; +import android.animation.ValueAnimator; +import android.content.Context; +import android.graphics.Color; +import android.graphics.drawable.ColorDrawable; +import android.graphics.drawable.Drawable; +import android.view.View; +import android.view.ViewAnimationUtils; + +import androidx.interpolator.view.animation.FastOutSlowInInterpolator; + +public class AnimationUtils { + public static void registerCircularRevealAnimation(final Context context, final View view, final RevealAnimationSetting revealSettings) { + final int startColor = revealSettings.getColorAccent(); + final int endColor = getBackgroundColor(view); + + view.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { + @Override + public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { + v.removeOnLayoutChangeListener(this); + view.setVisibility(View.VISIBLE); + int cx = revealSettings.getCenterX(); + int cy = revealSettings.getCenterY(); + int width = revealSettings.getWidth(); + int height = revealSettings.getHeight(); + int duration = context.getResources().getInteger(android.R.integer.config_longAnimTime); + + //Simply use the diagonal of the view + float finalRadius = (float) Math.sqrt(width * width + height * height); + Animator anim = ViewAnimationUtils.createCircularReveal(v, cx, cy, 0, finalRadius).setDuration(duration); + anim.setInterpolator(new FastOutSlowInInterpolator()); + anim.start(); + startColorAnimation(view, startColor, endColor, duration); + } + }); + } + + private static void startColorAnimation(final View view, final int startColor, final int endColor, int duration) { + ValueAnimator anim = new ValueAnimator(); + anim.setIntValues(startColor, endColor); + anim.setEvaluator(new ArgbEvaluator()); + anim.addUpdateListener(valueAnimator -> view.setBackgroundColor((Integer) valueAnimator.getAnimatedValue())); + anim.setDuration(duration); + anim.start(); + } + + @SuppressWarnings("unused") + public static void startCircularExitAnimation(final Context context, final View view, final RevealAnimationSetting revealSettings, final OnDismissedListener listener) { + final int startColor = getBackgroundColor(view); + final int endColor = revealSettings.getColorAccent(); + + int cx = revealSettings.getCenterX(); + int cy = revealSettings.getCenterY(); + int width = revealSettings.getWidth(); + int height = revealSettings.getHeight(); + int duration = context.getResources().getInteger(android.R.integer.config_longAnimTime); + + float initRadius = (float) Math.sqrt(width * width + height * height); + Animator anim = ViewAnimationUtils.createCircularReveal(view, cx, cy, initRadius, 0); + anim.setDuration(duration); + anim.setInterpolator(new FastOutSlowInInterpolator()); + anim.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + view.setVisibility(View.INVISIBLE); + listener.onDismissed(); + } + }); + anim.start(); + startColorAnimation(view, startColor, endColor, duration); + } + + private static int getBackgroundColor(View view) { + int color = Color.TRANSPARENT; + Drawable background = view.getBackground(); + if (background instanceof ColorDrawable) { + color = ((ColorDrawable) background).getColor(); + } + return color; + } + + public interface OnDismissedListener { + void onDismissed(); + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/ui/preferences/preferencesearch/Breadcrumb.java b/app/src/main/java/com/drdisagree/iconify/ui/preferences/preferencesearch/Breadcrumb.java new file mode 100644 index 000000000..4a6e56601 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/preferences/preferencesearch/Breadcrumb.java @@ -0,0 +1,25 @@ +package com.drdisagree.iconify.ui.preferences.preferencesearch; + +import android.text.TextUtils; + +import androidx.annotation.Nullable; + +class Breadcrumb { + private Breadcrumb() { + + } + + /** + * Joins two breadcrumbs + * + * @param s1 First breadcrumb, might be null + * @param s2 Second breadcrumb + * @return Both breadcrumbs joined + */ + static String concat(@Nullable String s1, String s2) { + if (TextUtils.isEmpty(s1)) { + return s2; + } + return s1 + " > " + s2; + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/ui/preferences/preferencesearch/HistoryItem.java b/app/src/main/java/com/drdisagree/iconify/ui/preferences/preferencesearch/HistoryItem.java new file mode 100644 index 000000000..ac192a6a2 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/preferences/preferencesearch/HistoryItem.java @@ -0,0 +1,28 @@ +package com.drdisagree.iconify.ui.preferences.preferencesearch; + +class HistoryItem extends ListItem { + static final int TYPE = 1; + private final String term; + + HistoryItem(String term) { + super(); + this.term = term; + } + + @Override + public int getType() { + return TYPE; + } + + String getTerm() { + return term; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof HistoryItem) { + return ((HistoryItem) obj).term.equals(term); + } + return false; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/ui/preferences/preferencesearch/ListItem.java b/app/src/main/java/com/drdisagree/iconify/ui/preferences/preferencesearch/ListItem.java new file mode 100644 index 000000000..7e142bef8 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/preferences/preferencesearch/ListItem.java @@ -0,0 +1,5 @@ +package com.drdisagree.iconify.ui.preferences.preferencesearch; + +public abstract class ListItem { + public abstract int getType(); +} diff --git a/app/src/main/java/com/drdisagree/iconify/ui/preferences/preferencesearch/PreferenceItem.java b/app/src/main/java/com/drdisagree/iconify/ui/preferences/preferencesearch/PreferenceItem.java new file mode 100644 index 000000000..58b690ba0 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/preferences/preferencesearch/PreferenceItem.java @@ -0,0 +1,175 @@ +package com.drdisagree.iconify.ui.preferences.preferencesearch; + +import android.annotation.SuppressLint; +import android.os.Parcel; +import android.os.Parcelable; +import android.text.TextUtils; + +import androidx.annotation.NonNull; +import androidx.annotation.XmlRes; + +import org.apache.commons.text.similarity.FuzzyScore; + +import java.util.ArrayList; +import java.util.Locale; + +public class PreferenceItem extends ListItem implements Parcelable { + public static final Creator CREATOR = new Creator<>() { + @Override + public PreferenceItem createFromParcel(Parcel in) { + return new PreferenceItem(in); + } + + @Override + public PreferenceItem[] newArray(int size) { + return new PreferenceItem[size]; + } + }; + static final int TYPE = 2; + @SuppressLint("ConstantLocale") + private static final FuzzyScore fuzzyScore = new FuzzyScore(Locale.getDefault()); + String title; + String summary; + String key; + String entries; + String breadcrumbs; + String keywords; + ArrayList keyBreadcrumbs = new ArrayList<>(); + int resId; + private float lastScore = 0; + private String lastKeyword = null; + + PreferenceItem() { + } + + private PreferenceItem(Parcel in) { + this.title = in.readString(); + this.summary = in.readString(); + this.key = in.readString(); + this.breadcrumbs = in.readString(); + this.keywords = in.readString(); + this.resId = in.readInt(); + } + + boolean hasData() { + return title != null || summary != null; + } + + boolean matchesFuzzy(String keyword) { + return getScore(keyword) > 0.3; + } + + boolean matches(String keyword) { + Locale locale = Locale.getDefault(); + return getInfo().toLowerCase(locale).contains(keyword.toLowerCase(locale)); + } + + float getScore(String keyword) { + if (TextUtils.isEmpty(keyword)) { + return 0; + } else if (TextUtils.equals(lastKeyword, keyword)) { + return lastScore; + } + String info = getInfo(); + + float score = fuzzyScore.fuzzyScore(info, "ø" + keyword); + float maxScore = (keyword.length() + 1) * 3 - 2; // First item can not get +2 bonus score + + lastScore = score / maxScore; + lastKeyword = keyword; + return lastScore; + } + + private String getInfo() { + StringBuilder infoBuilder = new StringBuilder(); + if (!TextUtils.isEmpty(title)) { + infoBuilder.append("ø").append(title); + } + if (!TextUtils.isEmpty(summary)) { + infoBuilder.append("ø").append(summary); + } + if (!TextUtils.isEmpty(entries)) { + infoBuilder.append("ø").append(entries); + } + if (!TextUtils.isEmpty(breadcrumbs)) { + infoBuilder.append("ø").append(breadcrumbs); + } + if (!TextUtils.isEmpty(keywords)) { + infoBuilder.append("ø").append(keywords); + } + return infoBuilder.toString(); + } + + @SuppressWarnings("unused") + public PreferenceItem withKey(String key) { + this.key = key; + return this; + } + + @SuppressWarnings("unused") + public PreferenceItem withSummary(String summary) { + this.summary = summary; + return this; + } + + @SuppressWarnings("unused") + public PreferenceItem withTitle(String title) { + this.title = title; + return this; + } + + @SuppressWarnings("unused") + public PreferenceItem withEntries(String entries) { + this.entries = entries; + return this; + } + + @SuppressWarnings("unused") + public PreferenceItem withKeywords(String keywords) { + this.keywords = keywords; + return this; + } + + @SuppressWarnings("unused") + public PreferenceItem withResId(@XmlRes Integer resId) { + this.resId = resId; + return this; + } + + /** + * @param breadcrumb The breadcrumb to add + * @return For chaining + */ + @SuppressWarnings("unused") + public PreferenceItem addBreadcrumb(String breadcrumb) { + this.breadcrumbs = Breadcrumb.concat(this.breadcrumbs, breadcrumb); + return this; + } + + @NonNull + @Override + public String toString() { + return "PreferenceItem: " + title + " " + summary + " " + key; + } + + @Override + public int getType() { + return TYPE; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel parcel, int i) { + parcel.writeString(title); + parcel.writeString(summary); + parcel.writeString(key); + parcel.writeString(breadcrumbs); + parcel.writeString(keywords); + parcel.writeInt(resId); + } + +} diff --git a/app/src/main/java/com/drdisagree/iconify/ui/preferences/preferencesearch/PreferenceParser.kt b/app/src/main/java/com/drdisagree/iconify/ui/preferences/preferencesearch/PreferenceParser.kt new file mode 100644 index 000000000..96f24c345 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/preferences/preferencesearch/PreferenceParser.kt @@ -0,0 +1,227 @@ +package com.drdisagree.iconify.ui.preferences.preferencesearch + +import android.content.Context +import android.text.TextUtils +import com.drdisagree.iconify.config.PrefsHelper.isVisible +import com.drdisagree.iconify.ui.preferences.preferencesearch.SearchConfiguration.SearchIndexItem +import org.xmlpull.v1.XmlPullParser + +internal class PreferenceParser(private val mContext: Context) { + + private val allEntries = ArrayList() + + fun addResourceFile(item: SearchIndexItem) { + allEntries.addAll(parseFile(item)) + } + + fun addPreferenceItems(preferenceItems: ArrayList) { + preferenceItems.removeIf { item: PreferenceItem -> !isVisible(item.key) } + allEntries.addAll(preferenceItems) + } + + private fun parseFile(item: SearchIndexItem): ArrayList { + val results = ArrayList() + val xpp: XmlPullParser = mContext.resources.getXml(item.resId) + val bannedKeys: MutableList = item.searchConfiguration.bannedKeys + + try { + xpp.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true) + xpp.setFeature(XmlPullParser.FEATURE_REPORT_NAMESPACE_ATTRIBUTES, true) + val breadcrumbs = ArrayList() + val keyBreadcrumbs = ArrayList() + if (!TextUtils.isEmpty(item.breadcrumb)) { + breadcrumbs.add(item.breadcrumb) + } + while (xpp.eventType != XmlPullParser.END_DOCUMENT) { + if (xpp.eventType == XmlPullParser.START_TAG) { + val result = parseSearchResult(xpp) + result.resId = item.resId + + try { + if (!isSearchable(result)) { + if (!bannedKeys.contains(result.key)) bannedKeys.add(result.key) + } else bannedKeys.remove(result.key) + } catch (ignored: Exception) { + } + + if (!BLACKLIST.contains(xpp.name) + && result.hasData() + && "true" != getAttribute(xpp, NS_SEARCH, "ignore") && !bannedKeys.contains( + result.key + ) + && shouldAddPreferenceItem(results, result) + ) { + result.breadcrumbs = joinBreadcrumbs(breadcrumbs) + result.keyBreadcrumbs = cleanupKeyBreadcrumbs(keyBreadcrumbs) + if (!results.contains(result)) { + results.add(result) + } + } + if (CONTAINERS.contains(xpp.name)) { + breadcrumbs.add(if (result.title == null) "" else result.title) + } + if (xpp.name == "PreferenceScreen") { + keyBreadcrumbs.add(getAttribute(xpp, "key")) + } + } else if (xpp.eventType == XmlPullParser.END_TAG && CONTAINERS.contains(xpp.name)) { + breadcrumbs.removeAt(breadcrumbs.size - 1) + if (xpp.name == "PreferenceScreen") { + keyBreadcrumbs.removeAt(keyBreadcrumbs.size - 1) + } + } + + xpp.next() + } + } catch (e: Exception) { + e.printStackTrace() + } + return results + } + + private fun isSearchable(result: PreferenceItem): Boolean { + if (TextUtils.isEmpty(result.key)) return false + return isVisible(result.key) + } + + private fun shouldAddPreferenceItem( + results: ArrayList, + result: PreferenceItem + ): Boolean { + var isAlreadyAdded = false + for (item in results) { + if (item.key == result.key && item.resId == result.resId) { + isAlreadyAdded = true + break + } + } + return !isAlreadyAdded + } + + private fun cleanupKeyBreadcrumbs(keyBreadcrumbs: ArrayList): ArrayList { + val result = ArrayList() + for (keyBreadcrumb in keyBreadcrumbs) { + if (keyBreadcrumb != null) { + result.add(keyBreadcrumb) + } + } + return result + } + + private fun joinBreadcrumbs(breadcrumbs: ArrayList): String? { + var result: String? = "" + for (crumb in breadcrumbs) { + if (!TextUtils.isEmpty(crumb)) { + result = Breadcrumb.concat(result, crumb) + } + } + return result + } + + private fun getAttribute(xpp: XmlPullParser, namespace: String?, attribute: String): String? { + for (i in 0 until xpp.attributeCount) { + if (attribute == xpp.getAttributeName(i) && + (namespace == null || namespace == xpp.getAttributeNamespace(i)) + ) { + return xpp.getAttributeValue(i) + } + } + return null + } + + private fun getAttribute(xpp: XmlPullParser, attribute: String): String? { + return if (hasAttribute(xpp, NS_SEARCH, attribute)) { + getAttribute(xpp, NS_SEARCH, attribute) + } else { + getAttribute(xpp, NS_ANDROID, attribute) + } + } + + private fun hasAttribute(xpp: XmlPullParser, namespace: String?, attribute: String): Boolean { + return getAttribute(xpp, namespace, attribute) != null + } + + private fun parseSearchResult(xpp: XmlPullParser): PreferenceItem { + val result = PreferenceItem() + result.title = readString(getAttribute(xpp, "title")) + result.summary = readString(getAttribute(xpp, "summary")) + result.key = readString(getAttribute(xpp, "key")) + result.entries = readStringArray(getAttribute(xpp, "entries")) + result.keywords = readString(getAttribute(xpp, NS_SEARCH, "keywords")) + return result + } + + private fun readStringArray(s: String?): String? { + if (s == null) { + return null + } + if (s.startsWith("@")) { + try { + val id = s.substring(1).toInt() + val elements = mContext.resources.getStringArray(id) + return TextUtils.join(",", elements) + } catch (e: Exception) { + e.printStackTrace() + } + } + return s + } + + private fun readString(s: String?): String? { + if (s == null) { + return null + } + if (s.startsWith("@")) { + try { + val id = s.substring(1).toInt() + return mContext.getString(id) + } catch (e: Exception) { + e.printStackTrace() + } + } + return s + } + + fun searchFor(keyword: String?, fuzzy: Boolean): List { + if (TextUtils.isEmpty(keyword)) { + return ArrayList() + } + val results = ArrayList() + + for (item in allEntries) { + if ((fuzzy && item.matchesFuzzy(keyword)) + || (!fuzzy && item.matches(keyword)) + ) { + results.add(item) + } + } + + results.sortWith { i1: PreferenceItem, i2: PreferenceItem -> + floatCompare( + i2.getScore(keyword), + i1.getScore(keyword) + ) + } + + return if (results.size > MAX_RESULTS) { + results.subList(0, MAX_RESULTS) + } else { + results + } + } + + companion object { + private const val MAX_RESULTS = 10 + private const val NS_ANDROID = "http://schemas.android.com/apk/res/android" + private const val NS_SEARCH = + "http://schemas.android.com/apk/com.drdisagree.iconify.ui.preferences.preferencesearch" + private val BLACKLIST: List = listOf( + SearchPreference::class.java.name, "PreferenceCategory" + ) + private val CONTAINERS: List = + mutableListOf("PreferenceCategory", "PreferenceScreen") + + private fun floatCompare(x: Float, y: Float): Int { + return if ((x < y)) -1 else (if ((x == y)) 0 else 1) + } + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/ui/preferences/preferencesearch/RevealAnimationSetting.java b/app/src/main/java/com/drdisagree/iconify/ui/preferences/preferencesearch/RevealAnimationSetting.java new file mode 100644 index 000000000..7b2c8fc4c --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/preferences/preferencesearch/RevealAnimationSetting.java @@ -0,0 +1,73 @@ +package com.drdisagree.iconify.ui.preferences.preferencesearch; + +import android.os.Parcel; +import android.os.Parcelable; + +public class RevealAnimationSetting implements Parcelable { + public static final Creator CREATOR = new Creator<>() { + @Override + public RevealAnimationSetting createFromParcel(Parcel in) { + return new RevealAnimationSetting(in); + } + + @Override + public RevealAnimationSetting[] newArray(int size) { + return new RevealAnimationSetting[size]; + } + }; + private final int centerX; + private final int centerY; + private final int width; + private final int height; + private final int colorAccent; + + public RevealAnimationSetting(int centerX, int centerY, int width, int height, int colorAccent) { + this.centerX = centerX; + this.centerY = centerY; + this.width = width; + this.height = height; + this.colorAccent = colorAccent; + } + + private RevealAnimationSetting(Parcel in) { + centerX = in.readInt(); + centerY = in.readInt(); + width = in.readInt(); + height = in.readInt(); + colorAccent = in.readInt(); + } + + public int getCenterX() { + return centerX; + } + + public int getCenterY() { + return centerY; + } + + public int getWidth() { + return width; + } + + public int getHeight() { + return height; + } + + public int getColorAccent() { + return colorAccent; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(centerX); + dest.writeInt(centerY); + dest.writeInt(width); + dest.writeInt(height); + dest.writeInt(colorAccent); + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/ui/preferences/preferencesearch/SearchConfiguration.java b/app/src/main/java/com/drdisagree/iconify/ui/preferences/preferencesearch/SearchConfiguration.java new file mode 100644 index 000000000..00a0e7b0c --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/preferences/preferencesearch/SearchConfiguration.java @@ -0,0 +1,394 @@ +package com.drdisagree.iconify.ui.preferences.preferencesearch; + +import android.os.Bundle; +import android.os.Parcel; +import android.os.Parcelable; + +import androidx.annotation.ColorInt; +import androidx.annotation.IdRes; +import androidx.annotation.NonNull; +import androidx.annotation.StringRes; +import androidx.annotation.XmlRes; +import androidx.appcompat.app.AppCompatActivity; +import androidx.preference.ListPreference; +import androidx.preference.Preference; + +import java.util.ArrayList; +import java.util.Arrays; + +public class SearchConfiguration { + private static final String ARGUMENT_INDEX_FILES = "items"; + private static final String ARGUMENT_INDEX_INDIVIDUAL_PREFERENCES = "individual_prefs"; + private static final String ARGUMENT_FUZZY_ENABLED = "fuzzy"; + private static final String ARGUMENT_HISTORY_ENABLED = "history_enabled"; + private static final String ARGUMENT_SEARCH_BAR_ENABLED = "search_bar_enabled"; + private static final String ARGUMENT_BREADCRUMBS_ENABLED = "breadcrumbs_enabled"; + private static final String ARGUMENT_REVEAL_ANIMATION_SETTING = "reveal_anim_setting"; + private static final String ARGUMENT_TEXT_HINT = "text_hint"; + private static final String ARGUMENT_TEXT_CLEAR_HISTORY = "text_clear_history"; + private static final String ARGUMENT_TEXT_NO_RESULTS = "text_no_results"; + private final ArrayList bannedKeys = new ArrayList<>(); + private ArrayList filesToIndex = new ArrayList<>(); + private ArrayList preferencesToIndex = new ArrayList<>(); + private boolean historyEnabled = true; + private boolean breadcrumbsEnabled = false; + private boolean fuzzySearchEnabled = true; + private boolean searchBarEnabled = true; + private AppCompatActivity activity; + private int containerResId = android.R.id.content; + private RevealAnimationSetting revealAnimationSetting = null; + private String textClearHistory; + private String textNoResults; + private String textHint; + + public SearchConfiguration() { + + } + + /** + * Creates a new search configuration + * + * @param activity The Activity that receives callbacks. Must implement SearchPreferenceResultListener. + */ + @SuppressWarnings("unused") + public SearchConfiguration(AppCompatActivity activity) { + setActivity(activity); + } + + static SearchConfiguration fromBundle(Bundle bundle) { + SearchConfiguration config = new SearchConfiguration(); + config.filesToIndex = bundle.getParcelableArrayList(ARGUMENT_INDEX_FILES); + config.preferencesToIndex = bundle.getParcelableArrayList(ARGUMENT_INDEX_INDIVIDUAL_PREFERENCES); + config.historyEnabled = bundle.getBoolean(ARGUMENT_HISTORY_ENABLED); + config.revealAnimationSetting = bundle.getParcelable(ARGUMENT_REVEAL_ANIMATION_SETTING); + config.fuzzySearchEnabled = bundle.getBoolean(ARGUMENT_FUZZY_ENABLED); + config.breadcrumbsEnabled = bundle.getBoolean(ARGUMENT_BREADCRUMBS_ENABLED); + config.searchBarEnabled = bundle.getBoolean(ARGUMENT_SEARCH_BAR_ENABLED); + config.textHint = bundle.getString(ARGUMENT_TEXT_HINT); + config.textClearHistory = bundle.getString(ARGUMENT_TEXT_CLEAR_HISTORY); + config.textNoResults = bundle.getString(ARGUMENT_TEXT_NO_RESULTS); + return config; + } + + /** + * Shows the fragment + * + * @return A reference to the fragment + */ + public SearchPreferenceFragment showSearchFragment() { + if (activity == null) { + throw new IllegalStateException("setActivity() not called"); + } + + Bundle arguments = this.toBundle(); + SearchPreferenceFragment fragment = new SearchPreferenceFragment(); + fragment.setArguments(arguments); + activity.getSupportFragmentManager().beginTransaction() + .add(containerResId, fragment, SearchPreferenceFragment.TAG) + .addToBackStack(SearchPreferenceFragment.TAG) + .commit(); + return fragment; + } + + private Bundle toBundle() { + Bundle arguments = new Bundle(); + arguments.putParcelableArrayList(ARGUMENT_INDEX_FILES, filesToIndex); + arguments.putParcelableArrayList(ARGUMENT_INDEX_INDIVIDUAL_PREFERENCES, preferencesToIndex); + arguments.putBoolean(ARGUMENT_HISTORY_ENABLED, historyEnabled); + arguments.putParcelable(ARGUMENT_REVEAL_ANIMATION_SETTING, revealAnimationSetting); + arguments.putBoolean(ARGUMENT_FUZZY_ENABLED, fuzzySearchEnabled); + arguments.putBoolean(ARGUMENT_BREADCRUMBS_ENABLED, breadcrumbsEnabled); + arguments.putBoolean(ARGUMENT_SEARCH_BAR_ENABLED, searchBarEnabled); + arguments.putString(ARGUMENT_TEXT_HINT, textHint); + arguments.putString(ARGUMENT_TEXT_CLEAR_HISTORY, textClearHistory); + arguments.putString(ARGUMENT_TEXT_NO_RESULTS, textNoResults); + return arguments; + } + + /** + * Sets the current activity that also receives callbacks + * + * @param activity The Activity that receives callbacks. Must implement SearchPreferenceResultListener. + */ + public void setActivity(@NonNull AppCompatActivity activity) { + this.activity = activity; + if (!(activity instanceof SearchPreferenceResultListener)) { + throw new IllegalArgumentException("Activity must implement SearchPreferenceResultListener"); + } + } + + /** + * Sets the container to use when loading the fragment + * + * @param containerResId Resource id of the container + */ + public void setFragmentContainerViewId(@IdRes int containerResId) { + this.containerResId = containerResId; + } + + /** + * Display a reveal animation + * + * @param centerX Origin of the reveal animation + * @param centerY Origin of the reveal animation + * @param width Size of the main container + * @param height Size of the main container + * @param colorAccent Accent color to use + */ + @SuppressWarnings("unused") + public void useAnimation(int centerX, int centerY, int width, int height, @ColorInt int colorAccent) { + revealAnimationSetting = new RevealAnimationSetting(centerX, centerY, width, height, colorAccent); + } + + /** + * Adds a new file to the index + * + * @param resId The preference file to index + */ + public SearchIndexItem index(@XmlRes int resId) { + SearchIndexItem item = new SearchIndexItem(resId, this); + if (!filesToIndex.contains(item)) { + filesToIndex.add(item); + } + return item; + } + + /** + * Indexes a single preference + * + * @return the indexed PreferenceItem to configure it with chaining + * @see PreferenceItem for the available methods for configuring it + */ + @SuppressWarnings("unused") + public PreferenceItem indexItem() { + PreferenceItem preferenceItem = new PreferenceItem(); + preferencesToIndex.add(preferenceItem); + return preferenceItem; + } + + /** + * Indexes a single android preference + * + * @param preference to get its key, summary, title and entries + * @return the indexed PreferenceItem to configure it with chaining + * @see PreferenceItem for the available methods for configuring it + */ + @SuppressWarnings("unused") + public PreferenceItem indexItem(@NonNull Preference preference) { + PreferenceItem preferenceItem = new PreferenceItem(); + + if (preference.getKey() != null) { + preferenceItem.key = preference.getKey(); + } + if (preference.getSummary() != null) { + preferenceItem.summary = preference.getSummary().toString(); + } + if (preference.getTitle() != null) { + preferenceItem.title = preference.getTitle().toString(); + } + if (preference instanceof ListPreference listPreference) { + if (listPreference.getEntries() != null) { + preferenceItem.entries = Arrays.toString(listPreference.getEntries()); + } + } + preferencesToIndex.add(preferenceItem); + return preferenceItem; + } + + ArrayList getBannedKeys() { + return bannedKeys; + } + + /** + * @param key of the preference to be ignored + */ + @SuppressWarnings("unused") + public void ignorePreference(@NonNull String key) { + bannedKeys.add(key); + } + + ArrayList getFiles() { + return filesToIndex; + } + + ArrayList getPreferencesToIndex() { + return preferencesToIndex; + } + + boolean isHistoryEnabled() { + return historyEnabled; + } + + /** + * Show a history of recent search terms if nothing was typed yet. Default is true + * + * @param historyEnabled True if history should be enabled + */ + public void setHistoryEnabled(boolean historyEnabled) { + this.historyEnabled = historyEnabled; + } + + boolean isBreadcrumbsEnabled() { + return breadcrumbsEnabled; + } + + /** + * Show breadcrumbs in the list of search results, containing of + * the prefix given in addResourceFileToIndex, PreferenceCategory and PreferenceScreen. + * Default is false + * + * @param breadcrumbsEnabled True if breadcrumbs should be shown + */ + public void setBreadcrumbsEnabled(boolean breadcrumbsEnabled) { + this.breadcrumbsEnabled = breadcrumbsEnabled; + } + + boolean isFuzzySearchEnabled() { + return fuzzySearchEnabled; + } + + /** + * Allow to enable and disable fuzzy searching. Default is true + * + * @param fuzzySearchEnabled True if search should be fuzzy + */ + public void setFuzzySearchEnabled(boolean fuzzySearchEnabled) { + this.fuzzySearchEnabled = fuzzySearchEnabled; + } + + boolean isSearchBarEnabled() { + return searchBarEnabled; + } + + /** + * Show the search bar above the list. When setting this to false, you have to use {@see SearchPreferenceFragment#setSearchTerm(String) setSearchTerm} instead + * Default is true + * + * @param searchBarEnabled True if search bar should be shown + */ + public void setSearchBarEnabled(boolean searchBarEnabled) { + this.searchBarEnabled = searchBarEnabled; + } + + RevealAnimationSetting getRevealAnimationSetting() { + return revealAnimationSetting; + } + + @SuppressWarnings("unused") + public String getTextClearHistory() { + return textClearHistory; + } + + public void setTextClearHistory(String textClearHistory) { + this.textClearHistory = textClearHistory; + } + + public String getTextNoResults() { + return textNoResults; + } + + public void setTextNoResults(String textNoResults) { + this.textNoResults = textNoResults; + } + + public String getTextHint() { + return textHint; + } + + public void setTextHint(String textHint) { + this.textHint = textHint; + } + + /** + * Adds a given R.xml resource to the search index + */ + public static class SearchIndexItem implements Parcelable { + public static final Creator CREATOR = new Creator() { + @Override + public SearchIndexItem createFromParcel(Parcel in) { + return new SearchIndexItem(in); + } + + @Override + public SearchIndexItem[] newArray(int size) { + return new SearchIndexItem[size]; + } + }; + private final @XmlRes int resId; + private final SearchConfiguration searchConfiguration; + private String breadcrumb = ""; + + /** + * Includes the given R.xml resource in the index + * + * @param resId The resource to index + */ + private SearchIndexItem(@XmlRes int resId, SearchConfiguration searchConfiguration) { + this.resId = resId; + this.searchConfiguration = searchConfiguration; + } + + private SearchIndexItem(Parcel parcel) { + this.breadcrumb = parcel.readString(); + this.resId = parcel.readInt(); + this.searchConfiguration = null; + } + + /** + * Adds a breadcrumb + * + * @param breadcrumb The breadcrumb to add + * @return For chaining + */ + @SuppressWarnings("unused") + public SearchIndexItem addBreadcrumb(@StringRes int breadcrumb) { + assertNotParcel(); + return addBreadcrumb(searchConfiguration.activity.getString(breadcrumb)); + } + + /** + * Adds a breadcrumb + * + * @param breadcrumb The breadcrumb to add + * @return For chaining + */ + public SearchIndexItem addBreadcrumb(String breadcrumb) { + assertNotParcel(); + this.breadcrumb = Breadcrumb.concat(this.breadcrumb, breadcrumb); + return this; + } + + /** + * Throws an exception if the item does not have a searchConfiguration (thus, is restored from a parcel) + */ + private void assertNotParcel() { + if (searchConfiguration == null) { + throw new IllegalStateException("SearchIndexItems that are restored from parcel can not be modified."); + } + } + + @XmlRes + int getResId() { + return resId; + } + + String getBreadcrumb() { + return breadcrumb; + } + + SearchConfiguration getSearchConfiguration() { + return searchConfiguration; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeString(this.breadcrumb); + dest.writeInt(this.resId); + } + + @Override + public int describeContents() { + return 0; + } + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/ui/preferences/preferencesearch/SearchPreference.java b/app/src/main/java/com/drdisagree/iconify/ui/preferences/preferencesearch/SearchPreference.java new file mode 100644 index 000000000..990e944f2 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/preferences/preferencesearch/SearchPreference.java @@ -0,0 +1,87 @@ +package com.drdisagree.iconify.ui.preferences.preferencesearch; + +import android.content.Context; +import android.content.res.TypedArray; +import android.text.InputType; +import android.util.AttributeSet; +import android.view.View; +import android.widget.EditText; + +import androidx.preference.Preference; +import androidx.preference.PreferenceViewHolder; + +import com.drdisagree.iconify.R; + +public class SearchPreference extends Preference implements View.OnClickListener { + private final SearchConfiguration searchConfiguration = new SearchConfiguration(); + private String hint = null; + + @SuppressWarnings("unused") + public SearchPreference(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + setLayoutResource(R.layout.searchpreference_preference); + parseAttrs(attrs); + } + + @SuppressWarnings("unused") + public SearchPreference(Context context, AttributeSet attrs) { + super(context, attrs); + setLayoutResource(R.layout.searchpreference_preference); + parseAttrs(attrs); + } + + @SuppressWarnings("unused") + public SearchPreference(Context context) { + super(context); + setLayoutResource(R.layout.searchpreference_preference); + } + + private void parseAttrs(AttributeSet attrs) { + TypedArray a = getContext().obtainStyledAttributes(attrs, new int[]{R.attr.textHint}); + if (a.getText(0) != null) { + hint = a.getText(0).toString(); + searchConfiguration.setTextHint(a.getText(0).toString()); + } + a.recycle(); + a = getContext().obtainStyledAttributes(attrs, new int[]{R.attr.textClearHistory}); + if (a.getText(0) != null) { + searchConfiguration.setTextClearHistory(a.getText(0).toString()); + } + a.recycle(); + a = getContext().obtainStyledAttributes(attrs, new int[]{R.attr.textNoResults}); + if (a.getText(0) != null) { + searchConfiguration.setTextNoResults(a.getText(0).toString()); + } + a.recycle(); + } + + @Override + public void onBindViewHolder(PreferenceViewHolder holder) { + EditText searchText = (EditText) holder.findViewById(R.id.search); + searchText.setFocusable(false); + searchText.setInputType(InputType.TYPE_NULL); + searchText.setOnClickListener(this); + + if (hint != null) { + searchText.setHint(hint); + } + + holder.findViewById(R.id.search_card).setOnClickListener(this); + holder.itemView.setOnClickListener(this); + holder.itemView.setBackgroundColor(0x0); + } + + @Override + public void onClick(View view) { + getSearchConfiguration().showSearchFragment(); + } + + /** + * Returns the search configuration object for this preference + * + * @return The search configuration + */ + public SearchConfiguration getSearchConfiguration() { + return searchConfiguration; + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/ui/preferences/preferencesearch/SearchPreferenceActionView.java b/app/src/main/java/com/drdisagree/iconify/ui/preferences/preferencesearch/SearchPreferenceActionView.java new file mode 100644 index 000000000..fc22e9fc5 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/preferences/preferencesearch/SearchPreferenceActionView.java @@ -0,0 +1,93 @@ +package com.drdisagree.iconify.ui.preferences.preferencesearch; + +import android.content.Context; +import android.util.AttributeSet; + +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.SearchView; +import androidx.fragment.app.FragmentManager; + +public class SearchPreferenceActionView extends SearchView { + protected SearchPreferenceFragment searchFragment; + protected SearchConfiguration searchConfiguration = new SearchConfiguration(); + protected AppCompatActivity activity; + + public SearchPreferenceActionView(Context context) { + super(context); + initView(); + } + + public SearchPreferenceActionView(Context context, AttributeSet attrs) { + super(context, attrs); + initView(); + } + + public SearchPreferenceActionView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + initView(); + } + + private void initView() { + searchConfiguration.setSearchBarEnabled(false); + setOnQueryTextListener(new OnQueryTextListener() { + @Override + public boolean onQueryTextSubmit(String query) { + return false; + } + + @Override + public boolean onQueryTextChange(String newText) { + if (searchFragment != null) { + searchFragment.setSearchTerm(newText); + } + return true; + } + }); + setOnQueryTextFocusChangeListener((v, hasFocus) -> { + if (hasFocus && (searchFragment == null || !searchFragment.isVisible())) { + searchFragment = searchConfiguration.showSearchFragment(); + searchFragment.setHistoryClickListener(entry -> setQuery(entry, false)); + } + }); + } + + @SuppressWarnings("unused") + public SearchConfiguration getSearchConfiguration() { + return searchConfiguration; + } + + /** + * Hides the search fragment + * + * @return true if it was hidden, so the calling activity should not go back itself. + */ + @SuppressWarnings("unused") + public boolean cancelSearch() { + setQuery("", false); + + boolean didSomething = false; + if (!isIconified()) { + setIconified(true); + didSomething = true; + } + if (searchFragment != null && searchFragment.isVisible()) { + removeFragment(); + didSomething = true; + } + return didSomething; + } + + protected void removeFragment() { + if (searchFragment.isVisible()) { + FragmentManager fm = activity.getSupportFragmentManager(); + fm.beginTransaction().remove(searchFragment).commit(); + fm.popBackStack(SearchPreferenceFragment.TAG, FragmentManager.POP_BACK_STACK_INCLUSIVE); + } + } + + @SuppressWarnings("unused") + public void setActivity(AppCompatActivity activity) { + searchConfiguration.setActivity(activity); + this.activity = activity; + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/ui/preferences/preferencesearch/SearchPreferenceAdapter.java b/app/src/main/java/com/drdisagree/iconify/ui/preferences/preferencesearch/SearchPreferenceAdapter.java new file mode 100644 index 000000000..380849a1d --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/preferences/preferencesearch/SearchPreferenceAdapter.java @@ -0,0 +1,139 @@ +package com.drdisagree.iconify.ui.preferences.preferencesearch; + + +import android.annotation.SuppressLint; +import android.text.TextUtils; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.drdisagree.iconify.R; + +import java.util.ArrayList; +import java.util.List; + +class SearchPreferenceAdapter extends RecyclerView.Adapter { + private List dataset; + private SearchConfiguration searchConfiguration; + private SearchClickListener onItemClickListener; + + + SearchPreferenceAdapter() { + dataset = new ArrayList<>(); + } + + @NonNull + @Override + public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + if (viewType == PreferenceItem.TYPE) { + return new PreferenceViewHolder( + LayoutInflater.from(parent.getContext()).inflate( + R.layout.searchpreference_list_item_result, parent, false)); + } else { + return new HistoryViewHolder( + LayoutInflater.from(parent.getContext()).inflate( + R.layout.searchpreference_list_item_history, parent, false)); + } + } + + @Override + public void onBindViewHolder(@NonNull final ViewHolder h, final int position) { + final ListItem listItem = dataset.get(position); + if (getItemViewType(position) == HistoryItem.TYPE) { + HistoryViewHolder holder = (HistoryViewHolder) h; + HistoryItem item = (HistoryItem) listItem; + holder.term.setText(item.getTerm()); + } else if (getItemViewType(position) == PreferenceItem.TYPE) { + PreferenceViewHolder holder = (PreferenceViewHolder) h; + PreferenceItem item = (PreferenceItem) listItem; + holder.title.setText(item.title); + + if (TextUtils.isEmpty(item.summary) || item.summary.contains("%s")) { + holder.summary.setVisibility(View.GONE); + } else { + holder.summary.setVisibility(View.VISIBLE); + holder.summary.setText(item.summary); + holder.summary.setAlpha(0.8f); + } + + if (searchConfiguration.isBreadcrumbsEnabled()) { + holder.breadcrumbs.setText(item.breadcrumbs); + holder.breadcrumbs.setAlpha(0.6f); + holder.summary.setAlpha(0.8f); + } else { + holder.breadcrumbs.setVisibility(View.GONE); + holder.summary.setAlpha(0.6f); + } + + } + + h.root.setOnClickListener(v -> { + if (onItemClickListener != null) { + onItemClickListener.onItemClicked(listItem, h.getBindingAdapterPosition()); + } + }); + } + + @SuppressLint("NotifyDataSetChanged") + void setContent(List items) { + dataset = new ArrayList<>(items); + this.notifyDataSetChanged(); + } + + @Override + public int getItemCount() { + return dataset.size(); + } + + @Override + public int getItemViewType(int position) { + return dataset.get(position).getType(); + } + + void setSearchConfiguration(SearchConfiguration searchConfiguration) { + this.searchConfiguration = searchConfiguration; + } + + void setOnItemClickListener(SearchClickListener onItemClickListener) { + this.onItemClickListener = onItemClickListener; + } + + interface SearchClickListener { + void onItemClicked(ListItem item, int position); + } + + static class ViewHolder extends RecyclerView.ViewHolder { + View root; + + ViewHolder(View v) { + super(v); + root = v; + } + } + + static class HistoryViewHolder extends ViewHolder { + TextView term; + + HistoryViewHolder(View v) { + super(v); + term = v.findViewById(R.id.term); + } + } + + static class PreferenceViewHolder extends ViewHolder { + TextView title; + TextView summary; + TextView breadcrumbs; + + PreferenceViewHolder(View v) { + super(v); + title = v.findViewById(R.id.title); + summary = v.findViewById(R.id.summary); + breadcrumbs = v.findViewById(R.id.breadcrumbs); + } + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/ui/preferences/preferencesearch/SearchPreferenceFragment.java b/app/src/main/java/com/drdisagree/iconify/ui/preferences/preferencesearch/SearchPreferenceFragment.java new file mode 100644 index 000000000..8d1696cd6 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/preferences/preferencesearch/SearchPreferenceFragment.java @@ -0,0 +1,355 @@ +package com.drdisagree.iconify.ui.preferences.preferencesearch; + +import android.content.Context; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.text.Editable; +import android.text.TextUtils; +import android.text.TextWatcher; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.view.inputmethod.InputMethodManager; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.PopupMenu; +import androidx.core.view.MenuHost; +import androidx.core.view.MenuProvider; +import androidx.fragment.app.Fragment; +import androidx.lifecycle.Lifecycle; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.drdisagree.iconify.R; +import com.google.android.material.appbar.MaterialToolbar; +import com.google.android.material.card.MaterialCardView; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Objects; +import java.util.Set; + +public class SearchPreferenceFragment extends Fragment implements SearchPreferenceAdapter.SearchClickListener { + /** + * Default tag used on the library's Fragment transactions with {@link SearchPreferenceFragment} + */ + public static final String TAG = SearchPreferenceFragment.class.getSimpleName(); + + private static final String SHARED_PREFS_FILE = "preferenceSearch"; + private static final int MAX_HISTORY = 5; + private PreferenceParser searcher; + private List results; + private List history; + private SharedPreferences prefs; + private SearchViewHolder viewHolder; + private SearchConfiguration searchConfiguration; + private SearchPreferenceAdapter adapter; + private HistoryClickListener historyClickListener; + private CharSequence searchTermPreset = null; + private final TextWatcher textWatcher = new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { + } + + @Override + public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { + } + + @Override + public void afterTextChanged(Editable editable) { + updateSearchResults(editable.toString()); + viewHolder.clearButton.setVisibility(editable.toString().isEmpty() ? View.GONE : View.VISIBLE); + } + }; + + private void initSearch() { + searcher = new PreferenceParser(requireContext()); + + assert getArguments() != null; + searchConfiguration = SearchConfiguration.fromBundle(getArguments()); + ArrayList files = searchConfiguration.getFiles(); + for (SearchConfiguration.SearchIndexItem file : files) { + searcher.addResourceFile(file); + } + searcher.addPreferenceItems(searchConfiguration.getPreferencesToIndex()); + loadHistory(); + } + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + prefs = requireContext().getSharedPreferences(SHARED_PREFS_FILE, Context.MODE_PRIVATE); + + initSearch(); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + inflater.getContext().setTheme(R.style.PrefsThemeToolbar); + View rootView = inflater.inflate(R.layout.searchpreference_fragment, container, false); + viewHolder = new SearchViewHolder(rootView); + + viewHolder.clearButton.setOnClickListener(view -> viewHolder.searchView.setText("")); + if (searchConfiguration.isHistoryEnabled()) { + viewHolder.moreButton.setVisibility(View.VISIBLE); + } + if (searchConfiguration.getTextHint() != null) { + viewHolder.searchView.setHint(searchConfiguration.getTextHint()); + } + if (searchConfiguration.getTextNoResults() != null) { + viewHolder.noResults.setText(searchConfiguration.getTextNoResults()); + } + viewHolder.moreButton.setOnClickListener(v -> { + PopupMenu popup = new PopupMenu(requireContext(), viewHolder.moreButton); + popup.getMenuInflater().inflate(R.menu.search_more, popup.getMenu()); + popup.setOnMenuItemClickListener(item -> { + if (item.getItemId() == R.id.clear_history) { + clearHistory(); + } + return true; + }); + popup.show(); + }); + + viewHolder.recyclerView.setLayoutManager(new LinearLayoutManager(requireContext())); + adapter = new SearchPreferenceAdapter(); + adapter.setSearchConfiguration(searchConfiguration); + adapter.setOnItemClickListener(this); + viewHolder.recyclerView.setAdapter(adapter); + + viewHolder.searchView.addTextChangedListener(textWatcher); + + if (!searchConfiguration.isSearchBarEnabled()) { + viewHolder.searchContainer.setVisibility(View.GONE); + } + + if (searchTermPreset != null) { + viewHolder.searchView.setText(searchTermPreset); + } + + RevealAnimationSetting anim = searchConfiguration.getRevealAnimationSetting(); + if (anim != null) { + AnimationUtils.registerCircularRevealAnimation(requireContext(), rootView, anim); + } + + return rootView; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + + MenuHost menuHost = requireActivity(); + menuHost.addMenuProvider(new MenuProvider() { + @Override + public void onCreateMenu(@NonNull Menu menu, @NonNull MenuInflater menuInflater) { + menu.clear(); + menuInflater.inflate(R.menu.search_menu, menu); + } + + @Override + public boolean onMenuItemSelected(@NonNull MenuItem menuItem) { + return false; + } + }, getViewLifecycleOwner(), Lifecycle.State.RESUMED); + } + + private void loadHistory() { + history = new ArrayList<>(); + if (!searchConfiguration.isHistoryEnabled()) { + return; + } + + int size = prefs.getInt("history_size", 0); + for (int i = 0; i < size; i++) { + String title = prefs.getString("history_" + i, null); + history.add(new HistoryItem(title)); + } + } + + private void saveHistory() { + SharedPreferences.Editor editor = prefs.edit(); + editor.putInt("history_size", history.size()); + for (int i = 0; i < history.size(); i++) { + editor.putString("history_" + i, history.get(i).getTerm()); + } + editor.apply(); + } + + private void clearHistory() { + viewHolder.searchView.setText(""); + history.clear(); + saveHistory(); + updateSearchResults(""); + } + + private void addHistoryEntry(String entry) { + HistoryItem newItem = new HistoryItem(entry); + if (!history.contains(newItem)) { + if (history.size() >= MAX_HISTORY) { + history.remove(history.size() - 1); + } + history.add(0, newItem); + saveHistory(); + updateSearchResults(viewHolder.searchView.getText().toString()); + } + } + + @Override + public void onResume() { + super.onResume(); + + initSearch(); + + updateSearchResults(viewHolder.searchView.getText().toString()); + + if (searchConfiguration.isSearchBarEnabled()) { + showKeyboard(); + } + + if (getContext() != null) { + if (viewHolder.toolbar != null) { + ((AppCompatActivity) getContext()).setSupportActionBar(viewHolder.toolbar); + viewHolder.toolbar.setTitle(R.string.search_title); + } + + if (getContext() instanceof AppCompatActivity) { + Objects.requireNonNull(((AppCompatActivity) getContext()) + .getSupportActionBar()).setDisplayHomeAsUpEnabled(true); + } + } + } + + private void showKeyboard() { + viewHolder.searchView.post(() -> { + viewHolder.searchView.requestFocus(); + InputMethodManager imm = (InputMethodManager) requireActivity().getSystemService(Context.INPUT_METHOD_SERVICE); + if (imm != null) { + imm.showSoftInput(viewHolder.searchView, InputMethodManager.SHOW_IMPLICIT); + } + }); + } + + private void hideKeyboard() { + View view = requireActivity().getCurrentFocus(); + InputMethodManager imm = (InputMethodManager) requireActivity().getSystemService(Context.INPUT_METHOD_SERVICE); + if (view != null && imm != null) { + imm.hideSoftInputFromWindow(view.getWindowToken(), 0); + } + } + + public void setSearchTerm(CharSequence term) { + if (viewHolder != null) { + viewHolder.searchView.setText(term); + } else { + searchTermPreset = term; + } + } + + private void updateSearchResults(String keyword) { + if (TextUtils.isEmpty(keyword)) { + showHistory(); + return; + } + + results = searcher.searchFor(keyword, searchConfiguration.isFuzzySearchEnabled()); + + Set seen = new HashSet<>(); + List distinctResults = new ArrayList<>(); + + for (PreferenceItem result : results) { + String key = result.title + result.summary + result.breadcrumbs; + if (seen.add(key)) { + distinctResults.add(result); + } + } + + adapter.setContent(new ArrayList<>(distinctResults)); + + setEmptyViewShown(distinctResults.isEmpty()); + } + + private void setEmptyViewShown(boolean shown) { + if (shown) { + viewHolder.noResults.setVisibility(View.VISIBLE); + viewHolder.recyclerView.setVisibility(View.GONE); + } else { + viewHolder.noResults.setVisibility(View.GONE); + viewHolder.recyclerView.setVisibility(View.VISIBLE); + } + } + + private void showHistory() { + viewHolder.noResults.setVisibility(View.GONE); + viewHolder.recyclerView.setVisibility(View.VISIBLE); + + adapter.setContent(new ArrayList<>(history)); + setEmptyViewShown(history.isEmpty()); + } + + @Override + public void onItemClicked(ListItem item, int position) { + if (item.getType() == HistoryItem.TYPE) { + CharSequence text = ((HistoryItem) item).getTerm(); + viewHolder.searchView.setText(text); + viewHolder.searchView.setSelection(text.length()); + if (historyClickListener != null) { + historyClickListener.onHistoryEntryClicked(text.toString()); + } + } else { + hideKeyboard(); + + try { + final SearchPreferenceResultListener callback = (SearchPreferenceResultListener) getActivity(); + PreferenceItem r = results.get(position); + addHistoryEntry(r.title); + String screen = null; + if (!r.keyBreadcrumbs.isEmpty()) { + screen = r.keyBreadcrumbs.get(r.keyBreadcrumbs.size() - 1); + } + SearchPreferenceResult result = new SearchPreferenceResult(r.key, r.resId, screen); + assert callback != null; + callback.onSearchResultClicked(result); + } catch (ClassCastException e) { + throw new ClassCastException(requireActivity() + " must implement SearchPreferenceResultListener"); + } + } + } + + public void setHistoryClickListener(HistoryClickListener historyClickListener) { + this.historyClickListener = historyClickListener; + } + + public interface HistoryClickListener { + void onHistoryEntryClicked(String entry); + } + + private static class SearchViewHolder { + private final ImageView clearButton; + private final ImageView moreButton; + private final EditText searchView; + private final RecyclerView recyclerView; + private final TextView noResults; + private final MaterialCardView searchContainer; + private final MaterialToolbar toolbar; + + SearchViewHolder(View root) { + searchView = root.findViewById(R.id.search); + clearButton = root.findViewById(R.id.clear); + recyclerView = root.findViewById(R.id.list); + moreButton = root.findViewById(R.id.more); + noResults = root.findViewById(R.id.no_results); + searchContainer = root.findViewById(R.id.search_card); + toolbar = root.findViewById(R.id.toolbar); + } + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/ui/preferences/preferencesearch/SearchPreferenceResult.java b/app/src/main/java/com/drdisagree/iconify/ui/preferences/preferencesearch/SearchPreferenceResult.java new file mode 100644 index 000000000..4e2b69970 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/preferences/preferencesearch/SearchPreferenceResult.java @@ -0,0 +1,170 @@ +package com.drdisagree.iconify.ui.preferences.preferencesearch; + +import android.graphics.drawable.Drawable; +import android.graphics.drawable.RippleDrawable; +import android.os.Handler; +import android.os.Looper; +import android.util.Log; +import android.view.View; + +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.view.ViewCompat; +import androidx.fragment.app.FragmentManager; +import androidx.preference.Preference; +import androidx.preference.PreferenceFragmentCompat; +import androidx.preference.PreferenceGroup; +import androidx.recyclerview.widget.RecyclerView; + +import com.drdisagree.iconify.R; +import com.google.android.material.appbar.AppBarLayout; + +import java.util.Objects; + +public class SearchPreferenceResult { + private final String key; + private final int file; + private final String screen; + + SearchPreferenceResult(String key, int file, String screen) { + this.key = key; + this.file = file; + this.screen = screen; + } + + public static void highlight(final PreferenceFragmentCompat prefsFragment, final String key) { + new Handler(Looper.getMainLooper()).post(() -> doHighlight(prefsFragment, key)); + } + + private static void doHighlight(final PreferenceFragmentCompat prefsFragment, final String key) { + final Preference prefResult = prefsFragment.findPreference(key); + + if (prefResult == null) { + Log.w("doHighlight", "Preference with key " + key + " not found on given screen " + prefsFragment.getClass().getSimpleName() + "."); + return; + } + + final RecyclerView recyclerView = prefsFragment.getListView(); + final RecyclerView.Adapter adapter = recyclerView.getAdapter(); + + if (adapter instanceof PreferenceGroup.PreferencePositionCallback callback) { + final int position = callback.getPreferenceAdapterPosition(prefResult); + + if (prefsFragment.getView() != null && prefsFragment.getView().findViewById(R.id.collapsing_toolbar) != null) { + AppBarLayout appBarLayout = (AppBarLayout) prefsFragment.getView().findViewById(R.id.collapsing_toolbar).getParent(); + appBarLayout.setExpanded(false); + } + + if (position != RecyclerView.NO_POSITION) { + recyclerView.post(() -> recyclerView.scrollToPosition(position)); + + recyclerView.postDelayed(() -> { + RecyclerView.ViewHolder holder = recyclerView.findViewHolderForAdapterPosition(position); + if (holder != null) { + Drawable background = holder.itemView.getBackground(); + if (background instanceof RippleDrawable) { + forceRippleAnimation((RippleDrawable) background); + return; + } + } + highlightFallback(prefsFragment, prefResult); + }, 200); + return; + } + } + + highlightFallback(prefsFragment, prefResult); + } + + /** + * Alternative (old) highlight method if ripple does not work + */ + private static void highlightFallback(PreferenceFragmentCompat prefsFragment, final Preference prefResult) { + prefsFragment.scrollToPreference(prefResult); + + new Handler(Looper.getMainLooper()).postDelayed(() -> { + try { + final RecyclerView recyclerView = prefsFragment.getListView(); + final RecyclerView.Adapter adapter = recyclerView.getAdapter(); + + if (adapter instanceof PreferenceGroup.PreferencePositionCallback callback) { + final int position = callback.getPreferenceAdapterPosition(prefResult); + + if (prefsFragment.getView() != null && prefsFragment.getView().findViewById(R.id.collapsing_toolbar) != null) { + AppBarLayout appBarLayout = (AppBarLayout) prefsFragment.getView().findViewById(R.id.collapsing_toolbar).getParent(); + appBarLayout.setExpanded(false); + } + + if (position != RecyclerView.NO_POSITION) { + recyclerView.post(() -> recyclerView.scrollToPosition(position)); + + recyclerView.postDelayed(() -> { + RecyclerView.ViewHolder holder = recyclerView.findViewHolderForAdapterPosition(position); + if (holder != null) { + Drawable background = holder.itemView.getBackground(); + if (background instanceof RippleDrawable) { + forceRippleAnimation((RippleDrawable) background); + } + } + }, 200); + } + } + } catch (Exception e) { + Log.e("highlightFallback", "Failed to highlight preference", e); + } + }, 400); + } + + protected static void forceRippleAnimation(RippleDrawable background) { + final RippleDrawable rippleDrawable = background; + rippleDrawable.setState(new int[]{android.R.attr.state_pressed, android.R.attr.state_enabled}); + new Handler(Looper.getMainLooper()).postDelayed(() -> rippleDrawable.setState(new int[]{}), 300); + } + + /** + * Returns the key of the preference pressed + * + * @return The key + */ + public String getKey() { + return key; + } + + /** + * Returns the file in which the result was found + * + * @return The file in which the result was found + */ + public int getResourceFile() { + return file; + } + + /** + * Returns the screen in which the result was found + * + * @return The screen in which the result was found + */ + public String getScreen() { + return screen; + } + + /** + * Highlight the preference that was found + * + * @param prefsFragment Fragment that contains the preference + */ + @SuppressWarnings("unused") + public void highlight(final PreferenceFragmentCompat prefsFragment) { + new Handler(Looper.getMainLooper()).post(() -> doHighlight(prefsFragment, getKey())); + } + + /** + * Closes the search results page + * + * @param activity The current activity + */ + @SuppressWarnings("unused") + public void closeSearchPage(AppCompatActivity activity) { + FragmentManager fm = activity.getSupportFragmentManager(); + fm.beginTransaction().remove(Objects.requireNonNull(fm.findFragmentByTag(SearchPreferenceFragment.TAG))).commit(); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/ui/preferences/preferencesearch/SearchPreferenceResultListener.java b/app/src/main/java/com/drdisagree/iconify/ui/preferences/preferencesearch/SearchPreferenceResultListener.java new file mode 100644 index 000000000..368360d44 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/preferences/preferencesearch/SearchPreferenceResultListener.java @@ -0,0 +1,7 @@ +package com.drdisagree.iconify.ui.preferences.preferencesearch; + +import androidx.annotation.NonNull; + +public interface SearchPreferenceResultListener { + void onSearchResultClicked(@NonNull SearchPreferenceResult result); +} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/ui/utils/Animatoo.kt b/app/src/main/java/com/drdisagree/iconify/ui/utils/Animatoo.kt index 85224841b..10b949038 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/utils/Animatoo.kt +++ b/app/src/main/java/com/drdisagree/iconify/ui/utils/Animatoo.kt @@ -7,7 +7,6 @@ import com.drdisagree.iconify.R @Suppress("deprecation") object Animatoo { - @JvmStatic fun animateZoom(context: Context) { (context as Activity).overridePendingTransition( R.anim.animate_zoom_enter, @@ -15,7 +14,6 @@ object Animatoo { ) } - @JvmStatic fun animateFade(context: Context) { (context as Activity).overridePendingTransition( R.anim.animate_fade_enter, @@ -23,7 +21,6 @@ object Animatoo { ) } - @JvmStatic fun animateWindmill(context: Context) { (context as Activity).overridePendingTransition( R.anim.animate_windmill_enter, @@ -31,7 +28,6 @@ object Animatoo { ) } - @JvmStatic fun animateSpin(context: Context) { (context as Activity).overridePendingTransition( R.anim.animate_spin_enter, @@ -39,7 +35,6 @@ object Animatoo { ) } - @JvmStatic fun animateDiagonal(context: Context) { (context as Activity).overridePendingTransition( R.anim.animate_diagonal_right_enter, @@ -47,7 +42,6 @@ object Animatoo { ) } - @JvmStatic fun animateSplit(context: Context) { (context as Activity).overridePendingTransition( R.anim.animate_split_enter, @@ -55,7 +49,6 @@ object Animatoo { ) } - @JvmStatic fun animateShrink(context: Context) { (context as Activity).overridePendingTransition( R.anim.animate_shrink_enter, @@ -63,7 +56,6 @@ object Animatoo { ) } - @JvmStatic fun animateCard(context: Context) { (context as Activity).overridePendingTransition( R.anim.animate_card_enter, @@ -71,7 +63,6 @@ object Animatoo { ) } - @JvmStatic fun animateInAndOut(context: Context) { (context as Activity).overridePendingTransition( R.anim.animate_in_out_enter, @@ -79,7 +70,6 @@ object Animatoo { ) } - @JvmStatic fun animateSwipeLeft(context: Context) { (context as Activity).overridePendingTransition( R.anim.animate_swipe_left_enter, @@ -87,7 +77,6 @@ object Animatoo { ) } - @JvmStatic fun animateSwipeRight(context: Context) { (context as Activity).overridePendingTransition( R.anim.animate_swipe_right_enter, @@ -95,7 +84,6 @@ object Animatoo { ) } - @JvmStatic fun animateSlideLeft(context: Context) { (context as Activity).overridePendingTransition( R.anim.animate_slide_left_enter, @@ -103,7 +91,6 @@ object Animatoo { ) } - @JvmStatic fun animateSlideRight(context: Context) { (context as Activity).overridePendingTransition( R.anim.animate_slide_in_left, @@ -111,7 +98,6 @@ object Animatoo { ) } - @JvmStatic fun animateSlideDown(context: Context) { (context as Activity).overridePendingTransition( R.anim.animate_slide_down_enter, @@ -119,7 +105,6 @@ object Animatoo { ) } - @JvmStatic fun animateSlideUp(context: Context) { (context as Activity).overridePendingTransition( R.anim.animate_slide_up_enter, diff --git a/app/src/main/java/com/drdisagree/iconify/ui/utils/FragmentHelper.kt b/app/src/main/java/com/drdisagree/iconify/ui/utils/FragmentHelper.kt new file mode 100644 index 000000000..7d1449184 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/utils/FragmentHelper.kt @@ -0,0 +1,124 @@ +package com.drdisagree.iconify.ui.utils + +import androidx.fragment.app.Fragment +import com.drdisagree.iconify.ui.fragments.home.BrightnessBar +import com.drdisagree.iconify.ui.fragments.home.BrightnessBarPixel +import com.drdisagree.iconify.ui.fragments.home.CellularIcons +import com.drdisagree.iconify.ui.fragments.home.Home +import com.drdisagree.iconify.ui.fragments.home.IconPack +import com.drdisagree.iconify.ui.fragments.home.IconShape +import com.drdisagree.iconify.ui.fragments.home.MediaIcons +import com.drdisagree.iconify.ui.fragments.home.Notification +import com.drdisagree.iconify.ui.fragments.home.NotificationPixel +import com.drdisagree.iconify.ui.fragments.home.ProgressBar +import com.drdisagree.iconify.ui.fragments.home.QsPanelTile +import com.drdisagree.iconify.ui.fragments.home.QsPanelTilePixel +import com.drdisagree.iconify.ui.fragments.home.SettingsIcons +import com.drdisagree.iconify.ui.fragments.home.Switch +import com.drdisagree.iconify.ui.fragments.home.ToastFrame +import com.drdisagree.iconify.ui.fragments.home.WiFiIcons +import com.drdisagree.iconify.ui.fragments.settings.AppUpdates +import com.drdisagree.iconify.ui.fragments.settings.Changelog +import com.drdisagree.iconify.ui.fragments.settings.Credits +import com.drdisagree.iconify.ui.fragments.settings.Experimental +import com.drdisagree.iconify.ui.fragments.settings.Settings +import com.drdisagree.iconify.ui.fragments.tweaks.BasicColors +import com.drdisagree.iconify.ui.fragments.tweaks.ColorEngine +import com.drdisagree.iconify.ui.fragments.tweaks.ColoredBattery +import com.drdisagree.iconify.ui.fragments.tweaks.MediaPlayer +import com.drdisagree.iconify.ui.fragments.tweaks.Miscellaneous +import com.drdisagree.iconify.ui.fragments.tweaks.MonetEngine +import com.drdisagree.iconify.ui.fragments.tweaks.NavigationBar +import com.drdisagree.iconify.ui.fragments.tweaks.QsIconLabel +import com.drdisagree.iconify.ui.fragments.tweaks.QsPanelMargin +import com.drdisagree.iconify.ui.fragments.tweaks.QsRowColumn +import com.drdisagree.iconify.ui.fragments.tweaks.QsTileSize +import com.drdisagree.iconify.ui.fragments.tweaks.Statusbar +import com.drdisagree.iconify.ui.fragments.tweaks.Tweaks +import com.drdisagree.iconify.ui.fragments.tweaks.UiRoundness +import com.drdisagree.iconify.ui.fragments.tweaks.VolumePanel +import com.drdisagree.iconify.ui.fragments.xposed.BackgroundChip +import com.drdisagree.iconify.ui.fragments.xposed.BatteryStyle +import com.drdisagree.iconify.ui.fragments.xposed.DepthWallpaper +import com.drdisagree.iconify.ui.fragments.xposed.HeaderClock +import com.drdisagree.iconify.ui.fragments.xposed.HeaderImage +import com.drdisagree.iconify.ui.fragments.xposed.LockscreenClock +import com.drdisagree.iconify.ui.fragments.xposed.LockscreenWeather +import com.drdisagree.iconify.ui.fragments.xposed.LockscreenWidget +import com.drdisagree.iconify.ui.fragments.xposed.Others +import com.drdisagree.iconify.ui.fragments.xposed.QuickSettings +import com.drdisagree.iconify.ui.fragments.xposed.Themes +import com.drdisagree.iconify.ui.fragments.xposed.TransparencyBlur +import com.drdisagree.iconify.ui.fragments.xposed.Xposed + +object FragmentHelper { + + fun isInGroup(fragment: Fragment, group: Int): Boolean { + return when (group) { + 0 -> { + fragment is Home || + fragment is IconPack || + fragment is ColoredBattery || + fragment is MediaIcons || + fragment is SettingsIcons || + fragment is CellularIcons || + fragment is WiFiIcons || + fragment is BrightnessBar || + fragment is BrightnessBarPixel || + fragment is QsPanelTile || + fragment is QsPanelTilePixel || + fragment is Notification || + fragment is NotificationPixel || + fragment is ProgressBar || + fragment is Switch || + fragment is ToastFrame || + fragment is IconShape + } + + 1 -> { + fragment is Tweaks || + fragment is ColorEngine || + fragment is BasicColors || + fragment is MonetEngine || + fragment is UiRoundness || + fragment is QsRowColumn || + fragment is QsIconLabel || + fragment is QsTileSize || + fragment is QsPanelMargin || + fragment is Statusbar || + fragment is NavigationBar || + fragment is MediaPlayer || + fragment is VolumePanel || + fragment is Miscellaneous + } + + 2 -> { + fragment is Xposed || + fragment is TransparencyBlur || + fragment is QuickSettings || + fragment is Themes || + fragment is BatteryStyle || + fragment is com.drdisagree.iconify.ui.fragments.xposed.Statusbar || + fragment is com.drdisagree.iconify.ui.fragments.xposed.VolumePanel || + fragment is HeaderImage || + fragment is HeaderClock || + fragment is LockscreenClock || + fragment is LockscreenWeather || + fragment is LockscreenWidget || + fragment is DepthWallpaper || + fragment is BackgroundChip || + fragment is Others + } + + 3 -> { + fragment is Settings || + fragment is AppUpdates || + fragment is Changelog || + fragment is Credits || + fragment is Experimental + } + + else -> false + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/ui/utils/SnapOnScrollListener.java b/app/src/main/java/com/drdisagree/iconify/ui/utils/SnapOnScrollListener.java new file mode 100644 index 000000000..d6b1ed4bb --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/utils/SnapOnScrollListener.java @@ -0,0 +1,72 @@ +package com.drdisagree.iconify.ui.utils; + +import android.view.View; + +import androidx.recyclerview.widget.RecyclerView; +import androidx.recyclerview.widget.SnapHelper; + +public class SnapOnScrollListener extends RecyclerView.OnScrollListener { + private final SnapHelper snapHelper; + private Behavior behavior = Behavior.NOTIFY_ON_SCROLL; + private OnSnapPositionChangeListener onSnapPositionChangeListener; + + private int snapPosition = RecyclerView.NO_POSITION; + + public SnapOnScrollListener(SnapHelper snapHelper) { + this.snapHelper = snapHelper; + } + + public SnapOnScrollListener(SnapHelper snapHelper, Behavior behavior, OnSnapPositionChangeListener onSnapPositionChangeListener) { + this.snapHelper = snapHelper; + this.behavior = behavior; + this.onSnapPositionChangeListener = onSnapPositionChangeListener; + } + + @Override + public void onScrolled(RecyclerView recyclerView, int dx, int dy) { + if (behavior == Behavior.NOTIFY_ON_SCROLL) { + maybeNotifySnapPositionChange(recyclerView); + } + } + + @Override + public void onScrollStateChanged(RecyclerView recyclerView, int newState) { + if (behavior == Behavior.NOTIFY_ON_SCROLL_STATE_IDLE + && newState == RecyclerView.SCROLL_STATE_IDLE) { + maybeNotifySnapPositionChange(recyclerView); + } + } + + private void maybeNotifySnapPositionChange(RecyclerView recyclerView) { + int snapPosition = getSnapPosition(recyclerView); + boolean snapPositionChanged = this.snapPosition != snapPosition; + if (snapPositionChanged) { + if (onSnapPositionChangeListener != null) { + onSnapPositionChangeListener.onSnapPositionChange(snapPosition); + } + this.snapPosition = snapPosition; + } + } + + public int getSnapPosition(RecyclerView recyclerView) { + RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager(); + if (layoutManager == null) { + return RecyclerView.NO_POSITION; + } + View snapView = snapHelper.findSnapView(layoutManager); + if (snapView == null) { + return RecyclerView.NO_POSITION; + } + return layoutManager.getPosition(snapView); + } + + + public enum Behavior { + NOTIFY_ON_SCROLL, + NOTIFY_ON_SCROLL_STATE_IDLE + } + + public interface OnSnapPositionChangeListener { + void onSnapPositionChange(int position); + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/ui/utils/ThemeHelper.kt b/app/src/main/java/com/drdisagree/iconify/ui/utils/ThemeHelper.kt index daaca2fe4..e739d6cc7 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/utils/ThemeHelper.kt +++ b/app/src/main/java/com/drdisagree/iconify/ui/utils/ThemeHelper.kt @@ -2,14 +2,14 @@ package com.drdisagree.iconify.ui.utils import androidx.appcompat.app.AppCompatDelegate import com.drdisagree.iconify.common.Preferences.APP_THEME -import com.drdisagree.iconify.config.Prefs.getInt +import com.drdisagree.iconify.config.RPrefs object ThemeHelper { - @JvmStatic val theme: Int get() { - val theme = getInt(APP_THEME, 2) + val theme = RPrefs.getString(APP_THEME, "2")!!.toInt() + return when (theme) { 0 -> AppCompatDelegate.MODE_NIGHT_NO 1 -> AppCompatDelegate.MODE_NIGHT_YES diff --git a/app/src/main/java/com/drdisagree/iconify/ui/utils/ViewBindingHelpers.kt b/app/src/main/java/com/drdisagree/iconify/ui/utils/ViewBindingHelpers.kt index 12af40a2a..684dcd342 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/utils/ViewBindingHelpers.kt +++ b/app/src/main/java/com/drdisagree/iconify/ui/utils/ViewBindingHelpers.kt @@ -13,25 +13,21 @@ import com.bumptech.glide.request.transition.Transition object ViewBindingHelpers { - @JvmStatic fun setImageUrl(imageView: ImageView, url: String) { Glide.with(imageView.context).load(url.replace("http://", "https://")) .apply(RequestOptions.centerCropTransform()) .transition(DrawableTransitionOptions.withCrossFade()).into(imageView) } - @JvmStatic fun setDrawable(imageView: ImageView, drawable: Drawable?) { Glide.with(imageView.context).load(drawable).into(imageView) } - @JvmStatic fun setDrawableWithAnimation(imageView: ImageView, drawable: Drawable?) { Glide.with(imageView.context).load(drawable) .transition(DrawableTransitionOptions.withCrossFade()).into(imageView) } - @JvmStatic fun setDrawable(viewGroup: ViewGroup, drawable: Drawable?) { Glide.with(viewGroup.context).load(drawable).into(object : CustomTarget() { override fun onResourceReady( @@ -45,7 +41,6 @@ object ViewBindingHelpers { }) } - @JvmStatic fun setDrawableWithAnimation(viewGroup: ViewGroup, drawable: Drawable?) { Glide.with(viewGroup.context).load(drawable) .transition(DrawableTransitionOptions.withCrossFade()) @@ -61,13 +56,11 @@ object ViewBindingHelpers { }) } - @JvmStatic fun setBitmap(imageView: ImageView, bitmap: Bitmap?) { val drawable: Drawable = BitmapDrawable(imageView.context.resources, bitmap) setDrawable(imageView, drawable) } - @JvmStatic fun setBitmapWithAnimation(imageView: ImageView, bitmap: Bitmap?) { val drawable: Drawable = BitmapDrawable(imageView.context.resources, bitmap) setDrawableWithAnimation(imageView, drawable) diff --git a/app/src/main/java/com/drdisagree/iconify/ui/utils/ViewHelper.kt b/app/src/main/java/com/drdisagree/iconify/ui/utils/ViewHelper.kt index 61679cda7..04197e037 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/utils/ViewHelper.kt +++ b/app/src/main/java/com/drdisagree/iconify/ui/utils/ViewHelper.kt @@ -8,6 +8,8 @@ import android.os.BatteryManager import android.os.Handler import android.os.Looper import android.util.TypedValue +import android.view.ViewGroup +import android.widget.TextView import androidx.annotation.DrawableRes import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.widget.Toolbar @@ -59,7 +61,6 @@ import com.drdisagree.iconify.xposed.modules.batterystyles.RLandscapeBatteryStyl object ViewHelper { - @JvmStatic fun disableNestedScrolling(viewPager: ViewPager2) { var recyclerView: RecyclerView? = null @@ -75,22 +76,38 @@ object ViewHelper { } } - @JvmStatic - fun setHeader(context: Context, toolbar: Toolbar, title: Int) { + fun setHeader(context: Context, toolbar: Toolbar, title: Any) { (context as AppCompatActivity).setSupportActionBar(toolbar) context.supportActionBar?.setDisplayHomeAsUpEnabled(true) context.supportActionBar?.setDisplayShowHomeEnabled(true) - toolbar.setTitle(title) + if (title is Int) { + toolbar.setTitle(title) + } else if (title is String) { + toolbar.setTitle(title) + } } - @JvmStatic fun setHeader( context: Context, fragmentManager: FragmentManager, toolbar: Toolbar, title: Int ) { - toolbar.setTitle(context.resources.getString(title)) + setHeader( + context, + fragmentManager, + toolbar, + context.resources.getString(title) + ) + } + + fun setHeader( + context: Context, + fragmentManager: FragmentManager, + toolbar: Toolbar, + title: String + ) { + toolbar.setTitle(title) (context as AppCompatActivity).setSupportActionBar(toolbar) context.supportActionBar?.setDisplayHomeAsUpEnabled(true) context.supportActionBar?.setDisplayShowHomeEnabled(true) @@ -106,7 +123,6 @@ object ViewHelper { return dp2px(dp.toInt()) } - @JvmStatic fun dp2px(dp: Int): Int { return TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, @@ -115,7 +131,6 @@ object ViewHelper { ).toInt() } - @JvmStatic fun getBatteryDrawables(context: Context): Array { val batteryColor = appContext.getColor(R.color.textColorPrimary) @@ -183,10 +198,10 @@ object ViewHelper { batteryDrawables[2] = getRotateDrawable(batteryIcon, -90f) } } + return batteryDrawables } - @JvmStatic fun getChargingIcons(context: Context): Array { val chargingIcons = arrayOf( getDrawable(context, R.drawable.ic_charging_bold)!!, // Bold @@ -257,4 +272,27 @@ object ViewHelper { private fun getDrawable(context: Context, @DrawableRes batteryRes: Int): Drawable? { return ResourcesCompat.getDrawable(context.resources, batteryRes, context.theme) } + + fun setTextRecursively(viewGroup: ViewGroup, text: String?) { + for (i in 0 until viewGroup.childCount) { + val child = viewGroup.getChildAt(i) + if (child is ViewGroup) { + setTextRecursively(child, text) + } else if (child is TextView) { + child.text = text + } + } + } + + fun applyTextSizeRecursively(viewGroup: ViewGroup, textSize: Int) { + for (i in 0 until viewGroup.childCount) { + val child = viewGroup.getChildAt(i) + if (child is ViewGroup) { + applyTextSizeRecursively(child, textSize) + } else if (child is TextView) { + child.setTextSize(TypedValue.COMPLEX_UNIT_SP, textSize.toFloat()) + } + } + } + } diff --git a/app/src/main/java/com/drdisagree/iconify/ui/views/OnboardingView.kt b/app/src/main/java/com/drdisagree/iconify/ui/views/OnboardingView.kt index 6f8cd4995..3a2679afb 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/views/OnboardingView.kt +++ b/app/src/main/java/com/drdisagree/iconify/ui/views/OnboardingView.kt @@ -30,13 +30,12 @@ import com.drdisagree.iconify.common.Preferences.UPDATE_DETECTED import com.drdisagree.iconify.common.Preferences.VER_CODE import com.drdisagree.iconify.common.Preferences.XPOSED_ONLY_MODE import com.drdisagree.iconify.common.Resources -import com.drdisagree.iconify.config.Prefs -import com.drdisagree.iconify.config.Prefs.clearPref -import com.drdisagree.iconify.config.Prefs.getBoolean -import com.drdisagree.iconify.config.Prefs.getInt -import com.drdisagree.iconify.config.Prefs.putBoolean -import com.drdisagree.iconify.config.Prefs.putInt import com.drdisagree.iconify.config.RPrefs +import com.drdisagree.iconify.config.RPrefs.clearPref +import com.drdisagree.iconify.config.RPrefs.getBoolean +import com.drdisagree.iconify.config.RPrefs.getInt +import com.drdisagree.iconify.config.RPrefs.putBoolean +import com.drdisagree.iconify.config.RPrefs.putInt import com.drdisagree.iconify.databinding.ViewOnboardingPageBinding import com.drdisagree.iconify.ui.activities.MainActivity import com.drdisagree.iconify.ui.adapters.OnboardingAdapter @@ -45,20 +44,20 @@ import com.drdisagree.iconify.ui.dialogs.ErrorDialog import com.drdisagree.iconify.ui.dialogs.InstallationDialog import com.drdisagree.iconify.ui.entity.OnboardingPage import com.drdisagree.iconify.ui.utils.Animatoo.animateSlideLeft -import com.drdisagree.iconify.utils.FileUtil.copyAssets -import com.drdisagree.iconify.utils.ModuleUtil.createModule -import com.drdisagree.iconify.utils.ModuleUtil.flashModule -import com.drdisagree.iconify.utils.ModuleUtil.handleModule -import com.drdisagree.iconify.utils.ModuleUtil.moduleExists -import com.drdisagree.iconify.utils.RootUtil.deviceProperlyRooted -import com.drdisagree.iconify.utils.RootUtil.isDeviceRooted -import com.drdisagree.iconify.utils.SystemUtil.hasStoragePermission -import com.drdisagree.iconify.utils.SystemUtil.requestStoragePermission -import com.drdisagree.iconify.utils.SystemUtil.restartDevice -import com.drdisagree.iconify.utils.SystemUtil.savedVersionCode +import com.drdisagree.iconify.utils.FileUtils.copyAssets +import com.drdisagree.iconify.utils.ModuleUtils.createModule +import com.drdisagree.iconify.utils.ModuleUtils.flashModule +import com.drdisagree.iconify.utils.ModuleUtils.handleModule +import com.drdisagree.iconify.utils.ModuleUtils.moduleExists +import com.drdisagree.iconify.utils.RootUtils.deviceProperlyRooted +import com.drdisagree.iconify.utils.RootUtils.isDeviceRooted +import com.drdisagree.iconify.utils.SystemUtils.hasStoragePermission +import com.drdisagree.iconify.utils.SystemUtils.requestStoragePermission +import com.drdisagree.iconify.utils.SystemUtils.restartDevice +import com.drdisagree.iconify.utils.SystemUtils.savedVersionCode import com.drdisagree.iconify.utils.helper.BackupRestore.restoreFiles import com.drdisagree.iconify.utils.helper.Logger.writeLog -import com.drdisagree.iconify.utils.overlay.OverlayUtil.overlayExists +import com.drdisagree.iconify.utils.overlay.OverlayUtils.overlayExists import com.drdisagree.iconify.utils.overlay.compiler.OnboardingCompiler.apkSigner import com.drdisagree.iconify.utils.overlay.compiler.OnboardingCompiler.createManifest import com.drdisagree.iconify.utils.overlay.compiler.OnboardingCompiler.runAapt @@ -213,7 +212,6 @@ class OnboardingView : FrameLayout { if (getInt(VER_CODE) != BuildConfig.VERSION_CODE || !moduleExists || !overlayExists) { if (!moduleExists || !overlayExists) { - Prefs.clearAllPrefs() RPrefs.clearAllPrefs() } @@ -271,12 +269,11 @@ class OnboardingView : FrameLayout { }, (if (clickedButton) 10 else 1000).toLong()) } else { if (!moduleExists()) { - Prefs.clearAllPrefs() RPrefs.clearAllPrefs() handleInstallation() } else { - putBoolean(XPOSED_ONLY_MODE, true) + putBoolean(XPOSED_ONLY_MODE, !overlayExists()) val intent = Intent(context, MainActivity::class.java) intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK) diff --git a/app/src/main/java/com/drdisagree/iconify/ui/widgets/BottomSheetWidget.kt b/app/src/main/java/com/drdisagree/iconify/ui/widgets/BottomSheetWidget.kt index f159be955..348285d4d 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/widgets/BottomSheetWidget.kt +++ b/app/src/main/java/com/drdisagree/iconify/ui/widgets/BottomSheetWidget.kt @@ -17,7 +17,8 @@ import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.RecyclerView import com.drdisagree.iconify.R import com.drdisagree.iconify.ui.adapters.IconsAdapter -import com.drdisagree.iconify.utils.SystemUtil +import com.drdisagree.iconify.ui.adapters.IconsAdapter.Companion.ICONS_ADAPTER +import com.drdisagree.iconify.utils.SystemUtils import com.google.android.material.appbar.MaterialToolbar import com.google.android.material.bottomsheet.BottomSheetDialog import kotlinx.parcelize.Parcelize @@ -37,7 +38,8 @@ class BottomSheetWidget : RelativeLayout, IconsAdapter.OnItemClickListener { private lateinit var mEntryValues: Array private var mDrawables: Array? = null private var mValue: String = selectedIndex.toString() - private var mAdapter: IconsAdapter? = null + private var mAdapter: RecyclerView.Adapter? = null + private var mLayoutManager: RecyclerView.LayoutManager? = null private var onItemClickListener: OnItemClickListener? = null constructor(context: Context) : super(context) { @@ -103,6 +105,11 @@ class BottomSheetWidget : RelativeLayout, IconsAdapter.OnItemClickListener { } private fun buildEntries() { + if (arrayResId == 0) { + mEntries = emptyArray() + mEntryValues = emptyArray() + return + } mEntries = resources.getTextArray(arrayResId) val mValues: MutableList = ArrayList() @@ -121,6 +128,10 @@ class BottomSheetWidget : RelativeLayout, IconsAdapter.OnItemClickListener { titleTextView.text = title } + fun setSummary(summary: String) { + summaryTextView.text = summary + } + private fun setSelectedText(summaryResId: Int) { setSelectedText(context.getString(summaryResId)) } @@ -144,12 +155,16 @@ class BottomSheetWidget : RelativeLayout, IconsAdapter.OnItemClickListener { fun setDrawable(drawable: Array) { mDrawables = drawable - mAdapter?.setDrawables(drawable) + if (mAdapter is IconsAdapter) (mAdapter as IconsAdapter).setDrawables(drawable) } fun setCurrentValue(currentValue: String) { mValue = currentValue - mAdapter?.setCurrentValue(currentValue) + if (mAdapter is IconsAdapter) (mAdapter as IconsAdapter).setCurrentValue(currentValue) + } + + fun setLayoutManager(layoutManager: RecyclerView.LayoutManager) { + mLayoutManager = layoutManager } fun setIconVisibility(visibility: Int) { @@ -161,6 +176,7 @@ class BottomSheetWidget : RelativeLayout, IconsAdapter.OnItemClickListener { } fun setSelectedIndex(selectedIndex: Int) { + if (arrayResId == 0) return var idx = selectedIndex val list = listOf(*resources.getStringArray(arrayResId)) @@ -185,15 +201,22 @@ class BottomSheetWidget : RelativeLayout, IconsAdapter.OnItemClickListener { toolbar.title = titleTextView.text toolbar.isTitleCentered = true - recyclerView.layoutManager = GridLayoutManager(context, 3) + recyclerView.layoutManager = mLayoutManager ?: GridLayoutManager(context, 3) - mAdapter = IconsAdapter(mEntries, mEntryValues, mValue, this) - mAdapter!!.setDrawables(mDrawables) + if (mAdapter == null) { + mAdapter = IconsAdapter(mEntries, mEntryValues, mValue, ICONS_ADAPTER, this) + (mAdapter!! as IconsAdapter).setDrawables(mDrawables) + } recyclerView.adapter = mAdapter mBottomSheetDialog.setContentView(view) } + fun setAdapter(adapter: RecyclerView.Adapter) { + mAdapter = adapter + initBottomSheetDialog() + } + override fun setEnabled(enabled: Boolean) { super.setEnabled(enabled) @@ -207,7 +230,7 @@ class BottomSheetWidget : RelativeLayout, IconsAdapter.OnItemClickListener { iconImageView.imageTintList = ColorStateList.valueOf(color) } else { - if (SystemUtil.isDarkMode) { + if (SystemUtils.isDarkMode) { iconImageView.imageTintList = ColorStateList.valueOf(Color.DKGRAY) } else { iconImageView.imageTintList = ColorStateList.valueOf(Color.LTGRAY) diff --git a/app/src/main/java/com/drdisagree/iconify/ui/widgets/ColorPickerSmallWidget.kt b/app/src/main/java/com/drdisagree/iconify/ui/widgets/ColorPickerSmallWidget.kt index a5a66046e..3c431e647 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/widgets/ColorPickerSmallWidget.kt +++ b/app/src/main/java/com/drdisagree/iconify/ui/widgets/ColorPickerSmallWidget.kt @@ -16,7 +16,7 @@ import com.drdisagree.iconify.R import com.drdisagree.iconify.ui.activities.MainActivity import com.drdisagree.iconify.ui.events.ColorDismissedEvent import com.drdisagree.iconify.ui.events.ColorSelectedEvent -import com.drdisagree.iconify.utils.SystemUtil +import com.drdisagree.iconify.utils.SystemUtils import kotlinx.parcelize.Parcelize import kotlinx.parcelize.RawValue import org.greenrobot.eventbus.EventBus @@ -108,7 +108,7 @@ class ColorPickerSmallWidget : RelativeLayout { selectedColor = colorCode if (!isEnabled) { - colorCode = if (SystemUtil.isDarkMode) { + colorCode = if (SystemUtils.isDarkMode) { Color.DKGRAY } else { Color.LTGRAY diff --git a/app/src/main/java/com/drdisagree/iconify/ui/widgets/ColorPickerWidget.kt b/app/src/main/java/com/drdisagree/iconify/ui/widgets/ColorPickerWidget.kt index 9fa58cef6..fceed6153 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/widgets/ColorPickerWidget.kt +++ b/app/src/main/java/com/drdisagree/iconify/ui/widgets/ColorPickerWidget.kt @@ -15,7 +15,7 @@ import com.drdisagree.iconify.R import com.drdisagree.iconify.ui.activities.MainActivity import com.drdisagree.iconify.ui.events.ColorDismissedEvent import com.drdisagree.iconify.ui.events.ColorSelectedEvent -import com.drdisagree.iconify.utils.SystemUtil +import com.drdisagree.iconify.utils.SystemUtils import kotlinx.parcelize.Parcelize import kotlinx.parcelize.RawValue import org.greenrobot.eventbus.EventBus @@ -53,18 +53,18 @@ class ColorPickerWidget : RelativeLayout { private fun init(context: Context, attrs: AttributeSet?) { inflate(context, R.layout.view_widget_colorpicker, this) - + initializeId() - + val typedArray = context.obtainStyledAttributes(attrs, R.styleable.ColorPickerWidget) - + setTitle(typedArray.getString(R.styleable.ColorPickerWidget_titleText)) setSummary(typedArray.getString(R.styleable.ColorPickerWidget_summaryText)) val colorResId = typedArray.getResourceId(R.styleable.ColorPickerWidget_previewColor, -1) selectedColor = typedArray.getColor(R.styleable.ColorPickerWidget_previewColor, Color.WHITE) - + typedArray.recycle() - + if (colorResId != -1) { previewColor = ContextCompat.getColor(getContext(), colorResId) } @@ -80,10 +80,20 @@ class ColorPickerWidget : RelativeLayout { fun setSummary(summaryResId: Int) { summaryTextView.setText(summaryResId) + if (summaryResId == 0) { + summaryTextView.visibility = View.GONE + } else { + summaryTextView.visibility = View.VISIBLE + } } fun setSummary(summary: String?) { summaryTextView.text = summary + if (summary.isNullOrEmpty()) { + summaryTextView.visibility = View.GONE + } else { + summaryTextView.visibility = View.VISIBLE + } } fun setColorPickerListener( @@ -117,7 +127,7 @@ class ColorPickerWidget : RelativeLayout { selectedColor = colorCode if (!isEnabled) { - colorCode = if (SystemUtil.isDarkMode) { + colorCode = if (SystemUtils.isDarkMode) { Color.DKGRAY } else { Color.LTGRAY diff --git a/app/src/main/java/com/drdisagree/iconify/ui/widgets/EditTextWidget.kt b/app/src/main/java/com/drdisagree/iconify/ui/widgets/EditTextWidget.kt new file mode 100644 index 000000000..71027d235 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/ui/widgets/EditTextWidget.kt @@ -0,0 +1,181 @@ +package com.drdisagree.iconify.ui.widgets + +import android.content.Context +import android.content.res.ColorStateList +import android.graphics.Color +import android.graphics.drawable.Drawable +import android.text.TextUtils +import android.util.AttributeSet +import android.util.TypedValue +import android.view.View +import android.widget.ImageView +import android.widget.RelativeLayout +import android.widget.TextView +import com.drdisagree.iconify.R +import com.drdisagree.iconify.ui.dialogs.EditTextDialog +import com.drdisagree.iconify.utils.SystemUtils + +class EditTextWidget : RelativeLayout { + + private lateinit var container: RelativeLayout + private lateinit var titleTextView: TextView + private lateinit var summaryTextView: TextView + private lateinit var iconImageView: ImageView + private lateinit var dialogTitle: String + private lateinit var dialogSubtitle: String + private lateinit var dialogHint: String + private lateinit var dialogText: String + private lateinit var mEditTextDialog: EditTextDialog + + constructor(context: Context) : super(context) { + init(context, null) + } + + constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) { + init(context, attrs) + } + + constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super( + context, + attrs, + defStyleAttr + ) { + init(context, attrs) + } + + private fun init(context: Context, attrs: AttributeSet?) { + inflate(context, R.layout.view_widget_bottomsheet, this) + + initializeId() + + val typedArray = context.obtainStyledAttributes(attrs, R.styleable.EditTextWidget) + dialogTitle = typedArray.getString(R.styleable.EditTextWidget_dialogTitleText).toString() + if (TextUtils.isEmpty(dialogTitle) || dialogTitle == "null") dialogTitle = typedArray.getString(R.styleable.EditTextWidget_titleText).toString(); + dialogSubtitle = typedArray.getString(R.styleable.EditTextWidget_dialogSubtitleText).toString() + if (dialogSubtitle.isEmpty() || dialogSubtitle == "null") dialogSubtitle = typedArray.getString(R.styleable.EditTextWidget_summaryText).toString(); + if (dialogSubtitle == "null") dialogSubtitle = "" // catch null summary + dialogHint = typedArray.getString(R.styleable.EditTextWidget_dialogHintText).toString() + dialogText = typedArray.getString(R.styleable.EditTextWidget_dialogText).toString() + + setTitle(typedArray.getString(R.styleable.EditTextWidget_titleText)) + setSummary(typedArray.getString(R.styleable.EditTextWidget_summaryText)) + + val icon = typedArray.getResourceId(R.styleable.BottomSheetWidget_icon, 0) + var iconSpaceReserved = + typedArray.getBoolean(R.styleable.BottomSheetWidget_iconSpaceReserved, false) + + typedArray.recycle() + + if (icon != 0) { + iconSpaceReserved = true + iconImageView.setImageResource(icon) + } + + if (!iconSpaceReserved) { + iconImageView.visibility = View.GONE + } + + container.setOnClickListener { mEditTextDialog.show(dialogTitle, dialogSubtitle, dialogHint, dialogText) } + } + + fun setTitle(titleResId: Int) { + titleTextView.setText(titleResId) + } + + fun setTitle(title: String?) { + titleTextView.text = title + } + + fun setSummary(summary: String?) { + summaryTextView.text = summary + } + + /** + * Set the text for the EditText in the dialog + * @param text The text to be displayed in the EditText + */ + fun setEditTextValue(text: String) { + dialogText = text + } + + /** + * Set the hint for the EditText in the dialog + * @param hint The hint to be displayed in the EditText + */ + fun setEditTextHint(hint: String) { + dialogHint = hint + } + + fun setIcon(icon: Int) { + iconImageView.setImageResource(icon) + iconImageView.visibility = View.VISIBLE + } + + fun setIcon(drawable: Drawable?) { + iconImageView.setImageDrawable(drawable) + iconImageView.visibility = View.VISIBLE + } + + fun setIconVisibility(visibility: Int) { + iconImageView.visibility = visibility + } + + override fun setEnabled(enabled: Boolean) { + super.setEnabled(enabled) + + if (enabled) { + val typedValue = TypedValue() + val a = context.obtainStyledAttributes( + typedValue.data, intArrayOf(com.google.android.material.R.attr.colorPrimary) + ) + val color = a.getColor(0, 0) + a.recycle() + + iconImageView.imageTintList = ColorStateList.valueOf(color) + } else { + if (SystemUtils.isDarkMode) { + iconImageView.imageTintList = ColorStateList.valueOf(Color.DKGRAY) + } else { + iconImageView.imageTintList = ColorStateList.valueOf(Color.LTGRAY) + } + } + + container.isEnabled = enabled + titleTextView.isEnabled = enabled + summaryTextView.isEnabled = enabled + iconImageView.isEnabled = enabled + } + + // to avoid listener bug, we need to re-generate unique id for each view + private fun initializeId() { + container = findViewById(R.id.container) + titleTextView = findViewById(R.id.title) + summaryTextView = findViewById(R.id.summary) + iconImageView = findViewById(R.id.icon) + container.setId(generateViewId()) + titleTextView.setId(generateViewId()) + summaryTextView.setId(generateViewId()) + iconImageView.setId(generateViewId()) + + mEditTextDialog = EditTextDialog(context, container.id) + + val layoutParams = findViewById(R.id.text_container).layoutParams as LayoutParams + layoutParams.addRule(END_OF, iconImageView.id) + findViewById(R.id.text_container).setLayoutParams(layoutParams) + } + + override fun onDetachedFromWindow() { + mEditTextDialog.dismiss() + super.onDetachedFromWindow() + } + + /** + * Set the listener for the EditTextDialog + * @param listener The listener to be set + * @see EditTextDialog.EditTextDialogListener + */ + fun setOnEditTextListener(listener: EditTextDialog.EditTextDialogListener?) { + mEditTextDialog.setDialogListener(listener) + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/ui/widgets/FilePickerWidget.kt b/app/src/main/java/com/drdisagree/iconify/ui/widgets/FilePickerWidget.kt index 3cda45d65..683711c5b 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/widgets/FilePickerWidget.kt +++ b/app/src/main/java/com/drdisagree/iconify/ui/widgets/FilePickerWidget.kt @@ -8,8 +8,8 @@ import android.widget.RelativeLayout import android.widget.TextView import androidx.activity.result.ActivityResultLauncher import com.drdisagree.iconify.R -import com.drdisagree.iconify.utils.FileUtil -import com.drdisagree.iconify.utils.SystemUtil +import com.drdisagree.iconify.utils.FileUtils +import com.drdisagree.iconify.utils.SystemUtils import com.google.android.material.button.MaterialButton class FilePickerWidget : RelativeLayout { @@ -102,11 +102,11 @@ class FilePickerWidget : RelativeLayout { activityResultLauncher = launcher buttonPicker.setOnClickListener { - if (!SystemUtil.hasStoragePermission()) { - SystemUtil.requestStoragePermission(context) + if (!SystemUtils.hasStoragePermission()) { + SystemUtils.requestStoragePermission(context) } else { if (::activityResultLauncher.isInitialized) { - FileUtil.launchFilePicker(activityResultLauncher, fileType) + FileUtils.launchFilePicker(activityResultLauncher, fileType) } } } @@ -151,10 +151,10 @@ class FilePickerWidget : RelativeLayout { if (::activityResultLauncher.isInitialized) { buttonPicker.setOnClickListener { - if (!SystemUtil.hasStoragePermission()) { - SystemUtil.requestStoragePermission(context) + if (!SystemUtils.hasStoragePermission()) { + SystemUtils.requestStoragePermission(context) } else { - FileUtil.launchFilePicker(activityResultLauncher, fileType) + FileUtils.launchFilePicker(activityResultLauncher, fileType) } } } diff --git a/app/src/main/java/com/drdisagree/iconify/ui/widgets/MenuWidget.kt b/app/src/main/java/com/drdisagree/iconify/ui/widgets/MenuWidget.kt index 30042b0e0..6cfba1a02 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/widgets/MenuWidget.kt +++ b/app/src/main/java/com/drdisagree/iconify/ui/widgets/MenuWidget.kt @@ -11,7 +11,7 @@ import android.widget.ImageView import android.widget.RelativeLayout import android.widget.TextView import com.drdisagree.iconify.R -import com.drdisagree.iconify.utils.SystemUtil +import com.drdisagree.iconify.utils.SystemUtils class MenuWidget : RelativeLayout { @@ -127,7 +127,7 @@ class MenuWidget : RelativeLayout { ) ) } else { - if (SystemUtil.isDarkMode) { + if (SystemUtils.isDarkMode) { iconImageView.setImageTintList(ColorStateList.valueOf(Color.DKGRAY)) endArrowImageView.setImageTintList(ColorStateList.valueOf(Color.DKGRAY)) } else { diff --git a/app/src/main/java/com/drdisagree/iconify/ui/widgets/RadioDialogWidget.kt b/app/src/main/java/com/drdisagree/iconify/ui/widgets/RadioDialogWidget.kt index 3d8fa94f7..09c1d6a1e 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/widgets/RadioDialogWidget.kt +++ b/app/src/main/java/com/drdisagree/iconify/ui/widgets/RadioDialogWidget.kt @@ -13,7 +13,7 @@ import android.widget.RelativeLayout import android.widget.TextView import com.drdisagree.iconify.R import com.drdisagree.iconify.ui.dialogs.RadioDialog -import com.drdisagree.iconify.utils.SystemUtil +import com.drdisagree.iconify.utils.SystemUtils import kotlinx.parcelize.Parcelize import kotlinx.parcelize.RawValue @@ -56,7 +56,14 @@ class RadioDialogWidget : RelativeLayout, RadioDialog.RadioDialogListener { showSelectedPrefix = typedArray.getBoolean(R.styleable.RadioDialogWidget_showSelectedPrefix, true) titleResId = typedArray.getResourceId(R.styleable.RadioDialogWidget_titleText, 0) - setTitle(titleResId) + if (titleResId != 0) { + setTitle(titleResId) + } else { + val title = typedArray.getString(R.styleable.RadioDialogWidget_titleText) + if (title != null) { + setTitle(title) + } + } arrayResId = typedArray.getResourceId(R.styleable.RadioDialogWidget_entries, 0) if (arrayResId != 0) { try { @@ -168,7 +175,7 @@ class RadioDialogWidget : RelativeLayout, RadioDialog.RadioDialogListener { iconImageView.setImageTintList(ColorStateList.valueOf(color)) } else { - if (SystemUtil.isDarkMode) { + if (SystemUtils.isDarkMode) { iconImageView.setImageTintList(ColorStateList.valueOf(Color.DKGRAY)) } else { iconImageView.setImageTintList(ColorStateList.valueOf(Color.LTGRAY)) diff --git a/app/src/main/java/com/drdisagree/iconify/ui/widgets/SliderWidget.kt b/app/src/main/java/com/drdisagree/iconify/ui/widgets/SliderWidget.kt index caf3801cf..12e5e787c 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/widgets/SliderWidget.kt +++ b/app/src/main/java/com/drdisagree/iconify/ui/widgets/SliderWidget.kt @@ -4,11 +4,12 @@ import android.content.Context import android.os.Parcelable import android.util.AttributeSet import android.view.View -import android.widget.ImageView import android.widget.LinearLayout import android.widget.RelativeLayout import android.widget.TextView import com.drdisagree.iconify.R +import com.drdisagree.iconify.utils.HapticUtils.weakVibrate +import com.google.android.material.button.MaterialButton import com.google.android.material.slider.Slider import kotlinx.parcelize.Parcelize import kotlinx.parcelize.RawValue @@ -21,7 +22,7 @@ class SliderWidget : RelativeLayout { private lateinit var titleTextView: TextView private lateinit var summaryTextView: TextView private lateinit var materialSlider: Slider - private lateinit var resetIcon: ImageView + private lateinit var resetButton: MaterialButton private var valueFormat: String? = "" private var defaultValue = 0 private var outputScale = 1f @@ -78,7 +79,7 @@ class SliderWidget : RelativeLayout { } setSelectedText() - handleResetVisibility() + handleResetButton() setOnSliderTouchListener(null) setResetClickListener(null) } @@ -117,7 +118,7 @@ class SliderWidget : RelativeLayout { set(value) { materialSlider.value = value.toFloat() setSelectedText() - handleResetVisibility() + handleResetButton() } fun setSliderValueFrom(value: Int) { @@ -153,7 +154,7 @@ class SliderWidget : RelativeLayout { override fun onStopTrackingTouch(slider: Slider) { setSelectedText() - handleResetVisibility() + handleResetButton() notifyOnSliderTouchStopped(slider) } }) @@ -175,21 +176,20 @@ class SliderWidget : RelativeLayout { fun setResetClickListener(listener: OnLongClickListener?) { resetClickListener = listener - resetIcon.setOnLongClickListener { v: View -> + resetButton.setOnClickListener { v: View -> if (defaultValue == Int.MAX_VALUE) { - return@setOnLongClickListener false + return@setOnClickListener } sliderValue = defaultValue - handleResetVisibility() + handleResetButton() notifyOnResetClicked(v) - true } } fun resetSlider() { - resetIcon.performLongClick() + resetButton.performLongClick() } private fun notifyOnSliderTouchStarted(slider: Slider) { @@ -201,24 +201,26 @@ class SliderWidget : RelativeLayout { } private fun notifyOnResetClicked(v: View) { + v.weakVibrate() resetClickListener?.onLongClick(v) } - private fun handleResetVisibility() { - if (defaultValue != Int.MAX_VALUE && materialSlider.value != defaultValue.toFloat()) { - resetIcon.setVisibility(VISIBLE) + private fun handleResetButton() { + if (defaultValue != Int.MAX_VALUE) { + resetButton.visibility = VISIBLE + resetButton.isEnabled = isEnabled && materialSlider.value != defaultValue.toFloat() } else { - resetIcon.setVisibility(GONE) + resetButton.visibility = GONE } } override fun setEnabled(enabled: Boolean) { super.setEnabled(enabled) - container.setEnabled(enabled) - titleTextView.setEnabled(enabled) - summaryTextView.setEnabled(enabled) - resetIcon.setEnabled(enabled) + container.isEnabled = enabled + titleTextView.isEnabled = enabled + summaryTextView.isEnabled = enabled + resetButton.isEnabled = enabled materialSlider.isEnabled = enabled } @@ -228,12 +230,12 @@ class SliderWidget : RelativeLayout { titleTextView = findViewById(R.id.title) summaryTextView = findViewById(R.id.summary) materialSlider = findViewById(R.id.slider_widget) - resetIcon = findViewById(R.id.reset) - container.setId(generateViewId()) - titleTextView.setId(generateViewId()) - summaryTextView.setId(generateViewId()) - materialSlider.setId(generateViewId()) - resetIcon.setId(generateViewId()) + resetButton = findViewById(R.id.reset_button) + container.id = generateViewId() + titleTextView.id = generateViewId() + summaryTextView.id = generateViewId() + materialSlider.id = generateViewId() + resetButton.id = generateViewId() } override fun onSaveInstanceState(): Parcelable { @@ -249,7 +251,7 @@ class SliderWidget : RelativeLayout { super.onRestoreInstanceState(state.superState) materialSlider.value = state.sliderValue setSelectedText() - handleResetVisibility() + handleResetButton() } @Parcelize diff --git a/app/src/main/java/com/drdisagree/iconify/ui/widgets/SwitchWidget.kt b/app/src/main/java/com/drdisagree/iconify/ui/widgets/SwitchWidget.kt index 1a707bc07..1f28d1cc9 100644 --- a/app/src/main/java/com/drdisagree/iconify/ui/widgets/SwitchWidget.kt +++ b/app/src/main/java/com/drdisagree/iconify/ui/widgets/SwitchWidget.kt @@ -12,7 +12,7 @@ import android.widget.ImageView import android.widget.RelativeLayout import android.widget.TextView import com.drdisagree.iconify.R -import com.drdisagree.iconify.utils.SystemUtil +import com.drdisagree.iconify.utils.SystemUtils import com.google.android.material.materialswitch.MaterialSwitch class SwitchWidget : RelativeLayout { @@ -83,10 +83,20 @@ class SwitchWidget : RelativeLayout { fun setSummary(summaryResId: Int) { summaryTextView.setText(summaryResId) + if (summaryResId == 0) { + summaryTextView.visibility = GONE + } else { + summaryTextView.visibility = VISIBLE + } } fun setSummary(summary: String?) { summaryTextView.text = summary + if (summary.isNullOrEmpty()) { + summaryTextView.visibility = GONE + } else { + summaryTextView.visibility = VISIBLE + } } fun setIcon(icon: Int) { @@ -130,7 +140,7 @@ class SwitchWidget : RelativeLayout { iconImageView.setImageTintList(ColorStateList.valueOf(color)) } else { - if (SystemUtil.isDarkMode) { + if (SystemUtils.isDarkMode) { iconImageView.setImageTintList(ColorStateList.valueOf(Color.DKGRAY)) } else { iconImageView.setImageTintList(ColorStateList.valueOf(Color.LTGRAY)) diff --git a/app/src/main/java/com/drdisagree/iconify/utils/AppUtil.kt b/app/src/main/java/com/drdisagree/iconify/utils/AppUtil.kt deleted file mode 100644 index 28616f82e..000000000 --- a/app/src/main/java/com/drdisagree/iconify/utils/AppUtil.kt +++ /dev/null @@ -1,127 +0,0 @@ -package com.drdisagree.iconify.utils - -import android.annotation.SuppressLint -import android.app.Activity -import android.content.Intent -import android.content.pm.ApplicationInfo -import android.content.pm.PackageManager -import android.graphics.drawable.Drawable -import android.os.Handler -import android.os.Looper -import android.widget.Toast -import androidx.core.content.ContextCompat -import com.drdisagree.iconify.Iconify -import com.drdisagree.iconify.Iconify.Companion.appContext -import com.drdisagree.iconify.R -import com.topjohnwu.superuser.Shell - -object AppUtil { - - fun isAppInstalled(packageName: String?): Boolean { - val pm = appContext.packageManager - - try { - pm.getPackageInfo(packageName!!, PackageManager.GET_ACTIVITIES) - return pm.getApplicationInfo(packageName, 0).enabled - } catch (ignored: PackageManager.NameNotFoundException) { - } - - return false - } - - @JvmStatic - fun isAppInstalledRoot(packageName: String): Boolean { - return Shell.cmd("res=$(pm path $packageName); if [ ! -z \"\$res\" ]; then echo \"installed\"; else echo \"not found\"; fi") - .exec().out[0].contains("installed") - } - - fun getAppUid(packageName: String?): Int { - val pm = appContext.packageManager - - try { - pm.getPackageInfo(packageName!!, PackageManager.GET_ACTIVITIES) - return pm.getApplicationInfo(packageName, 0).uid - } catch (ignored: PackageManager.NameNotFoundException) { - } - - return 0 - } - - @JvmStatic - @SuppressLint("UseCompatLoadingForDrawables") - fun getAppIcon(packageName: String?): Drawable? { - var appIcon = ContextCompat.getDrawable(appContext, R.drawable.ic_android) - - try { - appIcon = appContext.packageManager.getApplicationIcon(packageName!!) - } catch (ignored: PackageManager.NameNotFoundException) { - } - - return appIcon - } - - @JvmStatic - fun getAppName(packageName: String?): String { - val pm = appContext.applicationContext.packageManager - var ai: ApplicationInfo? = null - - try { - ai = pm.getApplicationInfo(packageName!!, 0) - } catch (ignored: PackageManager.NameNotFoundException) { - } - - return (if (ai == null) "Unavailable" else pm.getApplicationLabel(ai)) as String - } - - @JvmStatic - fun launchApp(activity: Activity, packageName: String?) { - val launchIntent = appContext.packageManager.getLaunchIntentForPackage( - packageName!! - ) - - if (launchIntent != null) { - activity.startActivity(launchIntent) - } else { - Toast.makeText( - appContext, - appContext.resources.getString(R.string.app_not_found), - Toast.LENGTH_SHORT - ).show() - } - } - - @JvmStatic - fun getSplitLocations(packageName: String?): Array { - try { - var splitLocations = appContext.packageManager.getApplicationInfo( - packageName!!, 0 - ).splitSourceDirs - - if (splitLocations == null) { - splitLocations = arrayOf( - appContext.packageManager.getApplicationInfo( - packageName, 0 - ).sourceDir - ) - } - return splitLocations - } catch (ignored: PackageManager.NameNotFoundException) { - } - - return arrayOfNulls(0) - } - - @JvmStatic - val isLsposedInstalled: Boolean - get() = RootUtil.fileExists("/data/adb/lspd/manager.apk") || RootUtil.fileExists("/data/adb/modules/*lsposed*/manager.apk") - - @JvmStatic - fun restartApplication(activity: Activity) { - Handler(Looper.getMainLooper()).postDelayed({ - val intent = activity.intent - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK) - activity.finish() - activity.startActivity(intent) - }, 600) - } -} diff --git a/app/src/main/java/com/drdisagree/iconify/utils/AppUtils.kt b/app/src/main/java/com/drdisagree/iconify/utils/AppUtils.kt new file mode 100644 index 000000000..d0ead23ce --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/utils/AppUtils.kt @@ -0,0 +1,119 @@ +package com.drdisagree.iconify.utils + +import android.annotation.SuppressLint +import android.app.Activity +import android.content.Intent +import android.content.pm.ApplicationInfo +import android.content.pm.PackageManager +import android.graphics.drawable.Drawable +import android.os.Handler +import android.os.Looper +import android.widget.Toast +import androidx.core.content.ContextCompat +import com.drdisagree.iconify.Iconify.Companion.appContext +import com.drdisagree.iconify.R +import com.topjohnwu.superuser.Shell + +object AppUtils { + + fun isAppInstalled(packageName: String?): Boolean { + val pm = appContext.packageManager + + try { + pm.getPackageInfo(packageName!!, PackageManager.GET_ACTIVITIES) + return pm.getApplicationInfo(packageName, 0).enabled + } catch (ignored: PackageManager.NameNotFoundException) { + } + + return false + } + + fun isAppInstalledRoot(packageName: String): Boolean { + return Shell.cmd("res=$(pm path $packageName); if [ ! -z \"\$res\" ]; then echo \"installed\"; else echo \"not found\"; fi") + .exec().out[0].contains("installed") + } + + fun getAppUid(packageName: String?): Int { + val pm = appContext.packageManager + + try { + pm.getPackageInfo(packageName!!, PackageManager.GET_ACTIVITIES) + return pm.getApplicationInfo(packageName, 0).uid + } catch (ignored: PackageManager.NameNotFoundException) { + } + + return 0 + } + + @SuppressLint("UseCompatLoadingForDrawables") + fun getAppIcon(packageName: String?): Drawable? { + var appIcon = ContextCompat.getDrawable(appContext, R.drawable.ic_android) + + try { + appIcon = appContext.packageManager.getApplicationIcon(packageName!!) + } catch (ignored: PackageManager.NameNotFoundException) { + } + + return appIcon + } + + fun getAppName(packageName: String?): String { + val pm = appContext.applicationContext.packageManager + var ai: ApplicationInfo? = null + + try { + ai = pm.getApplicationInfo(packageName!!, 0) + } catch (ignored: PackageManager.NameNotFoundException) { + } + + return (if (ai == null) "Unavailable" else pm.getApplicationLabel(ai)) as String + } + + fun launchApp(activity: Activity, packageName: String?) { + val launchIntent = appContext.packageManager.getLaunchIntentForPackage( + packageName!! + ) + + if (launchIntent != null) { + activity.startActivity(launchIntent) + } else { + Toast.makeText( + appContext, + appContext.resources.getString(R.string.app_not_found), + Toast.LENGTH_SHORT + ).show() + } + } + + fun getSplitLocations(packageName: String?): Array { + try { + var splitLocations = appContext.packageManager.getApplicationInfo( + packageName!!, 0 + ).splitSourceDirs + + if (splitLocations == null) { + splitLocations = arrayOf( + appContext.packageManager.getApplicationInfo( + packageName, 0 + ).sourceDir + ) + } + return splitLocations + } catch (ignored: PackageManager.NameNotFoundException) { + } + + return arrayOfNulls(0) + } + + val isLsposedInstalled: Boolean + get() = RootUtils.fileExists("/data/adb/lspd/manager.apk") || RootUtils.fileExists("/data/adb/modules/*lsposed*/manager.apk") + + fun restartApplication(activity: Activity) { + Handler(Looper.getMainLooper()).postDelayed({ + val intent = activity.intent + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK) + activity.finish() + activity.startActivity(intent) + }, 600) + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/utils/CacheUtil.kt b/app/src/main/java/com/drdisagree/iconify/utils/CacheUtil.kt deleted file mode 100644 index 3b2fa5502..000000000 --- a/app/src/main/java/com/drdisagree/iconify/utils/CacheUtil.kt +++ /dev/null @@ -1,43 +0,0 @@ -package com.drdisagree.iconify.utils - -import android.content.Context -import java.io.File - -object CacheUtil { - - @JvmStatic - fun clearCache(context: Context) { - try { - var dir = context.cacheDir - deleteDir(dir) - - dir = context.externalCacheDir - deleteDir(dir) - - dir = context.filesDir - deleteDir(dir) - } catch (e: Exception) { - e.printStackTrace() - } - } - - private fun deleteDir(dir: File?): Boolean { - return if (dir != null && dir.isDirectory()) { - val children = dir.list() ?: return false - - for (child in children) { - val success = deleteDir(File(dir, child)) - - if (!success) { - return false - } - } - - dir.delete() - } else if (dir != null && dir.isFile()) { - dir.delete() - } else { - false - } - } -} diff --git a/app/src/main/java/com/drdisagree/iconify/utils/CacheUtils.kt b/app/src/main/java/com/drdisagree/iconify/utils/CacheUtils.kt new file mode 100644 index 000000000..484f457d6 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/utils/CacheUtils.kt @@ -0,0 +1,42 @@ +package com.drdisagree.iconify.utils + +import android.content.Context +import java.io.File + +object CacheUtils { + + fun clearCache(context: Context) { + try { + var dir = context.cacheDir + deleteDir(dir) + + dir = context.externalCacheDir + deleteDir(dir) + + dir = context.filesDir + deleteDir(dir) + } catch (e: Exception) { + e.printStackTrace() + } + } + + private fun deleteDir(dir: File?): Boolean { + return if (dir != null && dir.isDirectory()) { + val children = dir.list() ?: return false + + for (child in children) { + val success = deleteDir(File(dir, child)) + + if (!success) { + return false + } + } + + dir.delete() + } else if (dir != null && dir.isFile()) { + dir.delete() + } else { + false + } + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/utils/FileUtil.kt b/app/src/main/java/com/drdisagree/iconify/utils/FileUtil.kt deleted file mode 100644 index 14f602ecf..000000000 --- a/app/src/main/java/com/drdisagree/iconify/utils/FileUtil.kt +++ /dev/null @@ -1,163 +0,0 @@ -package com.drdisagree.iconify.utils - -import android.annotation.SuppressLint -import android.content.Context -import android.content.Intent -import android.net.Uri -import android.provider.OpenableColumns -import androidx.activity.result.ActivityResultLauncher -import com.drdisagree.iconify.Iconify -import com.drdisagree.iconify.Iconify.Companion.appContext -import com.drdisagree.iconify.common.Resources -import com.topjohnwu.superuser.Shell -import java.io.File -import java.io.FileOutputStream -import java.io.IOException -import java.io.InputStream -import java.io.OutputStream -import java.nio.file.Files -import java.nio.file.Paths -import kotlin.math.min - -object FileUtil { - - val DATA_DIR = appContext.filesDir.toString() - - @JvmStatic - @Throws(IOException::class) - fun copyAssets(assetFolder: String) { - cleanDir(assetFolder) - createDir(assetFolder) - copyFileOrDirectory(appContext, assetFolder, "$DATA_DIR/$assetFolder") - } - - fun cleanDir(dirName: String) { - Shell.cmd("rm -rf $DATA_DIR/$dirName").exec() - } - - private fun createDir(dirName: String) { - val newFolder = File("$DATA_DIR/$dirName/") - newFolder.mkdirs() - } - - @Throws(IOException::class) - private fun copyFileOrDirectory(context: Context, dirName: String, outPath: String) { - val srcFiles = context.assets.list(dirName) ?: return - - for (srcFileName in srcFiles) { - val outFileName = outPath + File.separator + srcFileName - var inFileName = dirName + File.separator + srcFileName - - if (dirName == "") { - inFileName = srcFileName - } - - try { - val inputStream = context.assets.open(inFileName) - copyAndClose(inputStream, Files.newOutputStream(Paths.get(outFileName))) - } catch (e: IOException) { - File(outFileName).mkdir() - copyFileOrDirectory(context, inFileName, outFileName) - } - } - } - - private fun closeQuietly(autoCloseable: AutoCloseable?) { - try { - autoCloseable?.close() - } catch (ignored: Exception) { - } - } - - @Throws(IOException::class) - fun copyAndClose(input: InputStream, output: OutputStream) { - copy(input, output) - closeQuietly(input) - closeQuietly(output) - } - - @Throws(IOException::class) - fun copy(input: InputStream, output: OutputStream) { - val buffer = ByteArray(1024) - var n: Int - - while (-1 != input.read(buffer).also { n = it }) { - output.write(buffer, 0, n) - } - } - - @JvmStatic - fun getRealPath(obj: Any?): String? { - return when (obj) { - is Intent -> { - getRealPathFromURI(obj.data) - } - - is Uri -> { - getRealPathFromURI(obj as Uri?) - } - - else -> { - throw IllegalArgumentException("Object must be an Intent or Uri") - } - } - } - - @SuppressLint("Recycle") - private fun getRealPathFromURI(uri: Uri?): String? { - val file: File - try { - val returnCursor = - appContext.contentResolver.query( - uri!!, null, null, null, null - ) ?: return null - val nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME) - returnCursor.moveToFirst() - - val name = returnCursor.getString(nameIndex) - file = File(appContext.filesDir, name) - - val inputStream = - appContext.contentResolver.openInputStream( - uri - ) - val outputStream = FileOutputStream(file) - var read: Int - val maxBufferSize = 1024 * 1024 - - if (inputStream == null) return null - - val bytesAvailable = inputStream.available() - val bufferSize = min(bytesAvailable.toDouble(), maxBufferSize.toDouble()).toInt() - val buffers = ByteArray(bufferSize) - - while (inputStream.read(buffers).also { read = it } != -1) { - outputStream.write(buffers, 0, read) - } - - inputStream.close() - outputStream.close() - } catch (e: Exception) { - e.printStackTrace() - return null - } - - return file.path - } - - @JvmStatic - fun moveToIconifyHiddenDir(source: String, destination: String): Boolean { - return Shell.cmd( - "mkdir -p " + Resources.XPOSED_RESOURCE_TEMP_DIR, - "rm -f \"$destination\"", - "mv -f \"$source\" \"$destination\"" - ).exec().isSuccess - } - - fun launchFilePicker(launcher: ActivityResultLauncher, type: String?) { - val chooseFile = Intent(Intent.ACTION_GET_CONTENT) - chooseFile.addCategory(Intent.CATEGORY_OPENABLE) - chooseFile.setType(type) - launcher.launch(chooseFile) - } -} diff --git a/app/src/main/java/com/drdisagree/iconify/utils/FileUtils.kt b/app/src/main/java/com/drdisagree/iconify/utils/FileUtils.kt new file mode 100644 index 000000000..c6e13fb42 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/utils/FileUtils.kt @@ -0,0 +1,195 @@ +package com.drdisagree.iconify.utils + +import android.annotation.SuppressLint +import android.content.Context +import android.content.Intent +import android.net.Uri +import android.provider.OpenableColumns +import androidx.activity.result.ActivityResultLauncher +import com.drdisagree.iconify.Iconify.Companion.appContext +import com.drdisagree.iconify.common.Resources +import com.drdisagree.iconify.utils.SystemUtils.hasStoragePermission +import com.drdisagree.iconify.utils.SystemUtils.requestStoragePermission +import com.topjohnwu.superuser.Shell +import java.io.File +import java.io.FileOutputStream +import java.io.IOException +import java.io.InputStream +import java.io.OutputStream +import java.nio.file.Files +import java.nio.file.Paths +import kotlin.math.min + +object FileUtils { + + val DATA_DIR = appContext.filesDir.toString() + + @Throws(IOException::class) + fun copyAssets(assetFolder: String) { + cleanDir(assetFolder) + createDir(assetFolder) + copyFileOrDirectory(appContext, assetFolder, "$DATA_DIR/$assetFolder") + } + + fun cleanDir(dirName: String) { + Shell.cmd("rm -rf $DATA_DIR/$dirName").exec() + } + + private fun createDir(dirName: String) { + val newFolder = File("$DATA_DIR/$dirName/") + newFolder.mkdirs() + } + + @Throws(IOException::class) + private fun copyFileOrDirectory(context: Context, dirName: String, outPath: String) { + val srcFiles = context.assets.list(dirName) ?: return + + for (srcFileName in srcFiles) { + val outFileName = outPath + File.separator + srcFileName + var inFileName = dirName + File.separator + srcFileName + + if (dirName == "") { + inFileName = srcFileName + } + + try { + val inputStream = context.assets.open(inFileName) + copyAndClose(inputStream, Files.newOutputStream(Paths.get(outFileName))) + } catch (e: IOException) { + File(outFileName).mkdir() + copyFileOrDirectory(context, inFileName, outFileName) + } + } + } + + private fun closeQuietly(autoCloseable: AutoCloseable?) { + try { + autoCloseable?.close() + } catch (ignored: Exception) { + } + } + + @Throws(IOException::class) + fun copyAndClose(input: InputStream, output: OutputStream) { + copy(input, output) + closeQuietly(input) + closeQuietly(output) + } + + @Throws(IOException::class) + fun copy(input: InputStream, output: OutputStream) { + val buffer = ByteArray(1024) + var n: Int + + while (-1 != input.read(buffer).also { n = it }) { + output.write(buffer, 0, n) + } + } + + fun getRealPath(obj: Any?): String? { + return when (obj) { + is Intent -> { + getRealPathFromURI(obj.data) + } + + is Uri -> { + getRealPathFromURI(obj as Uri?) + } + + else -> { + throw IllegalArgumentException("Object must be an Intent or Uri") + } + } + } + + @SuppressLint("Recycle") + private fun getRealPathFromURI(uri: Uri?): String? { + val file: File + try { + val returnCursor = + appContext.contentResolver.query( + uri!!, null, null, null, null + ) ?: return null + val nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME) + returnCursor.moveToFirst() + + val name = returnCursor.getString(nameIndex) + file = File(appContext.filesDir, name) + + val inputStream = + appContext.contentResolver.openInputStream( + uri + ) + val outputStream = FileOutputStream(file) + var read: Int + val maxBufferSize = 1024 * 1024 + + if (inputStream == null) return null + + val bytesAvailable = inputStream.available() + val bufferSize = min(bytesAvailable.toDouble(), maxBufferSize.toDouble()).toInt() + val buffers = ByteArray(bufferSize) + + while (inputStream.read(buffers).also { read = it } != -1) { + outputStream.write(buffers, 0, read) + } + + inputStream.close() + outputStream.close() + } catch (e: Exception) { + e.printStackTrace() + return null + } + + return file.path + } + + fun moveToIconifyHiddenDir(source: String, destination: String): Boolean { + return Shell.cmd( + "mkdir -p " + Resources.XPOSED_RESOURCE_TEMP_DIR, + "rm -f \"$destination\"", + "mv -f \"$source\" \"$destination\"" + ).exec().isSuccess + } + + fun launchFilePicker( + context: Context, + type: String?, + launcher: ActivityResultLauncher + ) { + if (!hasStoragePermission()) { + requestStoragePermission(context) + } else { + var fileType = "*/*" + + if (type.isNullOrEmpty() || type == "all") { + fileType = "*/*" + } else if (type == "image") { + fileType = "image/*" + } else if (type == "font") { + fileType = "font/*" + } else if (type == "video") { + fileType = "video/*" + } else if (type == "audio") { + fileType = "audio/*" + } else if (type == "pdf") { + fileType = "application/pdf" + } else if (type == "text") { + fileType = "text/*" + } else if (type == "zip") { + fileType = "application/zip" + } else if (type == "apk") { + fileType = "application/vnd.android.package-archive" + } + + launchFilePicker(launcher, fileType) + } + } + + fun launchFilePicker(launcher: ActivityResultLauncher, type: String?) { + val chooseFile = Intent(Intent.ACTION_GET_CONTENT) + chooseFile.addCategory(Intent.CATEGORY_OPENABLE) + chooseFile.setType(type) + launcher.launch(chooseFile) + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/utils/HapticUtils.kt b/app/src/main/java/com/drdisagree/iconify/utils/HapticUtils.kt new file mode 100644 index 000000000..cee0c886d --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/utils/HapticUtils.kt @@ -0,0 +1,33 @@ +package com.drdisagree.iconify.utils + +import android.view.HapticFeedbackConstants +import android.view.View +import com.drdisagree.iconify.common.Preferences.VIBRATE_UI +import com.drdisagree.iconify.config.RPrefs + +object HapticUtils { + + enum class VibrationType { + Weak, + Strong + } + + private fun View.vibrate(type: VibrationType) { + if (RPrefs.getBoolean(VIBRATE_UI, true)) { + when (type) { + VibrationType.Weak -> performHapticFeedback(HapticFeedbackConstants.CLOCK_TICK) + VibrationType.Strong -> performHapticFeedback(HapticFeedbackConstants.LONG_PRESS) + } + } + } + + @JvmStatic + fun View.weakVibrate() { + vibrate(VibrationType.Weak) + } + + @JvmStatic + fun View.strongVibrate() { + vibrate(VibrationType.Strong) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/utils/MiscUtils.kt b/app/src/main/java/com/drdisagree/iconify/utils/MiscUtils.kt new file mode 100644 index 000000000..03c23a61c --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/utils/MiscUtils.kt @@ -0,0 +1,41 @@ +package com.drdisagree.iconify.utils + +import android.content.Context +import com.drdisagree.iconify.R +import com.google.android.material.dialog.MaterialAlertDialogBuilder + +object MiscUtils { + + @JvmStatic + fun showAlertDialog( + context: Context, + restartSystemUI: Boolean = false, + restartDevice: Boolean = false, + switchTheme: Boolean = false, + rotateDevice: Boolean = false + ) { + val title = when { + restartSystemUI -> R.string.systemui_restart_required_title + restartDevice -> R.string.device_restart_required_title + switchTheme -> R.string.switch_theme_required_title + rotateDevice -> R.string.device_rotation_required_title + else -> R.string.systemui_restart_required_title + } + val message = when { + restartSystemUI -> R.string.systemui_restart_required_desc + restartDevice -> R.string.device_restart_required_desc + switchTheme -> R.string.switch_theme_required_desc + rotateDevice -> R.string.device_rotation_required_desc + else -> R.string.systemui_restart_required_desc + } + + MaterialAlertDialogBuilder(context) + .setTitle(context.getString(title)) + .setMessage(context.getString(message)) + .setPositiveButton(android.R.string.ok) { dialog, _ -> + dialog.dismiss() + } + .setCancelable(true) + .show() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/utils/ModuleUtil.kt b/app/src/main/java/com/drdisagree/iconify/utils/ModuleUtil.kt deleted file mode 100644 index 2fcede46a..000000000 --- a/app/src/main/java/com/drdisagree/iconify/utils/ModuleUtil.kt +++ /dev/null @@ -1,236 +0,0 @@ -package com.drdisagree.iconify.utils - -import android.content.Context -import android.util.Log -import com.drdisagree.iconify.BuildConfig -import com.drdisagree.iconify.Iconify.Companion.appContext -import com.drdisagree.iconify.R -import com.drdisagree.iconify.common.Const -import com.drdisagree.iconify.common.Const.SYSTEMUI_PACKAGE -import com.drdisagree.iconify.common.Dynamic.skippedInstallation -import com.drdisagree.iconify.common.Preferences.COLOR_ACCENT_PRIMARY -import com.drdisagree.iconify.common.Preferences.COLOR_ACCENT_SECONDARY -import com.drdisagree.iconify.common.Preferences.RESTART_SYSUI_AFTER_BOOT -import com.drdisagree.iconify.common.References.ICONIFY_COLOR_ACCENT_PRIMARY -import com.drdisagree.iconify.common.References.ICONIFY_COLOR_ACCENT_SECONDARY -import com.drdisagree.iconify.common.Resources -import com.drdisagree.iconify.config.Prefs -import com.drdisagree.iconify.utils.helper.BackupRestore.backupFiles -import com.drdisagree.iconify.utils.helper.BinaryInstaller.symLinkBinaries -import com.drdisagree.iconify.utils.overlay.FabricatedUtil -import com.drdisagree.iconify.utils.overlay.OverlayUtil -import com.topjohnwu.superuser.Shell -import net.lingala.zip4j.ZipFile -import net.lingala.zip4j.model.ZipParameters -import net.lingala.zip4j.model.enums.CompressionLevel -import net.lingala.zip4j.model.enums.CompressionMethod -import java.io.File - -object ModuleUtil { - - private val TAG = ModuleUtil::class.java.getSimpleName() - - @JvmStatic - fun handleModule() { - if (moduleExists()) { - // Clean temporary directory - Shell.cmd("rm -rf " + Resources.TEMP_DIR).exec() - - // Backup necessary files - backupFiles() - } - - installModule() - } - - private fun installModule() { - Log.d(TAG, "Magisk module does not exist, creating...") - - // Clean temporary directory - Shell.cmd("mkdir -p " + Resources.TEMP_DIR).exec() - Shell.cmd("mkdir -p " + Resources.TEMP_MODULE_DIR).exec() - - Shell.cmd( - "printf 'id=Iconify\n" + - "name=Iconify\n" + - "version=${BuildConfig.VERSION_NAME}\n" + - "versionCode=${BuildConfig.VERSION_CODE}\n" + - "author=@DrDisagree\n" + - "description=Systemless module for Iconify. ${appContext.resources.getString(R.string.app_moto)}.\n" + - "' > ${Resources.TEMP_MODULE_DIR}/module.prop\n".trimIndent() - ).exec() - - Shell.cmd( - "printf 'MODDIR=${"$"}{0%%/*}\n\n" + - "' > ${Resources.TEMP_MODULE_DIR}/post-fs-data.sh\n".trimIndent() - ).exec() - - if (!skippedInstallation) { - Shell.cmd( - "printf 'MODDIR=${"$"}{0%%/*}\n\n" + - "while [ \"$(getprop sys.boot_completed | tr -d \"\\r\")\" != \"1\" ]\n" + - "do\n" + - " sleep 1\n" + - "done\n" + - "sleep 5\n\n" + - "sh ${"$"}MODDIR/post-exec.sh\n\n" + - "until [ -d /storage/emulated/0/Android ]; do\n" + - " sleep 1\n" + - "done\n" + - "sleep 3\n\n" + - "${ - if (Prefs.getBoolean( - RESTART_SYSUI_AFTER_BOOT, - false - ) - ) "killall $SYSTEMUI_PACKAGE\n" else "" - }sleep 6\n\n" + - "handle_overlay() {\n" + - " local overlay_name=\"\$1\"\n\n" + - " local overlay=\$(cmd overlay list | grep -E \"^.x..${"$"}{overlay_name}.overlay\" | sed -E \"s/^.x..//\")\n" + - " local disableMonet=\$(cmd overlay list | grep -E \"^.x..IconifyComponentDM.overlay\" | sed -E \"s/^.x..//\")\n\n" + - " if ([ ! -z \"${"$"}{overlay}\" ] && [ -z \"${"$"}{disableMonet}\" ])\n" + - " then\n" + - " cmd overlay disable --user current \"${"$"}{overlay_name}.overlay\"\n" + - " cmd overlay enable --user current \"${"$"}{overlay_name}.overlay\"\n" + - " cmd overlay set-priority \"${"$"}{overlay_name}.overlay\" highest\n" + - " fi\n" + - "}\n\n" + - "handle_overlay \"IconifyComponentQSPBD\"\n" + - "handle_overlay \"IconifyComponentQSPBA\"\n\n" + - "' > ${Resources.TEMP_MODULE_DIR}/service.sh".trimIndent() - ).exec() - } else { - Shell.cmd( - "printf 'MODDIR=${"$"}{0%%/*}\n\n" + - "while [ \"$(getprop sys.boot_completed | tr -d \"\\r\")\" != \"1\" ]\n" + - "do\n" + - " sleep 1\n" + - "done\n" + - "sleep 5\n\n" + - "sh ${"$"}MODDIR/post-exec.sh\n" + - "' > ${Resources.TEMP_MODULE_DIR}/service.sh".trimIndent() - ).exec() - } - - Shell.cmd("touch " + Resources.TEMP_MODULE_DIR + "/system.prop").exec() - Shell.cmd("touch " + Resources.TEMP_MODULE_DIR + "/auto_mount").exec() - Shell.cmd("mkdir -p " + Resources.TEMP_MODULE_DIR + "/system").exec() - Shell.cmd("mkdir -p " + Resources.TEMP_MODULE_DIR + "/system/product").exec() - Shell.cmd("mkdir -p " + Resources.TEMP_MODULE_DIR + "/system/product/overlay").exec() - - createMETAINF() - writePostExec() - symLinkBinaries() - - Log.i(TAG, "Magisk module successfully created.") - } - - private fun createMETAINF() { - Shell.cmd("mkdir -p " + Resources.TEMP_MODULE_DIR + "/META-INF").exec() - Shell.cmd("mkdir -p " + Resources.TEMP_MODULE_DIR + "/META-INF/com").exec() - Shell.cmd("mkdir -p " + Resources.TEMP_MODULE_DIR + "/META-INF/com/google").exec() - Shell.cmd("mkdir -p " + Resources.TEMP_MODULE_DIR + "/META-INF/com/google/android").exec() - Shell.cmd( - "printf '" + Const.MAGISK_UPDATE_BINARY + "' > " + Resources.TEMP_MODULE_DIR + "/META-INF/com/google/android/update-binary" - ).exec() - Shell.cmd( - "printf '#MAGISK' > " + Resources.TEMP_MODULE_DIR + "/META-INF/com/google/android/updater-script" - ).exec() - } - - private fun writePostExec() { - val postExec = StringBuilder() - var primaryColorEnabled = false - var secondaryColorEnabled = false - val prefs = appContext.getSharedPreferences(BuildConfig.APPLICATION_ID, Context.MODE_PRIVATE) - val map = prefs.all - - for ((key, value) in map) { - if (value is Boolean && value && key.startsWith("fabricated")) { - val name = key.replace("fabricated", "") - val commands = FabricatedUtil.buildCommands( - Prefs.getString("FOCMDtarget$name")!!, - Prefs.getString("FOCMDname$name")!!, - Prefs.getString("FOCMDtype$name")!!, - Prefs.getString("FOCMDresourceName$name")!!, - Prefs.getString("FOCMDval$name")!! - ) - - postExec.append(commands[0]).append('\n').append(commands[1]).append('\n') - - if (name.contains(COLOR_ACCENT_PRIMARY)) { - primaryColorEnabled = true - } else if (name.contains(COLOR_ACCENT_SECONDARY)) { - secondaryColorEnabled = true - } - } - } - - if (!primaryColorEnabled && shouldUseDefaultColors() && !skippedInstallation) { - postExec.append("cmd overlay fabricate --target android --name IconifyComponentcolorAccentPrimary android:color/holo_blue_light 0x1c $ICONIFY_COLOR_ACCENT_PRIMARY\n") - postExec.append("cmd overlay enable --user current com.android.shell:IconifyComponentcolorAccentPrimary\n") - postExec.append("cmd overlay fabricate --target android --name IconifyComponentcolorAccentPrimaryLight android:color/holo_green_light 0x1c $ICONIFY_COLOR_ACCENT_PRIMARY\n") - postExec.append("cmd overlay enable --user current com.android.shell:IconifyComponentcolorAccentPrimaryLight\n") - } - - if (!secondaryColorEnabled && shouldUseDefaultColors() && !skippedInstallation) { - postExec.append("cmd overlay fabricate --target android --name IconifyComponentcolorAccentSecondary android:color/holo_blue_dark 0x1c $ICONIFY_COLOR_ACCENT_SECONDARY\n") - postExec.append("cmd overlay enable --user current com.android.shell:IconifyComponentcolorAccentSecondary\n") - postExec.append("cmd overlay fabricate --target android --name IconifyComponentcolorAccentSecondaryLight android:color/holo_green_dark 0x1c $ICONIFY_COLOR_ACCENT_SECONDARY\n") - postExec.append("cmd overlay enable --user current com.android.shell:IconifyComponentcolorAccentSecondaryLight\n") - } - - Shell.cmd("printf '" + postExec + "' > " + Resources.TEMP_MODULE_DIR + "/post-exec.sh") - .exec() - } - - private fun shouldUseDefaultColors(): Boolean { - return OverlayUtil.isOverlayDisabled("IconifyComponentAMAC.overlay") && OverlayUtil.isOverlayDisabled( - "IconifyComponentAMGC.overlay" - ) && OverlayUtil.isOverlayDisabled("IconifyComponentME.overlay") - } - - @JvmStatic - fun moduleExists(): Boolean { - return RootUtil.folderExists(Resources.OVERLAY_DIR) - } - - @JvmStatic - @Throws(Exception::class) - fun createModule(sourceFolder: String, destinationFilePath: String): String { - val input = File(sourceFolder) - val output = File(destinationFilePath) - val parameters = ZipParameters() - parameters.isIncludeRootFolder = false - parameters.isOverrideExistingFilesInZip = true - parameters.compressionMethod = CompressionMethod.DEFLATE - parameters.compressionLevel = CompressionLevel.NORMAL - ZipFile(output).use { zipFile -> - zipFile.addFolder(input, parameters) - return zipFile.file.absolutePath - } - } - - @JvmStatic - @Throws(Exception::class) - fun flashModule(modulePath: String): Boolean { - var result: Shell.Result? = null - if (RootUtil.isMagiskInstalled) { - result = Shell.cmd("magisk --install-module $modulePath").exec() - } else if (RootUtil.isKSUInstalled) { - result = Shell.cmd("/data/adb/ksud module install $modulePath").exec() - } else if (RootUtil.isApatchInstalled) { - result = Shell.cmd("apd module install $modulePath").exec() - } - if (result == null) { - throw Exception("No supported root found") - } else if (result.isSuccess) { - Log.i(TAG, "Successfully flashed module") - } else { - Log.e(TAG, "Failed to flash module") - throw Exception(java.lang.String.join("\n", result.out)) - } - return !result.isSuccess - } -} diff --git a/app/src/main/java/com/drdisagree/iconify/utils/ModuleUtils.kt b/app/src/main/java/com/drdisagree/iconify/utils/ModuleUtils.kt new file mode 100644 index 000000000..0ce0cd49f --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/utils/ModuleUtils.kt @@ -0,0 +1,232 @@ +package com.drdisagree.iconify.utils + +import android.content.Context +import android.util.Log +import com.drdisagree.iconify.BuildConfig +import com.drdisagree.iconify.Iconify.Companion.appContext +import com.drdisagree.iconify.R +import com.drdisagree.iconify.common.Const +import com.drdisagree.iconify.common.Const.SYSTEMUI_PACKAGE +import com.drdisagree.iconify.common.Dynamic.skippedInstallation +import com.drdisagree.iconify.common.Preferences.COLOR_ACCENT_PRIMARY +import com.drdisagree.iconify.common.Preferences.COLOR_ACCENT_SECONDARY +import com.drdisagree.iconify.common.Preferences.RESTART_SYSUI_AFTER_BOOT +import com.drdisagree.iconify.common.References.ICONIFY_COLOR_ACCENT_PRIMARY +import com.drdisagree.iconify.common.References.ICONIFY_COLOR_ACCENT_SECONDARY +import com.drdisagree.iconify.common.Resources +import com.drdisagree.iconify.config.RPrefs +import com.drdisagree.iconify.utils.helper.BackupRestore.backupFiles +import com.drdisagree.iconify.utils.helper.BinaryInstaller.symLinkBinaries +import com.drdisagree.iconify.utils.overlay.FabricatedUtils +import com.drdisagree.iconify.utils.overlay.OverlayUtils +import com.topjohnwu.superuser.Shell +import net.lingala.zip4j.ZipFile +import net.lingala.zip4j.model.ZipParameters +import net.lingala.zip4j.model.enums.CompressionLevel +import net.lingala.zip4j.model.enums.CompressionMethod +import java.io.File + +object ModuleUtils { + + private val TAG = ModuleUtils::class.java.getSimpleName() + + fun handleModule() { + if (moduleExists()) { + // Clean temporary directory + Shell.cmd("rm -rf " + Resources.TEMP_DIR).exec() + + // Backup necessary files + backupFiles() + } + + installModule() + } + + private fun installModule() { + Log.d(TAG, "Magisk module does not exist, creating...") + + // Clean temporary directory + Shell.cmd("mkdir -p " + Resources.TEMP_DIR).exec() + Shell.cmd("mkdir -p " + Resources.TEMP_MODULE_DIR).exec() + + Shell.cmd( + "printf 'id=Iconify\n" + + "name=Iconify\n" + + "version=${BuildConfig.VERSION_NAME}\n" + + "versionCode=${BuildConfig.VERSION_CODE}\n" + + "author=@DrDisagree\n" + + "description=Systemless module for Iconify. ${appContext.resources.getString(R.string.app_moto)}.\n" + + "' > ${Resources.TEMP_MODULE_DIR}/module.prop\n".trimIndent() + ).exec() + + Shell.cmd( + "printf 'MODDIR=${"$"}{0%%/*}\n\n" + + "' > ${Resources.TEMP_MODULE_DIR}/post-fs-data.sh\n".trimIndent() + ).exec() + + if (!skippedInstallation) { + Shell.cmd( + "printf 'MODDIR=${"$"}{0%%/*}\n\n" + + "while [ \"$(getprop sys.boot_completed | tr -d \"\\r\")\" != \"1\" ]\n" + + "do\n" + + " sleep 1\n" + + "done\n" + + "sleep 5\n\n" + + "sh ${"$"}MODDIR/post-exec.sh\n\n" + + "until [ -d /storage/emulated/0/Android ]; do\n" + + " sleep 1\n" + + "done\n" + + "sleep 3\n\n" + + "${ + if (RPrefs.getBoolean( + RESTART_SYSUI_AFTER_BOOT, + false + ) + ) "killall $SYSTEMUI_PACKAGE\n" else "" + }sleep 6\n\n" + + "handle_overlay() {\n" + + " local overlay_name=\"\$1\"\n\n" + + " local overlay=\$(cmd overlay list | grep -E \"^.x..${"$"}{overlay_name}.overlay\" | sed -E \"s/^.x..//\")\n" + + " local disableMonet=\$(cmd overlay list | grep -E \"^.x..IconifyComponentDM.overlay\" | sed -E \"s/^.x..//\")\n\n" + + " if ([ ! -z \"${"$"}{overlay}\" ] && [ -z \"${"$"}{disableMonet}\" ])\n" + + " then\n" + + " cmd overlay disable --user current \"${"$"}{overlay_name}.overlay\"\n" + + " cmd overlay enable --user current \"${"$"}{overlay_name}.overlay\"\n" + + " cmd overlay set-priority \"${"$"}{overlay_name}.overlay\" highest\n" + + " fi\n" + + "}\n\n" + + "handle_overlay \"IconifyComponentQSPBD\"\n" + + "handle_overlay \"IconifyComponentQSPBA\"\n\n" + + "' > ${Resources.TEMP_MODULE_DIR}/service.sh".trimIndent() + ).exec() + } else { + Shell.cmd( + "printf 'MODDIR=${"$"}{0%%/*}\n\n" + + "while [ \"$(getprop sys.boot_completed | tr -d \"\\r\")\" != \"1\" ]\n" + + "do\n" + + " sleep 1\n" + + "done\n" + + "sleep 5\n\n" + + "sh ${"$"}MODDIR/post-exec.sh\n" + + "' > ${Resources.TEMP_MODULE_DIR}/service.sh".trimIndent() + ).exec() + } + + Shell.cmd("touch " + Resources.TEMP_MODULE_DIR + "/system.prop").exec() + Shell.cmd("touch " + Resources.TEMP_MODULE_DIR + "/auto_mount").exec() + Shell.cmd("mkdir -p " + Resources.TEMP_MODULE_DIR + "/system").exec() + Shell.cmd("mkdir -p " + Resources.TEMP_MODULE_DIR + "/system/product").exec() + Shell.cmd("mkdir -p " + Resources.TEMP_MODULE_DIR + "/system/product/overlay").exec() + + createMETAINF() + writePostExec() + symLinkBinaries() + + Log.i(TAG, "Magisk module successfully created.") + } + + private fun createMETAINF() { + Shell.cmd("mkdir -p " + Resources.TEMP_MODULE_DIR + "/META-INF").exec() + Shell.cmd("mkdir -p " + Resources.TEMP_MODULE_DIR + "/META-INF/com").exec() + Shell.cmd("mkdir -p " + Resources.TEMP_MODULE_DIR + "/META-INF/com/google").exec() + Shell.cmd("mkdir -p " + Resources.TEMP_MODULE_DIR + "/META-INF/com/google/android").exec() + Shell.cmd( + "printf '" + Const.MAGISK_UPDATE_BINARY + "' > " + Resources.TEMP_MODULE_DIR + "/META-INF/com/google/android/update-binary" + ).exec() + Shell.cmd( + "printf '#MAGISK' > " + Resources.TEMP_MODULE_DIR + "/META-INF/com/google/android/updater-script" + ).exec() + } + + private fun writePostExec() { + val postExec = StringBuilder() + var primaryColorEnabled = false + var secondaryColorEnabled = false + val prefs = appContext.getSharedPreferences(BuildConfig.APPLICATION_ID, Context.MODE_PRIVATE) + val map = prefs.all + + for ((key, value) in map) { + if (value is Boolean && value && key.startsWith("fabricated")) { + val name = key.replace("fabricated", "") + val commands = FabricatedUtils.buildCommands( + RPrefs.getString("FOCMDtarget$name")!!, + RPrefs.getString("FOCMDname$name")!!, + RPrefs.getString("FOCMDtype$name")!!, + RPrefs.getString("FOCMDresourceName$name")!!, + RPrefs.getString("FOCMDval$name")!! + ) + + postExec.append(commands[0]).append('\n').append(commands[1]).append('\n') + + if (name.contains(COLOR_ACCENT_PRIMARY)) { + primaryColorEnabled = true + } else if (name.contains(COLOR_ACCENT_SECONDARY)) { + secondaryColorEnabled = true + } + } + } + + if (!primaryColorEnabled && shouldUseDefaultColors() && !skippedInstallation) { + postExec.append("cmd overlay fabricate --target android --name IconifyComponentcolorAccentPrimary android:color/holo_blue_light 0x1c $ICONIFY_COLOR_ACCENT_PRIMARY\n") + postExec.append("cmd overlay enable --user current com.android.shell:IconifyComponentcolorAccentPrimary\n") + postExec.append("cmd overlay fabricate --target android --name IconifyComponentcolorAccentPrimaryLight android:color/holo_green_light 0x1c $ICONIFY_COLOR_ACCENT_PRIMARY\n") + postExec.append("cmd overlay enable --user current com.android.shell:IconifyComponentcolorAccentPrimaryLight\n") + } + + if (!secondaryColorEnabled && shouldUseDefaultColors() && !skippedInstallation) { + postExec.append("cmd overlay fabricate --target android --name IconifyComponentcolorAccentSecondary android:color/holo_blue_dark 0x1c $ICONIFY_COLOR_ACCENT_SECONDARY\n") + postExec.append("cmd overlay enable --user current com.android.shell:IconifyComponentcolorAccentSecondary\n") + postExec.append("cmd overlay fabricate --target android --name IconifyComponentcolorAccentSecondaryLight android:color/holo_green_dark 0x1c $ICONIFY_COLOR_ACCENT_SECONDARY\n") + postExec.append("cmd overlay enable --user current com.android.shell:IconifyComponentcolorAccentSecondaryLight\n") + } + + Shell.cmd("printf '" + postExec + "' > " + Resources.TEMP_MODULE_DIR + "/post-exec.sh") + .exec() + } + + private fun shouldUseDefaultColors(): Boolean { + return OverlayUtils.isOverlayDisabled("IconifyComponentAMAC.overlay") && OverlayUtils.isOverlayDisabled( + "IconifyComponentAMGC.overlay" + ) && OverlayUtils.isOverlayDisabled("IconifyComponentME.overlay") + } + + fun moduleExists(): Boolean { + return RootUtils.folderExists(Resources.OVERLAY_DIR) + } + + @Throws(Exception::class) + fun createModule(sourceFolder: String, destinationFilePath: String): String { + val input = File(sourceFolder) + val output = File(destinationFilePath) + val parameters = ZipParameters() + parameters.isIncludeRootFolder = false + parameters.isOverrideExistingFilesInZip = true + parameters.compressionMethod = CompressionMethod.DEFLATE + parameters.compressionLevel = CompressionLevel.NORMAL + ZipFile(output).use { zipFile -> + zipFile.addFolder(input, parameters) + return zipFile.file.absolutePath + } + } + + @Throws(Exception::class) + fun flashModule(modulePath: String): Boolean { + var result: Shell.Result? = null + if (RootUtils.isMagiskInstalled) { + result = Shell.cmd("magisk --install-module $modulePath").exec() + } else if (RootUtils.isKSUInstalled) { + result = Shell.cmd("/data/adb/ksud module install $modulePath").exec() + } else if (RootUtils.isApatchInstalled) { + result = Shell.cmd("apd module install $modulePath").exec() + } + if (result == null) { + throw Exception("No supported root found") + } else if (result.isSuccess) { + Log.i(TAG, "Successfully flashed module") + } else { + Log.e(TAG, "Failed to flash module") + throw Exception(java.lang.String.join("\n", result.out)) + } + return !result.isSuccess + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/utils/NetworkUtils.java b/app/src/main/java/com/drdisagree/iconify/utils/NetworkUtils.java new file mode 100644 index 000000000..680e0db11 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/utils/NetworkUtils.java @@ -0,0 +1,159 @@ +package com.drdisagree.iconify.utils; + +/* + * Copyright (C) 2018 The OmniROM Project + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +import android.util.Log; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import javax.net.ssl.HttpsURLConnection; + +public class NetworkUtils { + private static final boolean DEBUG = false; + private static final String TAG = "NetworkUtils"; + + private static final int HTTP_READ_TIMEOUT = 60000; + private static final int HTTP_CONNECTION_TIMEOUT = 60000; + + private static final ExecutorService executor = Executors.newSingleThreadExecutor(); + + public static void downloadUrlMemoryAsString(String url, DownloadCallback callback) { + executor.submit(() -> { + String result = downloadUrlMemoryAsString(url); + if (callback != null) { + callback.onDownloadComplete(result); + } + }); + } + + public static HttpsURLConnection setupHttpsRequest(String urlStr) { + URL url; + HttpsURLConnection urlConnection = null; + try { + url = new URL(urlStr); + urlConnection = (HttpsURLConnection) url.openConnection(); + urlConnection.setConnectTimeout(HTTP_CONNECTION_TIMEOUT); + urlConnection.setReadTimeout(HTTP_READ_TIMEOUT); + urlConnection.setRequestMethod("GET"); + urlConnection.setDoInput(true); + urlConnection.connect(); + int code = urlConnection.getResponseCode(); + if (code != HttpsURLConnection.HTTP_OK) { + Log.d(TAG, "response:" + code); + return null; + } + return urlConnection; + } catch (Exception e) { + Log.e(TAG, "Failed to connect to server", e); + return null; + } + } + + public static boolean downloadUrlFile(String url, File f) { + if (DEBUG) Log.d(TAG, "download:" + url); + + HttpsURLConnection urlConnection = null; + + if (f.exists()) + f.delete(); + + try { + urlConnection = setupHttpsRequest(url); + if (urlConnection == null) { + return false; + } + long len = urlConnection.getContentLength(); + if ((len > 0) && (len < 4L * 1024L * 1024L * 1024L)) { + byte[] buffer = new byte[262144]; + + InputStream is = urlConnection.getInputStream(); + FileOutputStream os = new FileOutputStream(f, false); + try { + int r; + while ((r = is.read(buffer)) > 0) { + os.write(buffer, 0, r); + } + } finally { + os.close(); + } + + return true; + } + return false; + } catch (Exception e) { + // Download failed for any number of reasons, timeouts, connection + // drops, etc. Just log it in debugging mode. + Log.e(TAG, "", e); + return false; + } finally { + if (urlConnection != null) { + urlConnection.disconnect(); + } + } + } + + + public static String downloadUrlMemoryAsString(String url) { + if (DEBUG) Log.d(TAG, "download: " + url); + + HttpsURLConnection urlConnection = null; + try { + urlConnection = setupHttpsRequest(url); + if (urlConnection == null) { + return null; + } + + InputStream is = urlConnection.getInputStream(); + ByteArrayOutputStream byteArray = new ByteArrayOutputStream(); + int byteInt; + + while ((byteInt = is.read()) >= 0) { + byteArray.write(byteInt); + } + + byte[] bytes = byteArray.toByteArray(); + if (bytes == null) { + return null; + } + + return new String(bytes, StandardCharsets.UTF_8); + } catch (Exception e) { + // Download failed for any number of reasons, timeouts, connection + // drops, etc. Just log it in debugging mode. + Log.e(TAG, "", e); + return null; + } finally { + if (urlConnection != null) { + urlConnection.disconnect(); + } + } + } + + public interface DownloadCallback { + void onDownloadComplete(String result); + } + +} diff --git a/app/src/main/java/com/drdisagree/iconify/utils/OmniJawsClient.kt b/app/src/main/java/com/drdisagree/iconify/utils/OmniJawsClient.kt new file mode 100644 index 000000000..b4a013802 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/utils/OmniJawsClient.kt @@ -0,0 +1,416 @@ +package com.drdisagree.iconify.utils + +import android.annotation.SuppressLint +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import android.content.IntentFilter +import android.content.res.Resources +import android.graphics.Color +import android.graphics.drawable.ColorDrawable +import android.graphics.drawable.Drawable +import android.net.Uri +import android.os.Build +import android.text.TextUtils +import android.text.format.DateFormat +import android.util.Log +import com.drdisagree.iconify.BuildConfig +import com.drdisagree.iconify.utils.weather.WeatherConfig +import java.text.DecimalFormat +import java.text.SimpleDateFormat +import java.util.Date +import java.util.Locale + +/* + * Copyright (C) 2021 The OmniROM Project + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +class OmniJawsClient(private val mContext: Context) { + + class WeatherInfo(private val mContext: Context) { + var city: String? = null + var windSpeed: String? = null + var windDirection: String? = null + var conditionCode: Int = 0 + var temp: String? = null + var humidity: String? = null + var condition: String? = null + var timeStamp: Long = 0 + var forecasts: List? = null + var tempUnits: String? = null + var windUnits: String? = null + var provider: String? = null + var pinWheel: String? = null + var iconPack: String? = null + + override fun toString(): String { + return city + ":" + Date(timeStamp) + ": " + windSpeed + ":" + windDirection + ":" + conditionCode + ":" + temp + ":" + humidity + ":" + condition + ":" + tempUnits + ":" + windUnits + ": " + forecasts + ": " + iconPack + } + + val lastUpdateTime: String + get() { + val hourFormat = if (DateFormat.is24HourFormat(mContext)) "HH" else "hh" + val sdf = SimpleDateFormat("$hourFormat:mm:ss", Locale.getDefault()) + return sdf.format(Date(timeStamp)) + } + } + + class DayForecast { + var low: String? = null + var high: String? = null + var conditionCode: Int = 0 + var condition: String? = null + var date: String? = null + + override fun toString(): String { + return "[$low:$high:$conditionCode:$condition:$date]" + } + } + + interface OmniJawsObserver { + fun weatherUpdated() + fun weatherError(errorReason: Int) + fun updateSettings() {} + } + + private inner class WeatherUpdateReceiver : BroadcastReceiver() { + override fun onReceive(context: Context, intent: Intent) { + val action = intent.action + for (observer in mObserver) { + if (action == WEATHER_UPDATE) { + observer.weatherUpdated() + } + if (action == WEATHER_ERROR) { + val errorReason = intent.getIntExtra(EXTRA_ERROR, 0) + observer.weatherError(errorReason) + } + } + } + } + + var weatherInfo: WeatherInfo? = null + private var mRes: Resources? = null + private var mPackageName: String? = null + private var mIconPrefix: String? = null + private var mSettingIconPackage: String? = null + private var mMetric = false + private val mObserver: MutableList = ArrayList() + private var mReceiver: WeatherUpdateReceiver? = null + + fun queryWeather() { + try { + weatherInfo = null + + var cursor = mContext.contentResolver.query( + WEATHER_URI, WEATHER_PROJECTION, + null, null, null + ) + + cursor?.use { + val count = it.count + + if (count > 0) { + weatherInfo = WeatherInfo(mContext) + val forecastList: MutableList = ArrayList() + var i = 0 + + while (i < count) { + it.moveToPosition(i) + + if (i == 0) { + weatherInfo?.apply { + city = it.getString(0) + windSpeed = getFormattedValue(it.getFloat(1)) + weatherInfo!!.windDirection = it.getInt(2).toString() + "\u00b0" + weatherInfo!!.conditionCode = it.getInt(3) + weatherInfo!!.temp = getFormattedValue(it.getFloat(4)) + weatherInfo!!.humidity = it.getString(5) + weatherInfo!!.condition = it.getString(6) + weatherInfo!!.timeStamp = it.getString(11).toLong() + weatherInfo!!.pinWheel = it.getString(13) + } + } else { + val day = DayForecast() + day.low = getFormattedValue(it.getFloat(7)) + day.high = getFormattedValue(it.getFloat(8)) + day.condition = it.getString(9) + day.conditionCode = it.getInt(10) + day.date = it.getString(12) + forecastList.add(day) + } + i++ + } + weatherInfo!!.forecasts = forecastList + } + } + + cursor = mContext.contentResolver.query( + SETTINGS_URI, SETTINGS_PROJECTION, + null, null, null + ) + + cursor?.use { + val count = it.count + + if (count == 1) { + it.moveToPosition(0) + mMetric = it.getInt(1) == 0 + + weatherInfo?.apply { + tempUnits = temperatureUnit + windUnits = windUnit + provider = it.getString(2) + iconPack = it.getString(4) + } + } + } + + updateSettings() + } catch (e: Exception) { + Log.e(TAG, "queryWeather", e) + } + } + + private fun loadDefaultIconsPackage() { + mPackageName = ICON_PACKAGE_DEFAULT + mIconPrefix = ICON_PREFIX_DEFAULT + mSettingIconPackage = "$mPackageName.$mIconPrefix" + + if (DEBUG) Log.d( + TAG, + "Load default icon pack $mSettingIconPackage $mPackageName $mIconPrefix" + ) + + try { + val packageManager = mContext.packageManager + mRes = packageManager.getResourcesForApplication(mPackageName!!) + } catch (e: Exception) { + Log.d(TAG, "loadDefaultIconsPackage", e) + mRes = null + } + + if (mRes == null) { + Log.w(TAG, "No default package found") + } + } + + @Suppress("deprecation") + private val defaultConditionImage: Drawable + @SuppressLint("DiscouragedApi", "UseCompatLoadingForDrawables") + get() { + val packageName = ICON_PACKAGE_DEFAULT + val iconPrefix = ICON_PREFIX_DEFAULT + + try { + val packageManager = mContext.packageManager + val res = packageManager.getResourcesForApplication(packageName) + val resId = res.getIdentifier(iconPrefix + "_na", "drawable", packageName) + val d = mRes!!.getDrawable(resId) + + if (d != null) { + return d + } + } catch (e: Exception) { + Log.e(TAG, "defaultConditionImage", e) + } + + // absolute absolute fallback + Log.w(TAG, "No default package found") + + return ColorDrawable(Color.RED) + } + + private fun loadCustomIconPackage() { + if (DEBUG) Log.d( + TAG, + "Load custom icon pack $mSettingIconPackage" + ) + + val idx = mSettingIconPackage!!.lastIndexOf(".") + mPackageName = mSettingIconPackage!!.substring(0, idx) + mIconPrefix = mSettingIconPackage!!.substring(idx + 1) + + if (DEBUG) Log.d( + TAG, + "Load custom icon pack $mPackageName $mIconPrefix" + ) + + try { + val packageManager = mContext.packageManager + mRes = packageManager.getResourcesForApplication(mPackageName!!) + } catch (e: Exception) { + Log.w(TAG, "Icon pack loading failed - loading default") + loadDefaultIconsPackage() + } + } + + @Suppress("deprecation") + @SuppressLint("DiscouragedApi", "UseCompatLoadingForDrawables") + fun getWeatherConditionImage(conditionCode: Int): Drawable { + try { + var resId = mRes!!.getIdentifier( + mIconPrefix + "_" + conditionCode, + "drawable", + mPackageName + ) + var d = mRes!!.getDrawable(resId) + if (d != null) { + return d + } + + Log.w( + TAG, + "Failed to get condition image for $conditionCode use default" + ) + + resId = mRes!!.getIdentifier(mIconPrefix + "_na", "drawable", mPackageName) + d = mRes!!.getDrawable(resId) + + if (d != null) { + return d + } + } catch (e: Exception) { + Log.e(TAG, "getWeatherConditionImage", e) + } + Log.w( + TAG, + "Failed to get condition image for $conditionCode" + ) + return defaultConditionImage + } + + val isOmniJawsEnabled: Boolean + get() = WeatherConfig.isEnabled(mContext) + + private val temperatureUnit: String + get() = "\u00b0" + (if (mMetric) "C" else "F") + + private val windUnit: String + get() = if (mMetric) "km/h" else "mph" + + private fun updateSettings() { + val iconPack = if (weatherInfo != null) weatherInfo!!.iconPack else null + if (TextUtils.isEmpty(iconPack)) { + Log.d(TAG, "updateSettings No icon pack set, using default") + loadDefaultIconsPackage() + } else if (iconPack != mSettingIconPackage) { + Log.d( + TAG, + "updateSettings New icon pack set, loading $iconPack" + ) + mSettingIconPackage = iconPack + loadCustomIconPackage() + } + } + + @SuppressLint("UnspecifiedRegisterReceiverFlag") + fun addObserver(observer: OmniJawsObserver) { + if (mObserver.isEmpty()) { + if (mReceiver != null) { + try { + mContext.unregisterReceiver(mReceiver) + } catch (ignored: Exception) { + } + } + mReceiver = WeatherUpdateReceiver() + val filter = IntentFilter() + filter.addAction(WEATHER_UPDATE) + filter.addAction(WEATHER_ERROR) + if (DEBUG) Log.d(TAG, "registerReceiver") + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + mContext.registerReceiver(mReceiver, filter, Context.RECEIVER_EXPORTED) + } else { + mContext.registerReceiver(mReceiver, filter) + } + } + mObserver.add(observer) + } + + fun removeObserver(observer: OmniJawsObserver) { + mObserver.remove(observer) + if (mObserver.isEmpty() && mReceiver != null) { + try { + if (DEBUG) Log.d(TAG, "unregisterReceiver") + mContext.unregisterReceiver(mReceiver) + } catch (ignored: Exception) { + } + mReceiver = null + } + } + + companion object { + private const val TAG = "OmniJawsClient" + private val DEBUG = BuildConfig.DEBUG + private const val SERVICE_PACKAGE: String = BuildConfig.APPLICATION_ID + val WEATHER_URI + : Uri = Uri.parse("content://com.drdisagree.iconify.weatherprovider/weather") + val SETTINGS_URI + : Uri = Uri.parse("content://com.drdisagree.iconify.weatherprovider/settings") + val CONTROL_URI + : Uri = Uri.parse("content://com.drdisagree.iconify.weatherprovider/control") + + private const val ICON_PACKAGE_DEFAULT = BuildConfig.APPLICATION_ID + private const val ICON_PREFIX_DEFAULT = "google" + private const val ICON_PREFIX_OUTLINE = "outline" + private const val EXTRA_ERROR = "error" + const val EXTRA_ERROR_NETWORK: Int = 0 // No Network + const val EXTRA_ERROR_LOCATION: Int = 1 // No Location Found + const val EXTRA_ERROR_DISABLED: Int = 2 // Disabled + const val EXTRA_ERROR_NO_PERMISSIONS: Int = 3 // No Permissions + + val WEATHER_PROJECTION: Array = arrayOf( + "city", + "wind_speed", + "wind_direction", + "condition_code", + "temperature", + "humidity", + "condition", + "forecast_low", + "forecast_high", + "forecast_condition", + "forecast_condition_code", + "time_stamp", + "forecast_date", + "pin_wheel" + ) + + val SETTINGS_PROJECTION: Array = arrayOf( + "enabled", + "units", + "provider", + "setup", + "icon_pack" + ) + + private const val WEATHER_UPDATE = "$SERVICE_PACKAGE.WEATHER_UPDATE" + private const val WEATHER_ERROR = "$SERVICE_PACKAGE.WEATHER_ERROR" + + private val sNoDigitsFormat = DecimalFormat("0") + + private fun getFormattedValue(value: Float): String { + if (java.lang.Float.isNaN(value)) { + return "-" + } + var formatted = sNoDigitsFormat.format(value.toDouble()) + if (formatted == "-0") { + formatted = "0" + } + return formatted + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/utils/RootUtil.kt b/app/src/main/java/com/drdisagree/iconify/utils/RootUtil.kt deleted file mode 100644 index 3cd197ea5..000000000 --- a/app/src/main/java/com/drdisagree/iconify/utils/RootUtil.kt +++ /dev/null @@ -1,67 +0,0 @@ -package com.drdisagree.iconify.utils - -import com.topjohnwu.superuser.Shell - -object RootUtil { - - @JvmStatic - val isDeviceRooted: Boolean - get() = java.lang.Boolean.TRUE == Shell.isAppGrantedRoot() - - @JvmStatic - val isMagiskInstalled: Boolean - get() = Shell.cmd("magisk -v").exec().isSuccess - - @JvmStatic - val isKSUInstalled: Boolean - get() = Shell.cmd("/data/adb/ksud -h").exec().isSuccess - - @JvmStatic - val isApatchInstalled: Boolean - get() = Shell.cmd("apd --help").exec().isSuccess - - fun moduleExists(moduleId: String): Boolean { - return folderExists("/data/adb/modules/$moduleId") - } - - @JvmStatic - fun setPermissions(permission: Int, filename: String) { - Shell.cmd("chmod $permission $filename").exec() - } - - fun setPermissionsRecursively(permission: Int, folderName: String) { - Shell.cmd("chmod -R $permission $folderName").exec() - val perm = permission.toString() - - if (!Shell.cmd("stat -c '%a' $folderName").exec().out.contains(perm) || !Shell.cmd( - "fl=$(find '$folderName' -type f -mindepth 1 -print -quit); stat -c '%a' \$fl" - ).exec().out.contains(perm) - ) Shell.cmd("for file in $folderName*; do chmod $permission \"\$file\"; done").exec() - } - - fun fileExists(dir: String): Boolean { - val lines = Shell.cmd("test -f $dir && echo '1'").exec().out - - for (line in lines) { - if (line.contains("1")) return true - } - - return false - } - - @JvmStatic - fun folderExists(dir: String): Boolean { - val lines = Shell.cmd("test -d $dir && echo '1'").exec().out - - for (line in lines) { - if (line.contains("1")) return true - } - - return false - } - - @JvmStatic - fun deviceProperlyRooted(): Boolean { - return isDeviceRooted && (isMagiskInstalled || isKSUInstalled || isApatchInstalled) - } -} diff --git a/app/src/main/java/com/drdisagree/iconify/utils/RootUtils.kt b/app/src/main/java/com/drdisagree/iconify/utils/RootUtils.kt new file mode 100644 index 000000000..1f21c20d1 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/utils/RootUtils.kt @@ -0,0 +1,60 @@ +package com.drdisagree.iconify.utils + +import com.topjohnwu.superuser.Shell + +object RootUtils { + + val isDeviceRooted: Boolean + get() = java.lang.Boolean.TRUE == Shell.isAppGrantedRoot() + + val isMagiskInstalled: Boolean + get() = Shell.cmd("magisk -v").exec().isSuccess + + val isKSUInstalled: Boolean + get() = Shell.cmd("/data/adb/ksud -h").exec().isSuccess + + val isApatchInstalled: Boolean + get() = Shell.cmd("apd --help").exec().isSuccess + + fun moduleExists(moduleId: String): Boolean { + return folderExists("/data/adb/modules/$moduleId") + } + + fun setPermissions(permission: Int, filename: String) { + Shell.cmd("chmod $permission $filename").exec() + } + + fun setPermissionsRecursively(permission: Int, folderName: String) { + Shell.cmd("chmod -R $permission $folderName").exec() + val perm = permission.toString() + + if (!Shell.cmd("stat -c '%a' $folderName").exec().out.contains(perm) || !Shell.cmd( + "fl=$(find '$folderName' -type f -mindepth 1 -print -quit); stat -c '%a' \$fl" + ).exec().out.contains(perm) + ) Shell.cmd("for file in $folderName*; do chmod $permission \"\$file\"; done").exec() + } + + fun fileExists(dir: String): Boolean { + val lines = Shell.cmd("test -f $dir && echo '1'").exec().out + + for (line in lines) { + if (line.contains("1")) return true + } + + return false + } + + fun folderExists(dir: String): Boolean { + val lines = Shell.cmd("test -d $dir && echo '1'").exec().out + + for (line in lines) { + if (line.contains("1")) return true + } + + return false + } + + fun deviceProperlyRooted(): Boolean { + return isDeviceRooted && (isMagiskInstalled || isKSUInstalled || isApatchInstalled) + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/utils/SystemUtil.kt b/app/src/main/java/com/drdisagree/iconify/utils/SystemUtil.kt deleted file mode 100644 index d52d0268e..000000000 --- a/app/src/main/java/com/drdisagree/iconify/utils/SystemUtil.kt +++ /dev/null @@ -1,279 +0,0 @@ -package com.drdisagree.iconify.utils - -import android.Manifest -import android.app.Activity -import android.content.Context -import android.content.Intent -import android.content.res.Configuration -import android.net.Uri -import android.os.Environment -import android.provider.Settings -import android.view.WindowInsets -import android.widget.Toast -import androidx.core.app.ActivityCompat -import com.drdisagree.iconify.BuildConfig -import com.drdisagree.iconify.Iconify.Companion.appContext -import com.drdisagree.iconify.R -import com.drdisagree.iconify.common.Const.SYSTEMUI_PACKAGE -import com.drdisagree.iconify.common.Preferences.BOOT_ID -import com.drdisagree.iconify.common.Preferences.FORCE_RELOAD_OVERLAY_STATE -import com.drdisagree.iconify.common.Preferences.FORCE_RELOAD_PACKAGE_NAME -import com.drdisagree.iconify.common.Preferences.RESTART_SYSUI_BEHAVIOR_EXT -import com.drdisagree.iconify.common.Preferences.VER_CODE -import com.drdisagree.iconify.common.References.DEVICE_BOOT_ID_CMD -import com.drdisagree.iconify.common.Resources -import com.drdisagree.iconify.config.Prefs -import com.drdisagree.iconify.config.Prefs.putString -import com.drdisagree.iconify.config.RPrefs -import com.drdisagree.iconify.xposed.utils.BootLoopProtector.LOAD_TIME_KEY_KEY -import com.drdisagree.iconify.xposed.utils.BootLoopProtector.PACKAGE_STRIKE_KEY_KEY -import com.topjohnwu.superuser.Shell -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.delay -import kotlinx.coroutines.launch -import java.util.Calendar - -object SystemUtil { - - private var darkSwitching = false - private const val BLUR_CMD_0 = - "resetprop ro.surface_flinger.supports_background_blur 1 && killall surfaceflinger" - private const val BLUR_CMD_1 = "ro.sf.blurs_are_expensive=1" - private const val BLUR_CMD_2 = "ro.surface_flinger.supports_background_blur=1" - private const val BLUR_CMD_3 = "persist.sys.sf.disable_blurs=0" - private const val BLUR_CMD_4 = "persist.sysui.disableBlur=false" - private const val BLUR_CMD_5 = "ro.config.avoid_gfx_accel=false" - - @JvmStatic - val isDarkMode: Boolean - get() = appContext.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_YES == Configuration.UI_MODE_NIGHT_YES - - @JvmStatic - fun restartSystemUI() { - val loadTimeKey = String.format("%s%s", LOAD_TIME_KEY_KEY, SYSTEMUI_PACKAGE) - val strikeKey = String.format("%s%s", PACKAGE_STRIKE_KEY_KEY, SYSTEMUI_PACKAGE) - val currentTime = Calendar.getInstance().time.time - - RPrefs.putLong(loadTimeKey, currentTime) - RPrefs.putInt(strikeKey, 0) - Shell.cmd("killall $SYSTEMUI_PACKAGE").submit() - } - - private fun forceReloadUI() { - val state = RPrefs.getBoolean(FORCE_RELOAD_OVERLAY_STATE, false) - val pkgName: String = FORCE_RELOAD_PACKAGE_NAME - - Shell.cmd( - "cmd overlay " + (if (state) "disable" else "enable") + " --user current " + pkgName + "; cmd overlay " + (if (state) "enable" else "disable") + " --user current " + pkgName - ).submit() - } - - @JvmStatic - fun handleSystemUIRestart() { - val selectedBehavior = RPrefs.getInt(RESTART_SYSUI_BEHAVIOR_EXT, 0) - - when (selectedBehavior) { - 0 -> { - restartSystemUI() - } - - 1 -> { - forceReloadUI() - } - - else -> { - Toast.makeText( - appContext, - appContext.resources.getString(R.string.settings_systemui_restart_required), - Toast.LENGTH_SHORT - ).show() - } - } - } - - @JvmStatic - fun restartDevice() { - Shell.cmd("am start -a android.intent.action.REBOOT").exec() - } - - @JvmStatic - fun disableBlur(force: Boolean) { - Shell.cmd( - if (!force) "mv " + Resources.MODULE_DIR + - "/system.prop " + - Resources.MODULE_DIR + - "/system.txt; " + - "grep -vE \"" + - BLUR_CMD_1 + "|" + - BLUR_CMD_2 + "|" + - BLUR_CMD_3 + "|" + - BLUR_CMD_4 + "|" + - BLUR_CMD_5 + "\" " + - Resources.MODULE_DIR + - "/system.txt > " + - Resources.MODULE_DIR + - "/system.txt.tmp; " + - "rm -rf " + - Resources.MODULE_DIR + - "/system.prop; " + - "mv " + Resources.MODULE_DIR + - "/system.txt.tmp " + - Resources.MODULE_DIR + - "/system.prop; " + - "rm -rf " + Resources.MODULE_DIR + - "/system.txt; " + - "rm -rf " + Resources.MODULE_DIR + - "/system.txt.tmp" else ":", // do nothing - "grep -v \"ro.surface_flinger.supports_background_blur\" " + - Resources.MODULE_DIR + "/service.sh > " + - Resources.MODULE_DIR + "/service.sh.tmp && mv " + - Resources.MODULE_DIR + "/service.sh.tmp " + - Resources.MODULE_DIR + "/service.sh" - ).submit() - } - - @JvmStatic - fun enableBlur(force: Boolean) { - disableBlur(false) - Shell.cmd( - "echo \"$BLUR_CMD_1\n$BLUR_CMD_2\n$BLUR_CMD_3\n$BLUR_CMD_4\n$BLUR_CMD_5\"" + - " >> ${Resources.MODULE_DIR}/system.prop", - if (force) "sed '/*}/a " + - BLUR_CMD_0 + "' " + - Resources.MODULE_DIR + - "/service.sh > " + - Resources.MODULE_DIR + - "/service.sh.tmp && mv " + - Resources.MODULE_DIR + - "/service.sh.tmp " + - Resources.MODULE_DIR + - "/service.sh" else ":" // do nothing - ).submit() - } - - @JvmStatic - fun mountRW() { - Shell.cmd("mount -o remount,rw /").exec() - - if (RootUtil.moduleExists("magisk_overlayfs")) { - Shell.cmd("-mm -c magic_remount_rw").exec() - } else if (RootUtil.moduleExists("overlayfs")) { - Shell.cmd("/data/overlayfs/tmp/overlayrw -rw /system/product/overlay").exec() - } - } - - @JvmStatic - fun mountRO() { - Shell.cmd("mount -o remount,ro /").exec() - - if (RootUtil.moduleExists("magisk_overlayfs")) { - Shell.cmd("-mm -c magic_remount_ro").exec() - } else if (RootUtil.moduleExists("overlayfs")) { - Shell.cmd("/data/overlayfs/tmp/overlayrw -ro /system/product/overlay").exec() - } - } - - /* - * From AOSPMods - * https://github.com/siavash79/AOSPMods/blob/canary/app/src/main/java/sh/siava/AOSPMods/utils/SystemUtils.java - */ - @JvmStatic - fun doubleToggleDarkMode() { - val isDark = isDarkMode - - CoroutineScope(Dispatchers.Default).launch { - try { - while (darkSwitching) { - delay(100) - } - - darkSwitching = true - - Shell.cmd("cmd uimode night ${if (isDark) "no" else "yes"}").exec() - delay(1000) - Shell.cmd("cmd uimode night ${if (isDark) "yes" else "no"}").exec() - delay(500) - - darkSwitching = false - } catch (ignored: Exception) { - } - } - } - - @JvmStatic - fun isBlurEnabled(force: Boolean): Boolean { - return Shell.cmd( - "if grep -q \"ro.surface_flinger.supports_background_blur\" " + - Resources.MODULE_DIR + - (if (force) "/service.sh;" else "/system.prop;") + - " then echo yes; else echo no; fi" - ).exec().out[0] == "yes" - } - - @JvmStatic - val saveBootId: Unit // Save unique id of each boot - get() { - putString(BOOT_ID, Shell.cmd(DEVICE_BOOT_ID_CMD).exec().out.toString()) - } - - @JvmStatic - fun saveVersionCode() { - Prefs.putInt(VER_CODE, BuildConfig.VERSION_CODE) - } - - @JvmStatic - val savedVersionCode: Int - get() = Prefs.getInt(VER_CODE, -1) - - @JvmStatic - fun hasStoragePermission(): Boolean { - return Environment.isExternalStorageManager() || Environment.isExternalStorageLegacy() - } - - @JvmStatic - fun requestStoragePermission(context: Context) { - val intent = Intent() - intent.setAction(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION) - intent.setData(Uri.fromParts("package", BuildConfig.APPLICATION_ID, null)) - - (context as Activity).startActivityForResult(intent, 0) - ActivityCompat.requestPermissions( - context, arrayOf( - Manifest.permission.READ_EXTERNAL_STORAGE, - Manifest.permission.WRITE_EXTERNAL_STORAGE, - Manifest.permission.MANAGE_EXTERNAL_STORAGE - ), 0 - ) - } - - @JvmStatic - fun enableRestartSystemuiAfterBoot() { - disableRestartSystemuiAfterBoot() - - Shell.cmd( - "sed '/^sleep.6/i killall " + SYSTEMUI_PACKAGE + "' " + Resources.MODULE_DIR + "/service.sh > " + Resources.MODULE_DIR + "/service.sh.tmp && mv " + Resources.MODULE_DIR + "/service.sh.tmp " + Resources.MODULE_DIR + "/service.sh" - ).submit() - } - - @JvmStatic - fun disableRestartSystemuiAfterBoot() { - Shell.cmd( - "grep -v \"killall " + SYSTEMUI_PACKAGE + "\" " + Resources.MODULE_DIR + "/service.sh > " + Resources.MODULE_DIR + "/service.sh.tmp && mv " + Resources.MODULE_DIR + "/service.sh.tmp " + Resources.MODULE_DIR + "/service.sh" - ).submit() - } - - fun getScreenWidth(activity: Activity): Int { - val windowMetrics = activity.windowManager.currentWindowMetrics - val insets = windowMetrics.getWindowInsets() - .getInsetsIgnoringVisibility(WindowInsets.Type.systemBars()) - return windowMetrics.bounds.width() - (insets.left + insets.right) - } - - fun getScreenHeight(activity: Activity): Int { - val windowMetrics = activity.windowManager.currentWindowMetrics - val insets = windowMetrics.getWindowInsets() - .getInsetsIgnoringVisibility(WindowInsets.Type.systemBars()) - return windowMetrics.bounds.height() - (insets.top + insets.bottom) - } -} diff --git a/app/src/main/java/com/drdisagree/iconify/utils/SystemUtils.kt b/app/src/main/java/com/drdisagree/iconify/utils/SystemUtils.kt new file mode 100644 index 000000000..b76c99b91 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/utils/SystemUtils.kt @@ -0,0 +1,286 @@ +package com.drdisagree.iconify.utils + +import android.Manifest +import android.app.Activity +import android.content.Context +import android.content.Intent +import android.content.res.Configuration +import android.net.Uri +import android.os.Build +import android.os.Environment +import android.provider.Settings +import android.util.Log +import android.view.WindowInsets +import android.widget.Toast +import androidx.core.app.ActivityCompat +import com.drdisagree.iconify.BuildConfig +import com.drdisagree.iconify.Iconify.Companion.appContext +import com.drdisagree.iconify.R +import com.drdisagree.iconify.common.Const.SYSTEMUI_PACKAGE +import com.drdisagree.iconify.common.Preferences.BOOT_ID +import com.drdisagree.iconify.common.Preferences.FORCE_RELOAD_OVERLAY_STATE +import com.drdisagree.iconify.common.Preferences.FORCE_RELOAD_PACKAGE_NAME +import com.drdisagree.iconify.common.Preferences.RESTART_SYSUI_BEHAVIOR_EXT +import com.drdisagree.iconify.common.Preferences.VER_CODE +import com.drdisagree.iconify.common.References.DEVICE_BOOT_ID_CMD +import com.drdisagree.iconify.common.Resources +import com.drdisagree.iconify.config.RPrefs +import com.drdisagree.iconify.config.RPrefs.getString +import com.drdisagree.iconify.config.RPrefs.putString +import com.drdisagree.iconify.xposed.utils.BootLoopProtector.LOAD_TIME_KEY_KEY +import com.drdisagree.iconify.xposed.utils.BootLoopProtector.PACKAGE_STRIKE_KEY_KEY +import com.topjohnwu.superuser.Shell +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch +import java.text.SimpleDateFormat +import java.util.Calendar +import java.util.Locale + +object SystemUtils { + + private var darkSwitching = false + private const val BLUR_CMD_0 = + "resetprop ro.surface_flinger.supports_background_blur 1 && killall surfaceflinger" + private const val BLUR_CMD_1 = "ro.sf.blurs_are_expensive=1" + private const val BLUR_CMD_2 = "ro.surface_flinger.supports_background_blur=1" + private const val BLUR_CMD_3 = "persist.sys.sf.disable_blurs=0" + private const val BLUR_CMD_4 = "persist.sysui.disableBlur=false" + private const val BLUR_CMD_5 = "ro.config.avoid_gfx_accel=false" + + val isDarkMode: Boolean + get() = appContext.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_YES == Configuration.UI_MODE_NIGHT_YES + + fun restartSystemUI() { + val loadTimeKey = String.format("%s%s", LOAD_TIME_KEY_KEY, SYSTEMUI_PACKAGE) + val strikeKey = String.format("%s%s", PACKAGE_STRIKE_KEY_KEY, SYSTEMUI_PACKAGE) + val currentTime = Calendar.getInstance().time.time + + RPrefs.putLong(loadTimeKey, currentTime) + RPrefs.putInt(strikeKey, 0) + Shell.cmd("killall $SYSTEMUI_PACKAGE").submit() + } + + private fun forceReloadUI() { + val state = RPrefs.getBoolean(FORCE_RELOAD_OVERLAY_STATE, false) + val pkgName: String = FORCE_RELOAD_PACKAGE_NAME + + Shell.cmd( + "cmd overlay " + (if (state) "disable" else "enable") + " --user current " + pkgName + "; cmd overlay " + (if (state) "enable" else "disable") + " --user current " + pkgName + ).submit() + } + + fun handleSystemUIRestart() { + val selectedBehavior = getString(RESTART_SYSUI_BEHAVIOR_EXT, "0")!!.toInt() + + when (selectedBehavior) { + 0 -> { + restartSystemUI() + } + + 1 -> { + forceReloadUI() + } + + else -> { + Toast.makeText( + appContext, + appContext.resources.getString(R.string.settings_systemui_restart_required), + Toast.LENGTH_SHORT + ).show() + } + } + } + + fun restartDevice() { + Shell.cmd("am start -a android.intent.action.REBOOT").exec() + } + + fun disableBlur(force: Boolean) { + Shell.cmd( + if (!force) "mv " + Resources.MODULE_DIR + + "/system.prop " + + Resources.MODULE_DIR + + "/system.txt; " + + "grep -vE \"" + + BLUR_CMD_1 + "|" + + BLUR_CMD_2 + "|" + + BLUR_CMD_3 + "|" + + BLUR_CMD_4 + "|" + + BLUR_CMD_5 + "\" " + + Resources.MODULE_DIR + + "/system.txt > " + + Resources.MODULE_DIR + + "/system.txt.tmp; " + + "rm -rf " + + Resources.MODULE_DIR + + "/system.prop; " + + "mv " + Resources.MODULE_DIR + + "/system.txt.tmp " + + Resources.MODULE_DIR + + "/system.prop; " + + "rm -rf " + Resources.MODULE_DIR + + "/system.txt; " + + "rm -rf " + Resources.MODULE_DIR + + "/system.txt.tmp" else ":", // do nothing + "grep -v \"ro.surface_flinger.supports_background_blur\" " + + Resources.MODULE_DIR + "/service.sh > " + + Resources.MODULE_DIR + "/service.sh.tmp && mv " + + Resources.MODULE_DIR + "/service.sh.tmp " + + Resources.MODULE_DIR + "/service.sh" + ).submit() + } + + fun enableBlur(force: Boolean) { + disableBlur(false) + Shell.cmd( + "echo \"$BLUR_CMD_1\n$BLUR_CMD_2\n$BLUR_CMD_3\n$BLUR_CMD_4\n$BLUR_CMD_5\"" + + " >> ${Resources.MODULE_DIR}/system.prop", + if (force) "sed '/*}/a " + + BLUR_CMD_0 + "' " + + Resources.MODULE_DIR + + "/service.sh > " + + Resources.MODULE_DIR + + "/service.sh.tmp && mv " + + Resources.MODULE_DIR + + "/service.sh.tmp " + + Resources.MODULE_DIR + + "/service.sh" else ":" // do nothing + ).submit() + } + + fun mountRW() { + Shell.cmd("mount -o remount,rw /").exec() + + if (RootUtils.moduleExists("magisk_overlayfs")) { + Shell.cmd("-mm -c magic_remount_rw").exec() + } else if (RootUtils.moduleExists("overlayfs")) { + Shell.cmd("/data/overlayfs/tmp/overlayrw -rw /system/product/overlay").exec() + } + } + + fun mountRO() { + Shell.cmd("mount -o remount,ro /").exec() + + if (RootUtils.moduleExists("magisk_overlayfs")) { + Shell.cmd("-mm -c magic_remount_ro").exec() + } else if (RootUtils.moduleExists("overlayfs")) { + Shell.cmd("/data/overlayfs/tmp/overlayrw -ro /system/product/overlay").exec() + } + } + + /* + * From AOSPMods + * https://github.com/siavash79/AOSPMods/blob/canary/app/src/main/java/sh/siava/AOSPMods/utils/SystemUtils.java + */ + fun doubleToggleDarkMode() { + val isDark = isDarkMode + + CoroutineScope(Dispatchers.Default).launch { + try { + while (darkSwitching) { + delay(100) + } + + darkSwitching = true + + Shell.cmd("cmd uimode night ${if (isDark) "no" else "yes"}").exec() + delay(1000) + Shell.cmd("cmd uimode night ${if (isDark) "yes" else "no"}").exec() + delay(500) + + darkSwitching = false + } catch (ignored: Exception) { + } + } + } + + fun isBlurEnabled(force: Boolean): Boolean { + return Shell.cmd( + "if grep -q \"ro.surface_flinger.supports_background_blur\" " + + Resources.MODULE_DIR + + (if (force) "/service.sh;" else "/system.prop;") + + " then echo yes; else echo no; fi" + ).exec().out[0] == "yes" + } + + val saveBootId: Unit // Save unique id of each boot + get() { + val bootId = Shell.cmd(DEVICE_BOOT_ID_CMD).exec().out.toString() + if (getString(BOOT_ID) != bootId) { + putString(BOOT_ID, bootId) + } + } + + fun saveVersionCode() { + RPrefs.putInt(VER_CODE, BuildConfig.VERSION_CODE) + } + + val savedVersionCode: Int + get() = RPrefs.getInt(VER_CODE, -1) + + fun hasStoragePermission(): Boolean { + return Environment.isExternalStorageManager() || Environment.isExternalStorageLegacy() + } + + fun requestStoragePermission(context: Context) { + val intent = Intent() + intent.setAction(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION) + intent.setData(Uri.fromParts("package", BuildConfig.APPLICATION_ID, null)) + + (context as Activity).startActivityForResult(intent, 0) + ActivityCompat.requestPermissions( + context, arrayOf( + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.MANAGE_EXTERNAL_STORAGE + ), 0 + ) + } + + fun enableRestartSystemuiAfterBoot() { + disableRestartSystemuiAfterBoot() + + Shell.cmd( + "sed '/^sleep.6/i killall " + SYSTEMUI_PACKAGE + "' " + Resources.MODULE_DIR + "/service.sh > " + Resources.MODULE_DIR + "/service.sh.tmp && mv " + Resources.MODULE_DIR + "/service.sh.tmp " + Resources.MODULE_DIR + "/service.sh" + ).submit() + } + + fun disableRestartSystemuiAfterBoot() { + Shell.cmd( + "grep -v \"killall " + SYSTEMUI_PACKAGE + "\" " + Resources.MODULE_DIR + "/service.sh > " + Resources.MODULE_DIR + "/service.sh.tmp && mv " + Resources.MODULE_DIR + "/service.sh.tmp " + Resources.MODULE_DIR + "/service.sh" + ).submit() + } + + fun isSecurityPatchBeforeJune2024(): Boolean { + val securityPatch = Build.VERSION.SECURITY_PATCH + val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.US) + + return try { + val securityPatchDate = dateFormat.parse(securityPatch) + + val june2024 = Calendar.getInstance() + june2024.set(2024, Calendar.JUNE, 1) + + (securityPatchDate != null && (securityPatchDate < june2024.time)) + } catch (e: Exception) { + Log.e("SECURITY_PATCH_CHECK", "Error parsing security patch date", e) + false + } + } + + fun getScreenWidth(activity: Activity): Int { + val windowMetrics = activity.windowManager.currentWindowMetrics + val insets = windowMetrics.windowInsets + .getInsetsIgnoringVisibility(WindowInsets.Type.systemBars()) + return windowMetrics.bounds.width() - (insets.left + insets.right) + } + + fun getScreenHeight(activity: Activity): Int { + val windowMetrics = activity.windowManager.currentWindowMetrics + val insets = windowMetrics.windowInsets + .getInsetsIgnoringVisibility(WindowInsets.Type.systemBars()) + return windowMetrics.bounds.height() - (insets.top + insets.bottom) + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/utils/TextUtil.kt b/app/src/main/java/com/drdisagree/iconify/utils/TextUtil.kt deleted file mode 100644 index a5ca7aeaf..000000000 --- a/app/src/main/java/com/drdisagree/iconify/utils/TextUtil.kt +++ /dev/null @@ -1,54 +0,0 @@ -package com.drdisagree.iconify.utils - -import android.view.View -import android.view.ViewGroup -import android.widget.TextView - -object TextUtil { - fun convertTextViewsToTitleCase(view: View?) { - if (view == null) return - - if (view is ViewGroup) { - val childCount: Int = view.childCount - - for (i in 0 until childCount) { - val child: View = view.getChildAt(i) - - if (child is ViewGroup) { - convertTextViewsToTitleCase(child) - } else if (child is TextView) { - val originalText: String = child.getText().toString() - val convertedText = convertToTitleCase(originalText) - child.text = convertedText - } - } - } else if (view is TextView) { - val originalText: String = view.getText().toString() - val convertedText = convertToTitleCase(originalText) - view.text = convertedText - } - } - - private fun convertToTitleCase(input: String?): String? { - if (input.isNullOrEmpty()) return input - - val result = StringBuilder() - var capitalizeNext = true - - for (c in input.toCharArray()) { - var char = c - - if (Character.isWhitespace(char)) { - capitalizeNext = true - } else if (Character.isLetter(char)) { - if (capitalizeNext) { - char = char.uppercaseChar() - capitalizeNext = false - } - } - - result.append(char) - } - return result.toString() - } -} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/utils/TextUtils.kt b/app/src/main/java/com/drdisagree/iconify/utils/TextUtils.kt new file mode 100644 index 000000000..a2c7ba78e --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/utils/TextUtils.kt @@ -0,0 +1,54 @@ +package com.drdisagree.iconify.utils + +import android.view.View +import android.view.ViewGroup +import android.widget.TextView + +object TextUtils { + fun convertTextViewsToTitleCase(view: View?) { + if (view == null) return + + if (view is ViewGroup) { + val childCount: Int = view.childCount + + for (i in 0 until childCount) { + val child: View = view.getChildAt(i) + + if (child is ViewGroup) { + convertTextViewsToTitleCase(child) + } else if (child is TextView) { + val originalText: String = child.getText().toString() + val convertedText = convertToTitleCase(originalText) + child.text = convertedText + } + } + } else if (view is TextView) { + val originalText: String = view.getText().toString() + val convertedText = convertToTitleCase(originalText) + view.text = convertedText + } + } + + private fun convertToTitleCase(input: String?): String? { + if (input.isNullOrEmpty()) return input + + val result = StringBuilder() + var capitalizeNext = true + + for (c in input.toCharArray()) { + var char = c + + if (Character.isWhitespace(char)) { + capitalizeNext = true + } else if (Character.isLetter(char)) { + if (capitalizeNext) { + char = char.uppercaseChar() + capitalizeNext = false + } + } + + result.append(char) + } + return result.toString() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/utils/WallpaperUtil.kt b/app/src/main/java/com/drdisagree/iconify/utils/WallpaperUtil.kt deleted file mode 100644 index 339eca311..000000000 --- a/app/src/main/java/com/drdisagree/iconify/utils/WallpaperUtil.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.drdisagree.iconify.utils - -import android.app.WallpaperManager -import android.content.Context -import android.graphics.Bitmap -import android.graphics.BitmapFactory -import android.graphics.drawable.BitmapDrawable -import java.io.ByteArrayOutputStream - -object WallpaperUtil { - - fun getCompressedWallpaper(context: Context?, quality: Int, which: Int): Bitmap? { - return try { - val wallpaperManager = WallpaperManager.getInstance(context) - val wallpaperFile = wallpaperManager.getWallpaperFile(which) - - if (wallpaperFile == null) { - val wallpaperDrawable = wallpaperManager.drawable - - if (wallpaperDrawable is BitmapDrawable) { - val bitmap = wallpaperDrawable.bitmap - compressBitmap(bitmap, quality) - } else { - Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888) - } - } else { - val bitmap = BitmapFactory.decodeFileDescriptor(wallpaperFile.fileDescriptor) - wallpaperFile.close() - compressBitmap(bitmap, quality) - } - } catch (e: Exception) { -// return Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); - null - } - } - - private fun compressBitmap(bitmap: Bitmap, quality: Int): Bitmap { - val stream = ByteArrayOutputStream() - bitmap.compress(Bitmap.CompressFormat.JPEG, quality, stream) - val byteArray = stream.toByteArray() - - return BitmapFactory.decodeByteArray(byteArray, 0, byteArray.size) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/utils/WallpaperUtils.kt b/app/src/main/java/com/drdisagree/iconify/utils/WallpaperUtils.kt new file mode 100644 index 000000000..c035df888 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/utils/WallpaperUtils.kt @@ -0,0 +1,44 @@ +package com.drdisagree.iconify.utils + +import android.app.WallpaperManager +import android.content.Context +import android.graphics.Bitmap +import android.graphics.BitmapFactory +import android.graphics.drawable.BitmapDrawable +import java.io.ByteArrayOutputStream + +object WallpaperUtils { + + fun getCompressedWallpaper(context: Context?, quality: Int, which: Int): Bitmap? { + return try { + val wallpaperManager = WallpaperManager.getInstance(context) + val wallpaperFile = wallpaperManager.getWallpaperFile(which) + + if (wallpaperFile == null) { + val wallpaperDrawable = wallpaperManager.drawable + + if (wallpaperDrawable is BitmapDrawable) { + val bitmap = wallpaperDrawable.bitmap + compressBitmap(bitmap, quality) + } else { + Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888) + } + } else { + val bitmap = BitmapFactory.decodeFileDescriptor(wallpaperFile.fileDescriptor) + wallpaperFile.close() + compressBitmap(bitmap, quality) + } + } catch (e: Exception) { +// return Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); + null + } + } + + private fun compressBitmap(bitmap: Bitmap, quality: Int): Bitmap { + val stream = ByteArrayOutputStream() + bitmap.compress(Bitmap.CompressFormat.JPEG, quality, stream) + val byteArray = stream.toByteArray() + + return BitmapFactory.decodeByteArray(byteArray, 0, byteArray.size) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/utils/color/ColorSchemeUtil.kt b/app/src/main/java/com/drdisagree/iconify/utils/color/ColorSchemeUtil.kt deleted file mode 100644 index 776799202..000000000 --- a/app/src/main/java/com/drdisagree/iconify/utils/color/ColorSchemeUtil.kt +++ /dev/null @@ -1,201 +0,0 @@ -package com.drdisagree.iconify.utils.color - -import android.content.Context -import com.drdisagree.iconify.R -import com.drdisagree.iconify.utils.SystemUtil -import com.drdisagree.iconify.utils.color.monet.hct.Hct -import com.drdisagree.iconify.utils.color.monet.scheme.SchemeContent -import com.drdisagree.iconify.utils.color.monet.scheme.SchemeExpressive -import com.drdisagree.iconify.utils.color.monet.scheme.SchemeFidelity -import com.drdisagree.iconify.utils.color.monet.scheme.SchemeFruitSalad -import com.drdisagree.iconify.utils.color.monet.scheme.SchemeMonochrome -import com.drdisagree.iconify.utils.color.monet.scheme.SchemeNeutral -import com.drdisagree.iconify.utils.color.monet.scheme.SchemeRainbow -import com.drdisagree.iconify.utils.color.monet.scheme.SchemeTonalSpot -import com.drdisagree.iconify.utils.color.monet.scheme.SchemeVibrant - -object ColorSchemeUtil { - - private val tones = intArrayOf(100, 99, 95, 90, 80, 70, 60, 50, 40, 30, 20, 10, 0) - - @JvmStatic - fun generateColorPalette(context: Context, style: String?, color: Int): List> { - val palette: MutableList> = ArrayList() - val systemAccent1: MutableList = ArrayList() - val systemAccent2: MutableList = ArrayList() - val systemAccent3: MutableList = ArrayList() - val systemNeutral1: MutableList = ArrayList() - val systemNeutral2: MutableList = ArrayList() - - when (style) { - context.resources.getString(R.string.monet_neutral) -> { - val schemeNeutral = SchemeNeutral(Hct.fromInt(color), SystemUtil.isDarkMode, 5.0) - - for (tone in tones) { - systemAccent1.add(schemeNeutral.primaryPalette.tone(tone)) - systemAccent2.add(schemeNeutral.secondaryPalette.tone(tone)) - systemAccent3.add(schemeNeutral.tertiaryPalette.tone(tone)) - systemNeutral1.add(schemeNeutral.neutralPalette.tone(tone)) - systemNeutral2.add(schemeNeutral.neutralVariantPalette.tone(tone)) - } - - palette.add(systemAccent1) - palette.add(systemAccent2) - palette.add(systemAccent3) - palette.add(systemNeutral1) - palette.add(systemNeutral2) - } - - context.resources.getString(R.string.monet_monochrome) -> { - val schemeMonochrome = - SchemeMonochrome(Hct.fromInt(color), SystemUtil.isDarkMode, 5.0) - - for (tone in tones) { - systemAccent1.add(schemeMonochrome.primaryPalette.tone(tone)) - systemAccent2.add(schemeMonochrome.secondaryPalette.tone(tone)) - systemAccent3.add(schemeMonochrome.tertiaryPalette.tone(tone)) - systemNeutral1.add(schemeMonochrome.neutralPalette.tone(tone)) - systemNeutral2.add(schemeMonochrome.neutralVariantPalette.tone(tone)) - } - - palette.add(systemAccent1) - palette.add(systemAccent2) - palette.add(systemAccent3) - palette.add(systemNeutral1) - palette.add(systemNeutral2) - } - - context.resources.getString(R.string.monet_tonalspot) -> { - val schemeTonalSpot = - SchemeTonalSpot(Hct.fromInt(color), SystemUtil.isDarkMode, 5.0) - - for (tone in tones) { - systemAccent1.add(schemeTonalSpot.primaryPalette.tone(tone)) - systemAccent2.add(schemeTonalSpot.secondaryPalette.tone(tone)) - systemAccent3.add(schemeTonalSpot.tertiaryPalette.tone(tone)) - systemNeutral1.add(schemeTonalSpot.neutralPalette.tone(tone)) - systemNeutral2.add(schemeTonalSpot.neutralVariantPalette.tone(tone)) - } - - palette.add(systemAccent1) - palette.add(systemAccent2) - palette.add(systemAccent3) - palette.add(systemNeutral1) - palette.add(systemNeutral2) - } - - context.resources.getString(R.string.monet_vibrant) -> { - val schemeVibrant = SchemeVibrant(Hct.fromInt(color), SystemUtil.isDarkMode, 5.0) - - for (tone in tones) { - systemAccent1.add(schemeVibrant.primaryPalette.tone(tone)) - systemAccent2.add(schemeVibrant.secondaryPalette.tone(tone)) - systemAccent3.add(schemeVibrant.tertiaryPalette.tone(tone)) - systemNeutral1.add(schemeVibrant.neutralPalette.tone(tone)) - systemNeutral2.add(schemeVibrant.neutralVariantPalette.tone(tone)) - } - - palette.add(systemAccent1) - palette.add(systemAccent2) - palette.add(systemAccent3) - palette.add(systemNeutral1) - palette.add(systemNeutral2) - } - - context.resources.getString(R.string.monet_rainbow) -> { - val schemeRainbow = SchemeRainbow(Hct.fromInt(color), SystemUtil.isDarkMode, 5.0) - - for (tone in tones) { - systemAccent1.add(schemeRainbow.primaryPalette.tone(tone)) - systemAccent2.add(schemeRainbow.secondaryPalette.tone(tone)) - systemAccent3.add(schemeRainbow.tertiaryPalette.tone(tone)) - systemNeutral1.add(schemeRainbow.neutralPalette.tone(tone)) - systemNeutral2.add(schemeRainbow.neutralVariantPalette.tone(tone)) - } - - palette.add(systemAccent1) - palette.add(systemAccent2) - palette.add(systemAccent3) - palette.add(systemNeutral1) - palette.add(systemNeutral2) - } - - context.resources.getString(R.string.monet_expressive) -> { - val schemeExpressive = - SchemeExpressive(Hct.fromInt(color), SystemUtil.isDarkMode, 5.0) - - for (tone in tones) { - systemAccent1.add(schemeExpressive.primaryPalette.tone(tone)) - systemAccent2.add(schemeExpressive.secondaryPalette.tone(tone)) - systemAccent3.add(schemeExpressive.tertiaryPalette.tone(tone)) - systemNeutral1.add(schemeExpressive.neutralPalette.tone(tone)) - systemNeutral2.add(schemeExpressive.neutralVariantPalette.tone(tone)) - } - - palette.add(systemAccent1) - palette.add(systemAccent2) - palette.add(systemAccent3) - palette.add(systemNeutral1) - palette.add(systemNeutral2) - } - - context.resources.getString(R.string.monet_fidelity) -> { - val schemeFidelity = - SchemeFidelity(Hct.fromInt(color), SystemUtil.isDarkMode, 5.0) - - for (tone in tones) { - systemAccent1.add(schemeFidelity.primaryPalette.tone(tone)) - systemAccent2.add(schemeFidelity.secondaryPalette.tone(tone)) - systemAccent3.add(schemeFidelity.tertiaryPalette.tone(tone)) - systemNeutral1.add(schemeFidelity.neutralPalette.tone(tone)) - systemNeutral2.add(schemeFidelity.neutralVariantPalette.tone(tone)) - } - - palette.add(systemAccent1) - palette.add(systemAccent2) - palette.add(systemAccent3) - palette.add(systemNeutral1) - palette.add(systemNeutral2) - } - - context.resources.getString(R.string.monet_content) -> { - val schemeContent = SchemeContent(Hct.fromInt(color), SystemUtil.isDarkMode, 5.0) - - for (tone in tones) { - systemAccent1.add(schemeContent.primaryPalette.tone(tone)) - systemAccent2.add(schemeContent.secondaryPalette.tone(tone)) - systemAccent3.add(schemeContent.tertiaryPalette.tone(tone)) - systemNeutral1.add(schemeContent.neutralPalette.tone(tone)) - systemNeutral2.add(schemeContent.neutralVariantPalette.tone(tone)) - } - - palette.add(systemAccent1) - palette.add(systemAccent2) - palette.add(systemAccent3) - palette.add(systemNeutral1) - palette.add(systemNeutral2) - } - - context.resources.getString(R.string.monet_fruitsalad) -> { - val schemeFruitSalad = - SchemeFruitSalad(Hct.fromInt(color), SystemUtil.isDarkMode, 5.0) - - for (tone in tones) { - systemAccent1.add(schemeFruitSalad.primaryPalette.tone(tone)) - systemAccent2.add(schemeFruitSalad.secondaryPalette.tone(tone)) - systemAccent3.add(schemeFruitSalad.tertiaryPalette.tone(tone)) - systemNeutral1.add(schemeFruitSalad.neutralPalette.tone(tone)) - systemNeutral2.add(schemeFruitSalad.neutralVariantPalette.tone(tone)) - } - - palette.add(systemAccent1) - palette.add(systemAccent2) - palette.add(systemAccent3) - palette.add(systemNeutral1) - palette.add(systemNeutral2) - } - } - - return palette - } -} diff --git a/app/src/main/java/com/drdisagree/iconify/utils/color/ColorSchemeUtils.kt b/app/src/main/java/com/drdisagree/iconify/utils/color/ColorSchemeUtils.kt new file mode 100644 index 000000000..c156d716e --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/utils/color/ColorSchemeUtils.kt @@ -0,0 +1,200 @@ +package com.drdisagree.iconify.utils.color + +import android.content.Context +import com.drdisagree.iconify.R +import com.drdisagree.iconify.utils.SystemUtils +import com.drdisagree.iconify.utils.color.monet.hct.Hct +import com.drdisagree.iconify.utils.color.monet.scheme.SchemeContent +import com.drdisagree.iconify.utils.color.monet.scheme.SchemeExpressive +import com.drdisagree.iconify.utils.color.monet.scheme.SchemeFidelity +import com.drdisagree.iconify.utils.color.monet.scheme.SchemeFruitSalad +import com.drdisagree.iconify.utils.color.monet.scheme.SchemeMonochrome +import com.drdisagree.iconify.utils.color.monet.scheme.SchemeNeutral +import com.drdisagree.iconify.utils.color.monet.scheme.SchemeRainbow +import com.drdisagree.iconify.utils.color.monet.scheme.SchemeTonalSpot +import com.drdisagree.iconify.utils.color.monet.scheme.SchemeVibrant + +object ColorSchemeUtils { + + private val tones = intArrayOf(100, 99, 95, 90, 80, 70, 60, 50, 40, 30, 20, 10, 0) + + fun generateColorPalette(context: Context, style: String?, color: Int): List> { + val palette: MutableList> = ArrayList() + val systemAccent1: MutableList = ArrayList() + val systemAccent2: MutableList = ArrayList() + val systemAccent3: MutableList = ArrayList() + val systemNeutral1: MutableList = ArrayList() + val systemNeutral2: MutableList = ArrayList() + + when (style) { + context.resources.getString(R.string.monet_neutral) -> { + val schemeNeutral = SchemeNeutral(Hct.fromInt(color), SystemUtils.isDarkMode, 5.0) + + for (tone in tones) { + systemAccent1.add(schemeNeutral.primaryPalette.tone(tone)) + systemAccent2.add(schemeNeutral.secondaryPalette.tone(tone)) + systemAccent3.add(schemeNeutral.tertiaryPalette.tone(tone)) + systemNeutral1.add(schemeNeutral.neutralPalette.tone(tone)) + systemNeutral2.add(schemeNeutral.neutralVariantPalette.tone(tone)) + } + + palette.add(systemAccent1) + palette.add(systemAccent2) + palette.add(systemAccent3) + palette.add(systemNeutral1) + palette.add(systemNeutral2) + } + + context.resources.getString(R.string.monet_monochrome) -> { + val schemeMonochrome = + SchemeMonochrome(Hct.fromInt(color), SystemUtils.isDarkMode, 5.0) + + for (tone in tones) { + systemAccent1.add(schemeMonochrome.primaryPalette.tone(tone)) + systemAccent2.add(schemeMonochrome.secondaryPalette.tone(tone)) + systemAccent3.add(schemeMonochrome.tertiaryPalette.tone(tone)) + systemNeutral1.add(schemeMonochrome.neutralPalette.tone(tone)) + systemNeutral2.add(schemeMonochrome.neutralVariantPalette.tone(tone)) + } + + palette.add(systemAccent1) + palette.add(systemAccent2) + palette.add(systemAccent3) + palette.add(systemNeutral1) + palette.add(systemNeutral2) + } + + context.resources.getString(R.string.monet_tonalspot) -> { + val schemeTonalSpot = + SchemeTonalSpot(Hct.fromInt(color), SystemUtils.isDarkMode, 5.0) + + for (tone in tones) { + systemAccent1.add(schemeTonalSpot.primaryPalette.tone(tone)) + systemAccent2.add(schemeTonalSpot.secondaryPalette.tone(tone)) + systemAccent3.add(schemeTonalSpot.tertiaryPalette.tone(tone)) + systemNeutral1.add(schemeTonalSpot.neutralPalette.tone(tone)) + systemNeutral2.add(schemeTonalSpot.neutralVariantPalette.tone(tone)) + } + + palette.add(systemAccent1) + palette.add(systemAccent2) + palette.add(systemAccent3) + palette.add(systemNeutral1) + palette.add(systemNeutral2) + } + + context.resources.getString(R.string.monet_vibrant) -> { + val schemeVibrant = SchemeVibrant(Hct.fromInt(color), SystemUtils.isDarkMode, 5.0) + + for (tone in tones) { + systemAccent1.add(schemeVibrant.primaryPalette.tone(tone)) + systemAccent2.add(schemeVibrant.secondaryPalette.tone(tone)) + systemAccent3.add(schemeVibrant.tertiaryPalette.tone(tone)) + systemNeutral1.add(schemeVibrant.neutralPalette.tone(tone)) + systemNeutral2.add(schemeVibrant.neutralVariantPalette.tone(tone)) + } + + palette.add(systemAccent1) + palette.add(systemAccent2) + palette.add(systemAccent3) + palette.add(systemNeutral1) + palette.add(systemNeutral2) + } + + context.resources.getString(R.string.monet_rainbow) -> { + val schemeRainbow = SchemeRainbow(Hct.fromInt(color), SystemUtils.isDarkMode, 5.0) + + for (tone in tones) { + systemAccent1.add(schemeRainbow.primaryPalette.tone(tone)) + systemAccent2.add(schemeRainbow.secondaryPalette.tone(tone)) + systemAccent3.add(schemeRainbow.tertiaryPalette.tone(tone)) + systemNeutral1.add(schemeRainbow.neutralPalette.tone(tone)) + systemNeutral2.add(schemeRainbow.neutralVariantPalette.tone(tone)) + } + + palette.add(systemAccent1) + palette.add(systemAccent2) + palette.add(systemAccent3) + palette.add(systemNeutral1) + palette.add(systemNeutral2) + } + + context.resources.getString(R.string.monet_expressive) -> { + val schemeExpressive = + SchemeExpressive(Hct.fromInt(color), SystemUtils.isDarkMode, 5.0) + + for (tone in tones) { + systemAccent1.add(schemeExpressive.primaryPalette.tone(tone)) + systemAccent2.add(schemeExpressive.secondaryPalette.tone(tone)) + systemAccent3.add(schemeExpressive.tertiaryPalette.tone(tone)) + systemNeutral1.add(schemeExpressive.neutralPalette.tone(tone)) + systemNeutral2.add(schemeExpressive.neutralVariantPalette.tone(tone)) + } + + palette.add(systemAccent1) + palette.add(systemAccent2) + palette.add(systemAccent3) + palette.add(systemNeutral1) + palette.add(systemNeutral2) + } + + context.resources.getString(R.string.monet_fidelity) -> { + val schemeFidelity = + SchemeFidelity(Hct.fromInt(color), SystemUtils.isDarkMode, 5.0) + + for (tone in tones) { + systemAccent1.add(schemeFidelity.primaryPalette.tone(tone)) + systemAccent2.add(schemeFidelity.secondaryPalette.tone(tone)) + systemAccent3.add(schemeFidelity.tertiaryPalette.tone(tone)) + systemNeutral1.add(schemeFidelity.neutralPalette.tone(tone)) + systemNeutral2.add(schemeFidelity.neutralVariantPalette.tone(tone)) + } + + palette.add(systemAccent1) + palette.add(systemAccent2) + palette.add(systemAccent3) + palette.add(systemNeutral1) + palette.add(systemNeutral2) + } + + context.resources.getString(R.string.monet_content) -> { + val schemeContent = SchemeContent(Hct.fromInt(color), SystemUtils.isDarkMode, 5.0) + + for (tone in tones) { + systemAccent1.add(schemeContent.primaryPalette.tone(tone)) + systemAccent2.add(schemeContent.secondaryPalette.tone(tone)) + systemAccent3.add(schemeContent.tertiaryPalette.tone(tone)) + systemNeutral1.add(schemeContent.neutralPalette.tone(tone)) + systemNeutral2.add(schemeContent.neutralVariantPalette.tone(tone)) + } + + palette.add(systemAccent1) + palette.add(systemAccent2) + palette.add(systemAccent3) + palette.add(systemNeutral1) + palette.add(systemNeutral2) + } + + context.resources.getString(R.string.monet_fruitsalad) -> { + val schemeFruitSalad = + SchemeFruitSalad(Hct.fromInt(color), SystemUtils.isDarkMode, 5.0) + + for (tone in tones) { + systemAccent1.add(schemeFruitSalad.primaryPalette.tone(tone)) + systemAccent2.add(schemeFruitSalad.secondaryPalette.tone(tone)) + systemAccent3.add(schemeFruitSalad.tertiaryPalette.tone(tone)) + systemNeutral1.add(schemeFruitSalad.neutralPalette.tone(tone)) + systemNeutral2.add(schemeFruitSalad.neutralVariantPalette.tone(tone)) + } + + palette.add(systemAccent1) + palette.add(systemAccent2) + palette.add(systemAccent3) + palette.add(systemNeutral1) + palette.add(systemNeutral2) + } + } + + return palette + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/utils/color/ColorUtil.kt b/app/src/main/java/com/drdisagree/iconify/utils/color/ColorUtil.kt deleted file mode 100644 index eeab0a506..000000000 --- a/app/src/main/java/com/drdisagree/iconify/utils/color/ColorUtil.kt +++ /dev/null @@ -1,441 +0,0 @@ -package com.drdisagree.iconify.utils.color - -import android.content.Context -import android.graphics.Color -import android.util.TypedValue -import androidx.annotation.AttrRes -import androidx.annotation.ColorInt - -object ColorUtil { - - fun hsl(hue: Float, saturation: Float, lightness: Float): Int { - return HSLColor.hslToColor(hue, saturation, lightness) - } - - fun getHue(color: Int): Float { - val r = Color.red(color) - val g = Color.green(color) - val b = Color.blue(color) - - val hsv = FloatArray(3) - Color.RGBToHSV(r, g, b, hsv) - - return hsv[0] - } - - fun setHue(color: Int, hue: Float): Int { - val r = Color.red(color) - val g = Color.green(color) - val b = Color.blue(color) - - val hsv = FloatArray(3) - Color.RGBToHSV(r, g, b, hsv) - hsv[0] = hue - - return Color.HSVToColor(hsv) - } - - fun getSaturation(color: Int): Float { - val r = Color.red(color) - val g = Color.green(color) - val b = Color.blue(color) - - val hsv = FloatArray(3) - Color.RGBToHSV(r, g, b, hsv) - - return hsv[1] - } - - @JvmStatic - fun setSaturation(color: Int, saturation: Float): Int { - val r = Color.red(color) - val g = Color.green(color) - val b = Color.blue(color) - - val hsv = FloatArray(3) - Color.RGBToHSV(r, g, b, hsv) - hsv[1] += saturation - - return Color.HSVToColor(hsv) - } - - fun getLightness(color: Int): Float { - val r = Color.red(color) - val g = Color.green(color) - val b = Color.blue(color) - - val hsv = FloatArray(3) - Color.RGBToHSV(r, g, b, hsv) - - return hsv[2] - } - - @JvmStatic - fun setLightness(color: Int, lightness: Float): Int { - val r = Color.red(color) - val g = Color.green(color) - val b = Color.blue(color) - - val hsv = FloatArray(3) - Color.RGBToHSV(r, g, b, hsv) - hsv[2] += lightness - - return Color.HSVToColor(hsv) - } - - @JvmStatic - fun colorToHex(color: Int): String { - val alpha = Color.alpha(color) - val blue = Color.blue(color) - val green = Color.green(color) - val red = Color.red(color) - - return String.format("#%02X%02X%02X%02X", alpha, red, green, blue) - } - - @JvmStatic - fun colorToSpecialHex(color: Int): String { - val blue = Color.blue(color) - val green = Color.green(color) - val red = Color.red(color) - - return String.format("0xff%02X%02X%02X", red, green, blue) - } - - val systemTintList: FloatArray - get() = floatArrayOf( - 1.0f, - 0.99f, - 0.95f, - 0.9f, - 0.8f, - 0.7f, - 0.6f, - 0.5f, - 0.4f, - 0.3f, - 0.2f, - 0.1f, - 0.0f - ) - - @JvmStatic - val colorNames: Array> - get() { - val accentTypes = arrayOf( - "system_accent1", - "system_accent2", - "system_accent3", - "system_neutral1", - "system_neutral2" - ) - val values = arrayOf( - "0", - "10", - "50", - "100", - "200", - "300", - "400", - "500", - "600", - "700", - "800", - "900", - "1000" - ) - - val colorNames = Array(accentTypes.size) { arrayOfNulls(values.size) } - for (i in accentTypes.indices) { - for (j in values.indices) { - colorNames[i][j] = accentTypes[i] + "_" + values[j] - } - } - - return colorNames - } - - @JvmStatic - fun getSystemColors(context: Context): Array { - return arrayOf( - intArrayOf( - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_primary100, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_primary99, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_primary95, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_primary90, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_primary80, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_primary70, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_primary60, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_primary50, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_primary40, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_primary30, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_primary20, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_primary10, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_primary0, - context.theme - ) - ), intArrayOf( - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_secondary100, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_secondary99, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_secondary95, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_secondary90, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_secondary80, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_secondary70, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_secondary60, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_secondary50, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_secondary40, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_secondary30, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_secondary20, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_secondary10, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_secondary0, - context.theme - ) - ), intArrayOf( - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_tertiary100, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_tertiary99, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_tertiary95, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_tertiary90, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_tertiary80, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_tertiary70, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_tertiary60, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_tertiary50, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_tertiary40, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_tertiary30, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_tertiary20, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_tertiary10, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_tertiary0, - context.theme - ) - ), intArrayOf( - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_neutral100, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_neutral99, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_neutral95, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_neutral90, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_neutral80, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_neutral70, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_neutral60, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_neutral50, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_neutral40, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_neutral30, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_neutral20, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_neutral10, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_neutral0, - context.theme - ) - ), intArrayOf( - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_neutral_variant100, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_neutral_variant99, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_neutral_variant95, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_neutral_variant90, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_neutral_variant80, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_neutral_variant70, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_neutral_variant60, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_neutral_variant50, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_neutral_variant40, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_neutral_variant30, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_neutral_variant20, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_neutral_variant10, - context.theme - ), - context.resources.getColor( - com.google.android.material.R.color.material_dynamic_neutral_variant0, - context.theme - ) - ) - ) - } - - fun getColorResCompat(context: Context, @AttrRes id: Int): Int { - val typedValue = TypedValue() - val theme = context.theme - theme.resolveAttribute(id, typedValue, false) - - val arr = context.obtainStyledAttributes(typedValue.data, intArrayOf(id)) - @ColorInt val color = arr.getColor(0, -1) - arr.recycle() - - return color - } -} diff --git a/app/src/main/java/com/drdisagree/iconify/utils/color/ColorUtils.kt b/app/src/main/java/com/drdisagree/iconify/utils/color/ColorUtils.kt new file mode 100644 index 000000000..fb8ef9fa6 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/utils/color/ColorUtils.kt @@ -0,0 +1,435 @@ +package com.drdisagree.iconify.utils.color + +import android.content.Context +import android.graphics.Color +import android.util.TypedValue +import androidx.annotation.AttrRes +import androidx.annotation.ColorInt + +object ColorUtils { + + fun hsl(hue: Float, saturation: Float, lightness: Float): Int { + return HSLColor.hslToColor(hue, saturation, lightness) + } + + fun getHue(color: Int): Float { + val r = Color.red(color) + val g = Color.green(color) + val b = Color.blue(color) + + val hsv = FloatArray(3) + Color.RGBToHSV(r, g, b, hsv) + + return hsv[0] + } + + fun setHue(color: Int, hue: Float): Int { + val r = Color.red(color) + val g = Color.green(color) + val b = Color.blue(color) + + val hsv = FloatArray(3) + Color.RGBToHSV(r, g, b, hsv) + hsv[0] = hue + + return Color.HSVToColor(hsv) + } + + fun getSaturation(color: Int): Float { + val r = Color.red(color) + val g = Color.green(color) + val b = Color.blue(color) + + val hsv = FloatArray(3) + Color.RGBToHSV(r, g, b, hsv) + + return hsv[1] + } + + fun setSaturation(color: Int, saturation: Float): Int { + val r = Color.red(color) + val g = Color.green(color) + val b = Color.blue(color) + + val hsv = FloatArray(3) + Color.RGBToHSV(r, g, b, hsv) + hsv[1] += saturation + + return Color.HSVToColor(hsv) + } + + fun getLightness(color: Int): Float { + val r = Color.red(color) + val g = Color.green(color) + val b = Color.blue(color) + + val hsv = FloatArray(3) + Color.RGBToHSV(r, g, b, hsv) + + return hsv[2] + } + + fun setLightness(color: Int, lightness: Float): Int { + val r = Color.red(color) + val g = Color.green(color) + val b = Color.blue(color) + + val hsv = FloatArray(3) + Color.RGBToHSV(r, g, b, hsv) + hsv[2] += lightness + + return Color.HSVToColor(hsv) + } + + fun colorToHex(color: Int): String { + val alpha = Color.alpha(color) + val blue = Color.blue(color) + val green = Color.green(color) + val red = Color.red(color) + + return String.format("#%02X%02X%02X%02X", alpha, red, green, blue) + } + + fun colorToSpecialHex(color: Int): String { + val blue = Color.blue(color) + val green = Color.green(color) + val red = Color.red(color) + + return String.format("0xff%02X%02X%02X", red, green, blue) + } + + val systemTintList: FloatArray + get() = floatArrayOf( + 1.0f, + 0.99f, + 0.95f, + 0.9f, + 0.8f, + 0.7f, + 0.6f, + 0.5f, + 0.4f, + 0.3f, + 0.2f, + 0.1f, + 0.0f + ) + + val colorNames: Array> + get() { + val accentTypes = arrayOf( + "system_accent1", + "system_accent2", + "system_accent3", + "system_neutral1", + "system_neutral2" + ) + val values = arrayOf( + "0", + "10", + "50", + "100", + "200", + "300", + "400", + "500", + "600", + "700", + "800", + "900", + "1000" + ) + + val colorNames = Array(accentTypes.size) { arrayOfNulls(values.size) } + for (i in accentTypes.indices) { + for (j in values.indices) { + colorNames[i][j] = accentTypes[i] + "_" + values[j] + } + } + + return colorNames + } + + fun getSystemColors(context: Context): Array { + return arrayOf( + intArrayOf( + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_primary100, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_primary99, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_primary95, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_primary90, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_primary80, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_primary70, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_primary60, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_primary50, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_primary40, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_primary30, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_primary20, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_primary10, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_primary0, + context.theme + ) + ), intArrayOf( + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_secondary100, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_secondary99, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_secondary95, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_secondary90, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_secondary80, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_secondary70, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_secondary60, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_secondary50, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_secondary40, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_secondary30, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_secondary20, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_secondary10, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_secondary0, + context.theme + ) + ), intArrayOf( + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_tertiary100, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_tertiary99, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_tertiary95, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_tertiary90, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_tertiary80, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_tertiary70, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_tertiary60, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_tertiary50, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_tertiary40, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_tertiary30, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_tertiary20, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_tertiary10, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_tertiary0, + context.theme + ) + ), intArrayOf( + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_neutral100, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_neutral99, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_neutral95, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_neutral90, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_neutral80, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_neutral70, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_neutral60, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_neutral50, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_neutral40, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_neutral30, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_neutral20, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_neutral10, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_neutral0, + context.theme + ) + ), intArrayOf( + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_neutral_variant100, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_neutral_variant99, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_neutral_variant95, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_neutral_variant90, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_neutral_variant80, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_neutral_variant70, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_neutral_variant60, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_neutral_variant50, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_neutral_variant40, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_neutral_variant30, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_neutral_variant20, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_neutral_variant10, + context.theme + ), + context.resources.getColor( + com.google.android.material.R.color.material_dynamic_neutral_variant0, + context.theme + ) + ) + ) + } + + fun getColorResCompat(context: Context, @AttrRes id: Int): Int { + val typedValue = TypedValue() + val theme = context.theme + theme.resolveAttribute(id, typedValue, false) + + val arr = context.obtainStyledAttributes(typedValue.data, intArrayOf(id)) + @ColorInt val color = arr.getColor(0, -1) + arr.recycle() + + return color + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/utils/extension/TaskExecutor.kt b/app/src/main/java/com/drdisagree/iconify/utils/extension/TaskExecutor.kt index a9a28b080..a13acc309 100644 --- a/app/src/main/java/com/drdisagree/iconify/utils/extension/TaskExecutor.kt +++ b/app/src/main/java/com/drdisagree/iconify/utils/extension/TaskExecutor.kt @@ -10,8 +10,8 @@ import kotlin.concurrent.Volatile abstract class TaskExecutor { - private val mHandler: Handler - private val mExecutor: Executor + private val mHandler: Handler = Handler(Looper.getMainLooper()) + private val mExecutor: Executor = Executors.newSingleThreadExecutor() private val mCancelled: AtomicBoolean private val preExecuteLatch: CountDownLatch private val isCancelled: Boolean @@ -22,8 +22,6 @@ abstract class TaskExecutor { private set init { - mExecutor = Executors.newSingleThreadExecutor() - mHandler = Handler(Looper.getMainLooper()) status = Status.PENDING mCancelled = AtomicBoolean(false) preExecuteLatch = CountDownLatch(1) diff --git a/app/src/main/java/com/drdisagree/iconify/utils/helper/BackupRestore.kt b/app/src/main/java/com/drdisagree/iconify/utils/helper/BackupRestore.kt index 222f65079..cb6709253 100644 --- a/app/src/main/java/com/drdisagree/iconify/utils/helper/BackupRestore.kt +++ b/app/src/main/java/com/drdisagree/iconify/utils/helper/BackupRestore.kt @@ -1,12 +1,11 @@ package com.drdisagree.iconify.utils.helper import com.drdisagree.iconify.common.Resources -import com.drdisagree.iconify.utils.RootUtil +import com.drdisagree.iconify.utils.RootUtils import com.topjohnwu.superuser.Shell object BackupRestore { - @JvmStatic fun backupFiles() { // Create backup directory Shell.cmd("rm -rf " + Resources.BACKUP_DIR, "mkdir -p " + Resources.BACKUP_DIR).exec() @@ -26,7 +25,6 @@ object BackupRestore { backupFile(Resources.OVERLAY_DIR + "/IconifyComponentDynamic2.apk") } - @JvmStatic fun restoreFiles() { restoreFile("system.prop", Resources.TEMP_MODULE_DIR) restoreFile("IconifyComponentME.apk", Resources.TEMP_MODULE_OVERLAY_DIR) @@ -49,11 +47,11 @@ object BackupRestore { } private fun backupExists(fileName: String): Boolean { - return RootUtil.fileExists(Resources.BACKUP_DIR + "/" + fileName) + return RootUtils.fileExists(Resources.BACKUP_DIR + "/" + fileName) } private fun backupFile(source: String) { - if (RootUtil.fileExists(source)) Shell.cmd("cp -rf " + source + " " + Resources.BACKUP_DIR + "/") + if (RootUtils.fileExists(source)) Shell.cmd("cp -rf " + source + " " + Resources.BACKUP_DIR + "/") .exec() } diff --git a/app/src/main/java/com/drdisagree/iconify/utils/helper/BinaryInstaller.kt b/app/src/main/java/com/drdisagree/iconify/utils/helper/BinaryInstaller.kt index d039305da..c3bedd754 100644 --- a/app/src/main/java/com/drdisagree/iconify/utils/helper/BinaryInstaller.kt +++ b/app/src/main/java/com/drdisagree/iconify/utils/helper/BinaryInstaller.kt @@ -10,14 +10,13 @@ import com.drdisagree.iconify.common.Dynamic.ZIPALIGN import com.drdisagree.iconify.common.Dynamic.ZIPALIGNLIB import com.drdisagree.iconify.common.Resources import com.drdisagree.iconify.common.Resources.BIN_DIR -import com.drdisagree.iconify.utils.FileUtil +import com.drdisagree.iconify.utils.FileUtils import com.topjohnwu.superuser.Shell object BinaryInstaller { private val TAG = BinaryInstaller::class.java.getSimpleName() - @JvmStatic fun symLinkBinaries() { Shell.cmd("mkdir -p $BIN_DIR").exec() @@ -37,12 +36,12 @@ object BinaryInstaller { Log.d(TAG, "Extracting tools...") try { - FileUtil.copyAssets("Tools") + FileUtils.copyAssets("Tools") Shell.cmd("for fl in " + Resources.DATA_DIR + "/Tools/*; do cp -f \"\$fl\" \"" + NATIVE_LIBRARY_DIR + "\"; chmod 755 \"" + NATIVE_LIBRARY_DIR + "/$(basename \$fl)\"; ln -sf \"" + NATIVE_LIBRARY_DIR + "/$(basename \$fl)\" \"" + BIN_DIR + "/$(basename \$fl)\"; done") .exec() - FileUtil.cleanDir("Tools") + FileUtils.cleanDir("Tools") } catch (e: Exception) { Log.e(TAG, "Failed to extract tools.\n$e") } diff --git a/app/src/main/java/com/drdisagree/iconify/utils/helper/ImportExport.kt b/app/src/main/java/com/drdisagree/iconify/utils/helper/ImportExport.kt index 4a2b19fd3..0570be862 100644 --- a/app/src/main/java/com/drdisagree/iconify/utils/helper/ImportExport.kt +++ b/app/src/main/java/com/drdisagree/iconify/utils/helper/ImportExport.kt @@ -1,7 +1,18 @@ package com.drdisagree.iconify.utils.helper +import android.app.Activity +import android.content.ContentResolver +import android.content.Context +import android.content.Intent import android.content.SharedPreferences +import android.os.Handler +import android.os.Looper import android.util.Log +import android.widget.Toast +import androidx.activity.result.ActivityResult +import androidx.activity.result.ActivityResultLauncher +import androidx.fragment.app.Fragment +import com.drdisagree.iconify.R import com.drdisagree.iconify.common.Const.FRAMEWORK_PACKAGE import com.drdisagree.iconify.common.Preferences.COLOR_ACCENT_PRIMARY import com.drdisagree.iconify.common.Preferences.COLOR_ACCENT_PRIMARY_LIGHT @@ -24,15 +35,20 @@ import com.drdisagree.iconify.common.References.ICONIFY_COLOR_ACCENT_PRIMARY import com.drdisagree.iconify.common.References.ICONIFY_COLOR_ACCENT_SECONDARY import com.drdisagree.iconify.common.Resources import com.drdisagree.iconify.common.Resources.MODULE_DIR -import com.drdisagree.iconify.utils.SystemUtil -import com.drdisagree.iconify.utils.color.ColorUtil.colorNames -import com.drdisagree.iconify.utils.overlay.FabricatedUtil +import com.drdisagree.iconify.config.RPrefs +import com.drdisagree.iconify.ui.dialogs.LoadingDialog +import com.drdisagree.iconify.utils.SystemUtils +import com.drdisagree.iconify.utils.SystemUtils.hasStoragePermission +import com.drdisagree.iconify.utils.SystemUtils.requestStoragePermission +import com.drdisagree.iconify.utils.color.ColorUtils.colorNames +import com.drdisagree.iconify.utils.overlay.FabricatedUtils import com.drdisagree.iconify.utils.overlay.compiler.DynamicCompiler import com.drdisagree.iconify.utils.overlay.compiler.OnDemandCompiler import com.drdisagree.iconify.utils.overlay.compiler.SwitchCompiler import com.drdisagree.iconify.utils.overlay.manager.MonetEngineManager import com.drdisagree.iconify.utils.overlay.manager.RoundnessManager import com.drdisagree.iconify.utils.overlay.manager.SettingsIconResourceManager +import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.topjohnwu.superuser.Shell import java.io.IOException import java.io.InputStream @@ -40,10 +56,142 @@ import java.io.ObjectInputStream import java.io.ObjectOutputStream import java.io.OutputStream import java.util.Objects +import java.util.concurrent.Executors object ImportExport { - @JvmStatic + fun importSettings( + fragment: Fragment, + activityIntent: ActivityResultLauncher + ) { + importExportSettings( + fragment = fragment, + export = false, + startExportActivityIntent = null, + startImportActivityIntent = activityIntent + ) + } + + fun exportSettings( + fragment: Fragment, + activityIntent: ActivityResultLauncher + ) { + importExportSettings( + fragment = fragment, + export = true, + startExportActivityIntent = activityIntent, + startImportActivityIntent = null + ) + } + + private fun importExportSettings( + fragment: Fragment, + export: Boolean, + startExportActivityIntent: ActivityResultLauncher? = null, + startImportActivityIntent: ActivityResultLauncher? = null + ) { + if (!hasStoragePermission()) { + requestStoragePermission(fragment.requireContext()) + } else { + val fileIntent = Intent().apply { + action = if (export) Intent.ACTION_CREATE_DOCUMENT else Intent.ACTION_GET_CONTENT + type = "*/*" + putExtra(Intent.EXTRA_TITLE, "configs.iconify") + } + + if (export) { + startExportActivityIntent!!.launch(fileIntent) + } else { + startImportActivityIntent!!.launch(fileIntent) + } + } + } + + fun handleExportResult( + result: ActivityResult, + context: Context, + contentResolver: ContentResolver + ) { + if (result.resultCode == Activity.RESULT_OK) { + val data = result.data ?: return + + Executors.newSingleThreadExecutor().execute { + try { + exportSettings( + RPrefs.getPrefs, + contentResolver.openOutputStream(data.data!!)!! + ) + + Handler(Looper.getMainLooper()).post { + Toast.makeText( + context, + context.getString(R.string.toast_export_settings_successfull), + Toast.LENGTH_SHORT + ).show() + } + } catch (exception: Exception) { + Handler(Looper.getMainLooper()).post { + Toast.makeText( + context, + context.getString(R.string.toast_error), + Toast.LENGTH_SHORT + ).show() + Log.e("Settings", "Error exporting settings", exception) + } + } + } + } + } + + fun handleImportResult( + result: ActivityResult, + fragment: Fragment, + loadingDialog: LoadingDialog + ) { + if (result.resultCode == Activity.RESULT_OK) { + val data = result.data ?: return + MaterialAlertDialogBuilder(fragment.requireContext()) + .setTitle(fragment.getString(R.string.import_settings_confirmation_title)) + .setMessage(fragment.getString(R.string.import_settings_confirmation_desc)) + .setPositiveButton(fragment.getString(R.string.btn_positive)) { dialog, _ -> + dialog.dismiss() + loadingDialog.show(fragment.getString(R.string.loading_dialog_wait)) + Executors.newSingleThreadExecutor().execute { + try { + val success = importSettings( + RPrefs.getPrefs, + fragment.requireContext().contentResolver.openInputStream(data.data!!)!!, + true + ) + Handler(Looper.getMainLooper()).post { + loadingDialog.hide() + Toast.makeText( + fragment.requireContext(), + if (success) fragment.getString(R.string.toast_import_settings_successfull) + else fragment.getString(R.string.toast_error), + Toast.LENGTH_SHORT + ).show() + } + } catch (exception: Exception) { + Handler(Looper.getMainLooper()).post { + loadingDialog.hide() + Toast.makeText( + fragment.requireContext(), + fragment.getString(R.string.toast_error), + Toast.LENGTH_SHORT + ).show() + Log.e("Settings", "Error importing settings", exception) + } + } + } + } + .setNegativeButton(fragment.getString(R.string.btn_negative)) { dialog, _ -> + dialog.dismiss() + } + .show() + } + } + fun exportSettings(preferences: SharedPreferences, outputStream: OutputStream) { try { outputStream.use { @@ -58,7 +206,6 @@ object ImportExport { } } - @JvmStatic @Suppress("UNCHECKED_CAST") @Throws(IOException::class) fun importSettings( @@ -121,9 +268,9 @@ object ImportExport { val commands: MutableList = ArrayList() commands.add("> $MODULE_DIR/system.prop; > $MODULE_DIR/post-exec.sh; for ol in $(cmd overlay list | grep -E '.x.*IconifyComponent' | sed -E 's/^.x..//'); do cmd overlay disable \$ol; done") - SystemUtil.saveBootId - SystemUtil.disableBlur(false) - SystemUtil.saveVersionCode() + SystemUtils.saveBootId + SystemUtils.disableBlur(false) + SystemUtils.saveVersionCode() editor.putBoolean(ON_HOME_PAGE, true) editor.putBoolean(FIRST_INSTALL, false) @@ -266,10 +413,9 @@ object ImportExport { key.contains("IconifyComponentCR") && !cornerRadius -> { // UI Roundness cornerRadius = true try { - val radius = - Objects.requireNonNull(map[UI_CORNER_RADIUS]) as Int + val radius = map[UI_CORNER_RADIUS] as Int? - RoundnessManager.buildOverlay(radius, false) + radius?.let { RoundnessManager.buildOverlay(it, false) } } catch (exception: Exception) { Log.e( "ImportSettings", @@ -370,7 +516,7 @@ object ImportExport { commands.add(enable) } } else { - val tempCommands = FabricatedUtil.buildCommands( + val tempCommands = FabricatedUtils.buildCommands( Objects.requireNonNull(map["FOCMDtarget$overlayName"]) as String, Objects.requireNonNull(map["FOCMDname$overlayName"]) as String, Objects.requireNonNull(map["FOCMDtype$overlayName"]) as String, diff --git a/app/src/main/java/com/drdisagree/iconify/utils/helper/LocaleHelper.kt b/app/src/main/java/com/drdisagree/iconify/utils/helper/LocaleHelper.kt index 362264212..d75c0de31 100644 --- a/app/src/main/java/com/drdisagree/iconify/utils/helper/LocaleHelper.kt +++ b/app/src/main/java/com/drdisagree/iconify/utils/helper/LocaleHelper.kt @@ -4,17 +4,15 @@ import android.content.Context import android.os.LocaleList import com.drdisagree.iconify.R import com.drdisagree.iconify.common.Preferences.APP_LANGUAGE -import com.drdisagree.iconify.config.Prefs.getString -import java.util.Arrays +import com.drdisagree.iconify.config.RPrefs.getString import java.util.Locale object LocaleHelper { - @JvmStatic fun setLocale(context: Context): Context { - var localeCode = getString(APP_LANGUAGE, "") + var localeCode = getString(APP_LANGUAGE, "")!! - if (localeCode!!.isEmpty()) { + if (localeCode.isEmpty()) { val locales = context.resources.configuration.getLocales() val localeCodes = listOf(*context.resources.getStringArray(R.array.locale_code)) @@ -29,7 +27,7 @@ object LocaleHelper { } } - if (localeCode!!.isEmpty()) { + if (localeCode.isEmpty()) { localeCode = "en-US" } } diff --git a/app/src/main/java/com/drdisagree/iconify/utils/helper/Logger.kt b/app/src/main/java/com/drdisagree/iconify/utils/helper/Logger.kt index c5053804c..213c88cbd 100644 --- a/app/src/main/java/com/drdisagree/iconify/utils/helper/Logger.kt +++ b/app/src/main/java/com/drdisagree/iconify/utils/helper/Logger.kt @@ -20,7 +20,6 @@ object Logger { private val TAG = Logger::class.java.getSimpleName() - @JvmStatic fun writeLog(tag: String?, header: String?, details: List) { val log = deviceInfo @@ -35,7 +34,6 @@ object Logger { writeLogToFile(log) } - @JvmStatic fun writeLog(tag: String?, header: String?, details: String?) { val log = deviceInfo @@ -47,7 +45,6 @@ object Logger { writeLogToFile(log) } - @JvmStatic fun writeLog(tag: String?, header: String?, exception: Exception) { val log = deviceInfo log.append("error: ").append(header).append('\n') diff --git a/app/src/main/java/com/drdisagree/iconify/utils/helper/TypedValueUtil.kt b/app/src/main/java/com/drdisagree/iconify/utils/helper/TypedValueUtil.kt deleted file mode 100644 index ad4655634..000000000 --- a/app/src/main/java/com/drdisagree/iconify/utils/helper/TypedValueUtil.kt +++ /dev/null @@ -1,36 +0,0 @@ -package com.drdisagree.iconify.utils.helper - -import android.util.TypedValue -import androidx.annotation.IntRange - -object TypedValueUtil { - - @JvmStatic - fun createComplexDimension( - @IntRange(from = -0x800000, to = 0x7FFFFF) value: Int, - @ComplexDimensionUnit units: Int - ): Int { - require(!(units < TypedValue.COMPLEX_UNIT_PX || units > TypedValue.COMPLEX_UNIT_MM)) { "Must be a valid COMPLEX_UNIT_*: $units" } - - return intToComplex(value) or units - } - - private fun intToComplex(value: Int): Int { - require(!(value < -0x800000 || value >= 0x800000)) { "Magnitude of the value is too large: $value" } - - return createComplex(value, TypedValue.COMPLEX_RADIX_23p0) - } - - private fun createComplex( - @IntRange(from = -0x800000, to = 0x7FFFFF) mantissa: Int, - radix: Int - ): Int { - require(!(mantissa < -0x800000 || mantissa >= 0x800000)) { "Magnitude of mantissa is too large: $mantissa" } - require(!(radix < TypedValue.COMPLEX_RADIX_23p0 || radix > TypedValue.COMPLEX_RADIX_0p23)) { "Invalid radix: $radix" } - - return (mantissa and TypedValue.COMPLEX_MANTISSA_MASK shl TypedValue.COMPLEX_MANTISSA_SHIFT - or (radix shl TypedValue.COMPLEX_RADIX_SHIFT)) - } - - annotation class ComplexDimensionUnit -} diff --git a/app/src/main/java/com/drdisagree/iconify/utils/helper/TypedValueUtils.kt b/app/src/main/java/com/drdisagree/iconify/utils/helper/TypedValueUtils.kt new file mode 100644 index 000000000..0e1af90df --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/utils/helper/TypedValueUtils.kt @@ -0,0 +1,35 @@ +package com.drdisagree.iconify.utils.helper + +import android.util.TypedValue +import androidx.annotation.IntRange + +object TypedValueUtils { + + fun createComplexDimension( + @IntRange(from = -0x800000, to = 0x7FFFFF) value: Int, + @ComplexDimensionUnit units: Int + ): Int { + require(!(units < TypedValue.COMPLEX_UNIT_PX || units > TypedValue.COMPLEX_UNIT_MM)) { "Must be a valid COMPLEX_UNIT_*: $units" } + + return intToComplex(value) or units + } + + private fun intToComplex(value: Int): Int { + require(!(value < -0x800000 || value >= 0x800000)) { "Magnitude of the value is too large: $value" } + + return createComplex(value, TypedValue.COMPLEX_RADIX_23p0) + } + + private fun createComplex( + @IntRange(from = -0x800000, to = 0x7FFFFF) mantissa: Int, + radix: Int + ): Int { + require(!(mantissa < -0x800000 || mantissa >= 0x800000)) { "Magnitude of mantissa is too large: $mantissa" } + require(!(radix < TypedValue.COMPLEX_RADIX_23p0 || radix > TypedValue.COMPLEX_RADIX_0p23)) { "Invalid radix: $radix" } + + return (mantissa and TypedValue.COMPLEX_MANTISSA_MASK shl TypedValue.COMPLEX_MANTISSA_SHIFT + or (radix shl TypedValue.COMPLEX_RADIX_SHIFT)) + } + + annotation class ComplexDimensionUnit +} diff --git a/app/src/main/java/com/drdisagree/iconify/utils/overlay/FabricatedUtil.kt b/app/src/main/java/com/drdisagree/iconify/utils/overlay/FabricatedUtil.kt deleted file mode 100644 index c9eb9022f..000000000 --- a/app/src/main/java/com/drdisagree/iconify/utils/overlay/FabricatedUtil.kt +++ /dev/null @@ -1,218 +0,0 @@ -package com.drdisagree.iconify.utils.overlay - -import android.os.Build -import android.util.TypedValue -import com.drdisagree.iconify.common.Resources -import com.drdisagree.iconify.config.Prefs -import com.drdisagree.iconify.utils.helper.TypedValueUtil.createComplexDimension -import com.topjohnwu.superuser.Shell - -object FabricatedUtil { - - @JvmStatic - val overlayList: List - get() = Shell.cmd( - "cmd overlay list | grep -E '....com.android.shell:IconifyComponent' | sed -E 's/^....com.android.shell:IconifyComponent//'" - ).exec().out - - @JvmStatic - val enabledOverlayList: List - get() = Shell.cmd( - "cmd overlay list | grep -E '.x..com.android.shell:IconifyComponent' | sed -E 's/^.x..com.android.shell:IconifyComponent//'" - ).exec().out - - @JvmStatic - val disabledOverlayList: List - get() = Shell.cmd( - "cmd overlay list | grep -E '. ..com.android.shell:IconifyComponent' | sed -E 's/^. ..com.android.shell:IconifyComponent//'" - ).exec().out - - @JvmStatic - fun buildAndEnableOverlay( - target: String?, - name: String?, - type: String?, - resourceName: String?, - `val`: String? - ) { - require(!(target == null || name == null || type == null || resourceName == null || `val` == null)) { "One or more arguments are null\ntarget: $target\nname: $name\ntype: $type\nresourceName: $resourceName\nval: $`val`" } - require(!(Build.VERSION.SDK_INT >= 34 && type == "dimen")) { "Android 14+ does not support dimen fabricated overlays." } - - val commands = buildCommands(target, name, type, resourceName, `val`) - - Prefs.putBoolean("fabricated$name", true) - Prefs.putString("FOCMDtarget$name", target) - Prefs.putString("FOCMDname$name", name) - Prefs.putString("FOCMDtype$name", type) - Prefs.putString("FOCMDresourceName$name", resourceName) - Prefs.putString("FOCMDval$name", `val`) - - Shell.cmd( - "mv " + Resources.MODULE_DIR + "/post-exec.sh " + Resources.MODULE_DIR + "/post-exec.txt; grep -v \"IconifyComponent" + name + "\" " + Resources.MODULE_DIR + "/post-exec.txt > " + Resources.MODULE_DIR + "/post-exec.txt.tmp && mv " + Resources.MODULE_DIR + "/post-exec.txt.tmp " + Resources.MODULE_DIR + "/post-exec.sh; rm -rf " + Resources.MODULE_DIR + "/post-exec.txt; rm -rf " + Resources.MODULE_DIR + "/post-exec.txt.tmp" - ).submit() - Shell.cmd( - "echo -e \"${commands[0]}\n${commands[1]}\" >> ${Resources.MODULE_DIR}/post-exec.sh" - ).submit() - Shell.cmd(commands[0], commands[1]).submit() - } - - @JvmStatic - fun buildAndEnableOverlays(vararg args: Array) { - val commands: MutableList = ArrayList() - val module: MutableList = ArrayList() - - for (arg in args) { - require(arg.size % 5 == 0) { "Mismatch in number of arguments." } - } - - for (arg in args) { - val tempCommands = buildCommands( - arg[0] as String, - arg[1] as String, - arg[2] as String, - arg[3] as String, - arg[4] as String - ) - - Prefs.putBoolean("fabricated" + arg[1], true) - Prefs.putString("FOCMDtarget" + arg[1], arg[0] as String) - Prefs.putString("FOCMDname" + arg[1], arg[1] as String) - Prefs.putString("FOCMDtype" + arg[1], arg[2] as String) - Prefs.putString("FOCMDresourceName" + arg[1], arg[3] as String) - Prefs.putString("FOCMDval" + arg[1], arg[4] as String) - - module.add("mv " + Resources.MODULE_DIR + "/post-exec.sh " + Resources.MODULE_DIR + "/post-exec.txt; grep -v \"IconifyComponent" + arg[1] + "\" " + Resources.MODULE_DIR + "/post-exec.txt > " + Resources.MODULE_DIR + "/post-exec.txt.tmp && mv " + Resources.MODULE_DIR + "/post-exec.txt.tmp " + Resources.MODULE_DIR + "/post-exec.sh; rm -rf " + Resources.MODULE_DIR + "/post-exec.txt; rm -rf " + Resources.MODULE_DIR + "/post-exec.txt.tmp") - module.add("echo -e \"${tempCommands[0]}\n${tempCommands[1]}\" >> ${Resources.MODULE_DIR}/post-exec.sh") - - commands.add(tempCommands[0]) - commands.add(tempCommands[1]) - } - - Shell.cmd(java.lang.String.join("; ", module), java.lang.String.join("; ", commands)) - .submit() - } - - fun buildCommands( - target: String, - name: String, - type: String, - resourceName: String, - `val`: String - ): List { - var localTarget = target - var localVal = `val` - var resourceType = "0x1c" - if (localTarget == "systemui" || localTarget == "sysui") { - localTarget = "com.android.systemui" - } - - when (type) { - "color" -> resourceType = "0x1c" - "dimen" -> resourceType = "0x05" - "bool" -> resourceType = "0x12" - "integer" -> resourceType = "0x10" - } - - if (type == "dimen") { - var valType = -1 - - when { - localVal.contains("dp") || localVal.contains("dip") -> { - valType = TypedValue.COMPLEX_UNIT_DIP - localVal = localVal.replace("dp", "").replace("dip", "") - } - - localVal.contains("sp") -> { - valType = TypedValue.COMPLEX_UNIT_SP - localVal = localVal.replace("sp", "") - } - - localVal.contains("px") -> { - valType = TypedValue.COMPLEX_UNIT_PX - localVal = localVal.replace("px", "") - } - - localVal.contains("in") -> { - valType = TypedValue.COMPLEX_UNIT_IN - localVal = localVal.replace("in", "") - } - - localVal.contains("pt") -> { - valType = TypedValue.COMPLEX_UNIT_PT - localVal = localVal.replace("pt", "") - } - - localVal.contains("mm") -> { - valType = TypedValue.COMPLEX_UNIT_MM - localVal = localVal.replace("mm", "") - } - } - - localVal = createComplexDimension(localVal.toInt(), valType).toString() - } - - val commands: MutableList = ArrayList() - commands.add("cmd overlay fabricate --target $localTarget --name IconifyComponent$name $localTarget:$type/$resourceName $resourceType $localVal") - commands.add("cmd overlay enable --user current com.android.shell:IconifyComponent$name") - - return commands - } - - @JvmStatic - fun disableOverlay(name: String) { - Prefs.putBoolean("fabricated$name", false) - Prefs.clearPrefs( - "FOCMDtarget$name", - "FOCMDname$name", - "FOCMDtype$name", - "FOCMDresourceName$name", - "FOCMDval$name" - ) - - val disableCmd = - "cmd overlay disable --user current com.android.shell:IconifyComponent$name" - - Shell.cmd( - "mv " + Resources.MODULE_DIR + "/post-exec.sh " + Resources.MODULE_DIR + "/post-exec.txt; grep -v \"IconifyComponent" + name + "\" " + Resources.MODULE_DIR + "/post-exec.txt > " + Resources.MODULE_DIR + "/post-exec.txt.tmp && mv " + Resources.MODULE_DIR + "/post-exec.txt.tmp " + Resources.MODULE_DIR + "/post-exec.sh; rm -rf " + Resources.MODULE_DIR + "/post-exec.txt; rm -rf " + Resources.MODULE_DIR + "/post-exec.txt.tmp" - ).submit() - Shell.cmd(disableCmd).submit() - } - - @JvmStatic - fun disableOverlays(vararg names: String) { - val command = StringBuilder() - - for (name in names) { - Prefs.putBoolean("fabricated$name", false) - Prefs.clearPrefs( - "FOCMDtarget$name", - "FOCMDname$name", - "FOCMDtype$name", - "FOCMDresourceName$name", - "FOCMDval$name" - ) - - command.append("cmd overlay disable --user current com.android.shell:IconifyComponent") - .append(name).append("; ") - - Shell.cmd( - "mv " + Resources.MODULE_DIR + "/post-exec.sh " + Resources.MODULE_DIR + "/post-exec.txt; grep -v \"IconifyComponent" + name + "\" " + Resources.MODULE_DIR + "/post-exec.txt > " + Resources.MODULE_DIR + "/post-exec.txt.tmp && mv " + Resources.MODULE_DIR + "/post-exec.txt.tmp " + Resources.MODULE_DIR + "/post-exec.sh; rm -rf " + Resources.MODULE_DIR + "/post-exec.txt; rm -rf " + Resources.MODULE_DIR + "/post-exec.txt.tmp" - ).submit() - } - - Shell.cmd(command.toString().trim { it <= ' ' }).submit() - } - - fun isOverlayEnabled(name: String): Boolean { - return Shell.cmd( - "[[ $(cmd overlay list | grep -o '\\[x\\] com.android.shell:IconifyComponent$name') ]] && echo 1 || echo 0" - ).exec().out[0] == "1" - } - - @JvmStatic - fun isOverlayDisabled(name: String): Boolean { - return Shell.cmd( - "[[ $(cmd overlay list | grep -o '\\[ \\] com.android.shell:IconifyComponent$name') ]] && echo 1 || echo 0" - ).exec().out[0] == "1" - } -} diff --git a/app/src/main/java/com/drdisagree/iconify/utils/overlay/FabricatedUtils.kt b/app/src/main/java/com/drdisagree/iconify/utils/overlay/FabricatedUtils.kt new file mode 100644 index 000000000..f672867bb --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/utils/overlay/FabricatedUtils.kt @@ -0,0 +1,210 @@ +package com.drdisagree.iconify.utils.overlay + +import android.os.Build +import android.util.TypedValue +import com.drdisagree.iconify.common.Resources +import com.drdisagree.iconify.config.RPrefs +import com.drdisagree.iconify.utils.helper.TypedValueUtils.createComplexDimension +import com.topjohnwu.superuser.Shell + +object FabricatedUtils { + + val overlayList: List + get() = Shell.cmd( + "cmd overlay list | grep -E '....com.android.shell:IconifyComponent' | sed -E 's/^....com.android.shell:IconifyComponent//'" + ).exec().out + + val enabledOverlayList: List + get() = Shell.cmd( + "cmd overlay list | grep -E '.x..com.android.shell:IconifyComponent' | sed -E 's/^.x..com.android.shell:IconifyComponent//'" + ).exec().out + + val disabledOverlayList: List + get() = Shell.cmd( + "cmd overlay list | grep -E '. ..com.android.shell:IconifyComponent' | sed -E 's/^. ..com.android.shell:IconifyComponent//'" + ).exec().out + + fun buildAndEnableOverlay( + target: String?, + name: String?, + type: String?, + resourceName: String?, + `val`: String? + ) { + require(!(target == null || name == null || type == null || resourceName == null || `val` == null)) { "One or more arguments are null\ntarget: $target\nname: $name\ntype: $type\nresourceName: $resourceName\nval: $`val`" } + require(!(Build.VERSION.SDK_INT >= 34 && type == "dimen")) { "Android 14+ does not support dimen fabricated overlays." } + + val commands = buildCommands(target, name, type, resourceName, `val`) + + RPrefs.putBoolean("fabricated$name", true) + RPrefs.putString("FOCMDtarget$name", target) + RPrefs.putString("FOCMDname$name", name) + RPrefs.putString("FOCMDtype$name", type) + RPrefs.putString("FOCMDresourceName$name", resourceName) + RPrefs.putString("FOCMDval$name", `val`) + + Shell.cmd( + "mv " + Resources.MODULE_DIR + "/post-exec.sh " + Resources.MODULE_DIR + "/post-exec.txt; grep -v \"IconifyComponent" + name + "\" " + Resources.MODULE_DIR + "/post-exec.txt > " + Resources.MODULE_DIR + "/post-exec.txt.tmp && mv " + Resources.MODULE_DIR + "/post-exec.txt.tmp " + Resources.MODULE_DIR + "/post-exec.sh; rm -rf " + Resources.MODULE_DIR + "/post-exec.txt; rm -rf " + Resources.MODULE_DIR + "/post-exec.txt.tmp" + ).submit() + Shell.cmd( + "echo -e \"${commands[0]}\n${commands[1]}\" >> ${Resources.MODULE_DIR}/post-exec.sh" + ).submit() + Shell.cmd(commands[0], commands[1]).submit() + } + + fun buildAndEnableOverlays(vararg args: Array) { + val commands: MutableList = ArrayList() + val module: MutableList = ArrayList() + + for (arg in args) { + require(arg.size % 5 == 0) { "Mismatch in number of arguments." } + } + + for (arg in args) { + val tempCommands = buildCommands( + arg[0] as String, + arg[1] as String, + arg[2] as String, + arg[3] as String, + arg[4] as String + ) + + RPrefs.putBoolean("fabricated" + arg[1], true) + RPrefs.putString("FOCMDtarget" + arg[1], arg[0] as String) + RPrefs.putString("FOCMDname" + arg[1], arg[1] as String) + RPrefs.putString("FOCMDtype" + arg[1], arg[2] as String) + RPrefs.putString("FOCMDresourceName" + arg[1], arg[3] as String) + RPrefs.putString("FOCMDval" + arg[1], arg[4] as String) + + module.add("mv " + Resources.MODULE_DIR + "/post-exec.sh " + Resources.MODULE_DIR + "/post-exec.txt; grep -v \"IconifyComponent" + arg[1] + "\" " + Resources.MODULE_DIR + "/post-exec.txt > " + Resources.MODULE_DIR + "/post-exec.txt.tmp && mv " + Resources.MODULE_DIR + "/post-exec.txt.tmp " + Resources.MODULE_DIR + "/post-exec.sh; rm -rf " + Resources.MODULE_DIR + "/post-exec.txt; rm -rf " + Resources.MODULE_DIR + "/post-exec.txt.tmp") + module.add("echo -e \"${tempCommands[0]}\n${tempCommands[1]}\" >> ${Resources.MODULE_DIR}/post-exec.sh") + + commands.add(tempCommands[0]) + commands.add(tempCommands[1]) + } + + Shell.cmd(java.lang.String.join("; ", module), java.lang.String.join("; ", commands)) + .submit() + } + + fun buildCommands( + target: String, + name: String, + type: String, + resourceName: String, + `val`: String + ): List { + var localTarget = target + var localVal = `val` + var resourceType = "0x1c" + if (localTarget == "systemui" || localTarget == "sysui") { + localTarget = "com.android.systemui" + } + + when (type) { + "color" -> resourceType = "0x1c" + "dimen" -> resourceType = "0x05" + "bool" -> resourceType = "0x12" + "integer" -> resourceType = "0x10" + } + + if (type == "dimen") { + var valType = -1 + + when { + localVal.contains("dp") || localVal.contains("dip") -> { + valType = TypedValue.COMPLEX_UNIT_DIP + localVal = localVal.replace("dp", "").replace("dip", "") + } + + localVal.contains("sp") -> { + valType = TypedValue.COMPLEX_UNIT_SP + localVal = localVal.replace("sp", "") + } + + localVal.contains("px") -> { + valType = TypedValue.COMPLEX_UNIT_PX + localVal = localVal.replace("px", "") + } + + localVal.contains("in") -> { + valType = TypedValue.COMPLEX_UNIT_IN + localVal = localVal.replace("in", "") + } + + localVal.contains("pt") -> { + valType = TypedValue.COMPLEX_UNIT_PT + localVal = localVal.replace("pt", "") + } + + localVal.contains("mm") -> { + valType = TypedValue.COMPLEX_UNIT_MM + localVal = localVal.replace("mm", "") + } + } + + localVal = createComplexDimension(localVal.toInt(), valType).toString() + } + + val commands: MutableList = ArrayList() + commands.add("cmd overlay fabricate --target $localTarget --name IconifyComponent$name $localTarget:$type/$resourceName $resourceType $localVal") + commands.add("cmd overlay enable --user current com.android.shell:IconifyComponent$name") + + return commands + } + + fun disableOverlay(name: String) { + RPrefs.putBoolean("fabricated$name", false) + RPrefs.clearPrefs( + "FOCMDtarget$name", + "FOCMDname$name", + "FOCMDtype$name", + "FOCMDresourceName$name", + "FOCMDval$name" + ) + + val disableCmd = + "cmd overlay disable --user current com.android.shell:IconifyComponent$name" + + Shell.cmd( + "mv " + Resources.MODULE_DIR + "/post-exec.sh " + Resources.MODULE_DIR + "/post-exec.txt; grep -v \"IconifyComponent" + name + "\" " + Resources.MODULE_DIR + "/post-exec.txt > " + Resources.MODULE_DIR + "/post-exec.txt.tmp && mv " + Resources.MODULE_DIR + "/post-exec.txt.tmp " + Resources.MODULE_DIR + "/post-exec.sh; rm -rf " + Resources.MODULE_DIR + "/post-exec.txt; rm -rf " + Resources.MODULE_DIR + "/post-exec.txt.tmp" + ).submit() + Shell.cmd(disableCmd).submit() + } + + fun disableOverlays(vararg names: String) { + val command = StringBuilder() + + for (name in names) { + RPrefs.putBoolean("fabricated$name", false) + RPrefs.clearPrefs( + "FOCMDtarget$name", + "FOCMDname$name", + "FOCMDtype$name", + "FOCMDresourceName$name", + "FOCMDval$name" + ) + + command.append("cmd overlay disable --user current com.android.shell:IconifyComponent") + .append(name).append("; ") + + Shell.cmd( + "mv " + Resources.MODULE_DIR + "/post-exec.sh " + Resources.MODULE_DIR + "/post-exec.txt; grep -v \"IconifyComponent" + name + "\" " + Resources.MODULE_DIR + "/post-exec.txt > " + Resources.MODULE_DIR + "/post-exec.txt.tmp && mv " + Resources.MODULE_DIR + "/post-exec.txt.tmp " + Resources.MODULE_DIR + "/post-exec.sh; rm -rf " + Resources.MODULE_DIR + "/post-exec.txt; rm -rf " + Resources.MODULE_DIR + "/post-exec.txt.tmp" + ).submit() + } + + Shell.cmd(command.toString().trim { it <= ' ' }).submit() + } + + fun isOverlayEnabled(name: String): Boolean { + return Shell.cmd( + "[[ $(cmd overlay list | grep -o '\\[x\\] com.android.shell:IconifyComponent$name') ]] && echo 1 || echo 0" + ).exec().out[0] == "1" + } + + fun isOverlayDisabled(name: String): Boolean { + return Shell.cmd( + "[[ $(cmd overlay list | grep -o '\\[ \\] com.android.shell:IconifyComponent$name') ]] && echo 1 || echo 0" + ).exec().out[0] == "1" + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/utils/overlay/OverlayUtil.kt b/app/src/main/java/com/drdisagree/iconify/utils/overlay/OverlayUtil.kt deleted file mode 100644 index 2e89db68d..000000000 --- a/app/src/main/java/com/drdisagree/iconify/utils/overlay/OverlayUtil.kt +++ /dev/null @@ -1,173 +0,0 @@ -package com.drdisagree.iconify.utils.overlay - -import com.drdisagree.iconify.Iconify.Companion.appContext -import com.drdisagree.iconify.common.Resources -import com.drdisagree.iconify.config.Prefs -import com.topjohnwu.superuser.Shell -import java.util.Objects - -object OverlayUtil { - - @JvmStatic - val overlayList: List - get() = Shell.cmd( - "cmd overlay list | grep -E '....IconifyComponent' | sed -E 's/^....//'" - ).exec().out - - @JvmStatic - val enabledOverlayList: List - get() = Shell.cmd( - "cmd overlay list | grep -E '.x..IconifyComponent' | sed -E 's/^.x..//'" - ).exec().out - - @JvmStatic - val disabledOverlayList: List - get() = Shell.cmd( - "cmd overlay list | grep -E '. ..IconifyComponent' | sed -E 's/^. ..//'" - ).exec().out - - @JvmStatic - fun isOverlayEnabled(pkgName: String): Boolean { - return Shell.cmd( - "[[ $(cmd overlay list | grep -o '\\[x\\] $pkgName') ]] && echo 1 || echo 0" - ).exec().out[0] == "1" - } - - @JvmStatic - fun isOverlayDisabled(pkgName: String): Boolean { - return !isOverlayEnabled(pkgName) - } - - @JvmStatic - fun isOverlayInstalled(enabledOverlays: List, pkgName: String): Boolean { - for (line in enabledOverlays) { - if (line == pkgName) return true - } - - return false - } - - @JvmStatic - fun enableOverlay(pkgName: String) { - Prefs.putBoolean(pkgName, true) - Shell.cmd( - "cmd overlay enable --user current $pkgName", - "cmd overlay set-priority $pkgName highest" - ).submit() - } - - @JvmStatic - fun enableOverlays(vararg pkgNames: String?) { - val command = StringBuilder() - - for (pkgName in pkgNames) { - Prefs.putBoolean(pkgName, true) - - command.append("cmd overlay enable --user current ").append(pkgName) - .append("; cmd overlay set-priority ").append(pkgName).append(" highest; ") - } - - Shell.cmd(command.toString().trim { it <= ' ' }).submit() - } - - @JvmStatic - fun enableOverlayExclusiveInCategory(pkgName: String) { - Prefs.putBoolean(pkgName, true) - Shell.cmd( - "cmd overlay enable-exclusive --user current --category $pkgName", - "cmd overlay set-priority $pkgName highest" - ).submit() - } - - @JvmStatic - fun enableOverlaysExclusiveInCategory(vararg pkgNames: String?) { - val command = StringBuilder() - - for (pkgName in pkgNames) { - Prefs.putBoolean(pkgName, true) - - command.append("cmd overlay enable-exclusive --user current --category ") - .append(pkgName).append("; cmd overlay set-priority ").append(pkgName) - .append(" highest; ") - } - - Shell.cmd(command.toString().trim { it <= ' ' }).submit() - } - - @JvmStatic - fun disableOverlay(pkgName: String) { - Prefs.putBoolean(pkgName, false) - Shell.cmd("cmd overlay disable --user current $pkgName").submit() - } - - @JvmStatic - fun disableOverlays(vararg pkgNames: String?) { - val command = StringBuilder() - - for (pkgName in pkgNames) { - Prefs.putBoolean(pkgName, false) - - command.append("cmd overlay disable --user current ").append(pkgName).append("; ") - } - - Shell.cmd(command.toString().trim { it <= ' ' }).submit() - } - - @JvmStatic - fun changeOverlayState(vararg args: Any) { - require(args.size % 2 == 0) { "Number of arguments must be even." } - - val command = StringBuilder() - var i = 0 - - while (i < args.size) { - val pkgName = args[i] as String - val state = args[i + 1] as Boolean - - Prefs.putBoolean(pkgName, state) - - if (state) { - command.append("cmd overlay enable --user current ").append(pkgName) - .append("; cmd overlay set-priority ").append(pkgName).append(" highest; ") - } else { - command.append("cmd overlay disable --user current ").append(pkgName).append("; ") - } - - i += 2 - } - - Shell.cmd(command.toString().trim { it <= ' ' }).submit() - } - - @JvmStatic - fun overlayExists(): Boolean { - return Shell.cmd( - "[ -f /system/product/overlay/IconifyComponentAMGC.apk ] && echo \"found\" || echo \"not found\"" - ).exec().out[0] == "found" - } - - @Suppress("unused") - fun matchOverlayAgainstAssets(): Boolean { - return try { - val packages = appContext.assets.list("Overlays") - var numberOfOverlaysInAssets = 0 - - for (overlay in packages!!) { - numberOfOverlaysInAssets += Objects.requireNonNull( - appContext.assets.list( - "Overlays/$overlay" - ) - ).size - } - - val numberOfOverlaysInstalled = - Shell.cmd("find /" + Resources.OVERLAY_DIR + "/ -maxdepth 1 -type f -print| wc -l") - .exec().out[0].toInt() - - numberOfOverlaysInAssets <= numberOfOverlaysInstalled - } catch (e: Exception) { - e.printStackTrace() - false - } - } -} diff --git a/app/src/main/java/com/drdisagree/iconify/utils/overlay/OverlayUtils.kt b/app/src/main/java/com/drdisagree/iconify/utils/overlay/OverlayUtils.kt new file mode 100644 index 000000000..97503b14a --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/utils/overlay/OverlayUtils.kt @@ -0,0 +1,219 @@ +package com.drdisagree.iconify.utils.overlay + +import android.content.Context +import android.content.pm.PackageManager +import android.graphics.drawable.Drawable +import android.util.Log +import com.drdisagree.iconify.Iconify.Companion.appContext +import com.drdisagree.iconify.common.Resources +import com.drdisagree.iconify.config.RPrefs +import com.topjohnwu.superuser.Shell +import java.util.Objects + +object OverlayUtils { + + val overlayList: List + get() = Shell.cmd( + "cmd overlay list | grep -E '....IconifyComponent' | sed -E 's/^....//'" + ).exec().out + + val enabledOverlayList: List + get() = Shell.cmd( + "cmd overlay list | grep -E '.x..IconifyComponent' | sed -E 's/^.x..//'" + ).exec().out + + val disabledOverlayList: List + get() = Shell.cmd( + "cmd overlay list | grep -E '. ..IconifyComponent' | sed -E 's/^. ..//'" + ).exec().out + + fun getOverlayForComponent(componentName: String): List { + return Shell.cmd("cmd overlay list | grep '....IconifyComponent$componentName'") + .exec().out + } + + fun isOverlayEnabled(pkgName: String): Boolean { + return Shell.cmd( + "[[ $(cmd overlay list | grep -o '\\[x\\] $pkgName') ]] && echo 1 || echo 0" + ).exec().out[0] == "1" + } + + fun isOverlayDisabled(pkgName: String): Boolean { + return !isOverlayEnabled(pkgName) + } + + fun isOverlayInstalled(enabledOverlays: List, pkgName: String): Boolean { + for (line in enabledOverlays) { + if (line == pkgName) return true + } + + return false + } + + fun enableOverlay(pkgName: String) { + RPrefs.putBoolean(pkgName, true) + Shell.cmd( + "cmd overlay enable --user current $pkgName", + "cmd overlay set-priority $pkgName highest" + ).submit() + } + + fun enableOverlay(pkgName: String, priority: String) { + RPrefs.putBoolean(pkgName, true) + Shell.cmd( + "cmd overlay enable --user current $pkgName", + "cmd overlay set-priority $pkgName $priority" + ).submit() + } + + fun enableOverlays(vararg pkgNames: String?) { + val command = StringBuilder() + + for (pkgName in pkgNames) { + RPrefs.putBoolean(pkgName, true) + + command.append("cmd overlay enable --user current ").append(pkgName) + .append("; cmd overlay set-priority ").append(pkgName).append(" highest; ") + } + + Shell.cmd(command.toString().trim { it <= ' ' }).submit() + } + + fun enableOverlayExclusiveInCategory(pkgName: String) { + RPrefs.putBoolean(pkgName, true) + Shell.cmd( + "cmd overlay enable-exclusive --user current --category $pkgName", + "cmd overlay set-priority $pkgName highest" + ).submit() + } + + fun enableOverlaysExclusiveInCategory(vararg pkgNames: String?) { + val command = StringBuilder() + + for (pkgName in pkgNames) { + RPrefs.putBoolean(pkgName, true) + + command.append("cmd overlay enable-exclusive --user current --category ") + .append(pkgName).append("; cmd overlay set-priority ").append(pkgName) + .append(" highest; ") + } + + Shell.cmd(command.toString().trim { it <= ' ' }).submit() + } + + fun disableOverlay(pkgName: String) { + RPrefs.putBoolean(pkgName, false) + Shell.cmd("cmd overlay disable --user current $pkgName").submit() + } + + fun disableOverlays(vararg pkgNames: String?) { + val command = StringBuilder() + + for (pkgName in pkgNames) { + RPrefs.putBoolean(pkgName, false) + + command.append("cmd overlay disable --user current ").append(pkgName).append("; ") + } + + Shell.cmd(command.toString().trim { it <= ' ' }).submit() + } + + fun changeOverlayState(vararg args: Any) { + require(args.size % 2 == 0) { "Number of arguments must be even." } + + val command = StringBuilder() + var i = 0 + + while (i < args.size) { + val pkgName = args[i] as String + val state = args[i + 1] as Boolean + + RPrefs.putBoolean(pkgName, state) + + if (state) { + command.append("cmd overlay enable --user current ").append(pkgName) + .append("; cmd overlay set-priority ").append(pkgName).append(" highest; ") + } else { + command.append("cmd overlay disable --user current ").append(pkgName).append("; ") + } + + i += 2 + } + + Shell.cmd(command.toString().trim { it <= ' ' }).submit() + } + + fun overlayExists(): Boolean { + return Shell.cmd( + "[ -f /system/product/overlay/IconifyComponentAMGC.apk ] && echo \"found\" || echo \"not found\"" + ).exec().out[0] == "found" + } + + @Suppress("unused") + fun matchOverlayAgainstAssets(): Boolean { + return try { + val packages = appContext.assets.list("Overlays") + var numberOfOverlaysInAssets = 0 + + for (overlay in packages!!) { + numberOfOverlaysInAssets += Objects.requireNonNull( + appContext.assets.list( + "Overlays/$overlay" + ) + ).size + } + + val numberOfOverlaysInstalled = + Shell.cmd("find /" + Resources.OVERLAY_DIR + "/ -maxdepth 1 -type f -print| wc -l") + .exec().out[0].toInt() + + numberOfOverlaysInAssets <= numberOfOverlaysInstalled + } catch (e: Exception) { + e.printStackTrace() + false + } + } + + fun getDrawableFromOverlay(context: Context, pkg: String?, drawableName: String?): Drawable? { + try { + val pm = context.packageManager + val res = pm.getResourcesForApplication(pkg!!) + val resId = res.getIdentifier(drawableName, "drawable", pkg) + return if (resId != 0X0) res.getDrawable(resId) + else null + } catch (e: PackageManager.NameNotFoundException) { + Log.d("OverlayUtil", "getDrawableFromOverlay: Package Not Found " + e.message) + return null + } + } + + fun getStringFromOverlay(context: Context, pkg: String, stringName: String): String? { + return try { + val pm = context.packageManager + val res = pm.getResourcesForApplication(pkg) + val resId = res.getIdentifier(stringName, "string", pkg) + if (resId != 0) res.getString(resId) else null + } catch (e: PackageManager.NameNotFoundException) { + Log.e("OverlayUtil", "getStringFromOverlay: Package Not Found" + e.message) + null + } + } + + fun checkEnabledOverlay(componentName: String) : String { + val component = + Shell.cmd("cmd overlay list | grep \".x..IconifyComponent$componentName\"") + .exec().out + Log.d("OverlayUtil", "checkEnabledOverlay: $component") + if (component.isNotEmpty()) { + val num = component[0].split("IconifyComponent$componentName".toRegex()) + .dropLastWhile { it.isEmpty() } + .toTypedArray()[1].split("\\.overlay".toRegex()).dropLastWhile { it.isEmpty() } + .toTypedArray()[0] + Log.d("OverlayUtil", "checkEnabledOverlay: $num") + Log.d("OverlayUtil", "checkEnabledOverlay: IconifyComponent$componentName$num.overlay") + return "IconifyComponent$componentName$num.overlay" + } + return ""; + } + +} diff --git a/app/src/main/java/com/drdisagree/iconify/utils/overlay/compiler/CompilerUtil.kt b/app/src/main/java/com/drdisagree/iconify/utils/overlay/compiler/CompilerUtil.kt deleted file mode 100644 index 534eda711..000000000 --- a/app/src/main/java/com/drdisagree/iconify/utils/overlay/compiler/CompilerUtil.kt +++ /dev/null @@ -1,193 +0,0 @@ -package com.drdisagree.iconify.utils.overlay.compiler - -import android.os.Build -import android.util.Log -import com.drdisagree.iconify.BuildConfig -import com.drdisagree.iconify.common.References -import java.io.File -import java.io.StringWriter -import java.util.Locale -import java.util.regex.Pattern -import javax.xml.parsers.DocumentBuilderFactory -import javax.xml.parsers.ParserConfigurationException -import javax.xml.transform.Result -import javax.xml.transform.Source -import javax.xml.transform.TransformerException -import javax.xml.transform.TransformerFactory -import javax.xml.transform.dom.DOMSource -import javax.xml.transform.stream.StreamResult - -object CompilerUtil { - - private val TAG = CompilerUtil::class.java.simpleName - - fun createManifestContent( - overlayName: String?, - targetPackage: String? - ): String { - var mOverlayName = overlayName - - try { - val category = getCategory(mOverlayName) - - if (!mOverlayName!!.startsWith("IconifyComponent")) { - mOverlayName = "IconifyComponent$mOverlayName" - } - - if (!mOverlayName.endsWith(".overlay")) { - mOverlayName = "$mOverlayName.overlay" - } - - val documentBuilderFactory = DocumentBuilderFactory.newInstance() - val documentBuilder = documentBuilderFactory.newDocumentBuilder() - val document = documentBuilder.newDocument() - - val rootElement = document.createElement("manifest") - rootElement.setAttribute("xmlns:android", "http://schemas.android.com/apk/res/android") - rootElement.setAttribute("package", mOverlayName) - rootElement.setAttribute("android:versionName", "v" + BuildConfig.VERSION_NAME) - - val usesSdkElement = document.createElement("uses-sdk") - usesSdkElement.setAttribute( - "android:minSdkVersion", - BuildConfig.MIN_SDK_VERSION.toString() - ) - usesSdkElement.setAttribute( - "android:targetSdkVersion", - Build.VERSION.SDK_INT.toString() - ) - rootElement.appendChild(usesSdkElement) - - val overlayElement = document.createElement("overlay") - overlayElement.setAttribute("android:category", category) - overlayElement.setAttribute("android:priority", 1.toString()) - overlayElement.setAttribute("android:targetPackage", targetPackage) - overlayElement.setAttribute("android:isStatic", "false") - rootElement.appendChild(overlayElement) - - val applicationElement = document.createElement("application") - applicationElement.setAttribute("android:label", mOverlayName.replace(".overlay", "")) - applicationElement.setAttribute("allowBackup", "false") - applicationElement.setAttribute("android:hasCode", "false") - - val metadataNameToValueMap = HashMap() - metadataNameToValueMap[References.METADATA_OVERLAY_PARENT] = BuildConfig.APPLICATION_ID - metadataNameToValueMap[References.METADATA_OVERLAY_TARGET] = targetPackage - metadataNameToValueMap[References.METADATA_THEME_VERSION] = - BuildConfig.VERSION_CODE.toString() - metadataNameToValueMap[References.METADATA_THEME_CATEGORY] = category - metadataNameToValueMap.forEach { (key: String?, value: String?) -> - val element = document.createElement("meta-data") - element.setAttribute("android:name", key) - element.setAttribute("android:value", value) - applicationElement.appendChild(element) - } - - rootElement.appendChild(applicationElement) - document.appendChild(rootElement) - - val transformerFactory = TransformerFactory.newInstance() - val transformer = transformerFactory.newTransformer() - val domSource: Source = DOMSource(document) - val outWriter = StringWriter() - val streamResult: Result = StreamResult(outWriter) - transformer.transform(domSource, streamResult) - - return outWriter.buffer.toString() - } catch (e: ParserConfigurationException) { - Log.i(TAG, "Failed to create manifest for $mOverlayName", e) - } catch (e: TransformerException) { - Log.i(TAG, "Failed to create manifest for $mOverlayName", e) - } - - return "" - } - - fun getOverlayName(filePath: String): String { - val file = File(filePath) - val fileName = file.getName() - - return fileName.replace("IconifyComponent|-unsigned|-unaligned|.apk".toRegex(), "") - } - - private fun getCategory(pkgName: String?): String { - var mPackageName = pkgName - var category = References.OVERLAY_CATEGORY_PREFIX - - mPackageName = mPackageName!!.replace("IconifyComponent", "").replace(".overlay", "") - - if (mPackageName.contains("MPIP")) { - mPackageName = keepFirstDigit(mPackageName) - - category += "media_player_icon_pack_" + mPackageName.lowercase(Locale.getDefault()) - } else { - mPackageName = removeAllDigits(mPackageName) - - category += when (mPackageName) { - "AMAC", "AMGC" -> { - "stock_monet_colors" - } - - "BBN", "BBP" -> { - "brightness_bar_style" - } - - "MPA", "MPB", "MPS" -> { - "media_player_style" - } - - "NFN", "NFP" -> { - "notification_style" - } - - "QSNT", "QSPT" -> { - "qs_tile_text_style" - } - - "QSSN", "QSSP" -> { - "qs_shape_style" - } - - "IPAS" -> { - "icon_pack_android_style" - } - - "IPSUI" -> { - "icon_pack_sysui_style" - } - - else -> { - "iconify_component_" + mPackageName.lowercase(Locale.getDefault()) - } - } - } - - return category - } - - private fun removeAllDigits(input: String): String { - val regex = "\\d+" - val pattern = Pattern.compile(regex) - val matcher = pattern.matcher(input) - - return matcher.replaceAll("") - } - - private fun keepFirstDigit(input: String): String { - val output = StringBuilder() - var firstDigitFound = false - - for (c in input.toCharArray()) { - if (Character.isDigit(c)) { - if (!firstDigitFound) { - output.append(c) - firstDigitFound = true - } - } else { - output.append(c) - } - } - - return output.toString() - } -} diff --git a/app/src/main/java/com/drdisagree/iconify/utils/overlay/compiler/CompilerUtils.kt b/app/src/main/java/com/drdisagree/iconify/utils/overlay/compiler/CompilerUtils.kt new file mode 100644 index 000000000..cdaa7cbbc --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/utils/overlay/compiler/CompilerUtils.kt @@ -0,0 +1,201 @@ +package com.drdisagree.iconify.utils.overlay.compiler + +import android.os.Build +import android.util.Log +import com.drdisagree.iconify.BuildConfig +import com.drdisagree.iconify.common.References +import java.io.File +import java.io.StringWriter +import java.util.Locale +import java.util.regex.Pattern +import javax.xml.parsers.DocumentBuilderFactory +import javax.xml.parsers.ParserConfigurationException +import javax.xml.transform.Result +import javax.xml.transform.Source +import javax.xml.transform.TransformerException +import javax.xml.transform.TransformerFactory +import javax.xml.transform.dom.DOMSource +import javax.xml.transform.stream.StreamResult + +object CompilerUtils { + + private val TAG = CompilerUtils::class.java.simpleName + + fun createManifestContent( + overlayName: String?, + targetPackage: String? + ): String { + var mOverlayName = overlayName + + try { + val category = getCategory(mOverlayName) + + if (!mOverlayName!!.startsWith("IconifyComponent")) { + mOverlayName = "IconifyComponent$mOverlayName" + } + + if (!mOverlayName.endsWith(".overlay")) { + mOverlayName = "$mOverlayName.overlay" + } + + val documentBuilderFactory = DocumentBuilderFactory.newInstance() + val documentBuilder = documentBuilderFactory.newDocumentBuilder() + val document = documentBuilder.newDocument() + + val rootElement = document.createElement("manifest") + rootElement.setAttribute("xmlns:android", "http://schemas.android.com/apk/res/android") + rootElement.setAttribute("package", mOverlayName) + rootElement.setAttribute("android:versionName", "v" + BuildConfig.VERSION_NAME) + + val usesSdkElement = document.createElement("uses-sdk") + usesSdkElement.setAttribute( + "android:minSdkVersion", + BuildConfig.MIN_SDK_VERSION.toString() + ) + usesSdkElement.setAttribute( + "android:targetSdkVersion", + Build.VERSION.SDK_INT.toString() + ) + rootElement.appendChild(usesSdkElement) + + val overlayElement = document.createElement("overlay") + overlayElement.setAttribute("android:category", category) + overlayElement.setAttribute("android:priority", 1.toString()) + overlayElement.setAttribute("android:targetPackage", targetPackage) + overlayElement.setAttribute("android:isStatic", "false") + rootElement.appendChild(overlayElement) + + val applicationElement = document.createElement("application") + applicationElement.setAttribute("android:label", mOverlayName.replace(".overlay", "")) + applicationElement.setAttribute("allowBackup", "false") + applicationElement.setAttribute("android:hasCode", "false") + + val metadataNameToValueMap = HashMap() + metadataNameToValueMap[References.METADATA_OVERLAY_PARENT] = BuildConfig.APPLICATION_ID + metadataNameToValueMap[References.METADATA_OVERLAY_TARGET] = targetPackage + metadataNameToValueMap[References.METADATA_THEME_VERSION] = + BuildConfig.VERSION_CODE.toString() + metadataNameToValueMap[References.METADATA_THEME_CATEGORY] = category + metadataNameToValueMap.forEach { (key: String?, value: String?) -> + val element = document.createElement("meta-data") + element.setAttribute("android:name", key) + element.setAttribute("android:value", value) + applicationElement.appendChild(element) + } + + rootElement.appendChild(applicationElement) + document.appendChild(rootElement) + + val transformerFactory = TransformerFactory.newInstance() + val transformer = transformerFactory.newTransformer() + val domSource: Source = DOMSource(document) + val outWriter = StringWriter() + val streamResult: Result = StreamResult(outWriter) + transformer.transform(domSource, streamResult) + + return outWriter.buffer.toString() + } catch (e: ParserConfigurationException) { + Log.i(TAG, "Failed to create manifest for $mOverlayName", e) + } catch (e: TransformerException) { + Log.i(TAG, "Failed to create manifest for $mOverlayName", e) + } + + return "" + } + + fun getOverlayName(filePath: String): String { + val file = File(filePath) + val fileName = file.getName() + + return fileName.replace("IconifyComponent|-unsigned|-unaligned|.apk".toRegex(), "") + } + + private fun getCategory(pkgName: String?): String { + var mPackageName = pkgName + var category = References.OVERLAY_CATEGORY_PREFIX + + mPackageName = mPackageName!!.replace("IconifyComponent", "").replace(".overlay", "") + + if (mPackageName.contains("MPIP")) { + mPackageName = keepFirstDigit(mPackageName) + + category += "media_player_icon_pack_" + mPackageName.lowercase(Locale.getDefault()) + } else { + mPackageName = removeAllDigits(mPackageName) + + category += when (mPackageName) { + "AMAC", "AMGC" -> { + "stock_monet_colors" + } + + "BBN", "BBP" -> { + "brightness_bar_style" + } + + "MPA", "MPB", "MPS" -> { + "media_player_style" + } + + "NFN", "NFP" -> { + "notification_style" + } + + "QSNT", "QSPT" -> { + "qs_tile_text_style" + } + + "QSSN", "QSSP" -> { + "qs_shape_style" + } + + "IPAS" -> { + "icon_pack_android_style" + } + + "IPSUI" -> { + "icon_pack_sysui_style" + } + + "WIFI" -> { + "icon_pack_wifi_icons" + } + + "SGIC" -> { + "icon_pack_signal_icons" + } + + else -> { + "iconify_component_" + mPackageName.lowercase(Locale.getDefault()) + } + } + } + + return category + } + + private fun removeAllDigits(input: String): String { + val regex = "\\d+" + val pattern = Pattern.compile(regex) + val matcher = pattern.matcher(input) + + return matcher.replaceAll("") + } + + private fun keepFirstDigit(input: String): String { + val output = StringBuilder() + var firstDigitFound = false + + for (c in input.toCharArray()) { + if (Character.isDigit(c)) { + if (!firstDigitFound) { + output.append(c) + firstDigitFound = true + } + } else { + output.append(c) + } + } + + return output.toString() + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/utils/overlay/compiler/DynamicCompiler.kt b/app/src/main/java/com/drdisagree/iconify/utils/overlay/compiler/DynamicCompiler.kt index 5302528f3..3fb988b7e 100644 --- a/app/src/main/java/com/drdisagree/iconify/utils/overlay/compiler/DynamicCompiler.kt +++ b/app/src/main/java/com/drdisagree/iconify/utils/overlay/compiler/DynamicCompiler.kt @@ -3,13 +3,13 @@ package com.drdisagree.iconify.utils.overlay.compiler import android.util.Log import com.drdisagree.iconify.common.Const import com.drdisagree.iconify.common.Resources -import com.drdisagree.iconify.utils.FileUtil.copyAssets -import com.drdisagree.iconify.utils.RootUtil.setPermissions -import com.drdisagree.iconify.utils.SystemUtil.mountRO -import com.drdisagree.iconify.utils.SystemUtil.mountRW +import com.drdisagree.iconify.utils.FileUtils.copyAssets +import com.drdisagree.iconify.utils.RootUtils.setPermissions +import com.drdisagree.iconify.utils.SystemUtils.mountRO +import com.drdisagree.iconify.utils.SystemUtils.mountRW import com.drdisagree.iconify.utils.helper.BinaryInstaller.symLinkBinaries -import com.drdisagree.iconify.utils.overlay.OverlayUtil.disableOverlays -import com.drdisagree.iconify.utils.overlay.OverlayUtil.enableOverlays +import com.drdisagree.iconify.utils.overlay.OverlayUtils.disableOverlays +import com.drdisagree.iconify.utils.overlay.OverlayUtils.enableOverlays import com.drdisagree.iconify.utils.overlay.manager.resource.ResourceManager import com.topjohnwu.superuser.Shell import org.json.JSONObject @@ -24,7 +24,6 @@ object DynamicCompiler { private var mPackage: String? = null private var mForce = false - @JvmStatic @JvmOverloads @Throws(IOException::class) fun buildOverlay(force: Boolean = true): Boolean { diff --git a/app/src/main/java/com/drdisagree/iconify/utils/overlay/compiler/MonetCompiler.kt b/app/src/main/java/com/drdisagree/iconify/utils/overlay/compiler/MonetCompiler.kt index 2b07cd703..96b67b877 100644 --- a/app/src/main/java/com/drdisagree/iconify/utils/overlay/compiler/MonetCompiler.kt +++ b/app/src/main/java/com/drdisagree/iconify/utils/overlay/compiler/MonetCompiler.kt @@ -3,13 +3,13 @@ package com.drdisagree.iconify.utils.overlay.compiler import android.util.Log import com.drdisagree.iconify.common.Const import com.drdisagree.iconify.common.Resources -import com.drdisagree.iconify.utils.FileUtil.copyAssets -import com.drdisagree.iconify.utils.RootUtil.setPermissions -import com.drdisagree.iconify.utils.SystemUtil.mountRO -import com.drdisagree.iconify.utils.SystemUtil.mountRW +import com.drdisagree.iconify.utils.FileUtils.copyAssets +import com.drdisagree.iconify.utils.RootUtils.setPermissions +import com.drdisagree.iconify.utils.SystemUtils.mountRO +import com.drdisagree.iconify.utils.SystemUtils.mountRW import com.drdisagree.iconify.utils.helper.BinaryInstaller.symLinkBinaries -import com.drdisagree.iconify.utils.overlay.OverlayUtil.disableOverlay -import com.drdisagree.iconify.utils.overlay.OverlayUtil.enableOverlays +import com.drdisagree.iconify.utils.overlay.OverlayUtils.disableOverlay +import com.drdisagree.iconify.utils.overlay.OverlayUtils.enableOverlays import com.topjohnwu.superuser.Shell import java.io.IOException @@ -17,7 +17,6 @@ object MonetCompiler { private val TAG = MonetCompiler::class.java.simpleName private var mForce = false - @JvmStatic @Throws(IOException::class) fun buildOverlay(resources: Array, force: Boolean): Boolean { mForce = force diff --git a/app/src/main/java/com/drdisagree/iconify/utils/overlay/compiler/OnDemandCompiler.kt b/app/src/main/java/com/drdisagree/iconify/utils/overlay/compiler/OnDemandCompiler.kt index 4cda9c6ae..ff5b6ed68 100644 --- a/app/src/main/java/com/drdisagree/iconify/utils/overlay/compiler/OnDemandCompiler.kt +++ b/app/src/main/java/com/drdisagree/iconify/utils/overlay/compiler/OnDemandCompiler.kt @@ -2,13 +2,13 @@ package com.drdisagree.iconify.utils.overlay.compiler import android.util.Log import com.drdisagree.iconify.common.Resources -import com.drdisagree.iconify.utils.FileUtil.copyAssets -import com.drdisagree.iconify.utils.RootUtil.setPermissions -import com.drdisagree.iconify.utils.SystemUtil.mountRO -import com.drdisagree.iconify.utils.SystemUtil.mountRW +import com.drdisagree.iconify.utils.FileUtils.copyAssets +import com.drdisagree.iconify.utils.RootUtils.setPermissions +import com.drdisagree.iconify.utils.SystemUtils.mountRO +import com.drdisagree.iconify.utils.SystemUtils.mountRW import com.drdisagree.iconify.utils.helper.BinaryInstaller.symLinkBinaries -import com.drdisagree.iconify.utils.overlay.OverlayUtil.disableOverlay -import com.drdisagree.iconify.utils.overlay.OverlayUtil.enableOverlay +import com.drdisagree.iconify.utils.overlay.OverlayUtils.disableOverlay +import com.drdisagree.iconify.utils.overlay.OverlayUtils.enableOverlay import com.topjohnwu.superuser.Shell import java.io.IOException @@ -20,7 +20,6 @@ object OnDemandCompiler { private var mStyle = 0 private var mForce = false - @JvmStatic @Throws(IOException::class) fun buildOverlay( overlayName: String, diff --git a/app/src/main/java/com/drdisagree/iconify/utils/overlay/compiler/OnboardingCompiler.kt b/app/src/main/java/com/drdisagree/iconify/utils/overlay/compiler/OnboardingCompiler.kt index f8649fd52..fdfa05c2c 100644 --- a/app/src/main/java/com/drdisagree/iconify/utils/overlay/compiler/OnboardingCompiler.kt +++ b/app/src/main/java/com/drdisagree/iconify/utils/overlay/compiler/OnboardingCompiler.kt @@ -26,7 +26,6 @@ object OnboardingCompiler { private var key: PrivateKey? = null private var cert: X509Certificate? = null - @JvmStatic fun createManifest(name: String?, target: String?, source: String): Boolean { var hasErroredOut = false var attempt = 3 @@ -46,7 +45,6 @@ object OnboardingCompiler { return !hasErroredOut } - @JvmStatic fun runAapt(source: String, name: String): Boolean { var result: Shell.Result? = null var attempt = 3 @@ -66,16 +64,25 @@ object OnboardingCompiler { while (attempt-- != 0) { result = Shell.cmd(command).exec() - if (!result.isSuccess && OverlayCompiler.listContains( - result.out, + if (!result.isSuccess) { + val keywords = listOf( "colorSurfaceHeader" ) - ) { - Shell.cmd( - "find $source/res -type f -name \"*.xml\" -exec sed -i '/colorSurfaceHeader/d' {} +" - ).exec() - result = Shell.cmd(command).exec() + + val foundKeywords = keywords.filter { keyword -> + result!!.out.any { it.contains(keyword, ignoreCase = true) } + } + + if (foundKeywords.isNotEmpty()) { + foundKeywords.forEach { keyword -> + Shell.cmd( + "find $source/res -type f -name \"*.xml\" -exec sed -i '/$keyword/d' {} +" + ).exec() + } + result = Shell.cmd(command).exec() + } } + if (result.isSuccess) { Log.i("$TAG - AAPT", "Successfully built APK for $name") break @@ -111,7 +118,6 @@ object OnboardingCompiler { return folderCommand + compileCommand + linkCommand } - @JvmStatic fun zipAlign(source: String, name: String): Boolean { var result: Shell.Result? = null var attempt = 3 @@ -154,7 +160,6 @@ object OnboardingCompiler { return !result.isSuccess } - @JvmStatic fun apkSigner(source: String?, name: String): Boolean { try { if (key == null) { diff --git a/app/src/main/java/com/drdisagree/iconify/utils/overlay/compiler/OverlayCompiler.kt b/app/src/main/java/com/drdisagree/iconify/utils/overlay/compiler/OverlayCompiler.kt index f5aeae6f9..bf6ada71f 100644 --- a/app/src/main/java/com/drdisagree/iconify/utils/overlay/compiler/OverlayCompiler.kt +++ b/app/src/main/java/com/drdisagree/iconify/utils/overlay/compiler/OverlayCompiler.kt @@ -8,14 +8,13 @@ import com.drdisagree.iconify.common.Dynamic.ZIPALIGN import com.drdisagree.iconify.common.Dynamic.isAtleastA14 import com.drdisagree.iconify.common.Resources import com.drdisagree.iconify.common.Resources.FRAMEWORK_DIR -import com.drdisagree.iconify.utils.AppUtil.getSplitLocations +import com.drdisagree.iconify.utils.AppUtils.getSplitLocations import com.drdisagree.iconify.utils.apksigner.CryptoUtils import com.drdisagree.iconify.utils.apksigner.SignAPK import com.drdisagree.iconify.utils.helper.Logger.writeLog import com.topjohnwu.superuser.Shell import java.security.PrivateKey import java.security.cert.X509Certificate -import java.util.Locale object OverlayCompiler { @@ -30,7 +29,7 @@ object OverlayCompiler { val module: MutableList = ArrayList() module.add( "printf '${ - CompilerUtil.createManifestContent( + CompilerUtils.createManifestContent( overlayName, targetPackage ) @@ -59,7 +58,7 @@ object OverlayCompiler { } fun runAapt(source: String, targetPackage: String?): Boolean { - val name = CompilerUtil.getOverlayName(source) + + val name = CompilerUtils.getOverlayName(source) + if (source.contains("SpecialOverlays")) { ".zip" } else { @@ -75,10 +74,23 @@ object OverlayCompiler { val command = aaptCommand.toString() var result = Shell.cmd(command).exec() - if (!result.isSuccess && listContains(result.out, "colorSurfaceHeader")) { - Shell.cmd("find $source/res -type f -name \"*.xml\" -exec sed -i '/colorSurfaceHeader/d' {} +") - .exec() - result = Shell.cmd(command).exec() + if (!result.isSuccess) { + val keywords = listOf( + "colorSurfaceHeader" + ) + + val foundKeywords = keywords.filter { keyword -> + result.out.any { it.contains(keyword, ignoreCase = true) } + } + + if (foundKeywords.isNotEmpty()) { + foundKeywords.forEach { keyword -> + Shell.cmd( + "find $source/res -type f -name \"*.xml\" -exec sed -i '/$keyword/d' {} +" + ).exec() + } + result = Shell.cmd(command).exec() + } } if (result.isSuccess) { @@ -120,7 +132,7 @@ object OverlayCompiler { } fun zipAlign(source: String): Boolean { - val fileName = CompilerUtil.getOverlayName(source) + val fileName = CompilerUtils.getOverlayName(source) val result = Shell.cmd( zipalign + " 4 " + source + ' ' + Resources.UNSIGNED_DIR + "/" + fileName + "-unsigned.apk" @@ -153,7 +165,7 @@ object OverlayCompiler { CryptoUtils.readCertificate(appContext.assets.open("Keystore/testkey.x509.pem")) } - fileName = CompilerUtil.getOverlayName(source) + fileName = CompilerUtils.getOverlayName(source) SignAPK.sign( cert, key, source, Resources.SIGNED_DIR + "/IconifyComponent" + fileName + ".apk" @@ -168,16 +180,4 @@ object OverlayCompiler { return false } - - fun listContains(list: List, target: String): Boolean { - for (item in list) { - if (item.lowercase(Locale.getDefault()) - .contains(target.lowercase(Locale.getDefault())) - ) { - return true - } - } - - return false - } } diff --git a/app/src/main/java/com/drdisagree/iconify/utils/overlay/compiler/RoundnessCompiler.kt b/app/src/main/java/com/drdisagree/iconify/utils/overlay/compiler/RoundnessCompiler.kt index b6eab4d47..9ff8772ac 100644 --- a/app/src/main/java/com/drdisagree/iconify/utils/overlay/compiler/RoundnessCompiler.kt +++ b/app/src/main/java/com/drdisagree/iconify/utils/overlay/compiler/RoundnessCompiler.kt @@ -4,14 +4,14 @@ import android.util.Log import com.drdisagree.iconify.common.Const.FRAMEWORK_PACKAGE import com.drdisagree.iconify.common.Const.SYSTEMUI_PACKAGE import com.drdisagree.iconify.common.Resources -import com.drdisagree.iconify.utils.FileUtil.copyAssets -import com.drdisagree.iconify.utils.RootUtil.setPermissions -import com.drdisagree.iconify.utils.SystemUtil.mountRO -import com.drdisagree.iconify.utils.SystemUtil.mountRW +import com.drdisagree.iconify.utils.FileUtils.copyAssets +import com.drdisagree.iconify.utils.RootUtils.setPermissions +import com.drdisagree.iconify.utils.SystemUtils.mountRO +import com.drdisagree.iconify.utils.SystemUtils.mountRW import com.drdisagree.iconify.utils.helper.BinaryInstaller.symLinkBinaries import com.drdisagree.iconify.utils.helper.Logger.writeLog -import com.drdisagree.iconify.utils.overlay.OverlayUtil.disableOverlays -import com.drdisagree.iconify.utils.overlay.OverlayUtil.enableOverlays +import com.drdisagree.iconify.utils.overlay.OverlayUtils.disableOverlays +import com.drdisagree.iconify.utils.overlay.OverlayUtils.enableOverlays import com.topjohnwu.superuser.Shell import java.io.IOException @@ -22,7 +22,6 @@ object RoundnessCompiler { private val mOverlayName = arrayOf("CR1", "CR2") private var mForce = false - @JvmStatic @Throws(IOException::class) fun buildOverlay(resources: Array, force: Boolean): Boolean { mForce = force diff --git a/app/src/main/java/com/drdisagree/iconify/utils/overlay/compiler/SettingsIconsCompiler.kt b/app/src/main/java/com/drdisagree/iconify/utils/overlay/compiler/SettingsIconsCompiler.kt index 75aa77eab..a4001a2db 100644 --- a/app/src/main/java/com/drdisagree/iconify/utils/overlay/compiler/SettingsIconsCompiler.kt +++ b/app/src/main/java/com/drdisagree/iconify/utils/overlay/compiler/SettingsIconsCompiler.kt @@ -5,14 +5,14 @@ import com.drdisagree.iconify.common.Const.GMS_PACKAGE import com.drdisagree.iconify.common.Const.SETTINGS_PACKAGE import com.drdisagree.iconify.common.Const.WELLBEING_PACKAGE import com.drdisagree.iconify.common.Resources -import com.drdisagree.iconify.utils.FileUtil.copyAssets -import com.drdisagree.iconify.utils.RootUtil.setPermissions -import com.drdisagree.iconify.utils.SystemUtil.mountRO -import com.drdisagree.iconify.utils.SystemUtil.mountRW +import com.drdisagree.iconify.utils.FileUtils.copyAssets +import com.drdisagree.iconify.utils.RootUtils.setPermissions +import com.drdisagree.iconify.utils.SystemUtils.mountRO +import com.drdisagree.iconify.utils.SystemUtils.mountRW import com.drdisagree.iconify.utils.helper.BinaryInstaller.symLinkBinaries import com.drdisagree.iconify.utils.helper.Logger.writeLog -import com.drdisagree.iconify.utils.overlay.OverlayUtil.disableOverlays -import com.drdisagree.iconify.utils.overlay.OverlayUtil.enableOverlays +import com.drdisagree.iconify.utils.overlay.OverlayUtils.disableOverlays +import com.drdisagree.iconify.utils.overlay.OverlayUtils.enableOverlays import com.topjohnwu.superuser.Shell import java.io.IOException @@ -23,7 +23,6 @@ object SettingsIconsCompiler { private var mIconBg = 1 private var mForce = false - @JvmStatic @Throws(IOException::class) fun buildOverlay(iconSet: Int, iconBg: Int, resources: String, force: Boolean): Boolean { mIconSet = iconSet diff --git a/app/src/main/java/com/drdisagree/iconify/utils/overlay/compiler/SwitchCompiler.kt b/app/src/main/java/com/drdisagree/iconify/utils/overlay/compiler/SwitchCompiler.kt index 104aed9d0..4c717b9b3 100644 --- a/app/src/main/java/com/drdisagree/iconify/utils/overlay/compiler/SwitchCompiler.kt +++ b/app/src/main/java/com/drdisagree/iconify/utils/overlay/compiler/SwitchCompiler.kt @@ -4,13 +4,13 @@ import android.util.Log import com.drdisagree.iconify.common.Const.SETTINGS_PACKAGE import com.drdisagree.iconify.common.Const.SYSTEMUI_PACKAGE import com.drdisagree.iconify.common.Resources -import com.drdisagree.iconify.utils.FileUtil.copyAssets -import com.drdisagree.iconify.utils.RootUtil.setPermissions -import com.drdisagree.iconify.utils.SystemUtil.mountRO -import com.drdisagree.iconify.utils.SystemUtil.mountRW +import com.drdisagree.iconify.utils.FileUtils.copyAssets +import com.drdisagree.iconify.utils.RootUtils.setPermissions +import com.drdisagree.iconify.utils.SystemUtils.mountRO +import com.drdisagree.iconify.utils.SystemUtils.mountRW import com.drdisagree.iconify.utils.helper.BinaryInstaller.symLinkBinaries -import com.drdisagree.iconify.utils.overlay.OverlayUtil.disableOverlays -import com.drdisagree.iconify.utils.overlay.OverlayUtil.enableOverlays +import com.drdisagree.iconify.utils.overlay.OverlayUtils.disableOverlays +import com.drdisagree.iconify.utils.overlay.OverlayUtils.enableOverlays import com.topjohnwu.superuser.Shell import java.io.IOException diff --git a/app/src/main/java/com/drdisagree/iconify/utils/overlay/compiler/VolumeCompiler.kt b/app/src/main/java/com/drdisagree/iconify/utils/overlay/compiler/VolumeCompiler.kt index 23d272d77..6248b117e 100644 --- a/app/src/main/java/com/drdisagree/iconify/utils/overlay/compiler/VolumeCompiler.kt +++ b/app/src/main/java/com/drdisagree/iconify/utils/overlay/compiler/VolumeCompiler.kt @@ -2,10 +2,10 @@ package com.drdisagree.iconify.utils.overlay.compiler import android.util.Log import com.drdisagree.iconify.common.Resources -import com.drdisagree.iconify.utils.FileUtil.copyAssets -import com.drdisagree.iconify.utils.ModuleUtil.createModule +import com.drdisagree.iconify.utils.FileUtils.copyAssets +import com.drdisagree.iconify.utils.ModuleUtils.createModule import com.drdisagree.iconify.utils.helper.BinaryInstaller.symLinkBinaries -import com.drdisagree.iconify.utils.overlay.OverlayUtil.enableOverlay +import com.drdisagree.iconify.utils.overlay.OverlayUtils.enableOverlay import com.topjohnwu.superuser.Shell import net.lingala.zip4j.ZipFile import java.io.File @@ -16,7 +16,6 @@ object VolumeCompiler { private val TAG = VolumeCompiler::class.java.simpleName private var mOverlayName: String? = null - @JvmStatic @Throws(Exception::class) fun buildModule(overlayName: String, targetPackage: String): Boolean { mOverlayName = overlayName diff --git a/app/src/main/java/com/drdisagree/iconify/utils/overlay/manager/BrightnessBarManager.kt b/app/src/main/java/com/drdisagree/iconify/utils/overlay/manager/BrightnessBarManager.kt index 580164bbe..46ef080f6 100644 --- a/app/src/main/java/com/drdisagree/iconify/utils/overlay/manager/BrightnessBarManager.kt +++ b/app/src/main/java/com/drdisagree/iconify/utils/overlay/manager/BrightnessBarManager.kt @@ -1,11 +1,11 @@ package com.drdisagree.iconify.utils.overlay.manager import com.drdisagree.iconify.common.Dynamic.TOTAL_BRIGHTNESSBARS -import com.drdisagree.iconify.config.Prefs.putBoolean -import com.drdisagree.iconify.utils.overlay.OverlayUtil.disableOverlay -import com.drdisagree.iconify.utils.overlay.OverlayUtil.enableOverlayExclusiveInCategory -import com.drdisagree.iconify.utils.overlay.OverlayUtil.enableOverlays -import com.drdisagree.iconify.utils.overlay.OverlayUtil.isOverlayEnabled +import com.drdisagree.iconify.config.RPrefs.putBoolean +import com.drdisagree.iconify.utils.overlay.OverlayUtils.disableOverlay +import com.drdisagree.iconify.utils.overlay.OverlayUtils.enableOverlayExclusiveInCategory +import com.drdisagree.iconify.utils.overlay.OverlayUtils.enableOverlays +import com.drdisagree.iconify.utils.overlay.OverlayUtils.isOverlayEnabled object BrightnessBarManager { diff --git a/app/src/main/java/com/drdisagree/iconify/utils/overlay/manager/BrightnessBarPixelManager.kt b/app/src/main/java/com/drdisagree/iconify/utils/overlay/manager/BrightnessBarPixelManager.kt index af537532a..f57a3b2aa 100644 --- a/app/src/main/java/com/drdisagree/iconify/utils/overlay/manager/BrightnessBarPixelManager.kt +++ b/app/src/main/java/com/drdisagree/iconify/utils/overlay/manager/BrightnessBarPixelManager.kt @@ -1,11 +1,11 @@ package com.drdisagree.iconify.utils.overlay.manager import com.drdisagree.iconify.common.Dynamic.TOTAL_BRIGHTNESSBARSPIXEL -import com.drdisagree.iconify.config.Prefs.putBoolean -import com.drdisagree.iconify.utils.overlay.OverlayUtil.disableOverlay -import com.drdisagree.iconify.utils.overlay.OverlayUtil.enableOverlayExclusiveInCategory -import com.drdisagree.iconify.utils.overlay.OverlayUtil.enableOverlays -import com.drdisagree.iconify.utils.overlay.OverlayUtil.isOverlayEnabled +import com.drdisagree.iconify.config.RPrefs.putBoolean +import com.drdisagree.iconify.utils.overlay.OverlayUtils.disableOverlay +import com.drdisagree.iconify.utils.overlay.OverlayUtils.enableOverlayExclusiveInCategory +import com.drdisagree.iconify.utils.overlay.OverlayUtils.enableOverlays +import com.drdisagree.iconify.utils.overlay.OverlayUtils.isOverlayEnabled object BrightnessBarPixelManager { fun enableOverlay(n: Int) { diff --git a/app/src/main/java/com/drdisagree/iconify/utils/overlay/manager/IconPackManager.kt b/app/src/main/java/com/drdisagree/iconify/utils/overlay/manager/IconPackManager.kt index 096622955..a81cb0a32 100644 --- a/app/src/main/java/com/drdisagree/iconify/utils/overlay/manager/IconPackManager.kt +++ b/app/src/main/java/com/drdisagree/iconify/utils/overlay/manager/IconPackManager.kt @@ -1,28 +1,36 @@ package com.drdisagree.iconify.utils.overlay.manager -import com.drdisagree.iconify.common.Dynamic.TOTAL_ICONPACKS -import com.drdisagree.iconify.config.Prefs.putBoolean -import com.drdisagree.iconify.utils.overlay.OverlayUtil.disableOverlays -import com.drdisagree.iconify.utils.overlay.OverlayUtil.enableOverlaysExclusiveInCategory +import com.drdisagree.iconify.config.RPrefs.putBoolean +import com.drdisagree.iconify.utils.overlay.OverlayUtils.disableOverlays +import com.drdisagree.iconify.utils.overlay.OverlayUtils.enableOverlaysExclusiveInCategory +import com.topjohnwu.superuser.Shell object IconPackManager { - fun enableOverlay(n: Int) { - disableOthers(n) + private fun getTotalIconPacks(category: String): Int { + return Shell.cmd("cmd overlay list | grep '....IconifyComponent$category'").exec().out.size + } + + fun enableOverlay(index: Int, vararg categories: String) { + disableOthers(index, *categories) enableOverlaysExclusiveInCategory( - "IconifyComponentIPAS$n.overlay", - "IconifyComponentIPSUI$n.overlay" + *categories.map { "IconifyComponent$it$index.overlay" }.toTypedArray() ) } - fun disableOverlay(n: Int) { - disableOverlays("IconifyComponentIPAS$n.overlay", "IconifyComponentIPSUI$n.overlay") + fun disableOverlay(index: Int, vararg categories: String) { + disableOverlays( + *categories.map { "IconifyComponent$it$index.overlay" }.toTypedArray() + ) } - private fun disableOthers(n: Int) { - for (i in 1..TOTAL_ICONPACKS) { - putBoolean("IconifyComponentIPAS$i.overlay", i == n) - putBoolean("IconifyComponentIPSUI$i.overlay", i == n) + private fun disableOthers(index: Int, vararg categories: String) { + val totalIconPacks = getTotalIconPacks(categories[0]) + + for (i in 1..totalIconPacks) { + categories.forEach { category -> + putBoolean("IconifyComponent$category$i.overlay", i == index) + } } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/drdisagree/iconify/utils/overlay/manager/MediaPlayerIconManager.kt b/app/src/main/java/com/drdisagree/iconify/utils/overlay/manager/MediaPlayerIconManager.kt index 8447865e1..c0f6fa245 100644 --- a/app/src/main/java/com/drdisagree/iconify/utils/overlay/manager/MediaPlayerIconManager.kt +++ b/app/src/main/java/com/drdisagree/iconify/utils/overlay/manager/MediaPlayerIconManager.kt @@ -1,12 +1,11 @@ package com.drdisagree.iconify.utils.overlay.manager -import com.drdisagree.iconify.config.Prefs.putBoolean -import com.drdisagree.iconify.utils.overlay.OverlayUtil.disableOverlay -import com.drdisagree.iconify.utils.overlay.OverlayUtil.enableOverlayExclusiveInCategory +import com.drdisagree.iconify.config.RPrefs.putBoolean +import com.drdisagree.iconify.utils.overlay.OverlayUtils.disableOverlay +import com.drdisagree.iconify.utils.overlay.OverlayUtils.enableOverlayExclusiveInCategory object MediaPlayerIconManager { - @JvmStatic fun enableOverlay(m: Int, n: Int) { disableOthers(m, n) enableOverlayExclusiveInCategory("IconifyComponentMPIP$m$n.overlay") diff --git a/app/src/main/java/com/drdisagree/iconify/utils/overlay/manager/MonetEngineManager.kt b/app/src/main/java/com/drdisagree/iconify/utils/overlay/manager/MonetEngineManager.kt index 7554bb860..60ebb1263 100644 --- a/app/src/main/java/com/drdisagree/iconify/utils/overlay/manager/MonetEngineManager.kt +++ b/app/src/main/java/com/drdisagree/iconify/utils/overlay/manager/MonetEngineManager.kt @@ -1,14 +1,13 @@ package com.drdisagree.iconify.utils.overlay.manager -import com.drdisagree.iconify.config.Prefs -import com.drdisagree.iconify.utils.color.ColorUtil.colorNames -import com.drdisagree.iconify.utils.color.ColorUtil.colorToHex +import com.drdisagree.iconify.config.RPrefs +import com.drdisagree.iconify.utils.color.ColorUtils.colorNames +import com.drdisagree.iconify.utils.color.ColorUtils.colorToHex import com.drdisagree.iconify.utils.overlay.compiler.MonetCompiler import java.io.IOException object MonetEngineManager { - @JvmStatic @Throws(IOException::class) fun buildOverlay(palette: List>>, force: Boolean): Boolean { val colors = colorNames @@ -19,8 +18,8 @@ object MonetEngineManager { for (i in colors.indices) { for (j in colors[i].indices) { - Prefs.putString(colors[i][j] + "_day", palette[0][i][j].toString()) - Prefs.putString(colors[i][j] + "_night", palette[1][i][j].toString()) + RPrefs.putString(colors[i][j] + "_day", palette[0][i][j].toString()) + RPrefs.putString(colors[i][j] + "_night", palette[1][i][j].toString()) resources .append(" ${colorToHex(palette[0][i][j] as Int)}\n") diff --git a/app/src/main/java/com/drdisagree/iconify/utils/overlay/manager/NotificationManager.kt b/app/src/main/java/com/drdisagree/iconify/utils/overlay/manager/NotificationManager.kt index c0a710f91..a1cc43dc2 100644 --- a/app/src/main/java/com/drdisagree/iconify/utils/overlay/manager/NotificationManager.kt +++ b/app/src/main/java/com/drdisagree/iconify/utils/overlay/manager/NotificationManager.kt @@ -1,15 +1,17 @@ package com.drdisagree.iconify.utils.overlay.manager import com.drdisagree.iconify.common.Dynamic.TOTAL_NOTIFICATIONS +import com.drdisagree.iconify.common.Dynamic.isAndroid14 import com.drdisagree.iconify.common.Dynamic.isAtleastA14 import com.drdisagree.iconify.common.Preferences.FIX_NOTIFICATION_COLOR -import com.drdisagree.iconify.config.Prefs +import com.drdisagree.iconify.common.Preferences.FIX_NOTIFICATION_FOOTER_BUTTON_COLOR import com.drdisagree.iconify.config.RPrefs -import com.drdisagree.iconify.utils.SystemUtil -import com.drdisagree.iconify.utils.overlay.OverlayUtil.disableOverlay -import com.drdisagree.iconify.utils.overlay.OverlayUtil.enableOverlayExclusiveInCategory -import com.drdisagree.iconify.utils.overlay.OverlayUtil.enableOverlays -import com.drdisagree.iconify.utils.overlay.OverlayUtil.isOverlayEnabled +import com.drdisagree.iconify.utils.SystemUtils +import com.drdisagree.iconify.utils.SystemUtils.isSecurityPatchBeforeJune2024 +import com.drdisagree.iconify.utils.overlay.OverlayUtils.disableOverlay +import com.drdisagree.iconify.utils.overlay.OverlayUtils.enableOverlayExclusiveInCategory +import com.drdisagree.iconify.utils.overlay.OverlayUtils.enableOverlays +import com.drdisagree.iconify.utils.overlay.OverlayUtils.isOverlayEnabled object NotificationManager { @@ -21,25 +23,55 @@ object NotificationManager { enableOverlays("IconifyComponentCR1.overlay", "IconifyComponentCR2.overlay") } - if (isAtleastA14 && !RPrefs.getBoolean(FIX_NOTIFICATION_COLOR, false)) { - RPrefs.putBoolean(FIX_NOTIFICATION_COLOR, true) - SystemUtil.restartSystemUI() + if (isAtleastA14) { + var requireReload = false + + if (!RPrefs.getBoolean(FIX_NOTIFICATION_COLOR, false) && + isAndroid14 && isSecurityPatchBeforeJune2024() + ) { + RPrefs.putBoolean(FIX_NOTIFICATION_COLOR, true) + requireReload = true + } + + if (!RPrefs.getBoolean(FIX_NOTIFICATION_FOOTER_BUTTON_COLOR, false)) { + RPrefs.putBoolean(FIX_NOTIFICATION_FOOTER_BUTTON_COLOR, true) + requireReload = true + } + + if (requireReload) { + SystemUtils.restartSystemUI() + } } } fun disableOverlay(n: Int) { disableOverlay("IconifyComponentNFN$n.overlay") - if (isAtleastA14 && RPrefs.getBoolean(FIX_NOTIFICATION_COLOR, false)) { - RPrefs.putBoolean(FIX_NOTIFICATION_COLOR, false) - SystemUtil.restartSystemUI() + if (isAtleastA14) { + var requireReload = false + + if (RPrefs.getBoolean(FIX_NOTIFICATION_COLOR, false) && + isAndroid14 && isSecurityPatchBeforeJune2024() + ) { + RPrefs.putBoolean(FIX_NOTIFICATION_COLOR, false) + requireReload = true + } + + if (RPrefs.getBoolean(FIX_NOTIFICATION_FOOTER_BUTTON_COLOR, false)) { + RPrefs.putBoolean(FIX_NOTIFICATION_FOOTER_BUTTON_COLOR, false) + requireReload = true + } + + if (requireReload) { + SystemUtils.restartSystemUI() + } } } private fun disableOthers(n: Int) { for (i in 1..TOTAL_NOTIFICATIONS) { - Prefs.putBoolean("IconifyComponentNFN$i.overlay", i == n) - Prefs.putBoolean("IconifyComponentNFP$i.overlay", false) + RPrefs.putBoolean("IconifyComponentNFN$i.overlay", i == n) + RPrefs.putBoolean("IconifyComponentNFP$i.overlay", false) } } } \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/utils/overlay/manager/NotificationPixelManager.kt b/app/src/main/java/com/drdisagree/iconify/utils/overlay/manager/NotificationPixelManager.kt index 7e1c07933..65c110477 100644 --- a/app/src/main/java/com/drdisagree/iconify/utils/overlay/manager/NotificationPixelManager.kt +++ b/app/src/main/java/com/drdisagree/iconify/utils/overlay/manager/NotificationPixelManager.kt @@ -1,15 +1,17 @@ package com.drdisagree.iconify.utils.overlay.manager import com.drdisagree.iconify.common.Dynamic.TOTAL_NOTIFICATIONSPIXEL +import com.drdisagree.iconify.common.Dynamic.isAndroid14 import com.drdisagree.iconify.common.Dynamic.isAtleastA14 import com.drdisagree.iconify.common.Preferences.FIX_NOTIFICATION_COLOR -import com.drdisagree.iconify.config.Prefs +import com.drdisagree.iconify.common.Preferences.FIX_NOTIFICATION_FOOTER_BUTTON_COLOR import com.drdisagree.iconify.config.RPrefs -import com.drdisagree.iconify.utils.SystemUtil -import com.drdisagree.iconify.utils.overlay.OverlayUtil.disableOverlay -import com.drdisagree.iconify.utils.overlay.OverlayUtil.enableOverlayExclusiveInCategory -import com.drdisagree.iconify.utils.overlay.OverlayUtil.enableOverlays -import com.drdisagree.iconify.utils.overlay.OverlayUtil.isOverlayEnabled +import com.drdisagree.iconify.utils.SystemUtils +import com.drdisagree.iconify.utils.SystemUtils.isSecurityPatchBeforeJune2024 +import com.drdisagree.iconify.utils.overlay.OverlayUtils.disableOverlay +import com.drdisagree.iconify.utils.overlay.OverlayUtils.enableOverlayExclusiveInCategory +import com.drdisagree.iconify.utils.overlay.OverlayUtils.enableOverlays +import com.drdisagree.iconify.utils.overlay.OverlayUtils.isOverlayEnabled object NotificationPixelManager { @@ -21,25 +23,55 @@ object NotificationPixelManager { enableOverlays("IconifyComponentCR1.overlay", "IconifyComponentCR2.overlay") } - if (isAtleastA14 && !RPrefs.getBoolean(FIX_NOTIFICATION_COLOR, false)) { - RPrefs.putBoolean(FIX_NOTIFICATION_COLOR, true) - SystemUtil.restartSystemUI() + if (isAtleastA14) { + var requireReload = false + + if (!RPrefs.getBoolean(FIX_NOTIFICATION_COLOR, false) && + isAndroid14 && isSecurityPatchBeforeJune2024() + ) { + RPrefs.putBoolean(FIX_NOTIFICATION_COLOR, true) + requireReload = true + } + + if (!RPrefs.getBoolean(FIX_NOTIFICATION_FOOTER_BUTTON_COLOR, false)) { + RPrefs.putBoolean(FIX_NOTIFICATION_FOOTER_BUTTON_COLOR, true) + requireReload = true + } + + if (requireReload) { + SystemUtils.restartSystemUI() + } } } fun disableOverlay(n: Int) { disableOverlay("IconifyComponentNFP$n.overlay") - if (isAtleastA14 && RPrefs.getBoolean(FIX_NOTIFICATION_COLOR, false)) { - RPrefs.putBoolean(FIX_NOTIFICATION_COLOR, false) - SystemUtil.restartSystemUI() + if (isAtleastA14) { + var requireReload = false + + if (RPrefs.getBoolean(FIX_NOTIFICATION_COLOR, false) && + isAndroid14 && isSecurityPatchBeforeJune2024() + ) { + RPrefs.putBoolean(FIX_NOTIFICATION_COLOR, false) + requireReload = true + } + + if (RPrefs.getBoolean(FIX_NOTIFICATION_FOOTER_BUTTON_COLOR, false)) { + RPrefs.putBoolean(FIX_NOTIFICATION_FOOTER_BUTTON_COLOR, false) + requireReload = true + } + + if (requireReload) { + SystemUtils.restartSystemUI() + } } } private fun disableOthers(n: Int) { for (i in 1..TOTAL_NOTIFICATIONSPIXEL) { - Prefs.putBoolean("IconifyComponentNFP$i.overlay", i == n) - Prefs.putBoolean("IconifyComponentNFN$i.overlay", false) + RPrefs.putBoolean("IconifyComponentNFP$i.overlay", i == n) + RPrefs.putBoolean("IconifyComponentNFN$i.overlay", false) } } } \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/utils/overlay/manager/QsShapeManager.kt b/app/src/main/java/com/drdisagree/iconify/utils/overlay/manager/QsShapeManager.kt index 97b44c523..cb6e5def4 100644 --- a/app/src/main/java/com/drdisagree/iconify/utils/overlay/manager/QsShapeManager.kt +++ b/app/src/main/java/com/drdisagree/iconify/utils/overlay/manager/QsShapeManager.kt @@ -3,14 +3,13 @@ package com.drdisagree.iconify.utils.overlay.manager import com.drdisagree.iconify.common.Dynamic.TOTAL_QSSHAPES import com.drdisagree.iconify.common.Dynamic.isAtleastA14 import com.drdisagree.iconify.common.Preferences.FIX_QS_TILE_COLOR -import com.drdisagree.iconify.config.Prefs import com.drdisagree.iconify.config.RPrefs -import com.drdisagree.iconify.utils.SystemUtil -import com.drdisagree.iconify.utils.overlay.OverlayUtil.changeOverlayState -import com.drdisagree.iconify.utils.overlay.OverlayUtil.disableOverlay -import com.drdisagree.iconify.utils.overlay.OverlayUtil.enableOverlayExclusiveInCategory -import com.drdisagree.iconify.utils.overlay.OverlayUtil.enableOverlays -import com.drdisagree.iconify.utils.overlay.OverlayUtil.isOverlayEnabled +import com.drdisagree.iconify.utils.SystemUtils +import com.drdisagree.iconify.utils.overlay.OverlayUtils.changeOverlayState +import com.drdisagree.iconify.utils.overlay.OverlayUtils.disableOverlay +import com.drdisagree.iconify.utils.overlay.OverlayUtils.enableOverlayExclusiveInCategory +import com.drdisagree.iconify.utils.overlay.OverlayUtils.enableOverlays +import com.drdisagree.iconify.utils.overlay.OverlayUtils.isOverlayEnabled object QsShapeManager { @@ -43,7 +42,7 @@ object QsShapeManager { if (isAtleastA14 && !RPrefs.getBoolean(FIX_QS_TILE_COLOR, false)) { RPrefs.putBoolean(FIX_QS_TILE_COLOR, true) - SystemUtil.restartSystemUI() + SystemUtils.restartSystemUI() } } @@ -52,14 +51,14 @@ object QsShapeManager { if (isAtleastA14 && RPrefs.getBoolean(FIX_QS_TILE_COLOR, false)) { RPrefs.putBoolean(FIX_QS_TILE_COLOR, false) - SystemUtil.restartSystemUI() + SystemUtils.restartSystemUI() } } private fun disableOthers(n: Int) { for (i in 1..TOTAL_QSSHAPES) { - Prefs.putBoolean("IconifyComponentQSSN$i.overlay", i == n) - Prefs.putBoolean("IconifyComponentQSSP$i.overlay", false) + RPrefs.putBoolean("IconifyComponentQSSN$i.overlay", i == n) + RPrefs.putBoolean("IconifyComponentQSSP$i.overlay", false) } } } \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/utils/overlay/manager/QsShapePixelManager.kt b/app/src/main/java/com/drdisagree/iconify/utils/overlay/manager/QsShapePixelManager.kt index 1c21305dd..046b9d8ae 100644 --- a/app/src/main/java/com/drdisagree/iconify/utils/overlay/manager/QsShapePixelManager.kt +++ b/app/src/main/java/com/drdisagree/iconify/utils/overlay/manager/QsShapePixelManager.kt @@ -3,14 +3,13 @@ package com.drdisagree.iconify.utils.overlay.manager import com.drdisagree.iconify.common.Dynamic.TOTAL_QSSHAPESPIXEL import com.drdisagree.iconify.common.Dynamic.isAtleastA14 import com.drdisagree.iconify.common.Preferences.FIX_QS_TILE_COLOR -import com.drdisagree.iconify.config.Prefs import com.drdisagree.iconify.config.RPrefs -import com.drdisagree.iconify.utils.SystemUtil -import com.drdisagree.iconify.utils.overlay.OverlayUtil.changeOverlayState -import com.drdisagree.iconify.utils.overlay.OverlayUtil.disableOverlay -import com.drdisagree.iconify.utils.overlay.OverlayUtil.enableOverlayExclusiveInCategory -import com.drdisagree.iconify.utils.overlay.OverlayUtil.enableOverlays -import com.drdisagree.iconify.utils.overlay.OverlayUtil.isOverlayEnabled +import com.drdisagree.iconify.utils.SystemUtils +import com.drdisagree.iconify.utils.overlay.OverlayUtils.changeOverlayState +import com.drdisagree.iconify.utils.overlay.OverlayUtils.disableOverlay +import com.drdisagree.iconify.utils.overlay.OverlayUtils.enableOverlayExclusiveInCategory +import com.drdisagree.iconify.utils.overlay.OverlayUtils.enableOverlays +import com.drdisagree.iconify.utils.overlay.OverlayUtils.isOverlayEnabled object QsShapePixelManager { fun enableOverlay(n: Int) { @@ -42,7 +41,7 @@ object QsShapePixelManager { if (isAtleastA14 && !RPrefs.getBoolean(FIX_QS_TILE_COLOR, false)) { RPrefs.putBoolean(FIX_QS_TILE_COLOR, true) - SystemUtil.restartSystemUI() + SystemUtils.restartSystemUI() } } @@ -51,14 +50,14 @@ object QsShapePixelManager { if (isAtleastA14 && RPrefs.getBoolean(FIX_QS_TILE_COLOR, false)) { RPrefs.putBoolean(FIX_QS_TILE_COLOR, false) - SystemUtil.restartSystemUI() + SystemUtils.restartSystemUI() } } private fun disableOthers(n: Int) { for (i in 1..TOTAL_QSSHAPESPIXEL) { - Prefs.putBoolean("IconifyComponentQSSP$i.overlay", i == n) - Prefs.putBoolean("IconifyComponentQSSN$i.overlay", false) + RPrefs.putBoolean("IconifyComponentQSSP$i.overlay", i == n) + RPrefs.putBoolean("IconifyComponentQSSN$i.overlay", false) } } } \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/utils/overlay/manager/RoundnessManager.kt b/app/src/main/java/com/drdisagree/iconify/utils/overlay/manager/RoundnessManager.kt index 9f4a48f93..2254fa44f 100644 --- a/app/src/main/java/com/drdisagree/iconify/utils/overlay/manager/RoundnessManager.kt +++ b/app/src/main/java/com/drdisagree/iconify/utils/overlay/manager/RoundnessManager.kt @@ -6,7 +6,6 @@ import kotlin.math.max object RoundnessManager { - @JvmStatic @Throws(IOException::class) fun buildOverlay(cornerRadius: Int, force: Boolean): Boolean { val frameworkResources = """ diff --git a/app/src/main/java/com/drdisagree/iconify/utils/overlay/manager/SettingsIconResourceManager.kt b/app/src/main/java/com/drdisagree/iconify/utils/overlay/manager/SettingsIconResourceManager.kt index eaa4a4224..452b4e70f 100644 --- a/app/src/main/java/com/drdisagree/iconify/utils/overlay/manager/SettingsIconResourceManager.kt +++ b/app/src/main/java/com/drdisagree/iconify/utils/overlay/manager/SettingsIconResourceManager.kt @@ -5,7 +5,6 @@ import java.io.IOException object SettingsIconResourceManager { - @JvmStatic @Throws(IOException::class) fun buildOverlay( iconSet: Int, diff --git a/app/src/main/java/com/drdisagree/iconify/utils/overlay/manager/SignalIconManager.kt b/app/src/main/java/com/drdisagree/iconify/utils/overlay/manager/SignalIconManager.kt new file mode 100644 index 000000000..451276750 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/utils/overlay/manager/SignalIconManager.kt @@ -0,0 +1,52 @@ +package com.drdisagree.iconify.utils.overlay.manager + +import com.drdisagree.iconify.config.RPrefs.putBoolean +import com.drdisagree.iconify.utils.overlay.OverlayUtils +import com.drdisagree.iconify.utils.overlay.OverlayUtils.checkEnabledOverlay +import com.drdisagree.iconify.utils.overlay.OverlayUtils.disableOverlays +import com.drdisagree.iconify.utils.overlay.OverlayUtils.enableOverlaysExclusiveInCategory +import com.topjohnwu.superuser.Shell + +object SignalIconManager { + private fun getTotalIconPacks(category: String): Int { + return Shell.cmd("cmd overlay list | grep '....IconifyComponent$category'").exec().out.size + } + + fun enableOverlay(n: Int, category: String) { + disableOthers(n, category) + + val iconPackPkgName = checkEnabledOverlay("IPAS") + if (iconPackPkgName.isNotEmpty()) { + OverlayUtils.disableOverlay(iconPackPkgName) + } + + enableOverlaysExclusiveInCategory("IconifyComponent$category$n.overlay") + + val otherSignalPack = checkEnabledOverlay(if (category == "WIFI") "SGIC" else "WIFI") + if (otherSignalPack.isNotEmpty()) { + enableOverlaysExclusiveInCategory(otherSignalPack) + } + + if (iconPackPkgName.isNotEmpty()) { + OverlayUtils.enableOverlay(iconPackPkgName, "high") + } + + enableOverlaysExclusiveInCategory("IconifyComponent$category$n.overlay") + + if (otherSignalPack.isNotEmpty()) { + enableOverlaysExclusiveInCategory(otherSignalPack) + } + } + + fun disableOverlay(n: Int, category: String) { + disableOverlays("IconifyComponent$category$n.overlay") + } + + private fun disableOthers(n: Int, category: String) { + val totalIconPacks = getTotalIconPacks(category) + + for (i in 1..totalIconPacks) { + putBoolean("IconifyComponent$category$i.overlay", i == n) + } + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/utils/overlay/manager/resource/ResourceManager.kt b/app/src/main/java/com/drdisagree/iconify/utils/overlay/manager/resource/ResourceManager.kt index 0852ec7c8..df4a4061f 100644 --- a/app/src/main/java/com/drdisagree/iconify/utils/overlay/manager/resource/ResourceManager.kt +++ b/app/src/main/java/com/drdisagree/iconify/utils/overlay/manager/resource/ResourceManager.kt @@ -11,10 +11,10 @@ import com.drdisagree.iconify.common.Const import com.drdisagree.iconify.common.Preferences.DYNAMIC_OVERLAY_RESOURCES import com.drdisagree.iconify.common.Preferences.DYNAMIC_OVERLAY_RESOURCES_LAND import com.drdisagree.iconify.common.Preferences.DYNAMIC_OVERLAY_RESOURCES_NIGHT -import com.drdisagree.iconify.config.Prefs.getString -import com.drdisagree.iconify.config.Prefs.putString -import com.drdisagree.iconify.utils.SystemUtil.hasStoragePermission -import com.drdisagree.iconify.utils.SystemUtil.requestStoragePermission +import com.drdisagree.iconify.config.RPrefs.getString +import com.drdisagree.iconify.config.RPrefs.putString +import com.drdisagree.iconify.utils.SystemUtils.hasStoragePermission +import com.drdisagree.iconify.utils.SystemUtils.requestStoragePermission import com.drdisagree.iconify.utils.extension.TaskExecutor import com.drdisagree.iconify.utils.overlay.compiler.DynamicCompiler.buildOverlay import org.json.JSONObject @@ -28,7 +28,6 @@ object ResourceManager { private val TAG = ResourceManager::class.java.getSimpleName() - @JvmStatic fun buildOverlayWithResource(vararg resourceEntries: ResourceEntry?): Boolean { val hasErroredOut = AtomicBoolean(false) @@ -42,7 +41,6 @@ object ResourceManager { return hasErroredOut.get() } - @JvmStatic fun buildOverlayWithResource(context: Context?, vararg resourceEntries: ResourceEntry?) { if (!hasStoragePermission()) { requestStoragePermission(context!!) @@ -55,7 +53,6 @@ object ResourceManager { } } - @JvmStatic fun removeResourceFromOverlay(vararg resourceEntries: ResourceEntry?): Boolean { val hasErroredOut = AtomicBoolean(false) @@ -69,7 +66,6 @@ object ResourceManager { return hasErroredOut.get() } - @JvmStatic fun removeResourceFromOverlay(context: Context?, vararg resourceEntries: ResourceEntry?) { if (!hasStoragePermission()) { requestStoragePermission(context!!) diff --git a/app/src/main/java/com/drdisagree/iconify/utils/weather/AbstractWeatherProvider.kt b/app/src/main/java/com/drdisagree/iconify/utils/weather/AbstractWeatherProvider.kt new file mode 100644 index 000000000..feab04ad1 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/utils/weather/AbstractWeatherProvider.kt @@ -0,0 +1,168 @@ +package com.drdisagree.iconify.utils.weather + +import android.content.Context +import android.location.Geocoder +import android.location.Location +import android.text.TextUtils +import android.util.Log +import com.drdisagree.iconify.R +import com.drdisagree.iconify.utils.NetworkUtils +import com.drdisagree.iconify.utils.weather.WeatherConfig.getLocationName +import com.drdisagree.iconify.utils.weather.WeatherConfig.isCustomLocation +import org.json.JSONObject +import java.io.IOException +import java.text.SimpleDateFormat +import java.util.Calendar +import java.util.Locale +import java.util.concurrent.CountDownLatch + +abstract class AbstractWeatherProvider(protected var mContext: Context) { + protected fun retrieve(url: String?): String { + response = "" + val latch = CountDownLatch(1) + + NetworkUtils.downloadUrlMemoryAsString(url) { result: String? -> + if (result != null) { + response = result + } else { + response = "" + Log.d(TAG, "Download failed") + } + latch.countDown() + } + + try { + latch.await() // Wait until the response is set + } catch (e: InterruptedException) { + Thread.currentThread().interrupt() // Restore interrupt status + Log.e(TAG, "retrieve interrupted", e) + } + + return response + } + + abstract fun getCustomWeather(lat: String?, lon: String?, metric: Boolean): WeatherInfo? + + abstract fun getLocationWeather(location: Location?, metric: Boolean): WeatherInfo? + + abstract fun shouldRetry(): Boolean + + protected fun log(tag: String, msg: String?) { + if (DEBUG) Log.d( + "WeatherService:$tag", + msg!! + ) + } + + private fun getCoordinatesLocalityWithGoogle(coordinate: String): String? { + val latitude = + coordinate.substring(coordinate.indexOf("=") + 1, coordinate.indexOf("&")).toDouble() + val longitude = coordinate.substring(coordinate.lastIndexOf("=") + 1).toDouble() + + val geocoder = Geocoder(mContext.applicationContext, Locale.getDefault()) + try { + val listAddresses = geocoder.getFromLocation(latitude, longitude, 1) + if (!listAddresses.isNullOrEmpty()) { + val a = listAddresses[0] + return if (TextUtils.isEmpty(a.locality)) a.adminArea else a.locality + } + } catch (e: IOException) { + e.printStackTrace() + } + return null + } + + protected fun getCoordinatesLocality(coordinate: String): String? { + val cityGoogle = getCoordinatesLocalityWithGoogle(coordinate) + if (!TextUtils.isEmpty(cityGoogle)) { + return cityGoogle + } + val latitude = + coordinate.substring(coordinate.indexOf("=") + 1, coordinate.indexOf("&")).toDouble() + val longitude = coordinate.substring(coordinate.lastIndexOf("=") + 1).toDouble() + + val lang = Locale.getDefault().language.replaceFirst("_".toRegex(), "-") + val url = String.format(URL_LOCALITY, latitude, longitude, lang) + val response = retrieve(url) ?: return null + log(TAG, "URL = $url returning a response of $response") + + try { + val jsonResults = JSONObject(response) + if (jsonResults.has("address")) { + val address = jsonResults.getJSONObject("address") + val city = address.getString("placename") + val area = address.getString("adminName2") + if (!TextUtils.isEmpty(city)) { + return city + } + if (!TextUtils.isEmpty(area)) { + return area + } + } else if (jsonResults.has("geonames")) { + val jsonResultsArray = jsonResults.getJSONArray("geonames") + val count = jsonResultsArray.length() + + for (i in count - 1 downTo 0) { + val geoname = jsonResultsArray.getJSONObject(i) + val fcode = geoname.getString("fcode") + val name = geoname.getString("name") + if (TextUtils.isEmpty(name)) { + continue + } + if (fcode == "ADM3") { + return name + } + if (fcode == "ADM2") { + return name + } + if (fcode == "ADM1") { + return name + } + } + } + } catch (e: Exception) { + Log.w( + TAG, + "Received malformed location data (coordinate=$coordinate)", e + ) + } + return null + } + + protected fun getWeatherDataLocality(coordinates: String): String? { + var city: String? + if (isCustomLocation(mContext)) { + city = getLocationName(mContext) + if (TextUtils.isEmpty(city)) { + city = getCoordinatesLocality(coordinates) + } + } else { + city = getCoordinatesLocality(coordinates) + } + if (TextUtils.isEmpty(city)) { + city = mContext.resources.getString(R.string.omnijaws_city_unkown) + } + log(TAG, "getWeatherDataLocality = $city") + return city + } + + protected fun getDay(i: Int): String { + val calendar = Calendar.getInstance() + if (i > 0) { + calendar.add(Calendar.DATE, i) + } + return dayFormat.format(calendar.time) + } + + companion object { + private const val TAG = "AbstractWeatherProvider" + private const val DEBUG = false + private val dayFormat = SimpleDateFormat("yyyy-MM-dd", Locale.US) + private const val URL_PLACES = + "https://secure.geonames.org/searchJSON?name_startsWith=%s&lang=%s&username=omnijaws&maxRows=20" + private const val URL_LOCALITY = + "https://secure.geonames.org/extendedFindNearbyJSON?lat=%f&lng=%f&lang=%s&username=omnijaws" + const val PART_COORDINATES: String = "lat=%f&lon=%f" + private var response = "" + } +} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/utils/weather/WeatherConfig.kt b/app/src/main/java/com/drdisagree/iconify/utils/weather/WeatherConfig.kt new file mode 100644 index 000000000..6b98a0d68 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/utils/weather/WeatherConfig.kt @@ -0,0 +1,171 @@ +package com.drdisagree.iconify.utils.weather + +import android.Manifest +import android.content.Context +import android.content.Context.MODE_PRIVATE +import android.content.SharedPreferences +import android.content.pm.PackageManager +import com.drdisagree.iconify.BuildConfig +import com.drdisagree.iconify.common.Preferences.LOCKSCREEN_WIDGETS +import com.drdisagree.iconify.common.Preferences.LOCKSCREEN_WIDGETS_EXTRAS +import com.drdisagree.iconify.common.Preferences.WEATHER_CUSTOM_LOCATION +import com.drdisagree.iconify.common.Preferences.WEATHER_ICON_PACK +import com.drdisagree.iconify.common.Preferences.WEATHER_OWM_KEY +import com.drdisagree.iconify.common.Preferences.WEATHER_PROVIDER +import com.drdisagree.iconify.common.Preferences.WEATHER_SWITCH +import com.drdisagree.iconify.common.Preferences.WEATHER_UNITS +import com.drdisagree.iconify.common.Preferences.WEATHER_UPDATE_INTERVAL +import com.drdisagree.iconify.common.Resources.SHARED_XPREFERENCES +import com.drdisagree.iconify.xposed.utils.XPrefs.Xprefs +import com.drdisagree.iconify.utils.weather.providers.OpenMeteoProvider +import com.drdisagree.iconify.utils.weather.providers.OpenWeatherMapProvider + +object WeatherConfig { + + private const val PREF_KEY_LOCATION_LAT: String = "location_lat" + private const val PREF_KEY_LOCATION_LON: String = "location_lon" + private const val PREF_KEY_LOCATION_NAME: String = "location_name" + private const val PREF_KEY_WEATHER_DATA: String = "weather_data" + private const val PREF_KEY_LAST_UPDATE: String = "last_update" + private const val PREF_KEY_UPDATE_ERROR: String = "update_error" + private const val WEATHER_PREFS: String = BuildConfig.APPLICATION_ID + "_weatherprefs" + + private fun getPrefs(context: Context): SharedPreferences { + try { + if (Xprefs != null) return Xprefs as SharedPreferences + return context.createDeviceProtectedStorageContext().getSharedPreferences( + SHARED_XPREFERENCES, MODE_PRIVATE + ) + } catch (t: Throwable) { + return context.createDeviceProtectedStorageContext().getSharedPreferences( + SHARED_XPREFERENCES, MODE_PRIVATE + ) + } + } + + private fun getWeatherPrefs(context: Context): SharedPreferences { + val deviceProtectedContext = context.createDeviceProtectedStorageContext() + return deviceProtectedContext.getSharedPreferences(WEATHER_PREFS, MODE_PRIVATE) + } + + fun clear(context: Context) { + getWeatherPrefs(context).edit().clear().apply() + val prefs = listOf( + WEATHER_PROVIDER, + WEATHER_UNITS, + WEATHER_UPDATE_INTERVAL, + WEATHER_OWM_KEY, + PREF_KEY_UPDATE_ERROR + ) + prefs.forEach { + getPrefs(context).edit().remove(it).apply() + } + } + + fun getProvider(context: Context): AbstractWeatherProvider { + val provider = getPrefs(context).getString(WEATHER_PROVIDER, "0") + return when (provider) { + "1" -> return OpenWeatherMapProvider(context) + else -> return OpenMeteoProvider(context) + } + } + + fun getProviderId(context: Context): String { + val provider = getPrefs(context).getString(WEATHER_PROVIDER, "0") + return when (provider) { + "1" -> "OpenWeatherMap" + else -> "OpenMeteo" + } + } + + fun isMetric(context: Context): Boolean { + return getPrefs(context).getString(WEATHER_UNITS, "0") == "0" + } + + fun isCustomLocation(context: Context): Boolean { + return getPrefs(context).getBoolean(WEATHER_CUSTOM_LOCATION, false) + } + + fun getLocationLat(context: Context): String? { + return getWeatherPrefs(context).getString(PREF_KEY_LOCATION_LAT, null) + } + + fun getLocationLon(context: Context): String? { + return getWeatherPrefs(context).getString(PREF_KEY_LOCATION_LON, null) + } + + fun setLocationId(context: Context, lat: String?, lon: String?) { + getWeatherPrefs(context).edit().putString(PREF_KEY_LOCATION_LAT, lat).apply() + getWeatherPrefs(context).edit().putString(PREF_KEY_LOCATION_LON, lon).apply() + } + + fun getLocationName(context: Context): String? { + return getWeatherPrefs(context).getString(PREF_KEY_LOCATION_NAME, null) + } + + fun setLocationName(context: Context, name: String?) { + getWeatherPrefs(context).edit().putString(PREF_KEY_LOCATION_NAME, name).apply() + } + + fun getWeatherData(context: Context): WeatherInfo? { + var str: String? = null + try { + str = getWeatherPrefs(context).getString(PREF_KEY_WEATHER_DATA, null) + } catch (ignored: Throwable) { + } + + if (str != null) { + return WeatherInfo.fromSerializedString(context, str) + } + return null + } + + fun setWeatherData(data: WeatherInfo, context: Context) { + getWeatherPrefs(context).edit().putString(PREF_KEY_WEATHER_DATA, data.toSerializedString()) + .apply() + getWeatherPrefs(context).edit().putLong(PREF_KEY_LAST_UPDATE, System.currentTimeMillis()) + .apply() + } + + fun clearLastUpdateTime(context: Context) { + getWeatherPrefs(context).edit().putLong(PREF_KEY_LAST_UPDATE, 0).apply() + } + + fun isEnabled(context: Context): Boolean { + val lsWeather = getPrefs(context).getBoolean(WEATHER_SWITCH, false) + val bigWidgets = getPrefs(context).getString(LOCKSCREEN_WIDGETS, "") + val miniWidgets = getPrefs(context).getString(LOCKSCREEN_WIDGETS_EXTRAS, "") + return lsWeather || bigWidgets!!.contains("weather") || miniWidgets!!.contains("weather") + } + + fun setEnabled(context: Context, value: Boolean, key: String?) { + getPrefs(context).edit().putBoolean(key, value).apply() + } + + fun getUpdateInterval(context: Context): Int { + var updateValue = 2 + try { + updateValue = getPrefs(context).getString(WEATHER_UPDATE_INTERVAL, "2")!!.toInt() + } catch (ignored: Throwable) { + } + + return updateValue + } + + fun getIconPack(context: Context): String? { + return getPrefs(context).getString(WEATHER_ICON_PACK, null) + } + + fun setUpdateError(context: Context, value: Boolean) { + getWeatherPrefs(context).edit().putBoolean(PREF_KEY_UPDATE_ERROR, value).apply() + } + + fun isSetupDone(context: Context): Boolean { + return (context.checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) + == PackageManager.PERMISSION_GRANTED) + } + + fun getOwmKey(context: Context): String { + return getPrefs(context).getString(WEATHER_OWM_KEY, "") ?: "" + } +} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/utils/weather/WeatherContentProvider.kt b/app/src/main/java/com/drdisagree/iconify/utils/weather/WeatherContentProvider.kt new file mode 100644 index 000000000..465f636c5 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/utils/weather/WeatherContentProvider.kt @@ -0,0 +1,212 @@ +package com.drdisagree.iconify.utils.weather + +import android.annotation.SuppressLint +import android.content.ContentProvider +import android.content.ContentValues +import android.content.Context +import android.content.UriMatcher +import android.database.Cursor +import android.database.MatrixCursor +import android.net.Uri +import com.drdisagree.iconify.services.WeatherScheduler.scheduleUpdateNow + +class WeatherContentProvider : ContentProvider() { + private var mContext: Context? = null + + override fun onCreate(): Boolean { + mContext = context + sCachedWeatherInfo = mContext?.let { WeatherConfig.getWeatherData(it) } + return true + } + + override fun query( + uri: Uri, + projection: Array?, + selection: String?, + selectionArgs: Array?, + sortOrder: String? + ): Cursor? { + val projectionType = sUriMatcher.match(uri) + val result = MatrixCursor(resolveProjection(projection, projectionType)) + + if (projectionType == URI_TYPE_SETTINGS) { + result.newRow() + .add(COLUMN_ENABLED, if (WeatherConfig.isEnabled(mContext!!)) 1 else 0) + .add(COLUMN_PROVIDER, WeatherConfig.getProviderId(mContext!!)) + .add(COLUMN_INTERVAL, WeatherConfig.getUpdateInterval(mContext!!)) + .add(COLUMN_UNITS, if (WeatherConfig.isMetric(mContext!!)) 0 else 1) + .add( + COLUMN_LOCATION, + if (WeatherConfig.isCustomLocation(mContext!!)) WeatherConfig.getLocationName( + mContext!! + ) else "" + ) + .add( + COLUMN_SETUP, + if (!WeatherConfig.isSetupDone(mContext!!) && sCachedWeatherInfo == null) 0 else 1 + ) + .add( + COLUMN_ICON_PACK, + if (WeatherConfig.getIconPack(mContext!!) != null) WeatherConfig.getIconPack( + mContext!! + ) else "" + ) + + return result + } else if (projectionType == URI_TYPE_WEATHER) { + val weather = sCachedWeatherInfo + if (weather != null) { + // current + result.newRow() + .add(COLUMN_CURRENT_CITY, weather.city) + .add(COLUMN_CURRENT_CITY_ID, weather.id) + .add(COLUMN_CURRENT_CONDITION, weather.getCondition()) + .add(COLUMN_CURRENT_HUMIDITY, weather.formattedHumidity) + .add(COLUMN_CURRENT_WIND_SPEED, weather.windSpeed) + .add(COLUMN_CURRENT_WIND_DIRECTION, weather.windDirection) + .add(COLUMN_CURRENT_TEMPERATURE, weather.temperature) + .add(COLUMN_CURRENT_TIME_STAMP, weather.timestamp.toString()) + .add(COLUMN_CURRENT_PIN_WHEEL, weather.pinWheel) + .add(COLUMN_CURRENT_CONDITION_CODE, weather.conditionCode) + + // forecast + for (day in weather.forecasts) { + result.newRow() + .add(COLUMN_FORECAST_CONDITION, day.getCondition(mContext!!)) + .add(COLUMN_FORECAST_LOW, day.low) + .add(COLUMN_FORECAST_HIGH, day.high) + .add(COLUMN_FORECAST_CONDITION_CODE, day.conditionCode) + .add(COLUMN_FORECAST_DATE, day.date) + } + + return result + } + } + return null + } + + private fun resolveProjection(projection: Array?, uriType: Int): Array { + if (projection != null) return projection + return when (uriType) { + URI_TYPE_SETTINGS -> PROJECTION_DEFAULT_SETTINGS + else -> { + PROJECTION_DEFAULT_WEATHER + PROJECTION_DEFAULT_SETTINGS + } + } + } + + override fun getType(uri: Uri): String? { + return null + } + + override fun insert(uri: Uri, values: ContentValues?): Uri? { + return null + } + + override fun delete(uri: Uri, selection: String?, selectionArgs: Array?): Int { + return 0 + } + + override fun update( + uri: Uri, + values: ContentValues?, + selection: String?, + selectionArgs: Array? + ): Int { + val projectionType = sUriMatcher.match(uri) + if (projectionType == URI_TYPE_CONTROL) { + if (values!!.containsKey(COLUMN_FORCE_REFRESH) && values.getAsBoolean( + COLUMN_FORCE_REFRESH + ) + ) { + scheduleUpdateNow(mContext!!) + } + } + return 0 + } + + companion object { + private const val TAG = "WeatherService:WeatherContentProvider" + private const val DEBUG = true + + @SuppressLint("StaticFieldLeak") + var sCachedWeatherInfo: WeatherInfo? = null + + private const val URI_TYPE_WEATHER = 1 + private const val URI_TYPE_SETTINGS = 2 + private const val URI_TYPE_CONTROL = 3 + + private const val COLUMN_CURRENT_CITY_ID = "city_id" + private const val COLUMN_CURRENT_CITY = "city" + private const val COLUMN_CURRENT_CONDITION = "condition" + private const val COLUMN_CURRENT_TEMPERATURE = "temperature" + private const val COLUMN_CURRENT_HUMIDITY = "humidity" + private const val COLUMN_CURRENT_WIND_SPEED = "wind_speed" + private const val COLUMN_CURRENT_WIND_DIRECTION = "wind_direction" + private const val COLUMN_CURRENT_TIME_STAMP = "time_stamp" + private const val COLUMN_CURRENT_CONDITION_CODE = "condition_code" + private const val COLUMN_CURRENT_PIN_WHEEL = "pin_wheel" + + private const val COLUMN_FORECAST_LOW = "forecast_low" + private const val COLUMN_FORECAST_HIGH = "forecast_high" + private const val COLUMN_FORECAST_CONDITION = "forecast_condition" + private const val COLUMN_FORECAST_CONDITION_CODE = "forecast_condition_code" + private const val COLUMN_FORECAST_DATE = "forecast_date" + + private const val COLUMN_ENABLED = "enabled" + private const val COLUMN_PROVIDER = "provider" + private const val COLUMN_INTERVAL = "interval" + private const val COLUMN_UNITS = "units" + private const val COLUMN_LOCATION = "location" + private const val COLUMN_SETUP = "setup" + private const val COLUMN_ICON_PACK = "icon_pack" + + const val COLUMN_FORCE_REFRESH: String = "update" + + private val PROJECTION_DEFAULT_WEATHER = arrayOf( + COLUMN_CURRENT_CITY_ID, + COLUMN_CURRENT_CITY, + COLUMN_CURRENT_CONDITION, + COLUMN_CURRENT_TEMPERATURE, + COLUMN_CURRENT_HUMIDITY, + COLUMN_CURRENT_WIND_SPEED, + COLUMN_CURRENT_WIND_DIRECTION, + COLUMN_CURRENT_TIME_STAMP, + COLUMN_CURRENT_PIN_WHEEL, + COLUMN_CURRENT_CONDITION_CODE, + COLUMN_FORECAST_LOW, + COLUMN_FORECAST_HIGH, + COLUMN_FORECAST_CONDITION, + COLUMN_FORECAST_CONDITION_CODE, + COLUMN_FORECAST_DATE + ) + + private val PROJECTION_DEFAULT_SETTINGS = arrayOf( + COLUMN_ENABLED, + COLUMN_PROVIDER, + COLUMN_INTERVAL, + COLUMN_UNITS, + COLUMN_LOCATION, + COLUMN_SETUP, + COLUMN_ICON_PACK + ) + + private const val AUTHORITY: String = "com.drdisagree.iconify.weatherprovider" + + private val sUriMatcher = UriMatcher(URI_TYPE_WEATHER) + + init { + sUriMatcher.addURI(AUTHORITY, "weather", URI_TYPE_WEATHER) + sUriMatcher.addURI(AUTHORITY, "settings", URI_TYPE_SETTINGS) + sUriMatcher.addURI(AUTHORITY, "control", URI_TYPE_CONTROL) + } + + fun updateCachedWeatherInfo(context: Context) { + sCachedWeatherInfo = WeatherConfig.getWeatherData(context) + context.contentResolver.notifyChange( + Uri.parse("content://$AUTHORITY/weather"), null + ) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/utils/weather/WeatherInfo.kt b/app/src/main/java/com/drdisagree/iconify/utils/weather/WeatherInfo.kt new file mode 100644 index 000000000..be9237b5a --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/utils/weather/WeatherInfo.kt @@ -0,0 +1,288 @@ +package com.drdisagree.iconify.utils.weather + +import android.content.Context +import java.text.DecimalFormat +import java.util.Date + +class WeatherInfo private constructor( + context: Context, val id: String, + val city: String, private val condition: String, val conditionCode: Int, var temperature: Float, + private val humidity: Float, private val wind: Float, val windDirection: Int, + private val metric: Boolean, val forecasts: ArrayList, val timestamp: Long, + var pinWheel: String +) { + private val mContext: Context = context.applicationContext + + constructor( + context: Context, id: String, + city: String, condition: String, conditionCode: Int, temp: Float, + humidity: Float, wind: Float, windDir: Int, + metric: Boolean, forecasts: ArrayList, timestamp: Long + ) : this( + context, id, city, condition, conditionCode, temp, humidity, wind, windDir, + metric, forecasts, timestamp, "" + ) { + this.pinWheel = getFormattedWindDirection(windDir) + } + + class WeatherLocation { + var id: String? = null + var city: String? = null + var postal: String? = null + var countryId: String? = null + var country: String? = null + } + + class DayForecast( + val low: Float, + val high: Float, + val condition: String, + val conditionCode: Int, + var date: String, + var metric: Boolean + ) { + fun getCondition(context: Context): String { + return getCondition(context, conditionCode, condition) + } + } + + + fun getCondition(): String { + return getCondition(mContext, conditionCode, condition) + } + + val formattedTimestamp: Date + get() = Date(timestamp) + + val formattedHumidity: String + get() = getFormattedValue(humidity, "%") + + val windSpeed: Float + get() { + if (wind < 0) { + return 0F + } + return wind + } + + private val formattedWindSpeed: String + get() { + if (wind < 0) { + return "0" + } + return getFormattedValue(wind, if (metric) "km/h" else "m/h") + } + + private fun getFormattedWindDirection(direction: Int): String { + val value = ((direction / 22.5) + 0.5).toInt() + val pw = WIND_DIRECTION[value % 16] + return pw + } + + private val temperatureUnit: String + get() = "\u00b0" + (if (metric) "C" else "F") + + override fun toString(): String { + val builder = StringBuilder() + builder.append("WeatherInfo for ") + builder.append(city) + builder.append(" (") + builder.append(id) + builder.append(") @ ") + builder.append(formattedTimestamp) + builder.append(": ") + builder.append(getCondition()) + builder.append("(") + builder.append(conditionCode) + builder.append("), temperature ") + builder.append( + getFormattedValue( + temperature, + temperatureUnit + ) + ) + builder.append(", humidity ") + builder.append(formattedHumidity) + builder.append(", wind ") + builder.append(formattedWindSpeed) + builder.append(" at ") + builder.append(windDirection) + if (!forecasts.isEmpty()) { + builder.append(", forecasts:") + } + for (i in forecasts.indices) { + val d = forecasts[i] + if (i != 0) { + builder.append(";") + } + builder.append(" day ").append(i + 1).append(":") + builder.append(d.date) + builder.append(" high ").append( + getFormattedValue( + d.high, + temperatureUnit + ) + ) + builder.append(", low ").append( + getFormattedValue( + d.low, + temperatureUnit + ) + ) + builder.append(", ").append(d.condition) + builder.append("(").append(d.conditionCode).append(")") + } + return builder.toString() + } + + fun toSerializedString(): String { + val builder = StringBuilder() + builder.append(id).append('|') + builder.append(city).append('|') + builder.append(condition).append('|') + builder.append(conditionCode).append('|') + builder.append(temperature).append('|') + builder.append(humidity).append('|') + builder.append(wind).append('|') + builder.append(windDirection).append('|') + builder.append(metric).append('|') + builder.append(timestamp).append('|') + builder.append(pinWheel) + if (!forecasts.isEmpty()) { + serializeForecasts(builder) + } + return builder.toString() + } + + private fun serializeForecasts(builder: StringBuilder) { + builder.append('|') + builder.append(forecasts.size) + for (d in forecasts) { + builder.append(';') + builder.append(d.high).append(';') + builder.append(d.low).append(';') + builder.append(d.condition).append(';') + builder.append(d.conditionCode).append(';') + builder.append(d.date) + } + } + + companion object { + private val sNoDigitsFormat = DecimalFormat("0") + + val WIND_DIRECTION: Array = arrayOf( + "N", + "NNE", + "NE", + "ENE", + "E", + "ESE", + "SE", + "SSE", + "S", + "SSW", + "SW", + "WSW", + "W", + "WNW", + "NW", + "NNW" + ) + + private fun getCondition(context: Context, conditionCode: Int, condition: String): String { + val res = context.resources + val resId = res.getIdentifier("weather_$conditionCode", "string", context.packageName) + if (resId != 0) { + return res.getString(resId) + } + return condition + } + + private fun getFormattedValue(value: Float, unit: String): String { + if (java.lang.Float.isNaN(value)) { + return "-" + } + var formatted = sNoDigitsFormat.format(value.toDouble()) + if (formatted == "-0") { + formatted = "0" + } + return formatted + unit + } + + fun fromSerializedString(context: Context, input: String?): WeatherInfo? { + if (input == null) { + return null + } + + val parts = input.split("\\|".toRegex()).dropLastWhile { it.isEmpty() } + .toTypedArray() + val hasForecast = parts.size == 12 + + val conditionCode: Int + val windDirection: Int + val timestamp: Long + val temperature: Float + val humidity: Float + val wind: Float + val metric: Boolean + val pinWheel: String + var forecastParts: Array? = null + if (hasForecast) { + forecastParts = + parts[11].split(";".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() + } + val forecastItems: Int + val forecasts = ArrayList() + + // Parse the core data + try { + conditionCode = parts[3].toInt() + temperature = parts[4].toFloat() + humidity = parts[5].toFloat() + wind = parts[6].toFloat() + windDirection = parts[7].toInt() + metric = parts[8].toBoolean() + timestamp = parts[9].toLong() + pinWheel = parts[10] + forecastItems = forecastParts?.get(0)?.toInt() ?: 0 + } catch (e: NumberFormatException) { + return null + } + + if (hasForecast && (forecastItems == 0 || forecastParts!!.size != 5 * forecastItems + 1)) { + return null + } + + // Parse the forecast data + try { + for (item in 0 until forecastItems) { + val offset = item * 5 + 1 + val day = DayForecast( /* low */ + forecastParts!![offset + 1].toFloat(), /* high */ + forecastParts[offset].toFloat(), /* condition */ + forecastParts[offset + 2], /* conditionCode */ + forecastParts[offset + 3].toInt(), + forecastParts[offset + 4], + metric + ) + if (!java.lang.Float.isNaN(day.low) && !java.lang.Float.isNaN(day.high) /*&& day.conditionCode >= 0*/) { + forecasts.add(day) + } + } + } catch (ignored: NumberFormatException) { + } + + if (hasForecast && forecasts.isEmpty()) { + return null + } + + return WeatherInfo( + context, /* id */ + parts[0], /* city */parts[1], /* condition */parts[2], + conditionCode, temperature, + humidity, wind, windDirection, metric, /* forecasts */ + forecasts, timestamp, pinWheel + ) + } + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/utils/weather/WeatherWork.kt b/app/src/main/java/com/drdisagree/iconify/utils/weather/WeatherWork.kt new file mode 100644 index 000000000..410b0a331 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/utils/weather/WeatherWork.kt @@ -0,0 +1,282 @@ +package com.drdisagree.iconify.utils.weather + +import android.Manifest +import android.annotation.SuppressLint +import android.content.Context +import android.content.Intent +import android.content.pm.PackageManager +import android.location.Criteria +import android.location.Location +import android.location.LocationManager +import android.text.TextUtils +import android.util.Log +import androidx.concurrent.futures.CallbackToFutureAdapter +import androidx.work.ListenableWorker +import androidx.work.WorkerParameters +import com.drdisagree.iconify.BuildConfig +import com.drdisagree.iconify.utils.OmniJawsClient.Companion.EXTRA_ERROR_DISABLED +import com.drdisagree.iconify.utils.OmniJawsClient.Companion.EXTRA_ERROR_LOCATION +import com.drdisagree.iconify.utils.OmniJawsClient.Companion.EXTRA_ERROR_NETWORK +import com.drdisagree.iconify.utils.OmniJawsClient.Companion.EXTRA_ERROR_NO_PERMISSIONS +import com.drdisagree.iconify.utils.weather.WeatherConfig.getLocationLat +import com.drdisagree.iconify.utils.weather.WeatherConfig.getLocationLon +import com.drdisagree.iconify.utils.weather.WeatherConfig.getProvider +import com.drdisagree.iconify.utils.weather.WeatherConfig.isCustomLocation +import com.drdisagree.iconify.utils.weather.WeatherConfig.isEnabled +import com.drdisagree.iconify.utils.weather.WeatherConfig.isMetric +import com.drdisagree.iconify.utils.weather.WeatherConfig.setUpdateError +import com.drdisagree.iconify.utils.weather.WeatherConfig.setWeatherData +import com.google.common.util.concurrent.ListenableFuture +import java.text.SimpleDateFormat +import java.util.Locale +import java.util.concurrent.CompletableFuture +import java.util.concurrent.ExecutorService +import java.util.concurrent.Executors +import java.util.concurrent.atomic.AtomicReference + +class WeatherWork(val mContext: Context, workerParams: WorkerParameters) : + ListenableWorker(mContext, workerParams) { + + override fun startWork(): ListenableFuture { + if (DEBUG) Log.d(TAG, "startWork") + + return CallbackToFutureAdapter.getFuture { completer: CallbackToFutureAdapter.Completer -> + if (!isEnabled(mContext)) { + handleError( + completer, + EXTRA_ERROR_DISABLED, + "Service started, but not enabled ... stopping" + ) + return@getFuture completer + } + + if (!isCustomLocation(mContext)) { + // Check permissions and location enabled + // only if not using custom location + if (!checkPermissions()) { + handleError( + completer, + EXTRA_ERROR_NO_PERMISSIONS, + "Location permissions are not granted" + ) + return@getFuture completer + } + + if (!doCheckLocationEnabled()) { + handleError(completer, EXTRA_ERROR_NETWORK, "Location services are disabled") + return@getFuture completer + } + } + + executor.execute { + getCurrentLocation().thenAccept { location: Location? -> + if (location != null) { + Log.d(TAG, "Location retrieved") + updateWeather(location, completer) + } else if (isCustomLocation(mContext)) { + Log.d(TAG, "Using custom location configuration") + updateWeather(null, completer) + } else { + handleError(completer, EXTRA_ERROR_LOCATION, "Failed to retrieve location") + } + } + } + completer + } + } + + private fun handleError( + completer: CallbackToFutureAdapter.Completer, + errorExtra: Int, + logMessage: String + ) { + Log.w(TAG, logMessage) + val errorIntent = Intent(ACTION_ERROR) + errorIntent.putExtra(EXTRA_ERROR, errorExtra) + mContext.sendBroadcast(errorIntent) + completer.set(Result.retry()) + } + + private fun doCheckLocationEnabled(): Boolean { + val locationManager = mContext.getSystemService(Context.LOCATION_SERVICE) as LocationManager + var gpsEnabled = false + var networkEnabled = false + + try { + gpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) + } catch (ex: Exception) { + Log.d(TAG, "doCheckLocationEnabled: " + ex.message) + } + + try { + networkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER) + } catch (ex: Exception) { + Log.d(TAG, "doCheckLocationEnabled: " + ex.message) + } + + if (DEBUG) Log.d( + TAG, + "gpsEnabled: $gpsEnabled networkEnabled: $networkEnabled" + ) + + return gpsEnabled || networkEnabled + } + + @SuppressLint("MissingPermission") + private fun getCurrentLocation(): CompletableFuture { + val locationFuture = CompletableFuture() + + if (isCustomLocation(mContext)) { + locationFuture.complete(null) + return locationFuture + } + + val lm = mContext.getSystemService(Context.LOCATION_SERVICE) as LocationManager + + if (!doCheckLocationEnabled()) { + Log.w(TAG, "locations disabled") + locationFuture.complete(null) + return locationFuture + } + + val location = AtomicReference(lm.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER)) + Log.d(TAG, "Current location is $location") + + if (location.get() != null && location.get()!!.accuracy > LOCATION_ACCURACY_THRESHOLD_METERS) { + Log.w(TAG, "Ignoring inaccurate location") + location.set(null) + } + + var needsUpdate = location.get() == null + if (location.get() != null) { + val delta = System.currentTimeMillis() - location.get()!!.time + needsUpdate = delta > OUTDATED_LOCATION_THRESHOLD_MILLIS + Log.d(TAG, "Location is " + delta + "ms old") + if (needsUpdate) { + Log.w( + TAG, "Ignoring too old location from " + dayFormat.format( + location.get()!!.time + ) + ) + location.set(null) + } + } + + if (needsUpdate) { + Log.d(TAG, "Requesting current location") + val locationProvider = lm.getBestProvider(sLocationCriteria, true) + if (TextUtils.isEmpty(locationProvider)) { + Log.e(TAG, "No available location providers matching criteria.") + locationFuture.complete(null) + } else { + Log.d( + TAG, + "Getting current location with provider $locationProvider" + ) + lm.getCurrentLocation( + locationProvider!!, null, mContext.mainExecutor + ) { location1: Location? -> + if (location1 != null) { + Log.d(TAG, "Got valid location now update") + location.set(location1) + locationFuture.complete(location1) + } else { + Log.e(TAG, "Failed to retrieve location") + locationFuture.complete(null) + } + } + } + } else { + locationFuture.complete(location.get()) + } + + return locationFuture + } + + private fun updateWeather( + location: Location?, + completer: CallbackToFutureAdapter.Completer + ) { + var w: WeatherInfo? = null + try { + val provider = getProvider(mContext) + val isMetric = isMetric(mContext) + var i = 0 + while (i < RETRY_MAX_NUM) { + w = if (location != null && !isCustomLocation(mContext)) { + provider.getLocationWeather(location, isMetric) + } else if (!TextUtils.isEmpty(getLocationLat(mContext)) && !TextUtils.isEmpty( + getLocationLon(mContext) + ) + ) { + provider.getCustomWeather( + getLocationLat(mContext)!!, + getLocationLon(mContext)!!, + isMetric + ) + } else { + Log.w(TAG, "No valid custom location and location is null") + break + } + + if (w != null) { + setWeatherData(w, mContext) + WeatherContentProvider.updateCachedWeatherInfo(mContext) + Log.d(TAG, "Weather updated updateCachedWeatherInfo") + completer.set(Result.success()) + return + } else { + if (!provider.shouldRetry()) { + break + } else { + Log.w(TAG, "retry count = $i") + try { + Thread.sleep(RETRY_DELAY_MS.toLong()) + } catch (ignored: InterruptedException) { + } + } + } + i++ + } + } finally { + if (w == null) { + Log.d(TAG, "error updating weather") + setUpdateError(mContext, true) + completer.set(Result.retry()) + } + val updateIntent = Intent(ACTION_BROADCAST) + mContext.sendBroadcast(updateIntent) + } + } + + private fun checkPermissions(): Boolean { + return mContext.checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED && + mContext.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED + } + + @Suppress("deprecation") + companion object { + private const val TAG = "WeatherWork" + private const val DEBUG = false + private const val ACTION_BROADCAST = "${BuildConfig.APPLICATION_ID}.WEATHER_UPDATE" + private const val ACTION_ERROR = "${BuildConfig.APPLICATION_ID}.WEATHER_ERROR" + + private const val EXTRA_ERROR = "error" + + private const val LOCATION_ACCURACY_THRESHOLD_METERS = 10000f + private const val OUTDATED_LOCATION_THRESHOLD_MILLIS = 10L * 60L * 1000L // 10 minutes + private const val RETRY_DELAY_MS = 5000 + private const val RETRY_MAX_NUM = 5 + + private val executor: ExecutorService = Executors.newSingleThreadExecutor() + private val dayFormat = SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.US) + + private val sLocationCriteria = Criteria() + + init { + sLocationCriteria.powerRequirement = Criteria.POWER_LOW + sLocationCriteria.accuracy = Criteria.ACCURACY_COARSE + sLocationCriteria.isCostAllowed = false + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/utils/weather/providers/OpenMeteoProvider.kt b/app/src/main/java/com/drdisagree/iconify/utils/weather/providers/OpenMeteoProvider.kt new file mode 100644 index 000000000..57552051e --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/utils/weather/providers/OpenMeteoProvider.kt @@ -0,0 +1,374 @@ +package com.drdisagree.iconify.utils.weather.providers + +import android.content.Context +import android.location.Location +import android.util.Log +import com.drdisagree.iconify.utils.weather.AbstractWeatherProvider +import com.drdisagree.iconify.utils.weather.WeatherInfo +import org.json.JSONException +import org.json.JSONObject +import java.text.SimpleDateFormat +import java.util.Calendar +import java.util.Locale +import java.util.TimeZone + +class OpenMeteoProvider(context: Context?) : AbstractWeatherProvider(context!!) { + + override fun getCustomWeather(lat: String?, lon: String?, metric: Boolean): WeatherInfo? { + val coordinates = + String.format(Locale.US, PART_COORDINATES, lat!!.toFloat(), lon!!.toFloat()) + return handleWeatherRequest(coordinates, metric) + } + + override fun getLocationWeather(location: Location?, metric: Boolean): WeatherInfo? { + val coordinates = + String.format(Locale.US, PART_COORDINATES, location!!.latitude, location.longitude) + return handleWeatherRequest(coordinates, metric) + } + + private fun handleWeatherRequest(selection: String?, metric: Boolean): WeatherInfo? { + val tempUnit = if (metric) "celsius" else "fahrenheit" + val speedUnit = if (metric) "kmh" else "mph" + val timeZone = TimeZone.getDefault().id + val conditionUrl = String.format( + Locale.US, + URL_WEATHER + PART_PARAMETERS, + selection, + tempUnit, + speedUnit, + timeZone + ) + val conditionResponse = retrieve(conditionUrl) ?: return null + log( + TAG, + "Condition URL = $conditionUrl returning a response of $conditionResponse" + ) + + try { + val weather = JSONObject(conditionResponse).getJSONObject("current_weather") + + val city = getWeatherDataLocality(selection!!) + + val weathercode = weather.getInt("weathercode") + val isDay = weather.getInt("is_day") == 1 + + val w: WeatherInfo = WeatherInfo( + mContext, /* id */ + selection, /* cityId */ + city!!, /* condition */ + getWeatherDescription(weathercode), /* conditionCode */ + mapConditionIconToCode(weathercode, isDay), /* temperature */ + weather.getDouble("temperature") + .toFloat(), // Api: Possibly future inclusion humidity in current weather; may eliminate need for hourly forecast request. + /* humidity */ + getCurrentHumidity(JSONObject(conditionResponse).getJSONObject("hourly")), /* wind */ + weather.getDouble("windspeed").toFloat(), /* windDir */ + weather.getInt("winddirection"), + metric, + parseForecasts(JSONObject(conditionResponse).getJSONObject("daily"), metric), + System.currentTimeMillis() + ) + return w + } catch (e: JSONException) { + Log.e( + TAG, + "Received malformed weather data (coordinates = $selection)", e + ) + } + + + return null + } + + @Throws(JSONException::class) + private fun parseForecasts( + dailyForecasts: JSONObject, + metric: Boolean + ): ArrayList { + val result: ArrayList = ArrayList(5) + + val timeJson = dailyForecasts.getJSONArray("time") + val temperatureMinJson = dailyForecasts.getJSONArray("temperature_2m_min_best_match") + val temperatureMaxJson = dailyForecasts.getJSONArray("temperature_2m_max_best_match") + val weatherCodeJson = dailyForecasts.getJSONArray("weathercode_best_match") + val altWeatherCodeJson = dailyForecasts.getJSONArray("weathercode_gfs_seamless") + val currentDay = + SimpleDateFormat("yyyy-MM-dd", Locale.US).format(Calendar.getInstance().time) + + var startIndex = 1 + if (currentDay == timeJson.getString(0)) startIndex = 0 + else if (currentDay == timeJson.getString(2)) startIndex = 2 + + var i = startIndex + while (i < timeJson.length() && result.size < 5) { + var item: WeatherInfo.DayForecast + var weatherCode = weatherCodeJson.getInt(i) + if (weatherCode == 45 || weatherCode == 48) weatherCode = altWeatherCodeJson.getInt(i) + + try { + item = WeatherInfo.DayForecast( /* low */ + temperatureMinJson.getDouble(i).toFloat(), /* high */ + temperatureMaxJson.getDouble(i).toFloat(), /* condition */ + getWeatherDescription(weatherCode), /* conditionCode */ + mapConditionIconToCode(weatherCode, true), + timeJson.getString(i), + metric + ) + } catch (e: JSONException) { + Log.w( + TAG, + "Invalid forecast for day $i creating dummy", e + ) + item = WeatherInfo.DayForecast( /* low */ + 0F, /* high */ + 0F, /* condition */ + "", /* conditionCode */ + -1, + "NaN", + metric + ) + } + result.add(item) + i++ + } + // clients assume there are 5 entries - so fill with dummy if needed + if (result.size < 5) { + for (i in result.size..4) { + Log.w( + TAG, + "Missing forecast for day $i creating dummy" + ) + val item: WeatherInfo.DayForecast = WeatherInfo.DayForecast( /* low */ + 0F, /* high */ + 0F, /* condition */ + "", /* conditionCode */ + -1, + "NaN", + metric + ) + result.add(item) + } + } + + return result + } + + private val languageCode: String + get() { + val locale = mContext.resources.configuration.locale + val selector = locale.language + "-" + locale.country + + for ((key, value) in LANGUAGE_CODE_MAPPING) { + if (selector.startsWith(key)) { + return value + } + } + + return "en" + } + + private fun mapConditionIconToCode(code: Int, isDay: Boolean): Int { + return when (code) { + 0 -> // Clear sky + if (isDay) 32 else 31 + + 1 -> // Mainly clear + if (isDay) 34 else 33 + + 2 -> // Partly cloudy + if (isDay) 30 else 29 + + 3 -> // Overcast + 26 + + 45, 48 -> // Depositing rime fog + 20 + + 51 -> // Light intensity drizzle + 9 + + 53 -> // Moderate intensity drizzle + 9 + + 55 -> // Dense intensity drizzle + 12 + + 56 -> // Light intensity freezing drizzle + 8 + + 57 -> // Dense intensity freezing drizzle + 8 + + 61 -> // Slight intensity rain + 9 + + 63 -> // Moderate intensity rain + 11 + + 65 -> // Heavy intensity rain + 12 + + 66 -> // Light intensity freezing rain + 10 + + 67 -> // Heavy intensity freezing rain + 10 + + 71 -> // Slight intensity snowfall + 14 + + 73 -> // Moderate intensity snowfall + 16 + + 75 -> // Heavy intensity snowfall + 43 + + 77 -> // Snow grains + 16 + + 80 -> // Slight intensity rain showers + 11 + + 81 -> // Moderate intensity rain showers + 40 + + 82 -> // Violent intensity rain showers + 40 + + 85 -> // Slight intensity snow showers + 14 + + 86 -> // Heavy intensity snow showers + 43 + + 95 -> // Slight or moderate thunderstorm + 4 + + 96, 99 -> // Thunderstorm with heavy hail + 38 + + else -> // Unknown + -1 + } + } + + override fun shouldRetry(): Boolean { + return false + } + + companion object { + private const val TAG = "OpenWeatherMapProvider" + + private const val FORECAST_DAYS = 5 + private const val URL_WEATHER = "https://api.open-meteo.com/v1/forecast?" + private const val PART_COORDINATES = "latitude=%f&longitude=%f" + private const val PART_PARAMETERS = + "%s&hourly=relativehumidity_2m&daily=weathercode,temperature_2m_max,temperature_2m_min¤t_weather=true&temperature_unit=%s&windspeed_unit=%s&timezone=%s&past_days=1&models=best_match,gfs_seamless" + + + /* OpenMeteo WMO Weather interpretation codes (WW) + * 0 Clear sky + * 1, 2, 3 Mainly clear, partly cloudy, and overcast + * 45, 48 Fog and depositing rime fog + * 51, 53, 55 Drizzle: Light, moderate, and dense intensity + * 56, 57 Freezing Drizzle: Light and dense intensity + * 61, 63, 65 Rain: Slight, moderate and heavy intensity + * 66, 67 Freezing Rain: Light and heavy intensity + * 71, 73, 75 Snow fall: Slight, moderate, and heavy intensity + * 77 Snow grains + * 80, 81, 82 Rain showers: Slight, moderate, and violent + * 85, 86 Snow showers slight and heavy + * 95 * Thunderstorm: Slight or moderate + * 96, 99 * Thunderstorm with slight and heavy hail + */ + private fun getWeatherDescription(code: Int): String { + return when (code) { + 0 -> "Clear sky" + 1 -> "Mainly clear" + 2 -> "Partly clouds" + 3 -> "Clouds" + 45 -> "Fog" + 48 -> "Depositing rime fog" + 51 -> "Light intensity drizzle rain" + 53 -> "Moderate intensity drizzle rain" + 55 -> "Dense intensity drizzle rain" + 56 -> "Light intensity freezing drizzle rain" + 57 -> "Dense intensity freezing drizzle rain" + 61 -> "Slight intensity rain" + 63 -> "Moderate intensity rain" + 65 -> "Heavy intensity rain" + 66 -> "Light intensity freezing rain" + 67 -> "Heavy intensity freezing rain" + 71 -> "Slight intensity snowfall" + 73 -> "Moderate intensity snowfall" + 75 -> "Heavy intensity snowfall" + 77 -> "Snow grains" + 80 -> "Slight intensity rain showers" + 81 -> "Moderate intensity rain showers" + 82 -> "Violent intensity rain showers" + 85 -> "Slight intensity snow showers" + 86 -> "Heavy intensity snow showers" + 95 -> "Slight or moderate thunderstorm" + 96 -> "Thunderstorm with slight hail" + 99 -> "Thunderstorm with heavy hail" + else -> "Unknown" + } + } + + @Throws(JSONException::class) + private fun getCurrentHumidity(hourlyJson: JSONObject): Float { + val currentHour = + SimpleDateFormat("yyyy-MM-dd'T'HH", Locale.US).format(Calendar.getInstance().time) + val hourlyTimes = hourlyJson.getJSONArray("time") + val hourlyHumidity = hourlyJson.getJSONArray("relativehumidity_2m_best_match") + + var currentIndex = 36 + for (i in 0 until hourlyTimes.length()) if (hourlyTimes.getString(i) + .startsWith(currentHour) + ) { + currentIndex = i + break + } + + return hourlyHumidity.getDouble(currentIndex).toFloat() + } + + // OpenWeatherMap sometimes returns temperatures in Kelvin even if we ask it + // for deg C or deg F. Detect this and convert accordingly. + private fun sanitizeTemperature(value: Double, metric: Boolean): Float { + // threshold chosen to work for both C and F. 170 deg F is hotter + // than the hottest place on earth. + var value = value + if (value > 170) { + // K -> deg C + value -= 273.15 + if (!metric) { + // deg C -> deg F + value = (value * 1.8) + 32 + } + } + return value.toFloat() + } + + private val LANGUAGE_CODE_MAPPING = HashMap() + + init { + LANGUAGE_CODE_MAPPING["bg-"] = "bg" + LANGUAGE_CODE_MAPPING["de-"] = "de" + LANGUAGE_CODE_MAPPING["es-"] = "sp" + LANGUAGE_CODE_MAPPING["fi-"] = "fi" + LANGUAGE_CODE_MAPPING["fr-"] = "fr" + LANGUAGE_CODE_MAPPING["it-"] = "it" + LANGUAGE_CODE_MAPPING["nl-"] = "nl" + LANGUAGE_CODE_MAPPING["pl-"] = "pl" + LANGUAGE_CODE_MAPPING["pt-"] = "pt" + LANGUAGE_CODE_MAPPING["ro-"] = "ro" + LANGUAGE_CODE_MAPPING["ru-"] = "ru" + LANGUAGE_CODE_MAPPING["se-"] = "se" + LANGUAGE_CODE_MAPPING["tr-"] = "tr" + LANGUAGE_CODE_MAPPING["uk-"] = "ua" + LANGUAGE_CODE_MAPPING["zh-CN"] = "zh_cn" + LANGUAGE_CODE_MAPPING["zh-TW"] = "zh_tw" + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/utils/weather/providers/OpenWeatherMapProvider.kt b/app/src/main/java/com/drdisagree/iconify/utils/weather/providers/OpenWeatherMapProvider.kt new file mode 100644 index 000000000..b185faf99 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/utils/weather/providers/OpenWeatherMapProvider.kt @@ -0,0 +1,303 @@ +package com.drdisagree.iconify.utils.weather.providers + +import android.content.Context +import android.location.Location +import android.text.TextUtils +import android.util.Log +import com.drdisagree.iconify.utils.weather.AbstractWeatherProvider +import com.drdisagree.iconify.utils.weather.WeatherConfig +import com.drdisagree.iconify.utils.weather.WeatherInfo +import org.json.JSONArray +import org.json.JSONException +import org.json.JSONObject +import java.util.Locale + +class OpenWeatherMapProvider(context: Context?) : AbstractWeatherProvider(context!!) { + + private val mHasAPIKey: Boolean + + override fun getCustomWeather(lat: String?, lon: String?, metric: Boolean): WeatherInfo? { + val coordinates = String.format(Locale.US, PART_COORDINATES, lat!!.toFloat(), lon!!.toFloat()) + return handleWeatherRequest(coordinates, metric) + } + + override fun getLocationWeather(location: Location?, metric: Boolean): WeatherInfo? { + val coordinates = String.format(Locale.US, PART_COORDINATES, location!!.latitude,location.longitude) + return handleWeatherRequest(coordinates, metric) + } + + private fun handleWeatherRequest(selection: String, metric: Boolean): WeatherInfo? { + if (!mHasAPIKey) { + return null + } + val units = if (metric) "metric" else "imperial" + val locale = languageCode + val conditionUrl = String.format( + Locale.US, URL_WEATHER, selection, units, locale, + aPIKey + ) + val conditionResponse: String = retrieve(conditionUrl) ?: return null + log( + TAG, + "Condition URL = $conditionUrl returning a response of $conditionResponse" + ) + + try { + val conditions = JSONObject(conditionResponse) + val conditionData = conditions.getJSONObject("main") + val weather = conditions.getJSONArray("weather").getJSONObject(0) + var forecasts: ArrayList = ArrayList() + if (conditions.has("daily")) { + forecasts = + parseForecasts(conditions.getJSONArray("daily"), metric) + } + val wind = conditions.getJSONObject("wind") + var windSpeed = wind.getDouble("speed").toFloat() + if (metric) { + // speeds are in m/s so convert to our common metric unit km/h + windSpeed *= 3.6f + } + + val city: String = getWeatherDataLocality(selection).toString() + + val w: WeatherInfo = WeatherInfo( + mContext, selection, city, /* condition */ + weather.getString("main"), /* conditionCode */ + mapConditionIconToCode( + weather.getString("icon"), weather.getInt("id") + ), /* temperature */ + sanitizeTemperature(conditionData.getDouble("temp"), metric), /* humidity */ + conditionData.getDouble("humidity").toFloat(), /* wind */ + windSpeed, /* windDir */ + if (wind.has("deg")) wind.getInt("deg") else 0, + metric, + forecasts, + System.currentTimeMillis() + ) + + log(TAG, "Weather updated: $w") + return w + } catch (e: JSONException) { + Log.w( + TAG, "Received malformed weather data (selection = " + selection + + ", lang = " + locale + ")", e + ) + } + + return null + } + + @Throws(JSONException::class) + private fun parseForecasts(forecasts: JSONArray, metric: Boolean): ArrayList { + val result: ArrayList = ArrayList() + val count = forecasts.length() + + if (count == 0) { + throw JSONException("Empty forecasts array") + } + for (i in 0 until count) { + val day: String = getDay(i) + var item: WeatherInfo.DayForecast + try { + val forecast = forecasts.getJSONObject(i) + val conditionData = forecast.getJSONObject("temp") + val data = forecast.getJSONArray("weather").getJSONObject(0) + item = WeatherInfo.DayForecast( /* low */ + sanitizeTemperature(conditionData.getDouble("min"), metric), /* high */ + sanitizeTemperature(conditionData.getDouble("max"), metric), /* condition */ + data.getString("main"), /* conditionCode */ + mapConditionIconToCode( + data.getString("icon"), data.getInt("id") + ), + day, + metric + ) + } catch (e: JSONException) { + Log.w( + TAG, + "Invalid forecast for day $i creating dummy", e + ) + item = WeatherInfo.DayForecast( /* low */ + 0F, /* high */ + 0F, /* condition */ + "", /* conditionCode */ + -1, + "NaN", + metric + ) + } + result.add(item) + } + // clients assume there are 5 entries - so fill with dummy if needed + if (result.size < 5) { + for (i in result.size..4) { + Log.w( + TAG, + "Missing forecast for day $i creating dummy" + ) + val item: WeatherInfo.DayForecast = WeatherInfo.DayForecast( /* low */ + 0F, /* high */ + 0F, /* condition */ + "", /* conditionCode */ + -1, + "NaN", + metric + ) + result.add(item) + } + } + return result + } + + init { + mHasAPIKey = aPIKey != null + } + + private val languageCode: String + get() { + val locale: Locale = mContext.resources.configuration.locale + val selector = locale.language + "-" + locale.country + + for ((key, value) in LANGUAGE_CODE_MAPPING) { + if (selector.startsWith(key)) { + return value + } + } + + return "en" + } + + private fun mapConditionIconToCode(icon: String, conditionId: Int): Int { + // First, use condition ID for specific cases + + return when (conditionId) { + 202, 232, 211 -> // thunderstorm + 4 + + 212 -> // heavy thunderstorm + 3 + + 221, 231, 201 -> // thunderstorm with rain + 38 + + 230, 200, 210 -> // light thunderstorm + 37 + + 300, 301, 302, 310, 311, 312, 313, 314, 321 -> // shower drizzle + 9 + + 500, 501, 520, 521, 531 -> // ragged shower rain + 11 + + 502, 503, 504, 522 -> // heavy intensity shower rain + 12 + + 511 -> // freezing rain + 10 + + 600, 620 -> 14 + 601, 621 -> 16 + 602, 622 -> 41 + 611, 612 -> 18 + 615, 616 -> 5 + 741 -> // fog + 20 + + 711, 762 -> // volcanic ash + 22 + + 701, 721 -> // haze + 21 + + 731, 751, 761 -> // dust + 19 + + 771 -> // squalls + 23 + + 781 -> // tornado + 0 + + 800 -> // clear sky + if (icon.endsWith("n")) 31 else 32 + + 801 -> // few clouds + if (icon.endsWith("n")) 33 else 34 + + 802 -> // scattered clouds + if (icon.endsWith("n")) 27 else 28 + + 803, 804 -> // overcast clouds + if (icon.endsWith("n")) 29 else 30 + + 900 -> 0 + 901 -> 1 + 902 -> 2 + 903 -> 25 + 904 -> 36 + 905 -> 24 + 906 -> 17 + else -> // hail + -1 + } + } + + private val aPIKey: String? + get() { + val customKey: String = WeatherConfig.getOwmKey(mContext).toString() + if (!TextUtils.isEmpty(customKey)) { + return customKey + } + return null + } + + override fun shouldRetry(): Boolean { + return false + } + + companion object { + private const val TAG = "OpenWeatherMapProvider" + + private const val FORECAST_DAYS = 5 + private const val URL_WEATHER = + "https://api.openweathermap.org/data/2.5/weather?%s&mode=json&units=%s&lang=%s&cnt=" + FORECAST_DAYS + "&appid=%s" + + // OpenWeatherMap sometimes returns temperatures in Kelvin even if we ask it + // for deg C or deg F. Detect this and convert accordingly. + private fun sanitizeTemperature(value: Double, metric: Boolean): Float { + // threshold chosen to work for both C and F. 170 deg F is hotter + // than the hottest place on earth. + var value = value + if (value > 170) { + // K -> deg C + value -= 273.15 + if (!metric) { + // deg C -> deg F + value = (value * 1.8) + 32 + } + } + return value.toFloat() + } + + private val LANGUAGE_CODE_MAPPING = HashMap() + + init { + LANGUAGE_CODE_MAPPING["bg-"] = "bg" + LANGUAGE_CODE_MAPPING["de-"] = "de" + LANGUAGE_CODE_MAPPING["es-"] = "sp" + LANGUAGE_CODE_MAPPING["fi-"] = "fi" + LANGUAGE_CODE_MAPPING["fr-"] = "fr" + LANGUAGE_CODE_MAPPING["it-"] = "it" + LANGUAGE_CODE_MAPPING["nl-"] = "nl" + LANGUAGE_CODE_MAPPING["pl-"] = "pl" + LANGUAGE_CODE_MAPPING["pt-"] = "pt" + LANGUAGE_CODE_MAPPING["ro-"] = "ro" + LANGUAGE_CODE_MAPPING["ru-"] = "ru" + LANGUAGE_CODE_MAPPING["se-"] = "se" + LANGUAGE_CODE_MAPPING["tr-"] = "tr" + LANGUAGE_CODE_MAPPING["uk-"] = "ua" + LANGUAGE_CODE_MAPPING["zh-CN"] = "zh_cn" + LANGUAGE_CODE_MAPPING["zh-TW"] = "zh_tw" + } + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/xposed/EntryList.kt b/app/src/main/java/com/drdisagree/iconify/xposed/EntryList.kt index d315fe5ca..8146b4377 100644 --- a/app/src/main/java/com/drdisagree/iconify/xposed/EntryList.kt +++ b/app/src/main/java/com/drdisagree/iconify/xposed/EntryList.kt @@ -5,14 +5,21 @@ import com.drdisagree.iconify.common.Const.PIXEL_LAUNCHER_PACKAGE import com.drdisagree.iconify.common.Const.SYSTEMUI_PACKAGE import com.drdisagree.iconify.xposed.modules.BackgroundChip import com.drdisagree.iconify.xposed.modules.BatteryStyleManager +import com.drdisagree.iconify.xposed.modules.ControllersProvider import com.drdisagree.iconify.xposed.modules.DepthWallpaper +import com.drdisagree.iconify.xposed.modules.DepthWallpaperA14 import com.drdisagree.iconify.xposed.modules.HeaderClock +import com.drdisagree.iconify.xposed.modules.HeaderClockA14 import com.drdisagree.iconify.xposed.modules.HeaderImage import com.drdisagree.iconify.xposed.modules.IconUpdater import com.drdisagree.iconify.xposed.modules.LockscreenClock +import com.drdisagree.iconify.xposed.modules.LockscreenWeather +import com.drdisagree.iconify.xposed.modules.LockscreenWidgets import com.drdisagree.iconify.xposed.modules.Miscellaneous +import com.drdisagree.iconify.xposed.modules.OpQsHeader import com.drdisagree.iconify.xposed.modules.QSTransparency import com.drdisagree.iconify.xposed.modules.QuickSettings +import com.drdisagree.iconify.xposed.modules.Statusbar import com.drdisagree.iconify.xposed.modules.VolumePanel import com.drdisagree.iconify.xposed.modules.themes.QSBlackThemeA13 import com.drdisagree.iconify.xposed.modules.themes.QSBlackThemeA14 @@ -32,34 +39,43 @@ object EntryList { ) private val systemUICommonModPacks = listOf( + ControllersProvider::class.java, BackgroundChip::class.java, - HeaderClock::class.java, HeaderImage::class.java, - DepthWallpaper::class.java, LockscreenClock::class.java, + LockscreenWidgets::class.java, + LockscreenWeather::class.java, Miscellaneous::class.java, QSTransparency::class.java, QuickSettings::class.java, + Statusbar::class.java, BatteryStyleManager::class.java, VolumePanel::class.java ) private val systemUiAndroid12ModPacks = listOf( + DepthWallpaper::class.java, QSFluidThemeA13::class.java, QSBlackThemeA13::class.java, - QSLightThemeA12::class.java + QSLightThemeA12::class.java, + HeaderClock::class.java ) private val systemUiAndroid13ModPacks = listOf( + DepthWallpaper::class.java, QSFluidThemeA13::class.java, QSBlackThemeA13::class.java, - QSLightThemeA13::class.java + QSLightThemeA13::class.java, + HeaderClock::class.java ) private val systemUiAndroid14ModPacks = listOf( + DepthWallpaperA14::class.java, QSFluidThemeA14::class.java, QSBlackThemeA14::class.java, - QSLightThemeA14::class.java + QSLightThemeA14::class.java, + HeaderClockA14::class.java, + OpQsHeader::class.java ) private val pixelLauncherModPacks = listOf( diff --git a/app/src/main/java/com/drdisagree/iconify/xposed/HookEntry.kt b/app/src/main/java/com/drdisagree/iconify/xposed/HookEntry.kt index 5f791506a..4ab71ed35 100644 --- a/app/src/main/java/com/drdisagree/iconify/xposed/HookEntry.kt +++ b/app/src/main/java/com/drdisagree/iconify/xposed/HookEntry.kt @@ -1,35 +1,46 @@ package com.drdisagree.iconify.xposed +import android.annotation.SuppressLint import android.app.Instrumentation +import android.content.ComponentName import android.content.Context +import android.content.Intent +import android.content.ServiceConnection +import android.os.IBinder +import android.os.RemoteException +import android.os.UserManager import com.drdisagree.iconify.BuildConfig +import com.drdisagree.iconify.IRootProviderProxy +import com.drdisagree.iconify.R import com.drdisagree.iconify.common.Const.FRAMEWORK_PACKAGE -import com.drdisagree.iconify.config.XPrefs -import com.drdisagree.iconify.config.XPrefs.Xprefs import com.drdisagree.iconify.xposed.utils.BootLoopProtector -import com.drdisagree.iconify.xposed.utils.SystemUtil -import de.robv.android.xposed.IXposedHookLoadPackage +import com.drdisagree.iconify.xposed.utils.SystemUtils +import com.drdisagree.iconify.xposed.utils.XPrefs +import com.drdisagree.iconify.xposed.utils.XPrefs.Xprefs import de.robv.android.xposed.XC_MethodHook import de.robv.android.xposed.XposedBridge.hookAllMethods import de.robv.android.xposed.XposedBridge.log import de.robv.android.xposed.XposedHelpers.findAndHookMethod import de.robv.android.xposed.XposedHelpers.findClass import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import java.util.LinkedList +import java.util.Queue import java.util.concurrent.CompletableFuture -class HookEntry : IXposedHookLoadPackage { +class HookEntry : ServiceConnection { - companion object { - var isChildProcess = false + private var mContext: Context? = null - @JvmField - val runningMods = ArrayList() + init { + instance = this } - private var mContext: Context? = null - private val tag = "Iconify - ${this::class.java.simpleName}: " - - override fun handleLoadPackage(loadPackageParam: LoadPackageParam) { + fun handleLoadPackage(loadPackageParam: LoadPackageParam) { isChildProcess = try { loadPackageParam.processName.contains(":") } catch (ignored: Throwable) { @@ -59,56 +70,66 @@ class HookEntry : IXposedHookLoadPackage { CompletableFuture.runAsync { waitForXprefsLoad(loadPackageParam) } } } catch (throwable: Throwable) { - log(tag + throwable) + log(TAG + throwable) } } }) } else -> { - findAndHookMethod( - Instrumentation::class.java, - "newApplication", - ClassLoader::class.java, - String::class.java, - Context::class.java, - object : XC_MethodHook() { - override fun afterHookedMethod(param: MethodHookParam) { - try { - if (mContext == null) { - mContext = param.args[2] as Context - - HookRes.modRes = mContext!!.createPackageContext( - BuildConfig.APPLICATION_ID, - Context.CONTEXT_IGNORE_SECURITY - ).resources - - XPrefs.init(mContext!!) - - waitForXprefsLoad(loadPackageParam) + if (!isChildProcess) { + findAndHookMethod( + Instrumentation::class.java, + "newApplication", + ClassLoader::class.java, + String::class.java, + Context::class.java, + object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + try { + if (mContext == null) { + mContext = param.args[2] as Context + + HookRes.modRes = mContext!!.createPackageContext( + BuildConfig.APPLICATION_ID, + Context.CONTEXT_IGNORE_SECURITY + ).resources + + XPrefs.init(mContext!!) + + waitForXprefsLoad(loadPackageParam) + } + } catch (throwable: Throwable) { + log(TAG + throwable) } - } catch (throwable: Throwable) { - log(throwable) } } - } - ) + ) + } } } } private fun onXPrefsReady(loadPackageParam: LoadPackageParam) { - if (BootLoopProtector.isBootLooped(loadPackageParam.packageName)) { + if (!isChildProcess && BootLoopProtector.isBootLooped(loadPackageParam.packageName)) { log("Possible bootloop in ${loadPackageParam.packageName} ; Iconify will not load for now...") return } - SystemUtil(mContext!!) + SystemUtils(mContext!!) loadModPacks(loadPackageParam) } private fun loadModPacks(loadPackageParam: LoadPackageParam) { + if (HookRes.modRes + .getStringArray(R.array.root_requirement) + .toList() + .contains(loadPackageParam.packageName) + ) { + forceConnectRootService() + } + for (mod in EntryList.getEntries(loadPackageParam.packageName)) { try { val instance = mod.getConstructor(Context::class.java).newInstance(mContext) @@ -122,7 +143,7 @@ class HookEntry : IXposedHookLoadPackage { runningMods.add(instance) } catch (throwable: Throwable) { log("Start Error Dump - Occurred in ${mod.name}") - log(tag + throwable) + log(TAG + throwable) } } } @@ -130,13 +151,10 @@ class HookEntry : IXposedHookLoadPackage { private fun waitForXprefsLoad(loadPackageParam: LoadPackageParam) { while (true) { try { - Xprefs?.getBoolean("LoadTestBooleanValue", false) + Xprefs.getBoolean("LoadTestBooleanValue", false) break } catch (ignored: Throwable) { - try { - Thread.sleep(1000) - } catch (ignored1: Throwable) { - } + SystemUtils.sleep(1000); } } @@ -144,4 +162,97 @@ class HookEntry : IXposedHookLoadPackage { onXPrefsReady(loadPackageParam) } + + private fun forceConnectRootService() { + CoroutineScope(Dispatchers.Main).launch { + val mUserManager = mContext!!.getSystemService(Context.USER_SERVICE) as UserManager? + + withContext(Dispatchers.IO) { + while (mUserManager == null || !mUserManager.isUserUnlocked) { + // device is still CE encrypted + delay(2000) + } + + delay(5000) // wait for the unlocked account to settle down a bit + + while (rootProxyIPC == null) { + connectRootService() + delay(5000) + } + } + } + } + + private fun connectRootService() { + try { + val intent = Intent().apply { + component = ComponentName( + BuildConfig.APPLICATION_ID, + "${ + BuildConfig.APPLICATION_ID.replace( + ".debug", + "" + ) + }.services.RootProviderProxy" + ) + } + + mContext!!.bindService( + intent, + instance!!, + Context.BIND_AUTO_CREATE or Context.BIND_ADJUST_WITH_ACTIVITY + ) + } catch (throwable: Throwable) { + log(TAG + throwable) + } + } + + override fun onServiceConnected(name: ComponentName?, service: IBinder?) { + rootProxyIPC = IRootProviderProxy.Stub.asInterface(service) + + synchronized(proxyQueue) { + while (!proxyQueue.isEmpty()) { + try { + proxyQueue.poll()!!.run(rootProxyIPC) + } catch (ignored: Throwable) { + } + } + } + } + + override fun onServiceDisconnected(name: ComponentName?) { + rootProxyIPC = null + forceConnectRootService() + } + + fun interface ProxyRunnable { + @Throws(RemoteException::class) + fun run(proxy: IRootProviderProxy?) + } + + companion object { + private val TAG = "Iconify - ${HookEntry::class.java.simpleName}: " + + @SuppressLint("StaticFieldLeak") + var instance: HookEntry? = null + val runningMods = ArrayList() + var isChildProcess = false + var rootProxyIPC: IRootProviderProxy? = null + val proxyQueue: Queue = LinkedList() + + fun enqueueProxyCommand(runnable: ProxyRunnable) { + rootProxyIPC?.let { + try { + runnable.run(it) + } catch (ignored: RemoteException) { + } + } ?: run { + synchronized(proxyQueue) { + proxyQueue.add(runnable) + } + + instance!!.forceConnectRootService() + } + } + } } diff --git a/app/src/main/java/com/drdisagree/iconify/xposed/HookRes.kt b/app/src/main/java/com/drdisagree/iconify/xposed/HookRes.kt index 31e2730ca..459dbdf9c 100644 --- a/app/src/main/java/com/drdisagree/iconify/xposed/HookRes.kt +++ b/app/src/main/java/com/drdisagree/iconify/xposed/HookRes.kt @@ -18,7 +18,7 @@ class HookRes : IXposedHookInitPackageResources, IXposedHookZygoteInit { } companion object { - var modRes: Resources? = null + lateinit var modRes: Resources val resParams = HashMap() } } \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/xposed/modules/BackgroundChip.kt b/app/src/main/java/com/drdisagree/iconify/xposed/modules/BackgroundChip.kt index 6dd147b99..791dc9260 100644 --- a/app/src/main/java/com/drdisagree/iconify/xposed/modules/BackgroundChip.kt +++ b/app/src/main/java/com/drdisagree/iconify/xposed/modules/BackgroundChip.kt @@ -8,36 +8,75 @@ import android.graphics.PorterDuff import android.graphics.PorterDuffXfermode import android.os.Build import android.os.Bundle -import android.util.Log import android.util.TypedValue import android.view.Gravity import android.view.View import android.view.ViewGroup import android.widget.FrameLayout import android.widget.LinearLayout -import android.widget.RelativeLayout import android.widget.TextView import androidx.constraintlayout.widget.ConstraintLayout import androidx.constraintlayout.widget.ConstraintSet -import androidx.core.content.res.ResourcesCompat -import com.drdisagree.iconify.BuildConfig -import com.drdisagree.iconify.R import com.drdisagree.iconify.common.Const.SYSTEMUI_PACKAGE -import com.drdisagree.iconify.common.Preferences.CHIP_QSSTATUSICONS_STYLE -import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCKBG_STYLE +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_ACCENT +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_END_COLOR +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_GRADIENT_DIRECTION +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_PADDING_BOTTOM +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_PADDING_LEFT +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_PADDING_RIGHT +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_PADDING_TOP +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_RADIUS_BOTTOM_LEFT +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_RADIUS_BOTTOM_RIGHT +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_RADIUS_TOP_LEFT +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_RADIUS_TOP_RIGHT +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_START_COLOR +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_STROKE_ACCENT +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_STROKE_COLOR +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_STROKE_DASH +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_STROKE_DASH_GAP +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_STROKE_DASH_WIDTH +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_STROKE_SWITCH +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_STROKE_WIDTH +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_STYLE_CHANGED +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_SWITCH +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_TEXT_COLOR_CODE +import com.drdisagree.iconify.common.Preferences.CHIP_STATUSBAR_CLOCK_TEXT_COLOR_OPTION +import com.drdisagree.iconify.common.Preferences.CHIP_STATUS_ICONS_ACCENT +import com.drdisagree.iconify.common.Preferences.CHIP_STATUS_ICONS_END_COLOR +import com.drdisagree.iconify.common.Preferences.CHIP_STATUS_ICONS_GRADIENT_DIRECTION +import com.drdisagree.iconify.common.Preferences.CHIP_STATUS_ICONS_PADDING_BOTTOM +import com.drdisagree.iconify.common.Preferences.CHIP_STATUS_ICONS_PADDING_LEFT +import com.drdisagree.iconify.common.Preferences.CHIP_STATUS_ICONS_PADDING_RIGHT +import com.drdisagree.iconify.common.Preferences.CHIP_STATUS_ICONS_PADDING_TOP +import com.drdisagree.iconify.common.Preferences.CHIP_STATUS_ICONS_RADIUS_BOTTOM_LEFT +import com.drdisagree.iconify.common.Preferences.CHIP_STATUS_ICONS_RADIUS_BOTTOM_RIGHT +import com.drdisagree.iconify.common.Preferences.CHIP_STATUS_ICONS_RADIUS_TOP_LEFT +import com.drdisagree.iconify.common.Preferences.CHIP_STATUS_ICONS_RADIUS_TOP_RIGHT +import com.drdisagree.iconify.common.Preferences.CHIP_STATUS_ICONS_START_COLOR +import com.drdisagree.iconify.common.Preferences.CHIP_STATUS_ICONS_STROKE_ACCENT +import com.drdisagree.iconify.common.Preferences.CHIP_STATUS_ICONS_STROKE_COLOR +import com.drdisagree.iconify.common.Preferences.CHIP_STATUS_ICONS_STROKE_DASH +import com.drdisagree.iconify.common.Preferences.CHIP_STATUS_ICONS_STROKE_DASH_GAP +import com.drdisagree.iconify.common.Preferences.CHIP_STATUS_ICONS_STROKE_DASH_WIDTH +import com.drdisagree.iconify.common.Preferences.CHIP_STATUS_ICONS_STROKE_SWITCH +import com.drdisagree.iconify.common.Preferences.CHIP_STATUS_ICONS_STROKE_WIDTH +import com.drdisagree.iconify.common.Preferences.CHIP_STATUS_ICONS_STYLE_CHANGED +import com.drdisagree.iconify.common.Preferences.CHIP_STATUS_ICONS_SWITCH import com.drdisagree.iconify.common.Preferences.FIXED_STATUS_ICONS_SIDEMARGIN import com.drdisagree.iconify.common.Preferences.FIXED_STATUS_ICONS_SWITCH import com.drdisagree.iconify.common.Preferences.FIXED_STATUS_ICONS_TOPMARGIN import com.drdisagree.iconify.common.Preferences.HEADER_CLOCK_SWITCH import com.drdisagree.iconify.common.Preferences.HIDE_STATUS_ICONS_SWITCH -import com.drdisagree.iconify.common.Preferences.QSPANEL_STATUSICONSBG_SWITCH -import com.drdisagree.iconify.common.Preferences.STATUSBAR_CLOCKBG_SWITCH -import com.drdisagree.iconify.common.Preferences.STATUSBAR_CLOCK_COLOR_CODE -import com.drdisagree.iconify.common.Preferences.STATUSBAR_CLOCK_COLOR_OPTION -import com.drdisagree.iconify.config.XPrefs.Xprefs import com.drdisagree.iconify.xposed.HookRes.Companion.resParams import com.drdisagree.iconify.xposed.ModPack +import com.drdisagree.iconify.xposed.modules.utils.Helpers.findClassInArray +import com.drdisagree.iconify.xposed.modules.utils.StatusBarClock +import com.drdisagree.iconify.xposed.modules.utils.StatusBarClock.setClockGravity import com.drdisagree.iconify.xposed.modules.utils.ViewHelper.toPx +import com.drdisagree.iconify.xposed.modules.views.ChipDrawable +import com.drdisagree.iconify.xposed.modules.views.ChipDrawable.GradientDirection.Companion.toIndex +import com.drdisagree.iconify.xposed.utils.XPrefs.Xprefs +import com.drdisagree.iconify.xposed.utils.XPrefs.XprefsIsInitialized import de.robv.android.xposed.XC_MethodHook import de.robv.android.xposed.XposedBridge.hookAllMethods import de.robv.android.xposed.XposedBridge.log @@ -62,8 +101,6 @@ class BackgroundChip(context: Context?) : ModPack(context!!) { private var showHeaderClock = false private var topMarginStatusIcons = 8 private var sideMarginStatusIcons = 0 - private var qsStatusIconsChipStyle = 0 - private var statusBarClockChipStyle = 0 private var statusBarClockColorOption = 0 private var statusBarClockColorCode = Color.WHITE private var fixedStatusIcons = false @@ -75,65 +112,165 @@ class BackgroundChip(context: Context?) : ModPack(context!!) { private var dependencyClass: Class<*>? = null private var darkIconDispatcherClass: Class<*>? = null private var mLoadPackageParam: LoadPackageParam? = null + private var accentFillEnabled: Boolean = true + private var startColor: Int = Color.RED + private var endColor: Int = Color.BLUE + private var gradientDirection: ChipDrawable.GradientDirection = + ChipDrawable.GradientDirection.LEFT_RIGHT + private var padding: IntArray = intArrayOf(8, 4, 8, 4) + private var strokeEnabled: Boolean = false + private var strokeWidth: Int = 2 + private var accentBorderEnabled: Boolean = true + private var strokeColor: Int = Color.GREEN + private var dashedBorderEnabled: Boolean = false + private var strokeDashWidth: Int = 4 + private var strokeDashGap: Int = 4 + private var cornerRadii: FloatArray = floatArrayOf(28f, 28f, 28f, 28f, 28f, 28f, 28f, 28f) + private var accentFillEnabled2: Boolean = true + private var startColor2: Int = Color.RED + private var endColor2: Int = Color.BLUE + private var gradientDirection2: ChipDrawable.GradientDirection = + ChipDrawable.GradientDirection.LEFT_RIGHT + private var padding2: IntArray = intArrayOf(8, 4, 8, 4) + private var strokeEnabled2: Boolean = false + private var strokeWidth2: Int = 2 + private var accentBorderEnabled2: Boolean = true + private var strokeColor2: Int = Color.GREEN + private var dashedBorderEnabled2: Boolean = false + private var strokeDashWidth2: Int = 4 + private var strokeDashGap2: Int = 4 + private var cornerRadii2: FloatArray = floatArrayOf(28f, 28f, 28f, 28f, 28f, 28f, 28f, 28f) override fun updatePrefs(vararg key: String) { - if (Xprefs == null) return - - mShowSBClockBg = Xprefs!!.getBoolean(STATUSBAR_CLOCKBG_SWITCH, false) - mShowQSStatusIconsBg = Xprefs!!.getBoolean(QSPANEL_STATUSICONSBG_SWITCH, false) - qsStatusIconsChipStyle = Xprefs!!.getInt(CHIP_QSSTATUSICONS_STYLE, 0) - statusBarClockChipStyle = Xprefs!!.getInt(CHIP_STATUSBAR_CLOCKBG_STYLE, 0) - statusBarClockColorOption = Xprefs!!.getInt(STATUSBAR_CLOCK_COLOR_OPTION, 0) - statusBarClockColorCode = Xprefs!!.getInt(STATUSBAR_CLOCK_COLOR_CODE, Color.WHITE) - showHeaderClock = Xprefs!!.getBoolean(HEADER_CLOCK_SWITCH, false) - hideStatusIcons = Xprefs!!.getBoolean(HIDE_STATUS_ICONS_SWITCH, false) - fixedStatusIcons = Xprefs!!.getBoolean(FIXED_STATUS_ICONS_SWITCH, false) - topMarginStatusIcons = Xprefs!!.getInt(FIXED_STATUS_ICONS_TOPMARGIN, 8) - sideMarginStatusIcons = Xprefs!!.getInt(FIXED_STATUS_ICONS_SIDEMARGIN, 0) + if (!XprefsIsInitialized) return + + Xprefs.apply { + // Status bar clock chip + mShowSBClockBg = getBoolean(CHIP_STATUSBAR_CLOCK_SWITCH, false) + statusBarClockColorOption = getInt(CHIP_STATUSBAR_CLOCK_TEXT_COLOR_OPTION, 0) + statusBarClockColorCode = getInt(CHIP_STATUSBAR_CLOCK_TEXT_COLOR_CODE, Color.WHITE) + accentFillEnabled = getBoolean(CHIP_STATUSBAR_CLOCK_ACCENT, true) + startColor = getInt(CHIP_STATUSBAR_CLOCK_START_COLOR, Color.RED) + endColor = getInt(CHIP_STATUSBAR_CLOCK_END_COLOR, Color.BLUE) + gradientDirection = + ChipDrawable.GradientDirection.fromIndex( + getInt( + CHIP_STATUSBAR_CLOCK_GRADIENT_DIRECTION, + ChipDrawable.GradientDirection.LEFT_RIGHT.toIndex() + ) + ) + padding = intArrayOf( + getInt(CHIP_STATUSBAR_CLOCK_PADDING_LEFT, 8), + getInt(CHIP_STATUSBAR_CLOCK_PADDING_TOP, 4), + getInt(CHIP_STATUSBAR_CLOCK_PADDING_RIGHT, 8), + getInt(CHIP_STATUSBAR_CLOCK_PADDING_BOTTOM, 4) + ) + strokeEnabled = getBoolean(CHIP_STATUSBAR_CLOCK_STROKE_SWITCH) + strokeWidth = getInt(CHIP_STATUSBAR_CLOCK_STROKE_WIDTH, 2) + accentBorderEnabled = getBoolean(CHIP_STATUSBAR_CLOCK_STROKE_ACCENT, true) + strokeColor = getInt(CHIP_STATUSBAR_CLOCK_STROKE_COLOR, Color.GREEN) + dashedBorderEnabled = getBoolean(CHIP_STATUSBAR_CLOCK_STROKE_DASH) + strokeDashWidth = getInt(CHIP_STATUSBAR_CLOCK_STROKE_DASH_WIDTH, 4) + strokeDashGap = getInt(CHIP_STATUSBAR_CLOCK_STROKE_DASH_GAP, 4) + cornerRadii = floatArrayOf( + getInt(CHIP_STATUSBAR_CLOCK_RADIUS_TOP_LEFT, 28).toFloat(), + getInt(CHIP_STATUSBAR_CLOCK_RADIUS_TOP_LEFT, 28).toFloat(), + getInt(CHIP_STATUSBAR_CLOCK_RADIUS_TOP_RIGHT, 28).toFloat(), + getInt(CHIP_STATUSBAR_CLOCK_RADIUS_TOP_RIGHT, 28).toFloat(), + getInt(CHIP_STATUSBAR_CLOCK_RADIUS_BOTTOM_RIGHT, 28).toFloat(), + getInt(CHIP_STATUSBAR_CLOCK_RADIUS_BOTTOM_RIGHT, 28).toFloat(), + getInt(CHIP_STATUSBAR_CLOCK_RADIUS_BOTTOM_LEFT, 28).toFloat(), + getInt(CHIP_STATUSBAR_CLOCK_RADIUS_BOTTOM_LEFT, 28).toFloat(), + ) + + // Status icons chip + mShowQSStatusIconsBg = getBoolean(CHIP_STATUS_ICONS_SWITCH, false) + accentFillEnabled2 = getBoolean(CHIP_STATUS_ICONS_ACCENT, true) + startColor2 = getInt(CHIP_STATUS_ICONS_START_COLOR, Color.RED) + endColor2 = getInt(CHIP_STATUS_ICONS_END_COLOR, Color.BLUE) + gradientDirection2 = + ChipDrawable.GradientDirection.fromIndex( + getInt( + CHIP_STATUS_ICONS_GRADIENT_DIRECTION, + ChipDrawable.GradientDirection.LEFT_RIGHT.toIndex() + ) + ) + padding2 = intArrayOf( + getInt(CHIP_STATUS_ICONS_PADDING_LEFT, 8), + getInt(CHIP_STATUS_ICONS_PADDING_TOP, 4), + getInt(CHIP_STATUS_ICONS_PADDING_RIGHT, 8), + getInt(CHIP_STATUS_ICONS_PADDING_BOTTOM, 4) + ) + strokeEnabled2 = getBoolean(CHIP_STATUS_ICONS_STROKE_SWITCH) + strokeWidth2 = getInt(CHIP_STATUS_ICONS_STROKE_WIDTH, 2) + accentBorderEnabled2 = getBoolean(CHIP_STATUS_ICONS_STROKE_ACCENT, true) + strokeColor2 = getInt(CHIP_STATUS_ICONS_STROKE_COLOR, Color.GREEN) + dashedBorderEnabled2 = getBoolean(CHIP_STATUS_ICONS_STROKE_DASH) + strokeDashWidth2 = getInt(CHIP_STATUS_ICONS_STROKE_DASH_WIDTH, 4) + strokeDashGap2 = getInt(CHIP_STATUS_ICONS_STROKE_DASH_GAP, 4) + cornerRadii2 = floatArrayOf( + getInt(CHIP_STATUS_ICONS_RADIUS_TOP_LEFT, 28).toFloat(), + getInt(CHIP_STATUS_ICONS_RADIUS_TOP_LEFT, 28).toFloat(), + getInt(CHIP_STATUS_ICONS_RADIUS_TOP_RIGHT, 28).toFloat(), + getInt(CHIP_STATUS_ICONS_RADIUS_TOP_RIGHT, 28).toFloat(), + getInt(CHIP_STATUS_ICONS_RADIUS_BOTTOM_RIGHT, 28).toFloat(), + getInt(CHIP_STATUS_ICONS_RADIUS_BOTTOM_RIGHT, 28).toFloat(), + getInt(CHIP_STATUS_ICONS_RADIUS_BOTTOM_LEFT, 28).toFloat(), + getInt(CHIP_STATUS_ICONS_RADIUS_BOTTOM_LEFT, 28).toFloat(), + ) + + // Others + showHeaderClock = getBoolean(HEADER_CLOCK_SWITCH, false) + hideStatusIcons = getBoolean(HIDE_STATUS_ICONS_SWITCH, false) + fixedStatusIcons = getBoolean(FIXED_STATUS_ICONS_SWITCH, false) + topMarginStatusIcons = getSliderInt(FIXED_STATUS_ICONS_TOPMARGIN, 8) + sideMarginStatusIcons = getSliderInt(FIXED_STATUS_ICONS_SIDEMARGIN, 0) + } if (key.isNotEmpty()) { - if (key[0] == STATUSBAR_CLOCKBG_SWITCH || - key[0] == CHIP_STATUSBAR_CLOCKBG_STYLE || - key[0] == STATUSBAR_CLOCK_COLOR_OPTION || - key[0] == STATUSBAR_CLOCK_COLOR_CODE + if (key[0] == CHIP_STATUSBAR_CLOCK_SWITCH || + key[0] == CHIP_STATUSBAR_CLOCK_STYLE_CHANGED ) { - updateStatusBarClock() + updateStatusBarClock(true) } - if (key[0] == QSPANEL_STATUSICONSBG_SWITCH || - key[0] == CHIP_STATUSBAR_CLOCKBG_STYLE || - key[0] == HEADER_CLOCK_SWITCH || - key[0] == HIDE_STATUS_ICONS_SWITCH || - key[0] == FIXED_STATUS_ICONS_SWITCH - ) { - setQSStatusIconsBgA12() - } + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { + if (key[0] == CHIP_STATUS_ICONS_SWITCH || + key[0] == CHIP_STATUS_ICONS_STYLE_CHANGED || + key[0] == HEADER_CLOCK_SWITCH || + key[0] == HIDE_STATUS_ICONS_SWITCH || + key[0] == FIXED_STATUS_ICONS_SWITCH + ) { + setQSStatusIconsBgA12() + } - if (key[0] == CHIP_QSSTATUSICONS_STYLE || - key[0] == FIXED_STATUS_ICONS_TOPMARGIN || - key[0] == FIXED_STATUS_ICONS_SIDEMARGIN - ) { - updateStatusIcons() + if (key[0] == CHIP_STATUS_ICONS_SWITCH || + key[0] == CHIP_STATUS_ICONS_STYLE_CHANGED || + key[0] == FIXED_STATUS_ICONS_TOPMARGIN || + key[0] == FIXED_STATUS_ICONS_SIDEMARGIN + ) { + updateStatusIcons() + } } } } override fun handleLoadPackage(loadPackageParam: LoadPackageParam) { mLoadPackageParam = loadPackageParam - statusbarClockChip(loadPackageParam) - statusIconsChip(loadPackageParam) + statusBarClockChip(loadPackageParam) + + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { + statusIconsChip(loadPackageParam) + } } - private fun statusbarClockChip(loadPackageParam: LoadPackageParam) { - var collapsedStatusBarFragment = findClassIfExists( - "$SYSTEMUI_PACKAGE.statusbar.phone.fragment.CollapsedStatusBarFragment", - loadPackageParam.classLoader + private fun statusBarClockChip(loadPackageParam: LoadPackageParam) { + val collapsedStatusBarFragment = findClassInArray( + loadPackageParam.classLoader, + "$SYSTEMUI_PACKAGE.statusbar.phone.CollapsedStatusBarFragment", + "$SYSTEMUI_PACKAGE.statusbar.phone.fragment.CollapsedStatusBarFragment" + ) - if (collapsedStatusBarFragment == null) collapsedStatusBarFragment = - findClass( - "$SYSTEMUI_PACKAGE.statusbar.phone.CollapsedStatusBarFragment", - loadPackageParam.classLoader - ) dependencyClass = findClass( "$SYSTEMUI_PACKAGE.Dependency", loadPackageParam.classLoader @@ -150,18 +287,18 @@ class BackgroundChip(context: Context?) : ModPack(context!!) { Bundle::class.java, object : XC_MethodHook() { override fun afterHookedMethod(param: MethodHookParam) { - mClockView = getLeftClockView(param) - mCenterClockView = getCenterClockView(param) - mRightClockView = getRightClockView(param) + mClockView = StatusBarClock.getLeftClockView(mContext, param) + mCenterClockView = StatusBarClock.getCenterClockView(mContext, param) + mRightClockView = StatusBarClock.getRightClockView(mContext, param) (getObjectField( param.thisObject, "mStatusBar" ) as ViewGroup).addOnLayoutChangeListener { _, _, _, _, _, _, _, _, _ -> - updateStatusBarClock() + updateStatusBarClock(false) } - updateStatusBarClock() + updateStatusBarClock(true) if (mShowSBClockBg) { try { @@ -178,9 +315,12 @@ class BackgroundChip(context: Context?) : ModPack(context!!) { mContext.packageName ) ) - statusBarStartSideContent.layoutParams.height = - FrameLayout.LayoutParams.MATCH_PARENT - statusBarStartSideContent.requestLayout() + + statusBarStartSideContent.post { + statusBarStartSideContent.layoutParams.height = + FrameLayout.LayoutParams.MATCH_PARENT + statusBarStartSideContent.requestLayout() + } val statusBarStartSideExceptHeadsUp = mStatusBar.findViewById( @@ -190,8 +330,12 @@ class BackgroundChip(context: Context?) : ModPack(context!!) { mContext.packageName ) ) - (statusBarStartSideExceptHeadsUp.layoutParams as FrameLayout.LayoutParams).gravity = - Gravity.START or Gravity.CENTER + + statusBarStartSideExceptHeadsUp.post { + (statusBarStartSideExceptHeadsUp.layoutParams as FrameLayout.LayoutParams).gravity = + Gravity.START or Gravity.CENTER + } + statusBarStartSideExceptHeadsUp.gravity = Gravity.START or Gravity.CENTER statusBarStartSideExceptHeadsUp.requestLayout() @@ -203,212 +347,74 @@ class BackgroundChip(context: Context?) : ModPack(context!!) { }) } - private fun getLeftClockView(param: XC_MethodHook.MethodHookParam) = try { - getObjectField(param.thisObject, "mClockView") as View - } catch (throwable1: Throwable) { - try { - getObjectField(param.thisObject, "mLeftClock") as View - } catch (throwable2: Throwable) { - try { - callMethod( - getObjectField( - param.thisObject, - "mClockController" - ), - "getClock" - ) as View - } catch (throwable3: Throwable) { - try { - val mActiveClock = getObjectField( - getObjectField( - param.thisObject, - "mClockController" - ), - "mActiveClock" - ) as View - val mLeftClockId = mContext.resources.getIdentifier( - "clock", - "id", - mContext.packageName - ) - - if (mActiveClock.id == mLeftClockId) { - mActiveClock - } else { - null - } - } catch (throwable4: Throwable) { - log(TAG + throwable4) - null - } - } - } - } - - private fun getCenterClockView(param: XC_MethodHook.MethodHookParam) = try { - getObjectField(param.thisObject, "mCenterClockView") as View - } catch (throwable1: Throwable) { - try { - getObjectField( - param.thisObject, - "mCenterClock" - ) as View - } catch (throwable2: Throwable) { - try { - callMethod( - getObjectField( - param.thisObject, - "mClockController" - ), - "mCenterClockView" - ) as View - } catch (throwable3: Throwable) { - try { - val mActiveClock = getObjectField( - getObjectField( - param.thisObject, - "mClockController" - ), - "mActiveClock" - ) as View - val mCenterClockId = mContext.resources.getIdentifier( - "clock_center", - "id", - mContext.packageName - ) - - if (mActiveClock.id == mCenterClockId) { - mActiveClock - } else { - null - } - } catch (throwable4: Throwable) { - try { - (getObjectField( - param.thisObject, - "mCenterClockLayout" - ) as LinearLayout).getChildAt(0) - } catch (throwable5: Throwable) { - null - } - } - } - } - } - - private fun getRightClockView(param: XC_MethodHook.MethodHookParam) = try { - getObjectField(param.thisObject, "mRightClockView") as View - } catch (throwable1: Throwable) { - try { - getObjectField(param.thisObject, "mRightClock") as View - } catch (throwable2: Throwable) { - try { - callMethod( - getObjectField( - param.thisObject, - "mClockController" - ), - "mRightClockView" - ) as View - } catch (throwable3: Throwable) { - try { - val mActiveClock = getObjectField( - getObjectField( - param.thisObject, - "mClockController" - ), - "mActiveClock" - ) as View - val mRightClockId = mContext.resources.getIdentifier( - "clock_right", - "id", - mContext.packageName - ) - - if (mActiveClock.id == mRightClockId) { - mActiveClock - } else { - null - } - } catch (throwable4: Throwable) { - null - } - } - } - } - private fun statusIconsChip(loadPackageParam: LoadPackageParam) { setQSStatusIconsBgA12() setQSStatusIconsBgA13Plus(loadPackageParam) } @SuppressLint("RtlHardcoded") - private fun updateStatusBarClock() { + private fun updateStatusBarClock(force: Boolean) { if (!mShowSBClockBg) return - val clockPaddingStartEnd: Int = mContext.toPx(8) - val clockPaddingTopBottom: Int = mContext.toPx(2) - - updateClockView( - mClockView, - clockPaddingStartEnd, - clockPaddingTopBottom, - Gravity.LEFT or Gravity.CENTER - ) + if (mClockView != null && mClockView!!.background == null || force) { + updateClockView( + mClockView, + Gravity.LEFT or Gravity.CENTER + ) + } - updateClockView( - mCenterClockView, - clockPaddingStartEnd, - clockPaddingTopBottom, - Gravity.CENTER - ) + if (mCenterClockView != null && mCenterClockView!!.background == null || force) { + updateClockView( + mCenterClockView, + Gravity.CENTER + ) + } - updateClockView( - mRightClockView, - clockPaddingStartEnd, - clockPaddingTopBottom, - Gravity.RIGHT or Gravity.CENTER - ) + if (mRightClockView != null && mRightClockView!!.background == null || force) { + updateClockView( + mRightClockView, + Gravity.RIGHT or Gravity.CENTER + ) + } } private fun updateStatusIcons() { if (mQsStatusIconsContainer.childCount == 0) return - val paddingTopBottom: Int = mContext.toPx(4) - val paddingStartEnd: Int = mContext.toPx(12) - if (mShowQSStatusIconsBg) { setStatusIconsBackgroundChip(mQsStatusIconsContainer) mQsStatusIconsContainer.setPadding( - paddingStartEnd, - paddingTopBottom, - paddingStartEnd, - paddingTopBottom + mContext.toPx(padding2[0]), + mContext.toPx(padding2[1]), + mContext.toPx(padding2[2]), + mContext.toPx(padding2[3]) ) } if (mQsStatusIconsContainer.layoutParams is FrameLayout.LayoutParams) { - (mQsStatusIconsContainer.layoutParams as FrameLayout.LayoutParams).setMargins( - 0, - mContext.toPx(topMarginStatusIcons), - 0, - 0 - ) + mQsStatusIconsContainer.post { + (mQsStatusIconsContainer.layoutParams as FrameLayout.LayoutParams).setMargins( + 0, + mContext.toPx(topMarginStatusIcons), + 0, + 0 + ) - (mQsStatusIconsContainer.layoutParams as FrameLayout.LayoutParams).setMarginEnd( - mContext.toPx(sideMarginStatusIcons) - ) + (mQsStatusIconsContainer.layoutParams as FrameLayout.LayoutParams).marginEnd = + mContext.toPx(sideMarginStatusIcons) + } } else if (mQsStatusIconsContainer.layoutParams is LinearLayout.LayoutParams) { - (mQsStatusIconsContainer.layoutParams as LinearLayout.LayoutParams).setMargins( - 0, - mContext.toPx(topMarginStatusIcons), - 0, - 0 - ) + mQsStatusIconsContainer.post { + (mQsStatusIconsContainer.layoutParams as LinearLayout.LayoutParams).setMargins( + 0, + mContext.toPx(topMarginStatusIcons), + 0, + 0 + ) - (mQsStatusIconsContainer.layoutParams as LinearLayout.LayoutParams).setMarginEnd( - mContext.toPx(sideMarginStatusIcons) - ) + (mQsStatusIconsContainer.layoutParams as LinearLayout.LayoutParams).marginEnd = + mContext.toPx(sideMarginStatusIcons) + } } else if (mLoadPackageParam != null && header != null && constraintLayoutId != -1) { try { val constraintSetClass = findClass( @@ -472,65 +478,60 @@ class BackgroundChip(context: Context?) : ModPack(context!!) { } private fun setSBClockBackgroundChip(view: View) { - try { - val pc = mContext.createPackageContext( - BuildConfig.APPLICATION_ID, - Context.CONTEXT_IGNORE_SECURITY + if (mShowSBClockBg) { + view.background = ChipDrawable.createChipDrawable( + context = mContext, + accentFill = accentFillEnabled, + startColor = startColor, + endColor = endColor, + gradientDirection = gradientDirection, + padding = intArrayOf(0, 0, 0, 0), + strokeEnabled = strokeEnabled, + accentStroke = accentBorderEnabled, + strokeWidth = strokeWidth, + strokeColor = strokeColor, + dashedBorderEnabled = dashedBorderEnabled, + dashWidth = strokeDashWidth, + dashGap = strokeDashGap, + cornerRadii = cornerRadii ) - - val res = pc.resources - - val bg = when (statusBarClockChipStyle) { - 0 -> ResourcesCompat.getDrawable(res, R.drawable.chip_status_bar_1, pc.theme) - 1 -> ResourcesCompat.getDrawable(res, R.drawable.chip_status_bar_2, pc.theme) - 2 -> ResourcesCompat.getDrawable(res, R.drawable.chip_status_bar_3, pc.theme) - 3 -> ResourcesCompat.getDrawable(res, R.drawable.chip_status_bar_4, pc.theme) - 4 -> ResourcesCompat.getDrawable(res, R.drawable.chip_status_bar_5, pc.theme) - 5 -> ResourcesCompat.getDrawable(res, R.drawable.chip_status_bar_6, pc.theme) - 6 -> ResourcesCompat.getDrawable(res, R.drawable.chip_status_bar_7, pc.theme) - else -> null - } - - if (bg != null) { - view.background = bg - } - } catch (throwable: Throwable) { - log(TAG + throwable) + } else { + view.background = null } } private fun setStatusIconsBackgroundChip(layout: LinearLayout) { - try { - val pc = mContext.createPackageContext( - BuildConfig.APPLICATION_ID, - Context.CONTEXT_IGNORE_SECURITY + if (mShowQSStatusIconsBg) { + layout.background = ChipDrawable.createChipDrawable( + context = mContext, + accentFill = accentFillEnabled2, + startColor = startColor2, + endColor = endColor2, + gradientDirection = gradientDirection2, + padding = intArrayOf(0, 0, 0, 0), + strokeEnabled = strokeEnabled2, + accentStroke = accentBorderEnabled2, + strokeWidth = strokeWidth2, + strokeColor = strokeColor2, + dashedBorderEnabled = dashedBorderEnabled2, + dashWidth = strokeDashWidth2, + dashGap = strokeDashGap2, + cornerRadii = cornerRadii2 ) - - val res = pc.resources - - val bg = when (qsStatusIconsChipStyle) { - 0 -> ResourcesCompat.getDrawable(res, R.drawable.chip_status_icons_1, pc.theme) - 1 -> ResourcesCompat.getDrawable(res, R.drawable.chip_status_icons_2, pc.theme) - 2 -> ResourcesCompat.getDrawable(res, R.drawable.chip_status_icons_3, pc.theme) - 3 -> ResourcesCompat.getDrawable(res, R.drawable.chip_status_icons_4, pc.theme) - 4 -> ResourcesCompat.getDrawable(res, R.drawable.chip_status_icons_5, pc.theme) - 5 -> ResourcesCompat.getDrawable(res, R.drawable.chip_status_icons_6, pc.theme) - else -> null - } - - if (bg != null) { - layout.background = bg - } - } catch (throwable: Throwable) { - log(TAG + throwable) + } else { + layout.background = null } } - @SuppressLint("RtlHardcoded") - private fun updateClockView(clockView: View?, startEnd: Int, topBottom: Int, gravity: Int) { + private fun updateClockView(clockView: View?, gravity: Int) { if (clockView == null) return - clockView.setPadding(startEnd, topBottom, startEnd, topBottom) + clockView.setPadding( + mContext.toPx(padding[0]), + mContext.toPx(padding[1]), + mContext.toPx(padding[2]), + mContext.toPx(padding[3]) + ) setSBClockBackgroundChip(clockView) @@ -567,10 +568,10 @@ class BackgroundChip(context: Context?) : ModPack(context!!) { (clockView as TextView).paint.setXfermode(null) try { callMethod( - callStaticMethod(dependencyClass, "get", darkIconDispatcherClass), - "removeDarkReceiver", - clockView - ) + callStaticMethod(dependencyClass, "get", darkIconDispatcherClass), + "removeDarkReceiver", + clockView + ) } catch (ignored: Throwable) { callMethod( callMethod( @@ -589,55 +590,7 @@ class BackgroundChip(context: Context?) : ModPack(context!!) { } } - val layoutParams = clockView.layoutParams - when (layoutParams) { - is LinearLayout.LayoutParams, -> { - layoutParams.gravity = gravity - } - - is FrameLayout.LayoutParams -> { - layoutParams.gravity = gravity - } - - is RelativeLayout.LayoutParams -> { - when (gravity) { - Gravity.LEFT or Gravity.CENTER -> { - layoutParams.addRule(RelativeLayout.CENTER_VERTICAL) - layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT) - } - - Gravity.CENTER -> { - layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT) - } - - Gravity.RIGHT or Gravity.CENTER -> { - layoutParams.addRule(RelativeLayout.CENTER_VERTICAL) - layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT) - } - - else -> { - Log.w( - "$TAG LayoutParamsCheck", - "Unsupported gravity type for RelativeLayout: $gravity" - ) - } - } - } - - else -> { - Log.w( - "$TAG LayoutParamsCheck", - "Unknown LayoutParams type: ${layoutParams.javaClass.name}" - ) - } - } - clockView.layoutParams = layoutParams - - (clockView as TextView).includeFontPadding = false - clockView.getLayoutParams().height = ViewGroup.LayoutParams.WRAP_CONTENT - clockView.setGravity(Gravity.CENTER) - clockView.setTextAlignment(View.TEXT_ALIGNMENT_CENTER) - clockView.requestLayout() + setClockGravity(clockView, gravity) } private fun setQSStatusIconsBgA12() { @@ -664,31 +617,22 @@ class BackgroundChip(context: Context?) : ModPack(context!!) { ) val statusIconContainer = statusIcons.parent as LinearLayout - (statusIconContainer.layoutParams as FrameLayout.LayoutParams).gravity = - Gravity.CENTER_VERTICAL or Gravity.END - statusIconContainer.layoutParams.height = TypedValue.applyDimension( - TypedValue.COMPLEX_UNIT_DIP, - 28f, - mContext.resources.displayMetrics - ).toInt() - statusIconContainer.requestLayout() - - val paddingTopBottom = TypedValue.applyDimension( - TypedValue.COMPLEX_UNIT_DIP, - 2f, - mContext.resources.displayMetrics - ).toInt() - val paddingStartEnd = TypedValue.applyDimension( - TypedValue.COMPLEX_UNIT_DIP, - 8f, - mContext.resources.displayMetrics - ).toInt() + statusIconContainer.post { + (statusIconContainer.layoutParams as FrameLayout.LayoutParams).gravity = + Gravity.CENTER_VERTICAL or Gravity.END + statusIconContainer.layoutParams.height = TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_DIP, + 28f, + mContext.resources.displayMetrics + ).toInt() + statusIconContainer.requestLayout() + } statusIconContainer.setPadding( - paddingStartEnd, - paddingTopBottom, - paddingStartEnd, - paddingTopBottom + mContext.toPx(padding2[0]), + mContext.toPx(padding2[1]), + mContext.toPx(padding2[2]), + mContext.toPx(padding2[3]) ) setStatusIconsBackgroundChip(statusIconContainer) @@ -717,22 +661,12 @@ class BackgroundChip(context: Context?) : ModPack(context!!) { ) if (statusIcons != null) { val statusIconContainer = statusIcons.parent as LinearLayout - val paddingTopBottom = TypedValue.applyDimension( - TypedValue.COMPLEX_UNIT_DIP, - 2f, - mContext.resources.displayMetrics - ).toInt() - val paddingStartEnd = TypedValue.applyDimension( - TypedValue.COMPLEX_UNIT_DIP, - 8f, - mContext.resources.displayMetrics - ).toInt() statusIconContainer.setPadding( - paddingStartEnd, - paddingTopBottom, - paddingStartEnd, - paddingTopBottom + mContext.toPx(padding2[0]), + mContext.toPx(padding2[1]), + mContext.toPx(padding2[2]), + mContext.toPx(padding2[3]) ) setStatusIconsBackgroundChip(statusIconContainer) @@ -754,7 +688,7 @@ class BackgroundChip(context: Context?) : ModPack(context!!) { var correctClass = false val fs = quickStatusBarHeader.declaredFields for (f in fs) { - if (f.getName() == "mIconContainer") { + if (f.name == "mIconContainer") { correctClass = true } } @@ -778,7 +712,10 @@ class BackgroundChip(context: Context?) : ModPack(context!!) { ViewGroup.LayoutParams.WRAP_CONTENT ) - mQsStatusIconsContainer.setLayoutParams(layoutParams) + mQsStatusIconsContainer.post { + mQsStatusIconsContainer.layoutParams = layoutParams + } + mQsStatusIconsContainer.gravity = Gravity.CENTER mQsStatusIconsContainer.orientation = LinearLayout.HORIZONTAL @@ -798,11 +735,17 @@ class BackgroundChip(context: Context?) : ModPack(context!!) { ) (mIconContainer.parent as ViewGroup).removeView(mIconContainer) - mIconContainer.setLayoutParams(layoutParams) - mIconContainer.layoutParams.height = mContext.toPx(32) + + mIconContainer.post { + mIconContainer.layoutParams = layoutParams + mIconContainer.layoutParams.height = mContext.toPx(32) + } (mBatteryRemainingIcon.parent as ViewGroup).removeView(mBatteryRemainingIcon) - mBatteryRemainingIcon.layoutParams.height = mContext.toPx(32) + + mBatteryRemainingIcon.post { + mBatteryRemainingIcon.layoutParams.height = mContext.toPx(32) + } mQsStatusIconsContainer.addView(mIconContainer) mQsStatusIconsContainer.addView(mBatteryRemainingIcon) @@ -812,8 +755,10 @@ class BackgroundChip(context: Context?) : ModPack(context!!) { mQuickStatusBarHeader.childCount - 1 ) - (mQsStatusIconsContainer.layoutParams as FrameLayout.LayoutParams).gravity = - Gravity.TOP or Gravity.END + mQsStatusIconsContainer.post { + (mQsStatusIconsContainer.layoutParams as FrameLayout.LayoutParams).gravity = + Gravity.TOP or Gravity.END + } updateStatusIcons() } @@ -859,10 +804,14 @@ class BackgroundChip(context: Context?) : ModPack(context!!) { constraintLayoutId = View.generateViewId() constraintLayoutParams.topToTop = ConstraintLayout.LayoutParams.PARENT_ID constraintLayoutParams.endToEnd = ConstraintLayout.LayoutParams.PARENT_ID - mQsStatusIconsContainer.setLayoutParams(constraintLayoutParams) + + mQsStatusIconsContainer.post { + mQsStatusIconsContainer.layoutParams = constraintLayoutParams + } + mQsStatusIconsContainer.gravity = Gravity.CENTER mQsStatusIconsContainer.orientation = LinearLayout.HORIZONTAL - mQsStatusIconsContainer.setId(constraintLayoutId) + mQsStatusIconsContainer.id = constraintLayoutId if (mQsStatusIconsContainer.parent != null) { (mQsStatusIconsContainer.parent as ViewGroup).removeView( @@ -880,11 +829,17 @@ class BackgroundChip(context: Context?) : ModPack(context!!) { ) (iconContainer.parent as ViewGroup).removeView(iconContainer) - iconContainer.setLayoutParams(linearLayoutParams) - iconContainer.layoutParams.height = mContext.toPx(32) + + iconContainer.post { + iconContainer.layoutParams = linearLayoutParams + iconContainer.layoutParams.height = mContext.toPx(32) + } (batteryIcon.parent as ViewGroup).removeView(batteryIcon) - batteryIcon.layoutParams.height = mContext.toPx(32) + + batteryIcon.post { + batteryIcon.layoutParams.height = mContext.toPx(32) + } mQsStatusIconsContainer.addView(iconContainer) mQsStatusIconsContainer.addView(batteryIcon) diff --git a/app/src/main/java/com/drdisagree/iconify/xposed/modules/BatteryStyleManager.kt b/app/src/main/java/com/drdisagree/iconify/xposed/modules/BatteryStyleManager.kt index 816a97fec..d8a5e798c 100644 --- a/app/src/main/java/com/drdisagree/iconify/xposed/modules/BatteryStyleManager.kt +++ b/app/src/main/java/com/drdisagree/iconify/xposed/modules/BatteryStyleManager.kt @@ -13,6 +13,7 @@ import android.view.View import android.view.View.OnAttachStateChangeListener import android.view.ViewGroup import android.view.ViewGroup.MarginLayoutParams +import android.widget.FrameLayout import android.widget.ImageView import android.widget.LinearLayout import android.widget.TextView @@ -85,7 +86,6 @@ import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_STYLE import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_SWAP_PERCENTAGE import com.drdisagree.iconify.common.Preferences.CUSTOM_BATTERY_WIDTH import com.drdisagree.iconify.common.Preferences.ICONIFY_CHARGING_ICON_TAG -import com.drdisagree.iconify.config.XPrefs.Xprefs import com.drdisagree.iconify.xposed.HookRes.Companion.modRes import com.drdisagree.iconify.xposed.HookRes.Companion.resParams import com.drdisagree.iconify.xposed.ModPack @@ -126,6 +126,8 @@ import com.drdisagree.iconify.xposed.modules.batterystyles.RLandscapeBatteryStyl import com.drdisagree.iconify.xposed.modules.batterystyles.RLandscapeBatteryStyleB import com.drdisagree.iconify.xposed.modules.utils.SettingsLibUtils import com.drdisagree.iconify.xposed.modules.utils.ViewHelper.toPx +import com.drdisagree.iconify.xposed.utils.XPrefs.Xprefs +import com.drdisagree.iconify.xposed.utils.XPrefs.XprefsIsInitialized import de.robv.android.xposed.XC_MethodHook import de.robv.android.xposed.XC_MethodHook.MethodHookParam import de.robv.android.xposed.XC_MethodReplacement @@ -175,63 +177,61 @@ class BatteryStyleManager(context: Context?) : ModPack(context!!) { private var mIsCharging = false override fun updatePrefs(vararg key: String) { - if (Xprefs == null) return - - val batteryStyle: Int = Xprefs!!.getInt(CUSTOM_BATTERY_STYLE, 0) - val hidePercentage: Boolean = Xprefs!!.getBoolean(CUSTOM_BATTERY_HIDE_PERCENTAGE, false) - val defaultInsidePercentage = batteryStyle == BATTERY_STYLE_LANDSCAPE_IOS_16 || - batteryStyle == BATTERY_STYLE_LANDSCAPE_BATTERYL || - batteryStyle == BATTERY_STYLE_LANDSCAPE_BATTERYM - val insidePercentage = defaultInsidePercentage || - Xprefs!!.getBoolean(CUSTOM_BATTERY_INSIDE_PERCENTAGE, false) - defaultLandscapeBatteryEnabled = batteryStyle == BATTERY_STYLE_DEFAULT_LANDSCAPE || - batteryStyle == BATTERY_STYLE_DEFAULT_RLANDSCAPE - customBatteryEnabled = batteryStyle != BATTERY_STYLE_DEFAULT && - batteryStyle != BATTERY_STYLE_DEFAULT_LANDSCAPE && - batteryStyle != BATTERY_STYLE_DEFAULT_RLANDSCAPE - - mBatteryRotation = if (defaultLandscapeBatteryEnabled) { - if (batteryStyle == BATTERY_STYLE_DEFAULT_RLANDSCAPE) { - 90 + if (!XprefsIsInitialized) return + + var batteryStyle: Int + + Xprefs.apply { + batteryStyle = getString(CUSTOM_BATTERY_STYLE, "0")!!.toInt() + val hidePercentage: Boolean = getBoolean(CUSTOM_BATTERY_HIDE_PERCENTAGE, false) + val defaultInsidePercentage = batteryStyle == BATTERY_STYLE_LANDSCAPE_IOS_16 || + batteryStyle == BATTERY_STYLE_LANDSCAPE_BATTERYL || + batteryStyle == BATTERY_STYLE_LANDSCAPE_BATTERYM + val insidePercentage = defaultInsidePercentage || + getBoolean(CUSTOM_BATTERY_INSIDE_PERCENTAGE, false) + defaultLandscapeBatteryEnabled = batteryStyle == BATTERY_STYLE_DEFAULT_LANDSCAPE || + batteryStyle == BATTERY_STYLE_DEFAULT_RLANDSCAPE + customBatteryEnabled = batteryStyle != BATTERY_STYLE_DEFAULT && + batteryStyle != BATTERY_STYLE_DEFAULT_LANDSCAPE && + batteryStyle != BATTERY_STYLE_DEFAULT_RLANDSCAPE + + mBatteryRotation = if (defaultLandscapeBatteryEnabled) { + if (batteryStyle == BATTERY_STYLE_DEFAULT_RLANDSCAPE) { + 90 + } else { + 270 + } } else { - 270 + 0 } - } else { - 0 - } - mHidePercentage = hidePercentage || insidePercentage - mShowPercentInside = insidePercentage && (defaultInsidePercentage || !hidePercentage) - mHideBattery = Xprefs!!.getBoolean(CUSTOM_BATTERY_HIDE_BATTERY, false) - mBatteryLayoutReverse = Xprefs!!.getBoolean(CUSTOM_BATTERY_LAYOUT_REVERSE, false) - mBatteryCustomDimension = Xprefs!!.getBoolean(CUSTOM_BATTERY_DIMENSION, false) - mBatteryScaleWidth = Xprefs!!.getInt(CUSTOM_BATTERY_WIDTH, 20) - mBatteryScaleHeight = Xprefs!!.getInt(CUSTOM_BATTERY_HEIGHT, 20) - mScaledPerimeterAlpha = Xprefs!!.getBoolean(CUSTOM_BATTERY_PERIMETER_ALPHA, false) - mScaledFillAlpha = Xprefs!!.getBoolean(CUSTOM_BATTERY_FILL_ALPHA, false) - mRainbowFillColor = Xprefs!!.getBoolean(CUSTOM_BATTERY_RAINBOW_FILL_COLOR, false) - mCustomBlendColor = Xprefs!!.getBoolean(CUSTOM_BATTERY_BLEND_COLOR, false) - mCustomChargingColor = Xprefs!!.getInt(CUSTOM_BATTERY_CHARGING_COLOR, Color.BLACK) - mCustomFillColor = Xprefs!!.getInt(CUSTOM_BATTERY_FILL_COLOR, Color.BLACK) - mCustomFillGradColor = Xprefs!!.getInt(CUSTOM_BATTERY_FILL_GRAD_COLOR, Color.BLACK) - mCustomPowerSaveColor = Xprefs!!.getInt( - CUSTOM_BATTERY_POWERSAVE_INDICATOR_COLOR, - Color.BLACK - ) - mCustomPowerSaveFillColor = Xprefs!!.getInt( - CUSTOM_BATTERY_POWERSAVE_FILL_COLOR, - Color.BLACK - ) - mSwapPercentage = Xprefs!!.getBoolean(CUSTOM_BATTERY_SWAP_PERCENTAGE, false) - mChargingIconSwitch = Xprefs!!.getBoolean(CUSTOM_BATTERY_CHARGING_ICON_SWITCH, false) - mChargingIconStyle = Xprefs!!.getInt(CUSTOM_BATTERY_CHARGING_ICON_STYLE, 0) - mChargingIconML = Xprefs!!.getInt(CUSTOM_BATTERY_CHARGING_ICON_MARGIN_LEFT, 1) - mChargingIconMR = Xprefs!!.getInt(CUSTOM_BATTERY_CHARGING_ICON_MARGIN_RIGHT, 0) - mChargingIconWH = Xprefs!!.getInt(CUSTOM_BATTERY_CHARGING_ICON_WIDTH_HEIGHT, 14) - mBatteryMarginLeft = mContext.toPx(Xprefs!!.getInt(CUSTOM_BATTERY_MARGIN_LEFT, 4)) - mBatteryMarginTop = mContext.toPx(Xprefs!!.getInt(CUSTOM_BATTERY_MARGIN_TOP, 0)) - mBatteryMarginRight = mContext.toPx(Xprefs!!.getInt(CUSTOM_BATTERY_MARGIN_RIGHT, 4)) - mBatteryMarginBottom = mContext.toPx(Xprefs!!.getInt(CUSTOM_BATTERY_MARGIN_BOTTOM, 0)) + mHidePercentage = hidePercentage || insidePercentage + mShowPercentInside = insidePercentage && (defaultInsidePercentage || !hidePercentage) + mHideBattery = getBoolean(CUSTOM_BATTERY_HIDE_BATTERY, false) + mBatteryLayoutReverse = getBoolean(CUSTOM_BATTERY_LAYOUT_REVERSE, false) + mBatteryCustomDimension = getBoolean(CUSTOM_BATTERY_DIMENSION, false) + mBatteryScaleWidth = getSliderInt(CUSTOM_BATTERY_WIDTH, 20) + mBatteryScaleHeight = getSliderInt(CUSTOM_BATTERY_HEIGHT, 20) + mScaledPerimeterAlpha = getBoolean(CUSTOM_BATTERY_PERIMETER_ALPHA, false) + mScaledFillAlpha = getBoolean(CUSTOM_BATTERY_FILL_ALPHA, false) + mRainbowFillColor = getBoolean(CUSTOM_BATTERY_RAINBOW_FILL_COLOR, false) + mCustomBlendColor = getBoolean(CUSTOM_BATTERY_BLEND_COLOR, false) + mCustomChargingColor = getInt(CUSTOM_BATTERY_CHARGING_COLOR, Color.BLACK) + mCustomFillColor = getInt(CUSTOM_BATTERY_FILL_COLOR, Color.BLACK) + mCustomFillGradColor = getInt(CUSTOM_BATTERY_FILL_GRAD_COLOR, Color.BLACK) + mCustomPowerSaveColor = getInt(CUSTOM_BATTERY_POWERSAVE_INDICATOR_COLOR, Color.BLACK) + mCustomPowerSaveFillColor = getInt(CUSTOM_BATTERY_POWERSAVE_FILL_COLOR, Color.BLACK) + mSwapPercentage = getBoolean(CUSTOM_BATTERY_SWAP_PERCENTAGE, false) + mChargingIconSwitch = getBoolean(CUSTOM_BATTERY_CHARGING_ICON_SWITCH, false) + mChargingIconStyle = getString(CUSTOM_BATTERY_CHARGING_ICON_STYLE, "0")!!.toInt() + mChargingIconML = getSliderInt(CUSTOM_BATTERY_CHARGING_ICON_MARGIN_LEFT, 1) + mChargingIconMR = getSliderInt(CUSTOM_BATTERY_CHARGING_ICON_MARGIN_RIGHT, 0) + mChargingIconWH = getSliderInt(CUSTOM_BATTERY_CHARGING_ICON_WIDTH_HEIGHT, 14) + mBatteryMarginLeft = mContext.toPx(getSliderInt(CUSTOM_BATTERY_MARGIN_LEFT, 4)) + mBatteryMarginTop = mContext.toPx(getSliderInt(CUSTOM_BATTERY_MARGIN_TOP, 0)) + mBatteryMarginRight = mContext.toPx(getSliderInt(CUSTOM_BATTERY_MARGIN_RIGHT, 4)) + mBatteryMarginBottom = mContext.toPx(getSliderInt(CUSTOM_BATTERY_MARGIN_BOTTOM, 0)) + } if (mBatteryStyle != batteryStyle) { mBatteryStyle = batteryStyle @@ -542,7 +542,7 @@ class BatteryStyleManager(context: Context?) : ModPack(context!!) { ) val mChargingIconView = - (param.thisObject as LinearLayout).findViewWithTag( + (param.thisObject as ViewGroup).findViewWithTag( ICONIFY_CHARGING_ICON_TAG ) mChargingIconView?.setImageTintList(ColorStateList.valueOf(param.args[2] as Int)) @@ -709,10 +709,17 @@ class BatteryStyleManager(context: Context?) : ModPack(context!!) { header.context, android.R.attr.textColorSecondary ) - val batteryIcon = getObjectField( - param.thisObject, - "batteryIcon" - ) as LinearLayout + val batteryIcon = try { + getObjectField( + param.thisObject, + "batteryIcon" + ) as LinearLayout + } catch (throwable: Throwable) { + getObjectField( + param.thisObject, + "batteryIcon" + ) as FrameLayout + } if (getObjectField(param.thisObject, "iconManager") != null) { try { @@ -771,7 +778,7 @@ class BatteryStyleManager(context: Context?) : ModPack(context!!) { ) as BatteryDrawable mBatteryDrawable.setShowPercentEnabled(mShowPercentInside) - mBatteryDrawable.alpha = Math.round(batteryIconOpacity * 2.55f) + mBatteryDrawable.alpha = Math.round(BATTERY_ICON_OPACITY * 2.55f) updateCustomizeBatteryDrawable(mBatteryDrawable) } catch (ignored: Throwable) { } @@ -917,7 +924,7 @@ class BatteryStyleManager(context: Context?) : ModPack(context!!) { if (mBatteryDrawable != null) { mBatteryDrawable.setShowPercentEnabled(mShowPercentInside) - mBatteryDrawable.alpha = Math.round(batteryIconOpacity * 2.55f) + mBatteryDrawable.alpha = Math.round(BATTERY_ICON_OPACITY * 2.55f) } return mBatteryDrawable @@ -990,145 +997,143 @@ class BatteryStyleManager(context: Context?) : ModPack(context!!) { private fun updateChargingIconView(thisObject: Any, mCharging: Boolean = mIsChargingImpl) { var mChargingIconView = - (thisObject as LinearLayout).findViewWithTag(ICONIFY_CHARGING_ICON_TAG) + (thisObject as ViewGroup).findViewWithTag(ICONIFY_CHARGING_ICON_TAG) if (mChargingIconView == null) { mChargingIconView = ImageView(mContext) mChargingIconView.tag = ICONIFY_CHARGING_ICON_TAG - (thisObject as ViewGroup).addView(mChargingIconView, 1) + thisObject.addView(mChargingIconView, 1) } - val drawable = if (modRes != null) { - when (mChargingIconStyle) { - 0 -> ResourcesCompat.getDrawable( - modRes!!, - R.drawable.ic_charging_bold, - mContext.theme - ) + val drawable = when (mChargingIconStyle) { + 0 -> ResourcesCompat.getDrawable( + modRes, + R.drawable.ic_charging_bold, + mContext.theme + ) - 1 -> ResourcesCompat.getDrawable( - modRes!!, - R.drawable.ic_charging_asus, - mContext.theme - ) + 1 -> ResourcesCompat.getDrawable( + modRes, + R.drawable.ic_charging_asus, + mContext.theme + ) - 2 -> ResourcesCompat.getDrawable( - modRes!!, - R.drawable.ic_charging_buddy, - mContext.theme - ) + 2 -> ResourcesCompat.getDrawable( + modRes, + R.drawable.ic_charging_buddy, + mContext.theme + ) - 3 -> ResourcesCompat.getDrawable( - modRes!!, - R.drawable.ic_charging_evplug, - mContext.theme - ) + 3 -> ResourcesCompat.getDrawable( + modRes, + R.drawable.ic_charging_evplug, + mContext.theme + ) - 4 -> ResourcesCompat.getDrawable( - modRes!!, - R.drawable.ic_charging_idc, - mContext.theme - ) + 4 -> ResourcesCompat.getDrawable( + modRes, + R.drawable.ic_charging_idc, + mContext.theme + ) - 5 -> ResourcesCompat.getDrawable( - modRes!!, - R.drawable.ic_charging_ios, - mContext.theme - ) + 5 -> ResourcesCompat.getDrawable( + modRes, + R.drawable.ic_charging_ios, + mContext.theme + ) - 6 -> ResourcesCompat.getDrawable( - modRes!!, - R.drawable.ic_charging_koplak, - mContext.theme - ) + 6 -> ResourcesCompat.getDrawable( + modRes, + R.drawable.ic_charging_koplak, + mContext.theme + ) - 7 -> ResourcesCompat.getDrawable( - modRes!!, - R.drawable.ic_charging_miui, - mContext.theme - ) + 7 -> ResourcesCompat.getDrawable( + modRes, + R.drawable.ic_charging_miui, + mContext.theme + ) - 8 -> ResourcesCompat.getDrawable( - modRes!!, - R.drawable.ic_charging_mmk, - mContext.theme - ) + 8 -> ResourcesCompat.getDrawable( + modRes, + R.drawable.ic_charging_mmk, + mContext.theme + ) - 9 -> ResourcesCompat.getDrawable( - modRes!!, - R.drawable.ic_charging_moto, - mContext.theme - ) + 9 -> ResourcesCompat.getDrawable( + modRes, + R.drawable.ic_charging_moto, + mContext.theme + ) - 10 -> ResourcesCompat.getDrawable( - modRes!!, - R.drawable.ic_charging_nokia, - mContext.theme - ) + 10 -> ResourcesCompat.getDrawable( + modRes, + R.drawable.ic_charging_nokia, + mContext.theme + ) - 11 -> ResourcesCompat.getDrawable( - modRes!!, - R.drawable.ic_charging_plug, - mContext.theme - ) + 11 -> ResourcesCompat.getDrawable( + modRes, + R.drawable.ic_charging_plug, + mContext.theme + ) - 12 -> ResourcesCompat.getDrawable( - modRes!!, - R.drawable.ic_charging_powercable, - mContext.theme - ) + 12 -> ResourcesCompat.getDrawable( + modRes, + R.drawable.ic_charging_powercable, + mContext.theme + ) - 13 -> ResourcesCompat.getDrawable( - modRes!!, - R.drawable.ic_charging_powercord, - mContext.theme - ) + 13 -> ResourcesCompat.getDrawable( + modRes, + R.drawable.ic_charging_powercord, + mContext.theme + ) - 14 -> ResourcesCompat.getDrawable( - modRes!!, - R.drawable.ic_charging_powerstation, - mContext.theme - ) + 14 -> ResourcesCompat.getDrawable( + modRes, + R.drawable.ic_charging_powerstation, + mContext.theme + ) - 15 -> ResourcesCompat.getDrawable( - modRes!!, - R.drawable.ic_charging_realme, - mContext.theme - ) + 15 -> ResourcesCompat.getDrawable( + modRes, + R.drawable.ic_charging_realme, + mContext.theme + ) - 16 -> ResourcesCompat.getDrawable( - modRes!!, - R.drawable.ic_charging_soak, - mContext.theme - ) + 16 -> ResourcesCompat.getDrawable( + modRes, + R.drawable.ic_charging_soak, + mContext.theme + ) - 17 -> ResourcesCompat.getDrawable( - modRes!!, - R.drawable.ic_charging_stres, - mContext.theme - ) + 17 -> ResourcesCompat.getDrawable( + modRes, + R.drawable.ic_charging_stres, + mContext.theme + ) - 18 -> ResourcesCompat.getDrawable( - modRes!!, - R.drawable.ic_charging_strip, - mContext.theme - ) + 18 -> ResourcesCompat.getDrawable( + modRes, + R.drawable.ic_charging_strip, + mContext.theme + ) - 19 -> ResourcesCompat.getDrawable( - modRes!!, - R.drawable.ic_charging_usbcable, - mContext.theme - ) + 19 -> ResourcesCompat.getDrawable( + modRes, + R.drawable.ic_charging_usbcable, + mContext.theme + ) - 20 -> ResourcesCompat.getDrawable( - modRes!!, - R.drawable.ic_charging_xiaomi, - mContext.theme - ) + 20 -> ResourcesCompat.getDrawable( + modRes, + R.drawable.ic_charging_xiaomi, + mContext.theme + ) - else -> null - } - } else null + else -> null + } if (drawable != null && drawable !== mChargingIconView.getDrawable()) { mChargingIconView.setImageDrawable(drawable) @@ -1137,7 +1142,11 @@ class BatteryStyleManager(context: Context?) : ModPack(context!!) { val left: Int = mContext.toPx(mChargingIconML) val right: Int = mContext.toPx(mChargingIconMR) val size: Int = mContext.toPx(mChargingIconWH) - val lp = LinearLayout.LayoutParams(size, size) + val lp = if (thisObject is LinearLayout) { + LinearLayout.LayoutParams(size, size) + } else { + FrameLayout.LayoutParams(size, size) + } lp.setMargins( left, @@ -1165,11 +1174,19 @@ class BatteryStyleManager(context: Context?) : ModPack(context!!) { } private fun updateFlipper(thisObject: Any) { - val batteryView = thisObject as LinearLayout - batteryView.orientation = LinearLayout.HORIZONTAL - batteryView.gravity = Gravity.CENTER_VERTICAL or Gravity.START - batteryView.layoutDirection = - if (mSwapPercentage) View.LAYOUT_DIRECTION_RTL else View.LAYOUT_DIRECTION_LTR + val batteryView = if (thisObject is LinearLayout) { + thisObject.orientation = LinearLayout.HORIZONTAL + thisObject.gravity = Gravity.CENTER_VERTICAL or Gravity.START + thisObject + } else { + thisObject as View + } + + batteryView.layoutDirection = if (mSwapPercentage) { + View.LAYOUT_DIRECTION_RTL + } else { + View.LAYOUT_DIRECTION_LTR + } } private fun updateBatteryRotation(thisObject: Any) { @@ -1178,8 +1195,11 @@ class BatteryStyleManager(context: Context?) : ModPack(context!!) { } private fun updateBatteryRotation(mBatteryIconView: View) { - mBatteryIconView.rotation = - (if (!defaultLandscapeBatteryEnabled && mBatteryLayoutReverse) 180 else mBatteryRotation).toFloat() + mBatteryIconView.rotation = if (!defaultLandscapeBatteryEnabled && mBatteryLayoutReverse) { + 180 + } else { + mBatteryRotation + }.toFloat() } private fun updateCustomizeBatteryDrawable(thisObject: Any) { @@ -1248,7 +1268,11 @@ class BatteryStyleManager(context: Context?) : ModPack(context!!) { mBatteryIconView.context.resources.displayMetrics ).toInt() - val scaledLayoutParams = mBatteryIconView.layoutParams as LinearLayout.LayoutParams + val scaledLayoutParams = try { + mBatteryIconView.layoutParams as LinearLayout.LayoutParams + } catch (throwable: Throwable) { + mBatteryIconView.layoutParams as FrameLayout.LayoutParams + } scaledLayoutParams.width = (batteryWidth * iconScaleFactor).toInt() scaledLayoutParams.height = (batteryHeight * iconScaleFactor).toInt() @@ -1284,7 +1308,6 @@ class BatteryStyleManager(context: Context?) : ModPack(context!!) { companion object { private val TAG = "Iconify - ${BatteryStyleManager::class.java.simpleName}: " private val batteryViews = ArrayList() - private val batteryIconOpacity = 100 private var mBatteryStyle = 0 private var mShowPercentInside = false private var mHidePercentage = false @@ -1298,5 +1321,6 @@ class BatteryStyleManager(context: Context?) : ModPack(context!!) { private var mBatteryMarginTop = 0 private var mBatteryMarginRight = 0 private var mBatteryMarginBottom = 0 + private const val BATTERY_ICON_OPACITY = 100 } } \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/xposed/modules/ControllersProvider.kt b/app/src/main/java/com/drdisagree/iconify/xposed/modules/ControllersProvider.kt new file mode 100644 index 000000000..77b4fa4c2 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/xposed/modules/ControllersProvider.kt @@ -0,0 +1,618 @@ +package com.drdisagree.iconify.xposed.modules + +import android.annotation.SuppressLint +import android.content.Context +import android.provider.Settings +import android.view.View +import com.drdisagree.iconify.common.Const.SYSTEMUI_PACKAGE +import com.drdisagree.iconify.xposed.ModPack +import com.drdisagree.iconify.xposed.modules.utils.Helpers.isMethodAvailable +import de.robv.android.xposed.XC_MethodHook +import de.robv.android.xposed.XposedBridge.hookAllConstructors +import de.robv.android.xposed.XposedBridge.hookAllMethods +import de.robv.android.xposed.XposedBridge.log +import de.robv.android.xposed.XposedHelpers +import de.robv.android.xposed.XposedHelpers.callMethod +import de.robv.android.xposed.XposedHelpers.findClass +import de.robv.android.xposed.XposedHelpers.findClassIfExists +import de.robv.android.xposed.XposedHelpers.getIntField +import de.robv.android.xposed.XposedHelpers.getObjectField +import de.robv.android.xposed.callbacks.XC_LoadPackage + +class ControllersProvider(context: Context?) : ModPack(context!!) { + + private var mBluetoothEnabled = false + + private var mAccessPointController: Any? = null + private var mInternetDialogManager: Any? = null + private var mInternetDialogFactory: Any? = null + private var mBluetoothTileDialogViewModel: Any? = null + + private var mCellularTile: Any? = null + private var mBluetoothTile: Any? = null + + private val mMobileDataChangedListeners = ArrayList() + private val mWifiChangedListeners = ArrayList() + private val mBluetoothChangedListeners = ArrayList() + private val mTorchModeChangedListeners = ArrayList() + private val mHotspotChangedListeners = ArrayList() + private val mDozeChangedListeners = ArrayList() + + override fun updatePrefs(vararg key: String) {} + + override fun handleLoadPackage(loadPackageParam: XC_LoadPackage.LoadPackageParam) { + + instance = this + + // Network Callbacks + val callbackHandler = findClassIfExists( + "$SYSTEMUI_PACKAGE.statusbar.connectivity.CallbackHandler", + loadPackageParam.classLoader + ) + + // Mobile Data + if (callbackHandler != null) { + hookAllMethods( + callbackHandler, + "setMobileDataIndicators", + object : XC_MethodHook() { + @Throws(Throwable::class) + override fun afterHookedMethod(param: MethodHookParam) { + onSetMobileDataIndicators(param.args[0]) + } + }) + + hookAllMethods(callbackHandler, "setIsAirplaneMode", object : XC_MethodHook() { + @Throws(Throwable::class) + override fun afterHookedMethod(param: MethodHookParam) { + //mAirplane = (boolean) param.args[0]; + onSetIsAirplaneMode(param.args[0]) + } + }) + + hookAllMethods(callbackHandler, "setNoSims", object : XC_MethodHook() { + @Throws(Throwable::class) + override fun afterHookedMethod(param: MethodHookParam) { + onSetNoSims(param.args[0] as Boolean, param.args[1] as Boolean) + } + }) + + + // WiFi + hookAllMethods(callbackHandler, "setWifiIndicators", object : XC_MethodHook() { + @Throws(Throwable::class) + override fun afterHookedMethod(param: MethodHookParam) { + onWifiChanged(param.args[0]) + } + }) + } + + // Internet Tile - for opening Internet Dialog + try { + val internetTile = findClass( + "$SYSTEMUI_PACKAGE.qs.tiles.InternetTile", + loadPackageParam.classLoader + ) + hookAllConstructors(internetTile, object : XC_MethodHook() { + @Throws(Throwable::class) + override fun afterHookedMethod(param: MethodHookParam) { + mCellularTile = param.thisObject + } + }) + } catch (t: Throwable) { + log(TAG + "InternetTile error " + t.message) + } + + // Stole also Internet Dialog Manager + // in case no tile is available + try { + val networkControllerImplClass = findClass( + "$SYSTEMUI_PACKAGE.statusbar.connectivity.NetworkControllerImpl", + loadPackageParam.classLoader + ) + hookAllConstructors(networkControllerImplClass, object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + try { + mAccessPointController = getObjectField(param.thisObject, "mAccessPoints") + } catch (ignored: Throwable) { + } + try { + mInternetDialogManager = + getObjectField(param.thisObject, "mInternetDialogManager") + } catch (ignored: Throwable) { + } + try { + mInternetDialogFactory = + getObjectField(param.thisObject, "mInternetDialogFactory") + } catch (ignored: Throwable) { + } + } + }) + } catch (t: Throwable) { + log(TAG + "NetworkControllerImpl not found " + t.message) + } + + // Bluetooth Controller + try { + val bluetoothControllerImpl = findClass( + "$SYSTEMUI_PACKAGE.statusbar.policy.BluetoothControllerImpl", + loadPackageParam.classLoader + ) + hookAllConstructors(bluetoothControllerImpl, object : XC_MethodHook() { + @Throws(Throwable::class) + override fun afterHookedMethod(param: MethodHookParam) { + mBluetoothController = param.thisObject + } + }) + hookAllMethods( + bluetoothControllerImpl, + "onBluetoothStateChanged", + object : XC_MethodHook() { + @Throws(Throwable::class) + override fun afterHookedMethod(param: MethodHookParam) { + mBluetoothEnabled = (param.args[0] == 12 || param.args[0] == 11) + onBluetoothChanged(mBluetoothEnabled) + } + }) + hookAllMethods( + bluetoothControllerImpl, + "onConnectionStateChanged", + object : XC_MethodHook() { + @Throws(Throwable::class) + override fun afterHookedMethod(param: MethodHookParam) { + onBluetoothChanged(mBluetoothEnabled) + } + }) + hookAllMethods( + bluetoothControllerImpl, + "onAclConnectionStateChanged", + object : XC_MethodHook() { + @Throws(Throwable::class) + override fun afterHookedMethod(param: MethodHookParam) { + onBluetoothChanged(mBluetoothEnabled) + } + }) + } catch (t: Throwable) { + log(TAG + "BluetoothControllerImpl not found " + t.message) + } + + // Get Bluetooth Tile for Dialog + try { + val bluetoothTile = findClass( + "$SYSTEMUI_PACKAGE.qs.tiles.BluetoothTile", + loadPackageParam.classLoader + ) + hookAllConstructors(bluetoothTile, object : XC_MethodHook() { + @Throws(Throwable::class) + override fun afterHookedMethod(param: MethodHookParam) { + mBluetoothTile = param.thisObject + try { + mBluetoothTileDialogViewModel = + getObjectField(param.thisObject, "mDialogViewModel") + } catch (ignored: Throwable) { + } + } + }) + } catch (t: Throwable) { + log(TAG + "BluetoothTile not found " + t.message) + } + + // Stole FlashLight Callback + try { + val flashlightControllerImpl = findClass( + "$SYSTEMUI_PACKAGE.statusbar.policy.FlashlightControllerImpl", + loadPackageParam.classLoader + ) + hookAllConstructors(flashlightControllerImpl, object : XC_MethodHook() { + @Throws(Throwable::class) + override fun afterHookedMethod(param: MethodHookParam) { + val mTorchCallback = getObjectField(param.thisObject, "mTorchCallback") + XposedHelpers.findAndHookMethod( + mTorchCallback.javaClass, + "onTorchModeChanged", + String::class.java, + Boolean::class.javaPrimitiveType, + object : XC_MethodHook() { + @Throws(Throwable::class) + override fun afterHookedMethod(param: MethodHookParam) { + onTorchModeChanged(param.args[1] as Boolean) + } + }) + } + }) + } catch (t: Throwable) { + log(TAG + "FlashlightControllerImpl not found " + t.message) + } + + + // Get an Hotspot Callback + try { + val hotspotControllerImpl = findClass( + "$SYSTEMUI_PACKAGE.statusbar.policy.HotspotControllerImpl", + loadPackageParam.classLoader + ) + hookAllMethods( + hotspotControllerImpl, + "fireHotspotChangedCallback", + object : XC_MethodHook() { + @Throws(Throwable::class) + override fun afterHookedMethod(param: MethodHookParam) { + val enabled = getIntField(param.thisObject, "mHotspotState") == 13 + val devices = + getIntField(param.thisObject, "mNumConnectedDevices") + onHotspotChanged(enabled, devices) + } + }) + } catch (t: Throwable) { + log(TAG + "HotspotCallback error: " + t.message) + } + + + // Hotspot Tile - for settings Hotspot + try { + val hotspotTile = + findClass("$SYSTEMUI_PACKAGE.qs.tiles.HotspotTile", loadPackageParam.classLoader) + hookAllConstructors(hotspotTile, object : XC_MethodHook() { + @Throws(Throwable::class) + override fun afterHookedMethod(param: MethodHookParam) { + mHotspotTile = param.thisObject + mHotspotController = getObjectField(param.thisObject, "mHotspotController") + } + }) + } catch (t: Throwable) { + log(TAG + "HotspotTile error: " + t.message) + } + + // Home Controls Tile - for ControlsActivity + try { + val deviceControlsTile = + findClass( + "$SYSTEMUI_PACKAGE.qs.tiles.DeviceControlsTile", + loadPackageParam.classLoader + ) + hookAllConstructors(deviceControlsTile, object : XC_MethodHook() { + @Throws(Throwable::class) + override fun afterHookedMethod(param: MethodHookParam) { + mDeviceControlsTile = param.thisObject + } + }) + } catch (t: Throwable) { + log(TAG + "DeviceControlsTile not found " + t.message) + } + + + // Wallet Tile - for opening wallet + try { + val quickAccessWalletTile = findClass( + "$SYSTEMUI_PACKAGE.qs.tiles.QuickAccessWalletTile", + loadPackageParam.classLoader + ) + hookAllConstructors(quickAccessWalletTile, object : XC_MethodHook() { + @Throws(Throwable::class) + override fun afterHookedMethod(param: MethodHookParam) { + mWalletTile = param.thisObject + } + }) + } catch (t: Throwable) { + log(TAG + "QuickAccessWalletTile not found") + } + + // Doze Callback + try { + val dozeScrimController = findClass( + "$SYSTEMUI_PACKAGE.statusbar.phone.DozeScrimController", + loadPackageParam.classLoader + ) + hookAllMethods(dozeScrimController, "onDozingChanged", object : XC_MethodHook() { + @Throws(Throwable::class) + override fun afterHookedMethod(param: MethodHookParam) { + onDozingChanged(param.args[0] as Boolean) + } + }) + + } catch (t: Throwable) { + log(TAG + "DozeServiceHost not found " + t.message) + } + + } + + /** + * Callbacks for Mobile Data + */ + interface OnMobileDataChanged { + fun setMobileDataIndicators(mMobileDataIndicators: Any?) + fun setNoSims(show: Boolean, simDetected: Boolean) + fun setIsAirplaneMode(mIconState: Any?) + } + + /** + * Callback for WiFi + */ + interface OnWifiChanged { + fun onWifiChanged(mWifiIndicators: Any?) + } + + /** + * Callback for Bluetooth + */ + interface OnBluetoothChanged { + fun onBluetoothChanged(enabled: Boolean) + } + + /** + * Callback for FlashLight + */ + interface OnTorchModeChanged { + fun onTorchModeChanged(enabled: Boolean) + } + + /** + * Callback for Hotspot + */ + interface OnHotspotChanged { + fun onHotspotChanged(enabled: Boolean, connectedDevices: Int) + } + + /** + * Callback for Doze + */ + interface OnDozingChanged { + fun onDozingChanged(dozing: Boolean) + } + + fun registerMobileDataCallback(callback: OnMobileDataChanged) { + instance!!.mMobileDataChangedListeners.add(callback) + } + + /** @noinspection unused + */ + fun unRegisterMobileDataCallback(callback: OnMobileDataChanged?) { + instance!!.mMobileDataChangedListeners.remove(callback) + } + + fun registerWifiCallback(callback: OnWifiChanged) { + instance!!.mWifiChangedListeners.add(callback) + } + + /** @noinspection unused + */ + fun unRegisterWifiCallback(callback: OnWifiChanged?) { + instance!!.mWifiChangedListeners.remove(callback) + } + + fun registerBluetoothCallback(callback: OnBluetoothChanged) { + instance!!.mBluetoothChangedListeners.add(callback) + } + + /** @noinspection unused + */ + fun unRegisterBluetoothCallback(callback: OnBluetoothChanged?) { + instance!!.mBluetoothChangedListeners.remove(callback) + } + + fun registerTorchModeCallback(callback: OnTorchModeChanged) { + instance!!.mTorchModeChangedListeners.add(callback) + } + + /** @noinspection unused + */ + fun unRegisterTorchModeCallback(callback: OnTorchModeChanged?) { + instance!!.mTorchModeChangedListeners.remove(callback) + } + + fun registerDozingCallback(callback: OnDozingChanged) { + instance!!.mDozeChangedListeners.add(callback) + } + + /** @noinspection unused */ + fun unRegisterDozingCallback(callback: OnDozingChanged?) { + instance!!.mDozeChangedListeners.remove(callback) + } + + fun registerHotspotCallback(callback: OnHotspotChanged) { + instance!!.mHotspotChangedListeners.add(callback) + } + + /** @noinspection unused */ + fun unRegisterHotspotCallback(callback: OnHotspotChanged?) { + instance!!.mHotspotChangedListeners.remove(callback) + } + + private fun onSetMobileDataIndicators(mMobileDataIndicators: Any) { + for (callback in mMobileDataChangedListeners) { + try { + callback.setMobileDataIndicators(mMobileDataIndicators) + } catch (ignored: Throwable) { + } + } + } + + private fun onSetIsAirplaneMode(mMobileDataIndicators: Any) { + for (callback in mMobileDataChangedListeners) { + try { + callback.setIsAirplaneMode(mMobileDataIndicators) + } catch (ignored: Throwable) { + } + } + } + + private fun onSetNoSims(show: Boolean, simDetected: Boolean) { + for (callback in mMobileDataChangedListeners) { + try { + callback.setNoSims(show, simDetected) + } catch (ignored: Throwable) { + } + } + } + + private fun onWifiChanged(wifiIndicators: Any) { + for (callback in mWifiChangedListeners) { + try { + callback.onWifiChanged(wifiIndicators) + } catch (ignored: Throwable) { + } + } + } + + private fun onBluetoothChanged(enabled: Boolean) { + for (callback in mBluetoothChangedListeners) { + try { + callback.onBluetoothChanged(enabled) + } catch (ignored: Throwable) { + } + } + } + + private fun onTorchModeChanged(enabled: Boolean) { + for (callback in mTorchModeChangedListeners) { + try { + callback.onTorchModeChanged(enabled) + } catch (ignored: Throwable) { + } + } + } + + private fun onHotspotChanged(enabled: Boolean, connectedDevices: Int) { + for (callback in mHotspotChangedListeners) { + try { + callback.onHotspotChanged(enabled, connectedDevices) + } catch (ignored: Throwable) { + } + } + } + + private fun onDozingChanged(isDozing: Boolean) { + for (callback in mDozeChangedListeners) { + try { + callback.onDozingChanged(isDozing) + } catch (ignored: Throwable) { + } + } + } + + companion object { + @SuppressLint("StaticFieldLeak") + @Volatile + private var instance: ControllersProvider? = null + + private val TAG: String = "Iconify - ${ControllersProvider::class.java.simpleName}: " + + var mBluetoothController: Any? = null + var mHotspotController: Any? = null + + var mHotspotTile: Any? = null + var mDeviceControlsTile: Any? = null + var mWalletTile: Any? = null + + fun getInstance(): ControllersProvider { + return instance!! + } + + fun showInternetDialog(view: View): Boolean { + if (instance == null) { + log(TAG + "Instance is null") + return false + } + if (instance!!.mCellularTile != null) { + if (isMethodAvailable(instance!!.mCellularTile, "handleClick", View::class.java)) { + callMethod(instance!!.mCellularTile, "handleClick", view) + return true + } + } + if (instance!!.mAccessPointController != null) { + if (isMethodAvailable( + instance!!.mInternetDialogManager, + "create", + Boolean::class.java, + Boolean::class.java, + Boolean::class.java, + View::class.java + ) + ) { + callMethod( + instance!!.mInternetDialogManager, + "create", + true, + callMethod(instance!!.mAccessPointController, "canConfigMobileData"), + callMethod(instance!!.mAccessPointController, "canConfigWifi"), + view + ) + return true + } else if (isMethodAvailable( + instance!!.mInternetDialogManager, + "create", + View::class.java, + Boolean::class.java, + Boolean::class.java + ) + ) { + callMethod( + instance!!.mInternetDialogManager, + "create", + view, + callMethod(instance!!.mAccessPointController, "canConfigMobileData"), + callMethod(instance!!.mAccessPointController, "canConfigWifi") + ) + return true + } else if (isMethodAvailable( + instance!!.mInternetDialogFactory, + "create", + Boolean::class.java, + Boolean::class.java, + View::class.java + ) + ) { + callMethod( + instance!!.mInternetDialogFactory, + "create", + callMethod(instance!!.mAccessPointController, "canConfigMobileData"), + callMethod(instance!!.mAccessPointController, "canConfigWifi"), + view + ) + return true + } else { + log(TAG + "No internet dialog available") + return false + } + } + return false + } + + fun showBluetoothDialog(context: Context, view: View): Boolean { + if (instance?.mBluetoothTileDialogViewModel != null) { + try { + callMethod( + instance!!.mBluetoothTileDialogViewModel, + "showDialog", + context, + view + ) + return true + } catch (ignored: Throwable) { + val isAutoOn = Settings.System.getInt( + context.contentResolver, + "qs_bt_auto_on", 0 + ) == 1 + callMethod( + instance!!.mBluetoothTileDialogViewModel, + "showDialog", + context, + view, + isAutoOn + ) + return true + } + } else if (instance?.mBluetoothTile != null) { + if (isMethodAvailable(instance!!.mBluetoothTile, "handleClick", View::class.java)) { + callMethod(instance!!.mBluetoothTile, "handleClick", view) + return true + } else { + log(TAG + "No bluetooth dialog available") + } + } + return false + } + + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/xposed/modules/DepthWallpaper.kt b/app/src/main/java/com/drdisagree/iconify/xposed/modules/DepthWallpaper.kt index a1a5aa648..68de345f3 100644 --- a/app/src/main/java/com/drdisagree/iconify/xposed/modules/DepthWallpaper.kt +++ b/app/src/main/java/com/drdisagree/iconify/xposed/modules/DepthWallpaper.kt @@ -29,10 +29,11 @@ import com.drdisagree.iconify.common.Preferences.DEPTH_WALLPAPER_SWITCH import com.drdisagree.iconify.common.Preferences.ICONIFY_DEPTH_WALLPAPER_TAG import com.drdisagree.iconify.common.Preferences.ICONIFY_LOCKSCREEN_CLOCK_TAG import com.drdisagree.iconify.common.Preferences.UNZOOM_DEPTH_WALLPAPER -import com.drdisagree.iconify.config.XPrefs.Xprefs import com.drdisagree.iconify.xposed.ModPack import com.drdisagree.iconify.xposed.modules.utils.ParallaxImageView import com.drdisagree.iconify.xposed.modules.utils.ViewHelper.toPx +import com.drdisagree.iconify.xposed.utils.XPrefs.Xprefs +import com.drdisagree.iconify.xposed.utils.XPrefs.XprefsIsInitialized import de.robv.android.xposed.XC_MethodHook import de.robv.android.xposed.XposedBridge.hookAllMethods import de.robv.android.xposed.XposedHelpers.findClass @@ -59,15 +60,19 @@ class DepthWallpaper(context: Context?) : ModPack(context!!) { private var foregroundAlpha = 1.0f override fun updatePrefs(vararg key: String) { - if (Xprefs == null) return - - showDepthWallpaper = Xprefs!!.getBoolean(DEPTH_WALLPAPER_SWITCH, false) - showFadingAnimation = Xprefs!!.getBoolean(DEPTH_WALLPAPER_FADE_ANIMATION, false) - enableParallaxEffect = Xprefs!!.getBoolean(DEPTH_WALLPAPER_PARALLAX_EFFECT, false) - backgroundMovement = Xprefs!!.getFloat(DEPTH_WALLPAPER_BACKGROUND_MOVEMENT_MULTIPLIER, 1.0f) - foregroundMovement = Xprefs!!.getFloat(DEPTH_WALLPAPER_FOREGROUND_MOVEMENT_MULTIPLIER, 3.0f) - unzoomWallpaper = Xprefs!!.getBoolean(UNZOOM_DEPTH_WALLPAPER, false) - foregroundAlpha = Xprefs!!.getInt(DEPTH_WALLPAPER_FOREGROUND_ALPHA, 80) / 100.0f + if (!XprefsIsInitialized) return + + Xprefs.apply { + showDepthWallpaper = getBoolean(DEPTH_WALLPAPER_SWITCH, false) + showFadingAnimation = getBoolean(DEPTH_WALLPAPER_FADE_ANIMATION, false) + enableParallaxEffect = getBoolean(DEPTH_WALLPAPER_PARALLAX_EFFECT, false) + backgroundMovement = + getSliderInt(DEPTH_WALLPAPER_BACKGROUND_MOVEMENT_MULTIPLIER, 1).toFloat() + foregroundMovement = + getSliderInt(DEPTH_WALLPAPER_FOREGROUND_MOVEMENT_MULTIPLIER, 3).toFloat() + unzoomWallpaper = getBoolean(UNZOOM_DEPTH_WALLPAPER, false) + foregroundAlpha = getSliderInt(DEPTH_WALLPAPER_FOREGROUND_ALPHA, 80) / 100.0f + } if (key.isNotEmpty() && (key[0] == DEPTH_WALLPAPER_SWITCH || diff --git a/app/src/main/java/com/drdisagree/iconify/xposed/modules/DepthWallpaperA14.kt b/app/src/main/java/com/drdisagree/iconify/xposed/modules/DepthWallpaperA14.kt new file mode 100644 index 000000000..f23fffe7f --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/xposed/modules/DepthWallpaperA14.kt @@ -0,0 +1,592 @@ +package com.drdisagree.iconify.xposed.modules + +import android.annotation.SuppressLint +import android.app.WallpaperManager +import android.content.Context +import android.graphics.Bitmap +import android.graphics.Color +import android.graphics.drawable.BitmapDrawable +import android.graphics.drawable.Drawable +import android.graphics.drawable.LayerDrawable +import android.os.Build +import android.os.Environment +import android.os.Handler +import android.os.Looper +import android.view.View +import android.view.ViewGroup +import android.view.WindowManager +import android.widget.FrameLayout +import android.widget.Toast +import androidx.annotation.RequiresApi +import com.drdisagree.iconify.IExtractSubjectCallback +import com.drdisagree.iconify.common.Const.SYSTEMUI_PACKAGE +import com.drdisagree.iconify.common.Preferences.CUSTOM_DEPTH_WALLPAPER_SWITCH +import com.drdisagree.iconify.common.Preferences.DEPTH_WALLPAPER_CHANGED +import com.drdisagree.iconify.common.Preferences.DEPTH_WALLPAPER_FOREGROUND_ALPHA +import com.drdisagree.iconify.common.Preferences.DEPTH_WALLPAPER_ON_AOD +import com.drdisagree.iconify.common.Preferences.DEPTH_WALLPAPER_SWITCH +import com.drdisagree.iconify.xposed.HookEntry.Companion.enqueueProxyCommand +import com.drdisagree.iconify.xposed.ModPack +import com.drdisagree.iconify.xposed.modules.utils.Helpers.findClassInArray +import com.drdisagree.iconify.xposed.utils.XPrefs.Xprefs +import com.drdisagree.iconify.xposed.utils.XPrefs.XprefsIsInitialized +import de.robv.android.xposed.XC_MethodHook +import de.robv.android.xposed.XposedBridge.hookAllConstructors +import de.robv.android.xposed.XposedBridge.hookAllMethods +import de.robv.android.xposed.XposedBridge.log +import de.robv.android.xposed.XposedHelpers.callMethod +import de.robv.android.xposed.XposedHelpers.findClass +import de.robv.android.xposed.XposedHelpers.getFloatField +import de.robv.android.xposed.XposedHelpers.getObjectField +import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam +import java.io.ByteArrayOutputStream +import java.io.File +import java.io.FileInputStream +import java.io.FileOutputStream +import java.io.IOException +import java.util.concurrent.Executors +import java.util.concurrent.TimeUnit +import kotlin.math.max + +@SuppressLint("DiscouragedApi") +class DepthWallpaperA14(context: Context?) : ModPack(context!!) { + + private var showDepthWallpaper = false + private var showCustomImages = false + private var foregroundAlpha = 1.0f + private var mScrimController: Any? = null + private var mForegroundDimmingOverlay: Drawable? = null + private lateinit var mWallpaperForeground: FrameLayout + private lateinit var mWallpaperBackground: FrameLayout + private lateinit var mWallpaperBitmapContainer: FrameLayout + private lateinit var mWallpaperDimmingOverlay: FrameLayout + private var mWallpaperForegroundCacheValid = false + private var mLayersCreated = false + private var showOnAOD = true + private var foregroundPath = Environment.getExternalStorageDirectory() + .toString() + "/.iconify_files/depth_wallpaper_fg.png" + private var backgroundPath = Environment.getExternalStorageDirectory() + .toString() + "/.iconify_files/depth_wallpaper_bg.png" + + override fun updatePrefs(vararg key: String) { + if (!XprefsIsInitialized) return + + Xprefs.apply { + showDepthWallpaper = getBoolean(DEPTH_WALLPAPER_SWITCH, false) + showCustomImages = getBoolean(CUSTOM_DEPTH_WALLPAPER_SWITCH, false) + foregroundAlpha = getSliderInt(DEPTH_WALLPAPER_FOREGROUND_ALPHA, 80) / 100.0f + showOnAOD = getBoolean(DEPTH_WALLPAPER_ON_AOD, true) + } + + if (key.isNotEmpty()) { + key[0].let { + if (it == DEPTH_WALLPAPER_SWITCH || + it == DEPTH_WALLPAPER_CHANGED || + it == CUSTOM_DEPTH_WALLPAPER_SWITCH + ) { + if (it == DEPTH_WALLPAPER_CHANGED) { + mWallpaperForegroundCacheValid = false + } + + if (it == CUSTOM_DEPTH_WALLPAPER_SWITCH && !showCustomImages) { + invalidateCache() + } + + setCustomDepthWallpaper() + } + } + } + } + + override fun handleLoadPackage(loadPackageParam: LoadPackageParam) { + val qsImplClass = findClassInArray( + loadPackageParam.classLoader, + "$SYSTEMUI_PACKAGE.qs.QSImpl", + "$SYSTEMUI_PACKAGE.qs.QSFragment" + ) + val canvasEngineClass = findClass( + "$SYSTEMUI_PACKAGE.wallpapers.ImageWallpaper\$CanvasEngine", + loadPackageParam.classLoader + ) + val centralSurfacesImplClass = findClass( + "$SYSTEMUI_PACKAGE.statusbar.phone.CentralSurfacesImpl", + loadPackageParam.classLoader + ) + val scrimControllerClass = findClass( + "$SYSTEMUI_PACKAGE.statusbar.phone.ScrimController", + loadPackageParam.classLoader + ) + val scrimViewClass = findClass( + "$SYSTEMUI_PACKAGE.scrim.ScrimView", + loadPackageParam.classLoader + ) + + hookAllMethods(scrimViewClass, "setViewAlpha", object : XC_MethodHook() { + @Throws(Throwable::class) + override fun beforeHookedMethod(param: MethodHookParam) { + if (!mLayersCreated) return + + if (showOnAOD && getObjectField( + mScrimController, + "mState" + ).toString() != "KEYGUARD" + ) { + mWallpaperForeground.post { mWallpaperForeground.alpha = foregroundAlpha } + } else if (getObjectField( + mScrimController, + "mNotificationsScrim" + ) == param.thisObject + ) { // instead of using the mScrimName since older ones don't have that field + val mScrimBehindAlphaKeyguard = getFloatField( + mScrimController, + "mScrimBehindAlphaKeyguard" + ) + + var notificationAlpha = param.args[0] as Float + + if (notificationAlpha < mScrimBehindAlphaKeyguard) { + notificationAlpha = 0f + } + + val foregroundAlpha = if (notificationAlpha > mScrimBehindAlphaKeyguard) { + (1f - notificationAlpha) / (1f - mScrimBehindAlphaKeyguard) + } else { + 1f + } + + mWallpaperForeground.post { mWallpaperForeground.alpha = foregroundAlpha } + } + } + }) + + hookAllMethods(centralSurfacesImplClass, "start", object : XC_MethodHook() { + @Throws(Throwable::class) + override fun afterHookedMethod(param: MethodHookParam) { + val scrimBehind = getObjectField(mScrimController, "mScrimBehind") as View + val rootView = scrimBehind.parent as ViewGroup + + val targetView = rootView.findViewById( + mContext.resources.getIdentifier( + "notification_container_parent", + "id", + mContext.packageName + ) + ) + + if (!mLayersCreated) { + createLayers() + } + + rootView.addView(mWallpaperBackground, 0) + + targetView.addView(mWallpaperForeground, 1) + } + }) + + hookAllMethods(centralSurfacesImplClass, "onStartedWakingUp", object : XC_MethodHook() { + @Throws(Throwable::class) + override fun afterHookedMethod(param: MethodHookParam) { + setDepthWallpaper() + } + }) + + hookAllMethods(canvasEngineClass, "onSurfaceDestroyed", object : XC_MethodHook() { + // lockscreen wallpaper changed + @Throws(Throwable::class) + override fun afterHookedMethod(param: MethodHookParam) { + if (showDepthWallpaper && !showCustomImages && isLockScreenWallpaper(param.thisObject)) { + invalidateCache() + } + } + }) + + hookAllMethods(canvasEngineClass, "onCreate", object : XC_MethodHook() { + @Throws(Throwable::class) + override fun afterHookedMethod(param: MethodHookParam) { + if (callMethod( + getObjectField( + param.thisObject, + "mWallpaperManager" + ), + "getWallpaperInfo", + WallpaperManager.FLAG_LOCK + ) != null && !showCustomImages + ) { // it's live wallpaper. we can't use that + invalidateCache() + } + } + }) + + hookAllMethods(canvasEngineClass, "drawFrameOnCanvas", object : XC_MethodHook() { + @RequiresApi(Build.VERSION_CODES.TIRAMISU) + @Throws(Throwable::class) + override fun afterHookedMethod(param: MethodHookParam) { + if (showDepthWallpaper && !showCustomImages && isLockScreenWallpaper(param.thisObject)) { + val wallpaperBitmap = Bitmap.createBitmap((param.args[0] as Bitmap)) + + val cacheIsValid: Boolean = assertCache(wallpaperBitmap) + + val displayBounds = (callMethod( + param.thisObject, + "getDisplayContext" + ) as Context) + .getSystemService( + WindowManager::class.java + ) + .currentWindowMetrics + .bounds + + val ratioW = 1f * displayBounds.width() / wallpaperBitmap.width + val ratioH = 1f * displayBounds.height() / wallpaperBitmap.height + + val desiredHeight = Math.round( + max( + ratioH.toDouble(), + ratioW.toDouble() + ) * wallpaperBitmap.height + ).toInt() + val desiredWidth = Math.round( + max( + ratioH.toDouble(), + ratioW.toDouble() + ) * wallpaperBitmap.width + ).toInt() + + val xPixelShift = (desiredWidth - displayBounds.width()) / 2 + val yPixelShift = (desiredHeight - displayBounds.height()) / 2 + + var scaledWallpaperBitmap = Bitmap.createScaledBitmap( + wallpaperBitmap, + desiredWidth, + desiredHeight, + true + ) + + // crop to display bounds + scaledWallpaperBitmap = Bitmap.createBitmap( + scaledWallpaperBitmap, + xPixelShift, + yPixelShift, + displayBounds.width(), + displayBounds.height() + ) + val finalScaledWallpaperBitmap = scaledWallpaperBitmap + + try { + val file = File(backgroundPath) + file.parentFile?.mkdirs() + val out = FileOutputStream(file) + finalScaledWallpaperBitmap.compress(Bitmap.CompressFormat.PNG, 100, out) + out.flush() + out.close() + } catch (throwable: IOException) { + log(TAG + throwable) + } + + if (!mLayersCreated) { + createLayers() + } + + mWallpaperBackground.post { + mWallpaperBitmapContainer.background = BitmapDrawable( + mContext.resources, + finalScaledWallpaperBitmap + ) + if (mScrimController != null) { + mWallpaperDimmingOverlay.setBackgroundColor(Color.BLACK) + mWallpaperDimmingOverlay.alpha = getFloatField( + mScrimController, + "mScrimBehindAlphaKeyguard" + ) + } + } + + if (!cacheIsValid) { + val callback = object : IExtractSubjectCallback.Stub() { + override fun onStart(message: String) { + Handler(Looper.getMainLooper()).post { + Toast.makeText(mContext, message, Toast.LENGTH_LONG).show() + } + } + + override fun onResult(success: Boolean, message: String) { + Handler(Looper.getMainLooper()).post { + Toast.makeText(mContext, message, Toast.LENGTH_SHORT).show() + } + } + } + + enqueueProxyCommand { proxy -> + proxy?.extractSubject( + finalScaledWallpaperBitmap, + foregroundPath, + callback + ) + } + } + } + } + }) + + hookAllConstructors(scrimControllerClass, object : XC_MethodHook() { + @Throws(Throwable::class) + override fun afterHookedMethod(param: MethodHookParam) { + mScrimController = param.thisObject + } + }) + + hookAllMethods(scrimControllerClass, "applyAndDispatchState", object : XC_MethodHook() { + @Throws(Throwable::class) + override fun afterHookedMethod(param: MethodHookParam) { + setDepthWallpaper() + } + }) + + hookAllMethods(qsImplClass, "setQsExpansion", object : XC_MethodHook() { + @Throws(Throwable::class) + override fun beforeHookedMethod(param: MethodHookParam) { + if (callMethod(param.thisObject, "isKeyguardState") as Boolean) { + setDepthWallpaper() + } + } + }) + + /* + * Custom depth wallpaper images + */ + val keyguardBottomAreaViewClass = findClass( + "$SYSTEMUI_PACKAGE.statusbar.phone.KeyguardBottomAreaView", + loadPackageParam.classLoader + ) + + hookAllMethods( + keyguardBottomAreaViewClass, + "onConfigurationChanged", + object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + setCustomDepthWallpaper() + } + }) + + setCustomDepthWallpaper() + } + + @RequiresApi(Build.VERSION_CODES.TIRAMISU) + private fun assertCache(wallpaperBitmap: Bitmap): Boolean { + var cacheIsValid = false + + try { + val wallpaperCacheFile = File(backgroundPath) + + val compressedBitmap = ByteArrayOutputStream() + wallpaperBitmap.compress(Bitmap.CompressFormat.JPEG, 100, compressedBitmap) + if (wallpaperCacheFile.exists()) { + val cacheStream = FileInputStream(wallpaperCacheFile) + + if (cacheStream.readAllBytes().contentEquals(compressedBitmap.toByteArray())) { + cacheIsValid = true + } else { + val newCacheStream = FileOutputStream(wallpaperCacheFile) + compressedBitmap.writeTo(newCacheStream) + newCacheStream.close() + } + cacheStream.close() + } + compressedBitmap.close() + } catch (ignored: Throwable) { + } + + if (!cacheIsValid) { + invalidateCache() + } + + return cacheIsValid + } + + private fun createLayers() { + mWallpaperForeground = FrameLayout(mContext) + mWallpaperBackground = FrameLayout(mContext) + mWallpaperDimmingOverlay = FrameLayout(mContext) + mWallpaperBitmapContainer = FrameLayout(mContext) + + val layoutParams = FrameLayout.LayoutParams(-1, -1) + + mWallpaperDimmingOverlay.setBackgroundColor( + if (File(backgroundPath).exists()) { + Color.BLACK + } else { + Color.TRANSPARENT + } + ) + mWallpaperDimmingOverlay.alpha = 0F + + mWallpaperDimmingOverlay.layoutParams = layoutParams + mWallpaperBitmapContainer.layoutParams = layoutParams + + mWallpaperBackground.addView(mWallpaperBitmapContainer) + mWallpaperBackground.addView(mWallpaperDimmingOverlay) + + mWallpaperForeground.layoutParams = layoutParams + mWallpaperBackground.layoutParams = layoutParams + + mLayersCreated = true + } + + private fun isLockScreenWallpaper(canvasEngine: Any): Boolean { + return ((getWallpaperFlag(canvasEngine) and WallpaperManager.FLAG_LOCK) == WallpaperManager.FLAG_LOCK) + } + + private fun setDepthWallpaper() { + if (mScrimController == null) return + + val state = getObjectField(mScrimController, "mState").toString() + val showForeground = (showDepthWallpaper && + (state == "KEYGUARD" || (showOnAOD && (state == "AOD" || state == "PULSING")))) + + if (showForeground) { + if ((!mWallpaperForegroundCacheValid || mWallpaperForeground.background == null) && + File(foregroundPath).exists() + ) { + try { + FileInputStream(foregroundPath).use { inputStream -> + val bitmapDrawable = BitmapDrawable.createFromStream( + inputStream, + "" + ) + bitmapDrawable!!.alpha = 255 + + mForegroundDimmingOverlay = bitmapDrawable.constantState!! + .newDrawable().mutate() + mForegroundDimmingOverlay!!.setTint(Color.BLACK) + + mWallpaperForeground.background = LayerDrawable( + arrayOf( + bitmapDrawable, + mForegroundDimmingOverlay + ) + ) + mWallpaperForegroundCacheValid = true + } + } catch (ignored: Throwable) { + } + } + + if (mWallpaperForegroundCacheValid) { + mWallpaperForeground.background.alpha = (foregroundAlpha * 255).toInt() + + if (state != "KEYGUARD") { // AOD + mForegroundDimmingOverlay!!.alpha = 192 + } else { + // this is the dimmed wallpaper coverage + mForegroundDimmingOverlay!!.alpha = Math.round( + getFloatField( + mScrimController, + "mScrimBehindAlphaKeyguard" + ) * 240 + ) // A tad bit lower than max. show it a bit lighter than other stuff + + mWallpaperDimmingOverlay.alpha = getFloatField( + mScrimController, + "mScrimBehindAlphaKeyguard" + ) + } + + mWallpaperBackground.visibility = View.VISIBLE + mWallpaperForeground.visibility = View.VISIBLE + } + } else if (mLayersCreated) { + mWallpaperForeground.visibility = View.GONE + + if (state == "UNLOCKED") { + mWallpaperBackground.visibility = View.GONE + } + } + } + + private fun getWallpaperFlag(canvasEngine: Any): Int { + return callMethod(canvasEngine, "getWallpaperFlags") as Int + } + + private fun invalidateCache() { // invalidate lock screen wallpaper subject cache + mWallpaperForegroundCacheValid = false + + if (mLayersCreated) { + mWallpaperForeground.post { + mWallpaperForeground.visibility = View.GONE + mWallpaperForeground.background = null + mWallpaperBackground.visibility = View.GONE + mWallpaperBitmapContainer.background = null + } + } + + try { + if (File(foregroundPath).exists()) { + File(foregroundPath).delete() + } + } catch (ignored: Throwable) { + } + } + + /* + * Custom depth wallpaper images + */ + private fun setCustomDepthWallpaper() { + if (!showDepthWallpaper || !showCustomImages) return + + if (!mLayersCreated) { + createLayers() + } + + try { + val mainHandler = Handler(Looper.getMainLooper()) + val executor = Executors.newSingleThreadScheduledExecutor() + + executor.scheduleAtFixedRate({ + val androidDir = + File(Environment.getExternalStorageDirectory().toString() + "/Android") + + if (androidDir.isDirectory) { + mainHandler.post { + try { + if (File(backgroundPath).exists()) { + FileInputStream(backgroundPath).use { inputStream -> + val bitmapDrawable = BitmapDrawable.createFromStream( + inputStream, + "" + ) + bitmapDrawable!!.alpha = 255 + + mWallpaperBackground.post { + mWallpaperBitmapContainer.background = bitmapDrawable + + if (mScrimController != null) { + mWallpaperDimmingOverlay.setBackgroundColor(Color.BLACK) + mWallpaperDimmingOverlay.alpha = getFloatField( + mScrimController, + "mScrimBehindAlphaKeyguard" + ) + } + + mWallpaperBackground.visibility = View.VISIBLE + } + } + } + } catch (ignored: Throwable) { + } + + // this sets the dimmed foreground wallpaper + setDepthWallpaper() + } + + executor.shutdown() + executor.shutdownNow() + } + }, 0, 5, TimeUnit.SECONDS) + } catch (ignored: Throwable) { + } + } + + companion object { + private val TAG = "Iconify - ${DepthWallpaperA14::class.java.simpleName}: " + } +} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/xposed/modules/HeaderClock.kt b/app/src/main/java/com/drdisagree/iconify/xposed/modules/HeaderClock.kt index b4e846d05..44f96c602 100644 --- a/app/src/main/java/com/drdisagree/iconify/xposed/modules/HeaderClock.kt +++ b/app/src/main/java/com/drdisagree/iconify/xposed/modules/HeaderClock.kt @@ -1,8 +1,10 @@ package com.drdisagree.iconify.xposed.modules import android.annotation.SuppressLint +import android.content.BroadcastReceiver import android.content.Context import android.content.Intent +import android.content.IntentFilter import android.content.pm.PackageManager import android.content.res.Configuration import android.graphics.Bitmap @@ -29,6 +31,7 @@ import androidx.core.content.res.ResourcesCompat import androidx.core.text.TextUtilsCompat import com.drdisagree.iconify.BuildConfig import com.drdisagree.iconify.R +import com.drdisagree.iconify.common.Const.ACTION_BOOT_COMPLETED import com.drdisagree.iconify.common.Const.SYSTEMUI_PACKAGE import com.drdisagree.iconify.common.Preferences.HEADER_CLOCK_CENTERED import com.drdisagree.iconify.common.Preferences.HEADER_CLOCK_COLOR_CODE_ACCENT1 @@ -46,8 +49,7 @@ import com.drdisagree.iconify.common.Preferences.HEADER_CLOCK_SWITCH import com.drdisagree.iconify.common.Preferences.HEADER_CLOCK_TOPMARGIN import com.drdisagree.iconify.common.Preferences.ICONIFY_HEADER_CLOCK_TAG import com.drdisagree.iconify.common.Resources -import com.drdisagree.iconify.config.XPrefs.Xprefs -import com.drdisagree.iconify.utils.TextUtil +import com.drdisagree.iconify.utils.TextUtils import com.drdisagree.iconify.xposed.HookRes.Companion.resParams import com.drdisagree.iconify.xposed.ModPack import com.drdisagree.iconify.xposed.modules.utils.Helpers.getColorResCompat @@ -56,6 +58,8 @@ import com.drdisagree.iconify.xposed.modules.utils.ViewHelper.applyTextScalingRe import com.drdisagree.iconify.xposed.modules.utils.ViewHelper.findViewContainsTag import com.drdisagree.iconify.xposed.modules.utils.ViewHelper.findViewWithTagAndChangeColor import com.drdisagree.iconify.xposed.modules.utils.ViewHelper.setMargins +import com.drdisagree.iconify.xposed.utils.XPrefs.Xprefs +import com.drdisagree.iconify.xposed.utils.XPrefs.XprefsIsInitialized import de.robv.android.xposed.XC_MethodHook import de.robv.android.xposed.XposedBridge.hookAllConstructors import de.robv.android.xposed.XposedBridge.hookAllMethods @@ -73,6 +77,7 @@ import java.util.Locale import java.util.concurrent.Executors import java.util.concurrent.TimeUnit + @SuppressLint("DiscouragedApi") class HeaderClock(context: Context?) : ModPack(context!!) { @@ -80,7 +85,7 @@ class HeaderClock(context: Context?) : ModPack(context!!) { private var showHeaderClock = false private var centeredClockView = false private var hideLandscapeHeaderClock = true - private var mQsClockContainer: LinearLayout? = LinearLayout(mContext) + private var mQsClockContainer: LinearLayout = LinearLayout(mContext) private var mUserManager: UserManager? = null private var mActivityStarter: Any? = null private val mOnClickListener = View.OnClickListener { v: View -> @@ -91,13 +96,25 @@ class HeaderClock(context: Context?) : ModPack(context!!) { onDateClick() } } + private var mBroadcastRegistered = false + private val mReceiver: BroadcastReceiver = object : BroadcastReceiver() { + override fun onReceive(context: Context?, intent: Intent?) { + if (intent != null && intent.action != null) { + if (intent.action == ACTION_BOOT_COMPLETED) { + updateClockView() + } + } + } + } override fun updatePrefs(vararg key: String) { - if (Xprefs == null) return + if (!XprefsIsInitialized) return - showHeaderClock = Xprefs!!.getBoolean(HEADER_CLOCK_SWITCH, false) - centeredClockView = Xprefs!!.getBoolean(HEADER_CLOCK_CENTERED, false) - hideLandscapeHeaderClock = Xprefs!!.getBoolean(HEADER_CLOCK_LANDSCAPE_SWITCH, true) + Xprefs.apply { + showHeaderClock = getBoolean(HEADER_CLOCK_SWITCH, false) + centeredClockView = getBoolean(HEADER_CLOCK_CENTERED, false) + hideLandscapeHeaderClock = getBoolean(HEADER_CLOCK_LANDSCAPE_SWITCH, true) + } if (key.isNotEmpty() && (key[0] == HEADER_CLOCK_SWITCH || @@ -119,7 +136,28 @@ class HeaderClock(context: Context?) : ModPack(context!!) { } } + @SuppressLint("UnspecifiedRegisterReceiverFlag") override fun handleLoadPackage(loadPackageParam: LoadPackageParam) { + if (!mBroadcastRegistered) { + val intentFilter = IntentFilter() + intentFilter.addAction(ACTION_BOOT_COMPLETED) + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + mContext.registerReceiver( + mReceiver, + intentFilter, + Context.RECEIVER_EXPORTED + ) + } else { + mContext.registerReceiver( + mReceiver, + intentFilter + ) + } + + mBroadcastRegistered = true + } + initResources(mContext) val qsSecurityFooterUtilsClass = findClassIfExists( @@ -158,16 +196,15 @@ class HeaderClock(context: Context?) : ModPack(context!!) { if (!showHeaderClock) return val mQuickStatusBarHeader = param.thisObject as FrameLayout - val layoutParams = LinearLayout.LayoutParams( + + mQsClockContainer.layoutParams = LinearLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT ) + mQsClockContainer.visibility = View.GONE - mQsClockContainer!!.setLayoutParams(layoutParams) - mQsClockContainer!!.visibility = View.GONE - - if (mQsClockContainer!!.parent != null) { - (mQsClockContainer!!.parent as ViewGroup).removeView(mQsClockContainer) + if (mQsClockContainer.parent != null) { + (mQsClockContainer.parent as ViewGroup).removeView(mQsClockContainer) } mQuickStatusBarHeader.addView( @@ -287,7 +324,7 @@ class HeaderClock(context: Context?) : ModPack(context!!) { val androidDir = File(Environment.getExternalStorageDirectory().toString() + "/Android") - if (androidDir.isDirectory()) { + if (androidDir.isDirectory) { updateClockView() executor.shutdown() executor.shutdownNow() @@ -414,21 +451,19 @@ class HeaderClock(context: Context?) : ModPack(context!!) { } private fun updateClockView() { - if (mQsClockContainer == null) return - if (!showHeaderClock) { - mQsClockContainer!!.visibility = View.GONE + mQsClockContainer.visibility = View.GONE return } val isClockAdded = - mQsClockContainer!!.findViewWithTag(ICONIFY_HEADER_CLOCK_TAG) != null + mQsClockContainer.findViewWithTag(ICONIFY_HEADER_CLOCK_TAG) != null val clockView = clockView if (isClockAdded) { - mQsClockContainer!!.removeView( - mQsClockContainer!!.findViewWithTag( + mQsClockContainer.removeView( + mQsClockContainer.findViewWithTag( ICONIFY_HEADER_CLOCK_TAG ) ) @@ -436,16 +471,16 @@ class HeaderClock(context: Context?) : ModPack(context!!) { if (clockView != null) { if (centeredClockView) { - mQsClockContainer!!.gravity = Gravity.CENTER + mQsClockContainer.gravity = Gravity.CENTER } else { - mQsClockContainer!!.gravity = Gravity.START + mQsClockContainer.gravity = Gravity.START } clockView.tag = ICONIFY_HEADER_CLOCK_TAG - TextUtil.convertTextViewsToTitleCase(clockView) + TextUtils.convertTextViewsToTitleCase(clockView) - mQsClockContainer!!.addView(clockView) + mQsClockContainer.addView(clockView) modifyClockView(clockView) setOnClickListener(clockView) @@ -454,18 +489,18 @@ class HeaderClock(context: Context?) : ModPack(context!!) { val config = mContext.resources.configuration if (config.orientation == Configuration.ORIENTATION_LANDSCAPE && hideLandscapeHeaderClock) { - mQsClockContainer!!.visibility = View.GONE + mQsClockContainer.visibility = View.GONE } else { - mQsClockContainer!!.visibility = View.VISIBLE + mQsClockContainer.visibility = View.VISIBLE } } private val clockView: View? get() { - if (appContext == null || Xprefs == null) return null + if (appContext == null || !XprefsIsInitialized) return null val inflater = LayoutInflater.from(appContext) - val clockStyle: Int = Xprefs!!.getInt(HEADER_CLOCK_STYLE, 0) + val clockStyle: Int = Xprefs.getInt(HEADER_CLOCK_STYLE, 0) return inflater.inflate( appContext!!.resources.getIdentifier( @@ -478,54 +513,83 @@ class HeaderClock(context: Context?) : ModPack(context!!) { } private fun modifyClockView(clockView: View) { - if (Xprefs == null) return + if (!XprefsIsInitialized) return - val clockStyle: Int = Xprefs!!.getInt(HEADER_CLOCK_STYLE, 0) - val customFontEnabled: Boolean = Xprefs!!.getBoolean(HEADER_CLOCK_FONT_SWITCH, false) + val clockStyle: Int = Xprefs.getInt(HEADER_CLOCK_STYLE, 0) + val customFontEnabled: Boolean = Xprefs.getBoolean(HEADER_CLOCK_FONT_SWITCH, false) val clockScale: Float = - (Xprefs!!.getInt(HEADER_CLOCK_FONT_TEXT_SCALING, 10) / 10.0).toFloat() - val sideMargin: Int = Xprefs!!.getInt(HEADER_CLOCK_SIDEMARGIN, 0) - val topMargin: Int = Xprefs!!.getInt(HEADER_CLOCK_TOPMARGIN, 8) + (Xprefs.getSliderInt(HEADER_CLOCK_FONT_TEXT_SCALING, 10) / 10.0).toFloat() + val sideMargin: Int = Xprefs.getSliderInt(HEADER_CLOCK_SIDEMARGIN, 0) + val topMargin: Int = Xprefs.getSliderInt(HEADER_CLOCK_TOPMARGIN, 8) val customFont = Environment.getExternalStorageDirectory().toString() + "/.iconify_files/headerclock_font.ttf" - val accent1: Int = Xprefs!!.getInt( - HEADER_CLOCK_COLOR_CODE_ACCENT1, - mContext.resources.getColor( - mContext.resources.getIdentifier( - "android:color/system_accent1_300", - "color", - mContext.packageName - ), mContext.theme - ) - ) - val accent2: Int = Xprefs!!.getInt( - HEADER_CLOCK_COLOR_CODE_ACCENT2, - mContext.resources.getColor( - mContext.resources.getIdentifier( - "android:color/system_accent2_300", - "color", - mContext.packageName - ), mContext.theme - ) - ) - val accent3: Int = Xprefs!!.getInt( - HEADER_CLOCK_COLOR_CODE_ACCENT3, - mContext.resources.getColor( - mContext.resources.getIdentifier( - "android:color/system_accent3_300", - "color", - mContext.packageName - ), mContext.theme - ) + + val customColorEnabled = Xprefs.getBoolean(HEADER_CLOCK_COLOR_SWITCH, false) + var accent1: Int = mContext.resources.getColor( + mContext.resources.getIdentifier( + "android:color/system_accent1_300", + "color", + mContext.packageName + ), mContext.theme ) - val textPrimary: Int = Xprefs!!.getInt( - HEADER_CLOCK_COLOR_CODE_TEXT1, - getColorResCompat(mContext, android.R.attr.textColorPrimary) + var accent2: Int = mContext.resources.getColor( + mContext.resources.getIdentifier( + "android:color/system_accent2_300", + "color", + mContext.packageName + ), mContext.theme ) - val textInverse: Int = Xprefs!!.getInt( - HEADER_CLOCK_COLOR_CODE_TEXT2, - getColorResCompat(mContext, android.R.attr.textColorPrimaryInverse) + var accent3: Int = mContext.resources.getColor( + mContext.resources.getIdentifier( + "android:color/system_accent3_300", + "color", + mContext.packageName + ), mContext.theme ) + var textPrimary: Int = getColorResCompat(mContext, android.R.attr.textColorPrimary) + var textInverse: Int = getColorResCompat(mContext, android.R.attr.textColorPrimaryInverse) + + if (customColorEnabled) { + accent1 = Xprefs.getInt( + HEADER_CLOCK_COLOR_CODE_ACCENT1, + mContext.resources.getColor( + mContext.resources.getIdentifier( + "android:color/system_accent1_300", + "color", + mContext.packageName + ), mContext.theme + ) + ) + accent2 = Xprefs.getInt( + HEADER_CLOCK_COLOR_CODE_ACCENT2, + mContext.resources.getColor( + mContext.resources.getIdentifier( + "android:color/system_accent2_300", + "color", + mContext.packageName + ), mContext.theme + ) + ) + accent3 = Xprefs.getInt( + HEADER_CLOCK_COLOR_CODE_ACCENT3, + mContext.resources.getColor( + mContext.resources.getIdentifier( + "android:color/system_accent3_300", + "color", + mContext.packageName + ), mContext.theme + ) + ) + textPrimary = Xprefs.getInt( + HEADER_CLOCK_COLOR_CODE_TEXT1, + getColorResCompat(mContext, android.R.attr.textColorPrimary) + ) + textInverse = Xprefs.getInt( + HEADER_CLOCK_COLOR_CODE_TEXT2, + getColorResCompat(mContext, android.R.attr.textColorPrimaryInverse) + ) + } + var typeface: Typeface? = null if (customFontEnabled && File(customFont).exists()) typeface = @@ -542,6 +606,7 @@ class HeaderClock(context: Context?) : ModPack(context!!) { findViewWithTagAndChangeColor(clockView, "accent3", accent3) findViewWithTagAndChangeColor(clockView, "text1", textPrimary) findViewWithTagAndChangeColor(clockView, "text2", textInverse) + findViewWithTagAndChangeColor(clockView, "gradient", accent1, accent2, 26); if (typeface != null) { applyFontRecursively(clockView, typeface) diff --git a/app/src/main/java/com/drdisagree/iconify/xposed/modules/HeaderClockA14.kt b/app/src/main/java/com/drdisagree/iconify/xposed/modules/HeaderClockA14.kt new file mode 100644 index 000000000..3eae1c84c --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/xposed/modules/HeaderClockA14.kt @@ -0,0 +1,1127 @@ +package com.drdisagree.iconify.xposed.modules + +import android.annotation.SuppressLint +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import android.content.IntentFilter +import android.content.pm.PackageManager +import android.content.res.Configuration +import android.graphics.Bitmap +import android.graphics.Typeface +import android.graphics.drawable.BitmapDrawable +import android.graphics.drawable.Drawable +import android.os.Build +import android.os.Environment +import android.os.Handler +import android.os.Looper +import android.os.UserHandle +import android.os.UserManager +import android.provider.AlarmClock +import android.provider.CalendarContract +import android.view.Gravity +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.FrameLayout +import android.widget.ImageView +import android.widget.LinearLayout +import android.widget.TextView +import androidx.core.content.res.ResourcesCompat +import androidx.core.text.TextUtilsCompat +import com.drdisagree.iconify.BuildConfig +import com.drdisagree.iconify.R +import com.drdisagree.iconify.common.Const.ACTION_BOOT_COMPLETED +import com.drdisagree.iconify.common.Const.SYSTEMUI_PACKAGE +import com.drdisagree.iconify.common.Preferences.HEADER_CLOCK_CENTERED +import com.drdisagree.iconify.common.Preferences.HEADER_CLOCK_COLOR_CODE_ACCENT1 +import com.drdisagree.iconify.common.Preferences.HEADER_CLOCK_COLOR_CODE_ACCENT2 +import com.drdisagree.iconify.common.Preferences.HEADER_CLOCK_COLOR_CODE_ACCENT3 +import com.drdisagree.iconify.common.Preferences.HEADER_CLOCK_COLOR_CODE_TEXT1 +import com.drdisagree.iconify.common.Preferences.HEADER_CLOCK_COLOR_CODE_TEXT2 +import com.drdisagree.iconify.common.Preferences.HEADER_CLOCK_COLOR_SWITCH +import com.drdisagree.iconify.common.Preferences.HEADER_CLOCK_EXPANSION_Y +import com.drdisagree.iconify.common.Preferences.HEADER_CLOCK_FONT_SWITCH +import com.drdisagree.iconify.common.Preferences.HEADER_CLOCK_FONT_TEXT_SCALING +import com.drdisagree.iconify.common.Preferences.HEADER_CLOCK_LANDSCAPE_SWITCH +import com.drdisagree.iconify.common.Preferences.HEADER_CLOCK_SIDEMARGIN +import com.drdisagree.iconify.common.Preferences.HEADER_CLOCK_STYLE +import com.drdisagree.iconify.common.Preferences.HEADER_CLOCK_SWITCH +import com.drdisagree.iconify.common.Preferences.HEADER_CLOCK_TOPMARGIN +import com.drdisagree.iconify.common.Preferences.HIDE_STATUS_ICONS_SWITCH +import com.drdisagree.iconify.common.Preferences.ICONIFY_HEADER_CLOCK_TAG +import com.drdisagree.iconify.common.Preferences.ICONIFY_QS_HEADER_CONTAINER_SHADE_TAG +import com.drdisagree.iconify.common.Preferences.ICONIFY_QS_HEADER_CONTAINER_TAG +import com.drdisagree.iconify.common.Preferences.OP_QS_HEADER_SWITCH +import com.drdisagree.iconify.common.Preferences.QSPANEL_HIDE_CARRIER +import com.drdisagree.iconify.common.Resources +import com.drdisagree.iconify.utils.TextUtils +import com.drdisagree.iconify.xposed.HookRes.Companion.resParams +import com.drdisagree.iconify.xposed.ModPack +import com.drdisagree.iconify.xposed.modules.utils.Helpers.findClassInArray +import com.drdisagree.iconify.xposed.modules.utils.Helpers.getColorResCompat +import com.drdisagree.iconify.xposed.modules.utils.TouchAnimator +import com.drdisagree.iconify.xposed.modules.utils.ViewHelper.applyFontRecursively +import com.drdisagree.iconify.xposed.modules.utils.ViewHelper.applyTextScalingRecursively +import com.drdisagree.iconify.xposed.modules.utils.ViewHelper.findViewContainsTag +import com.drdisagree.iconify.xposed.modules.utils.ViewHelper.findViewWithTagAndChangeColor +import com.drdisagree.iconify.xposed.modules.utils.ViewHelper.setMargins +import com.drdisagree.iconify.xposed.modules.utils.ViewHelper.toPx +import com.drdisagree.iconify.xposed.utils.XPrefs.Xprefs +import com.drdisagree.iconify.xposed.utils.XPrefs.XprefsIsInitialized +import de.robv.android.xposed.XC_MethodHook +import de.robv.android.xposed.XC_MethodReplacement +import de.robv.android.xposed.XposedBridge.hookAllConstructors +import de.robv.android.xposed.XposedBridge.hookAllMethods +import de.robv.android.xposed.XposedBridge.log +import de.robv.android.xposed.XposedHelpers.callMethod +import de.robv.android.xposed.XposedHelpers.callStaticMethod +import de.robv.android.xposed.XposedHelpers.findAndHookMethod +import de.robv.android.xposed.XposedHelpers.findClass +import de.robv.android.xposed.XposedHelpers.findClassIfExists +import de.robv.android.xposed.XposedHelpers.getObjectField +import de.robv.android.xposed.callbacks.XC_InitPackageResources.InitPackageResourcesParam +import de.robv.android.xposed.callbacks.XC_LayoutInflated +import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam +import java.io.File +import java.util.Locale +import java.util.concurrent.Executors +import java.util.concurrent.TimeUnit + +@SuppressLint("DiscouragedApi") +class HeaderClockA14(context: Context?) : ModPack(context!!) { + + private var appContext: Context? = null + private var showHeaderClock = false + private var centeredClockView = false + private var mQsHeaderClockContainer: LinearLayout = LinearLayout(mContext) + private var mQsHeaderContainerShade: LinearLayout = LinearLayout(mContext).apply { + tag = ICONIFY_QS_HEADER_CONTAINER_SHADE_TAG + } + private var mQsClockContainer: LinearLayout = LinearLayout(mContext) + private var mQsIconsContainer: LinearLayout = LinearLayout(mContext) + private var mQsPanelView: ViewGroup? = null + private var mQuickStatusBarHeader: FrameLayout? = null + private var mUserManager: UserManager? = null + private var mActivityStarter: Any? = null + private var mQQSContainerAnimator: TouchAnimator? = null + private var mQQSExpansionY: Float = 8f + private var hideQsCarrierGroup = false + private var hideStatusIcons = false + private var mBroadcastRegistered = false + private val mReceiver: BroadcastReceiver = object : BroadcastReceiver() { + override fun onReceive(context: Context?, intent: Intent?) { + if (intent != null && intent.action != null) { + if (intent.action == ACTION_BOOT_COMPLETED) { + updateClockView() + } + } + } + } + private val mViewOnClickListener = View.OnClickListener { v: View -> + val tag = v.tag.toString() + if (tag == "clock") { + onClockClick() + } else if (tag == "date") { + onDateClick() + } + } + private var showOpQsHeaderView = false + + override fun updatePrefs(vararg key: String) { + if (!XprefsIsInitialized) return + + Xprefs.apply { + showHeaderClock = getBoolean(HEADER_CLOCK_SWITCH, false) + centeredClockView = getBoolean(HEADER_CLOCK_CENTERED, false) + mQQSExpansionY = getSliderInt(HEADER_CLOCK_EXPANSION_Y, 24).toFloat() + hideQsCarrierGroup = getBoolean(QSPANEL_HIDE_CARRIER, false) + hideStatusIcons = getBoolean(HIDE_STATUS_ICONS_SWITCH, false) + showOpQsHeaderView = getBoolean(OP_QS_HEADER_SWITCH, false) + } + + if (key.isNotEmpty()) { + if (key[0] == HEADER_CLOCK_EXPANSION_Y) { + buildHeaderViewExpansion() + } + + if (key[0] == HEADER_CLOCK_SWITCH || + key[0] == HEADER_CLOCK_COLOR_SWITCH || + key[0] == HEADER_CLOCK_COLOR_CODE_ACCENT1 || + key[0] == HEADER_CLOCK_COLOR_CODE_ACCENT2 || + key[0] == HEADER_CLOCK_COLOR_CODE_ACCENT3 || + key[0] == HEADER_CLOCK_COLOR_CODE_TEXT1 || + key[0] == HEADER_CLOCK_COLOR_CODE_TEXT2 || + key[0] == HEADER_CLOCK_FONT_SWITCH || + key[0] == HEADER_CLOCK_SIDEMARGIN || + key[0] == HEADER_CLOCK_TOPMARGIN || + key[0] == HEADER_CLOCK_STYLE || + key[0] == HEADER_CLOCK_CENTERED || + key[0] == HEADER_CLOCK_FONT_TEXT_SCALING || + key[0] == HEADER_CLOCK_LANDSCAPE_SWITCH + ) { + updateClockView() + } + } + } + + @SuppressLint("UnspecifiedRegisterReceiverFlag") + override fun handleLoadPackage(loadPackageParam: LoadPackageParam) { + if (!mBroadcastRegistered) { + val intentFilter = IntentFilter() + intentFilter.addAction(ACTION_BOOT_COMPLETED) + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + mContext.registerReceiver( + mReceiver, + intentFilter, + Context.RECEIVER_EXPORTED + ) + } else { + mContext.registerReceiver( + mReceiver, + intentFilter + ) + } + + mBroadcastRegistered = true + } + + initResources(mContext) + + val qsPanelClass = findClass( + "$SYSTEMUI_PACKAGE.qs.QSPanel", + loadPackageParam.classLoader + ) + val qsImplClass = findClassInArray( + loadPackageParam.classLoader, + "$SYSTEMUI_PACKAGE.qs.QSImpl", + "$SYSTEMUI_PACKAGE.qs.QSFragment" + ) + val shadeHeaderControllerClass = findClassInArray( + loadPackageParam.classLoader, + "$SYSTEMUI_PACKAGE.shade.LargeScreenShadeHeaderController", + "$SYSTEMUI_PACKAGE.shade.ShadeHeaderController" + ) + val qsPanelControllerBase = findClassIfExists( + "$SYSTEMUI_PACKAGE.qs.QSPanelControllerBase", + loadPackageParam.classLoader + ) + val qsSecurityFooterUtilsClass = findClassIfExists( + "$SYSTEMUI_PACKAGE.qs.QSSecurityFooterUtils", + loadPackageParam.classLoader + ) + val quickStatusBarHeaderClass = findClass( + "$SYSTEMUI_PACKAGE.qs.QuickStatusBarHeader", + loadPackageParam.classLoader + ) + val dependencyClass = findClass( + "$SYSTEMUI_PACKAGE.Dependency", + loadPackageParam.classLoader + ) + val activityStarterClass = findClass( + "$SYSTEMUI_PACKAGE.plugins.ActivityStarter", + loadPackageParam.classLoader + ) + + if (qsSecurityFooterUtilsClass == null) { + hookAllConstructors(quickStatusBarHeaderClass, object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + mActivityStarter = callStaticMethod( + dependencyClass, + "get", + activityStarterClass + ) + } + }) + } else { + hookAllConstructors(qsSecurityFooterUtilsClass, object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + mActivityStarter = getObjectField( + param.thisObject, + "mActivityStarter" + ) + } + }) + } + + hookAllMethods(quickStatusBarHeaderClass, "onFinishInflate", object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + if (!showHeaderClock) return + + mQuickStatusBarHeader = param.thisObject as FrameLayout + + mQsHeaderClockContainer.apply { + layoutParams = LinearLayout.LayoutParams( + LinearLayout.LayoutParams.MATCH_PARENT, + LinearLayout.LayoutParams.WRAP_CONTENT + ).apply { + bottomMargin = mContext.toPx(16) + } + orientation = LinearLayout.HORIZONTAL + } + + mQsHeaderContainerShade.apply { + layoutParams = LinearLayout.LayoutParams( + LinearLayout.LayoutParams.MATCH_PARENT, + LinearLayout.LayoutParams.WRAP_CONTENT + ) + orientation = LinearLayout.VERTICAL + } + + mQsClockContainer.apply { + layoutParams = LinearLayout.LayoutParams( + 0, + LinearLayout.LayoutParams.MATCH_PARENT, + 1f + ) + orientation = LinearLayout.VERTICAL + } + + mQsIconsContainer.apply { + layoutParams = LinearLayout.LayoutParams( + LinearLayout.LayoutParams.WRAP_CONTENT, + LinearLayout.LayoutParams.MATCH_PARENT + ) + orientation = LinearLayout.VERTICAL + gravity = Gravity.END or Gravity.CENTER + } + + mQsHeaderClockContainer.apply { + (this.parent as? ViewGroup)?.removeView(this) + removeAllViews() + addView(mQsClockContainer) + addView(mQsIconsContainer) + } + + (mQsHeaderClockContainer.parent as? ViewGroup)?.removeView(mQsHeaderClockContainer) + val headerImageAvailable = mQuickStatusBarHeader!!.findViewWithTag( + ICONIFY_QS_HEADER_CONTAINER_TAG + ) + mQuickStatusBarHeader!!.addView( + mQsHeaderClockContainer, + if (headerImageAvailable == null) { + -1 + } else { + mQuickStatusBarHeader!!.indexOfChild(headerImageAvailable) + 1 + } + ) + + handleOldHeaderView(param) + + updateClockView() + } + }) + + hookAllMethods(quickStatusBarHeaderClass, "updateResources", object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + if (!showHeaderClock) return + + mQuickStatusBarHeader = param.thisObject as FrameLayout + + buildHeaderViewExpansion() + + val isLandscape = + mContext.resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE + + if (isLandscape) { + if (mQsHeaderClockContainer.parent != mQsHeaderContainerShade) { + (mQsHeaderClockContainer.parent as? ViewGroup)?.removeView( + mQsHeaderClockContainer + ) + mQsHeaderContainerShade.addView(mQsHeaderClockContainer, 0) + } + mQsHeaderContainerShade.visibility = View.VISIBLE + } else { + if (mQsHeaderClockContainer.parent != mQuickStatusBarHeader) { + val headerImageAvailable = + mQuickStatusBarHeader!!.findViewWithTag( + ICONIFY_QS_HEADER_CONTAINER_TAG + ) + (mQsHeaderClockContainer.parent as? ViewGroup)?.removeView( + mQsHeaderClockContainer + ) + mQuickStatusBarHeader?.addView( + mQsHeaderClockContainer, + if (headerImageAvailable == null) { + 0 + } else { + mQuickStatusBarHeader!!.indexOfChild(headerImageAvailable) + 1 + } + ) + } + mQsHeaderContainerShade.visibility = View.GONE + } + + updateClockView() + } + }) + + val hasSwitchAllContentToParent = qsPanelClass.declaredMethods.any { + it.name == "switchAllContentToParent" + } + val hasSwitchToParentMethod = qsPanelClass.declaredMethods.any { method -> + method.name == "switchToParent" && + method.parameterTypes.contentEquals( + arrayOf(View::class.java, ViewGroup::class.java, Int::class.java) + ) + } + + if (hasSwitchAllContentToParent && hasSwitchToParentMethod) { + hookAllMethods(qsPanelClass, "switchAllContentToParent", object : XC_MethodHook() { + override fun beforeHookedMethod(param: MethodHookParam) { + if (!showHeaderClock) return + + val parent = param.args[0] as ViewGroup + val mMovableContentStartIndex = getObjectField( + param.thisObject, "mMovableContentStartIndex" + ) as Int + val index = if (parent === param.thisObject) mMovableContentStartIndex else 0 + val targetParentId = mContext.resources.getIdentifier( + "quick_settings_panel", + "id", + mContext.packageName + ) + + if (parent.id == targetParentId) { + val checkExistingView = + parent.findViewWithTag(ICONIFY_QS_HEADER_CONTAINER_SHADE_TAG) + if (checkExistingView != null) { + mQsHeaderContainerShade = checkExistingView as LinearLayout + if (parent.indexOfChild(mQsHeaderContainerShade) == index) { + return + } + } + + callMethod( + param.thisObject, + "switchToParent", + mQsHeaderContainerShade, + parent, + index + ) + } + } + }) + + if (showHeaderClock) { + findAndHookMethod( + qsPanelClass, + "switchToParent", + View::class.java, + ViewGroup::class.java, + Int::class.java, + object : XC_MethodReplacement() { + override fun replaceHookedMethod(param: MethodHookParam): Any? { + val view = param.args[0] as View + val parent = param.args[1] as ViewGroup + val tempIndex = param.args[2] as Int + val index = if (view.tag == ICONIFY_QS_HEADER_CONTAINER_SHADE_TAG) { + tempIndex + } else { + tempIndex + 1 + } + val tag = callMethod(param.thisObject, "getDumpableTag") + + callMethod( + param.thisObject, + "switchToParent", + view, + parent, + index.coerceAtMost(parent.childCount), + tag + ) + + return null + } + } + ) + } + + if (showHeaderClock) { + findAndHookMethod( + qsPanelClass, + "switchToParent", + View::class.java, + ViewGroup::class.java, + Int::class.java, + String::class.java, + object : XC_MethodReplacement() { + override fun replaceHookedMethod(param: MethodHookParam): Any? { + val view = param.args[0] as View + val newParent = param.args[1] as? ViewGroup + val tempIndex = param.args[2] as Int + + if (newParent == null) { + return null + } + + val index = if (view.tag == ICONIFY_QS_HEADER_CONTAINER_SHADE_TAG) { + tempIndex + } else { + tempIndex + 1 + }.coerceAtMost(newParent.childCount) + + val currentParent = view.parent as? ViewGroup + + if (currentParent != newParent) { + currentParent?.removeView(view) + newParent.addView(view, index.coerceAtMost(newParent.childCount)) + } else if (newParent.indexOfChild(view) == index) { + return null + } else { + newParent.removeView(view) + newParent.addView(view, index.coerceAtMost(newParent.childCount)) + } + + return null + } + } + ) + } + } else { // Some ROMs don't have this method switchAllContentToParent() + hookAllMethods( + qsPanelControllerBase, + "onInit", + object : XC_MethodHook() { + override fun beforeHookedMethod(param: MethodHookParam) { + mQsPanelView = getObjectField( + param.thisObject, + "mView" + ) as ViewGroup + } + } + ) + + findAndHookMethod( + qsPanelClass, + "switchToParent", + View::class.java, + ViewGroup::class.java, + Int::class.java, + String::class.java, + object : XC_MethodHook() { + override fun beforeHookedMethod(param: MethodHookParam) { + if (!showHeaderClock || + mQsPanelView == null || + (param.args[1] as? ViewGroup) == null + ) return + + val parent = param.args[1] as ViewGroup + val mMovableContentStartIndex = getObjectField( + mQsPanelView, "mMovableContentStartIndex" + ) as Int + val index = if (parent === mQsPanelView) mMovableContentStartIndex else 0 + val targetParentId = mContext.resources.getIdentifier( + "quick_settings_panel", + "id", + SYSTEMUI_PACKAGE + ) + + if (parent.id == targetParentId) { + val mQsHeaderContainerShadeParent = + mQsHeaderContainerShade.parent as? ViewGroup + if (mQsHeaderContainerShadeParent != parent || + mQsHeaderContainerShadeParent.indexOfChild(mQsHeaderContainerShade) != index + ) { + mQsHeaderContainerShadeParent?.removeView(mQsHeaderContainerShade) + parent.addView( + mQsHeaderContainerShade, + index.coerceAtMost(parent.childCount) + ) + } + } + + param.args[2] = (param.args[2] as Int) + 1 + } + } + ) + } + + hookAllMethods(qsImplClass, "setQsExpansion", object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + if (!showHeaderClock) return + + val onKeyguard = callMethod( + param.thisObject, + "isKeyguardState" + ) as Boolean + val mShowCollapsedOnKeyguard = getObjectField( + param.thisObject, + "mShowCollapsedOnKeyguard" + ) as Boolean + + val onKeyguardAndExpanded = onKeyguard && !mShowCollapsedOnKeyguard + val expansion = param.args[0] as Float + + setExpansion(onKeyguardAndExpanded, expansion); + } + }) + + hookAllMethods( + android.content.res.Resources::class.java, + "getBoolean", + object : XC_MethodHook() { + override fun beforeHookedMethod(param: MethodHookParam) { + if (!showHeaderClock) return + + val resId1 = mContext.resources.getIdentifier( + "config_use_split_notification_shade", + "bool", + SYSTEMUI_PACKAGE + ) + + val resId2 = mContext.resources.getIdentifier( + "config_skinnyNotifsInLandscape", + "bool", + SYSTEMUI_PACKAGE + ) + + if (param.args[0] == resId1) { + val isLandscape = + mContext.resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE + + param.result = isLandscape + } else if (param.args[0] == resId2) { + param.result = false + } + } + } + ) + + hookAllMethods( + android.content.res.Resources::class.java, + "getDimensionPixelSize", + object : XC_MethodHook() { + override fun beforeHookedMethod(param: MethodHookParam) { + if (!showHeaderClock) return + + val res1 = mContext.resources.getIdentifier( + "qs_brightness_margin_top", + "dimen", + SYSTEMUI_PACKAGE + ) + + if (res1 != 0 && param.args[0] == res1) { + param.result = 0 + } + } + } + ) + + hookAllMethods(shadeHeaderControllerClass, "onInit", object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + if (!showHeaderClock) return + + val clock = getObjectField(param.thisObject, "clock") as TextView + (clock.parent as? ViewGroup)?.removeView(clock) + + val date = getObjectField(param.thisObject, "date") as TextView + (date.parent as? ViewGroup)?.removeView(date) + + mQsIconsContainer.removeAllViews() + + try { + val qsCarrierGroup = + getObjectField(param.thisObject, "qsCarrierGroup") as LinearLayout + (qsCarrierGroup.parent as? ViewGroup)?.removeView(qsCarrierGroup) + if (hideQsCarrierGroup) qsCarrierGroup.visibility = View.GONE + mQsIconsContainer.addView(qsCarrierGroup) + } catch (ignored: Throwable) { + val mShadeCarrierGroup = + getObjectField( + param.thisObject, + "mShadeCarrierGroup" + ) as LinearLayout + (mShadeCarrierGroup.parent as? ViewGroup)?.removeView(mShadeCarrierGroup) + if (hideQsCarrierGroup) mShadeCarrierGroup.visibility = View.GONE + mQsIconsContainer.addView(mShadeCarrierGroup) + } + + try { + val systemIconsHoverContainer = + getObjectField( + param.thisObject, + "systemIconsHoverContainer" + ) as LinearLayout + (systemIconsHoverContainer.parent as? ViewGroup)?.removeView( + systemIconsHoverContainer + ) + if (hideStatusIcons) systemIconsHoverContainer.visibility = View.GONE + mQsIconsContainer.addView(systemIconsHoverContainer) + } catch (ignored: Throwable) { + val iconsContainer = LinearLayout(mContext).apply { + layoutParams = LinearLayout.LayoutParams( + LinearLayout.LayoutParams.WRAP_CONTENT, + mContext.toPx(32) + ) + orientation = LinearLayout.HORIZONTAL + gravity = Gravity.END or Gravity.CENTER + } + + val statusIcons = getObjectField(param.thisObject, "iconContainer") as View + (statusIcons.parent as? ViewGroup)?.removeView(statusIcons) + + val batteryIcon = getObjectField(param.thisObject, "batteryIcon") as View + (batteryIcon.parent as? ViewGroup)?.removeView(batteryIcon) + + iconsContainer.apply { + addView(statusIcons) + addView(batteryIcon) + if (hideStatusIcons) visibility = View.GONE + mQsIconsContainer.addView(this) + } + } + } + }) + + handleLegacyHeaderView() + + try { + val executor = Executors.newSingleThreadScheduledExecutor() + executor.scheduleAtFixedRate({ + val androidDir = + File(Environment.getExternalStorageDirectory().toString() + "/Android") + + if (androidDir.isDirectory) { + updateClockView() + executor.shutdown() + executor.shutdownNow() + } + }, 0, 5, TimeUnit.SECONDS) + } catch (ignored: Throwable) { + } + } + + private fun buildHeaderViewExpansion() { + val isLandscape = + mContext.resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE + val mQQSExpansionY = if (isLandscape) 0 else mQQSExpansionY + + val builderP: TouchAnimator.Builder = TouchAnimator.Builder() + .addFloat( + mQsHeaderClockContainer, + "translationY", + 0F, + mContext.toPx(mQQSExpansionY.toInt()).toFloat() + ) + + mQQSContainerAnimator = builderP.build() + } + + private fun setExpansion(forceExpanded: Boolean, expansionFraction: Float) { + val keyguardExpansionFraction = if (forceExpanded) 1f else expansionFraction + mQQSContainerAnimator?.setPosition(keyguardExpansionFraction) + + mQsHeaderClockContainer.alpha = if (forceExpanded) expansionFraction else 1f + } + + private fun initResources(context: Context) { + try { + appContext = context.createPackageContext( + BuildConfig.APPLICATION_ID, + Context.CONTEXT_IGNORE_SECURITY + ) + } catch (ignored: PackageManager.NameNotFoundException) { + } + + Handler(Looper.getMainLooper()).post { + mUserManager = context.getSystemService(Context.USER_SERVICE) as UserManager + } + } + + private fun updateClockView() { + if (!showHeaderClock) return + + val isClockAdded = + mQsClockContainer.findViewWithTag(ICONIFY_HEADER_CLOCK_TAG) != null + + if (isClockAdded) { + mQsClockContainer.removeView( + mQsClockContainer.findViewWithTag( + ICONIFY_HEADER_CLOCK_TAG + ) + ) + } + + clockView?.let { + if (centeredClockView) { + mQsClockContainer.gravity = Gravity.CENTER + } else { + mQsClockContainer.gravity = Gravity.START + } + + it.tag = ICONIFY_HEADER_CLOCK_TAG + + TextUtils.convertTextViewsToTitleCase(it) + + mQsClockContainer.addView(it) + + it.layoutParams.width = LinearLayout.LayoutParams.WRAP_CONTENT + + modifyClockView(it) + setOnClickListener(it) + } + } + + private val clockView: View? + get() { + if (appContext == null || !XprefsIsInitialized) return null + + val inflater = LayoutInflater.from(appContext) + val clockStyle: Int = Xprefs.getInt(HEADER_CLOCK_STYLE, 0) + + return inflater.inflate( + appContext!!.resources.getIdentifier( + Resources.HEADER_CLOCK_LAYOUT + clockStyle, + "layout", + BuildConfig.APPLICATION_ID + ), + null + ) + } + + private fun modifyClockView(clockView: View) { + if (!XprefsIsInitialized) return + + val isLandscape = + mContext.resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE + val clockStyle: Int = Xprefs.getInt(HEADER_CLOCK_STYLE, 0) + val customFontEnabled: Boolean = Xprefs.getBoolean(HEADER_CLOCK_FONT_SWITCH, false) + val clockScale: Float = + (Xprefs.getSliderInt(HEADER_CLOCK_FONT_TEXT_SCALING, 10) / 10.0).toFloat() + val sideMargin: Int = Xprefs.getSliderInt(HEADER_CLOCK_SIDEMARGIN, 0) + val topMargin: Int = if (isLandscape) 0 else Xprefs.getSliderInt(HEADER_CLOCK_TOPMARGIN, 8) + val customFont = Environment.getExternalStorageDirectory().toString() + + "/.iconify_files/headerclock_font.ttf" + + val customColorEnabled = Xprefs.getBoolean(HEADER_CLOCK_COLOR_SWITCH, false) + var accent1: Int = mContext.resources.getColor( + mContext.resources.getIdentifier( + "android:color/system_accent1_300", + "color", + mContext.packageName + ), mContext.theme + ) + var accent2: Int = mContext.resources.getColor( + mContext.resources.getIdentifier( + "android:color/system_accent2_300", + "color", + mContext.packageName + ), mContext.theme + ) + var accent3: Int = mContext.resources.getColor( + mContext.resources.getIdentifier( + "android:color/system_accent3_300", + "color", + mContext.packageName + ), mContext.theme + ) + var textPrimary: Int = getColorResCompat(mContext, android.R.attr.textColorPrimary) + var textInverse: Int = getColorResCompat(mContext, android.R.attr.textColorPrimaryInverse) + + if (customColorEnabled) { + accent1 = Xprefs.getInt( + HEADER_CLOCK_COLOR_CODE_ACCENT1, + mContext.resources.getColor( + mContext.resources.getIdentifier( + "android:color/system_accent1_300", + "color", + mContext.packageName + ), mContext.theme + ) + ) + accent2 = Xprefs.getInt( + HEADER_CLOCK_COLOR_CODE_ACCENT2, + mContext.resources.getColor( + mContext.resources.getIdentifier( + "android:color/system_accent2_300", + "color", + mContext.packageName + ), mContext.theme + ) + ) + accent3 = Xprefs.getInt( + HEADER_CLOCK_COLOR_CODE_ACCENT3, + mContext.resources.getColor( + mContext.resources.getIdentifier( + "android:color/system_accent3_300", + "color", + mContext.packageName + ), mContext.theme + ) + ) + textPrimary = Xprefs.getInt( + HEADER_CLOCK_COLOR_CODE_TEXT1, + getColorResCompat(mContext, android.R.attr.textColorPrimary) + ) + textInverse = Xprefs.getInt( + HEADER_CLOCK_COLOR_CODE_TEXT2, + getColorResCompat(mContext, android.R.attr.textColorPrimaryInverse) + ) + } + + var typeface: Typeface? = null + + if (customFontEnabled && File(customFont).exists()) typeface = + Typeface.createFromFile(File(customFont)) + + + setMargins(mQsHeaderClockContainer, mContext, 0, topMargin, 0, 0) + + if (TextUtilsCompat.getLayoutDirectionFromLocale(Locale.getDefault()) == View.LAYOUT_DIRECTION_RTL) { + setMargins(clockView, mContext, 0, 0, sideMargin, 0) + } else { + setMargins(clockView, mContext, sideMargin, 0, 0, 0) + } + + findViewWithTagAndChangeColor(clockView, "accent1", accent1) + findViewWithTagAndChangeColor(clockView, "accent2", accent2) + findViewWithTagAndChangeColor(clockView, "accent3", accent3) + findViewWithTagAndChangeColor(clockView, "text1", textPrimary) + findViewWithTagAndChangeColor(clockView, "text2", textInverse) + findViewWithTagAndChangeColor(clockView, "gradient", accent1, accent2, 26); + + if (typeface != null) { + applyFontRecursively(clockView, typeface) + } + + if (clockScale != 1f) { + applyTextScalingRecursively(clockView, clockScale) + } + + when (clockStyle) { + 6 -> { + val imageView = + clockView.findViewContainsTag("user_profile_image") as ImageView? + userImage?.let { imageView?.setImageDrawable(it) } + } + } + } + + private val userImage: Drawable? + get() = if (mUserManager == null) { + ResourcesCompat.getDrawable( + appContext!!.resources, + R.drawable.default_avatar, + appContext!!.theme + ) + } else try { + val getUserIconMethod = + mUserManager!!.javaClass.getMethod( + "getUserIcon", + Int::class.javaPrimitiveType + ) + val userId = + UserHandle::class.java.getDeclaredMethod("myUserId").invoke(null) as Int + val bitmapUserIcon = getUserIconMethod.invoke(mUserManager, userId) as Bitmap + + BitmapDrawable(mContext.resources, bitmapUserIcon) + } catch (throwable: Throwable) { + if (throwable !is NullPointerException) { + log(TAG + throwable) + } + + ResourcesCompat.getDrawable( + appContext!!.resources, + R.drawable.default_avatar, + appContext!!.theme + ) + } + + private fun setOnClickListener(view: View?) { + if (view == null) return + + if (view is ViewGroup) { + for (i in 0 until view.childCount) { + val child: View = view.getChildAt(i) + val tag = if (child.tag == null) "" else child.tag.toString() + + if (tag.lowercase(Locale.getDefault()).contains("clock") || + tag.lowercase(Locale.getDefault()).contains("date") + ) { + child.setOnClickListener(mViewOnClickListener) + } + + (child as? ViewGroup)?.let { setOnClickListener(it) } + } + } else { + val tag = if (view.tag == null) "" else view.tag.toString() + + if (tag.lowercase(Locale.getDefault()).contains("clock") || + tag.lowercase(Locale.getDefault()).contains("date") + ) { + view.setOnClickListener(mViewOnClickListener) + } + } + } + + private fun onClockClick() { + if (mActivityStarter == null) return + + val intent = Intent(AlarmClock.ACTION_SHOW_ALARMS) + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP + Intent.FLAG_ACTIVITY_SINGLE_TOP) + + callMethod(mActivityStarter, "postStartActivityDismissingKeyguard", intent, 0) + } + + private fun onDateClick() { + if (mActivityStarter == null) return + + val builder = CalendarContract.CONTENT_URI.buildUpon() + builder.appendPath("time") + builder.appendPath(System.currentTimeMillis().toString()) + + val intent = Intent(Intent.ACTION_VIEW, builder.build()) + + callMethod(mActivityStarter, "postStartActivityDismissingKeyguard", intent, 0) + } + + private fun handleOldHeaderView(param: XC_MethodHook.MethodHookParam) { + if (!showHeaderClock) return + + try { + val mDateView = + getObjectField(param.thisObject, "mDateView") as View + mDateView.layoutParams.height = 0 + mDateView.layoutParams.width = 0 + mDateView.visibility = View.INVISIBLE + } catch (ignored: Throwable) { + } + + try { + val mClockView = + getObjectField(param.thisObject, "mClockView") as TextView + mClockView.visibility = View.INVISIBLE + mClockView.setTextAppearance(0) + mClockView.setTextColor(0) + } catch (ignored: Throwable) { + } + + try { + val mClockDateView = getObjectField( + param.thisObject, + "mClockDateView" + ) as TextView + mClockDateView.visibility = View.INVISIBLE + mClockDateView.setTextAppearance(0) + mClockDateView.setTextColor(0) + } catch (ignored: Throwable) { + } + + try { + val mQSCarriers = + getObjectField(param.thisObject, "mQSCarriers") as View + mQSCarriers.visibility = View.INVISIBLE + } catch (ignored: Throwable) { + } + } + + private fun handleLegacyHeaderView() { + if (!showHeaderClock) return + + val resParam: InitPackageResourcesParam = resParams[SYSTEMUI_PACKAGE] ?: return + + try { + resParam.res.hookLayout( + SYSTEMUI_PACKAGE, + "layout", + "quick_qs_status_icons", + object : XC_LayoutInflated() { + override fun handleLayoutInflated(liparam: LayoutInflatedParam) { + if (!showHeaderClock) return + + // Ricedroid date + try { + val date = + liparam.view.findViewById( + liparam.res.getIdentifier( + "date", + "id", + mContext.packageName + ) + ) + date.layoutParams.height = 0 + date.layoutParams.width = 0 + date.setTextAppearance(0) + date.setTextColor(0) + date.visibility = View.GONE + } catch (ignored: Throwable) { + } + + // Nusantara clock + try { + val jrClock = + liparam.view.findViewById( + liparam.res.getIdentifier( + "jr_clock", + "id", + mContext.packageName + ) + ) + jrClock.layoutParams.height = 0 + jrClock.layoutParams.width = 0 + jrClock.setTextAppearance(0) + jrClock.setTextColor(0) + jrClock.visibility = View.GONE + } catch (ignored: Throwable) { + } + + // Nusantara date + try { + val jrDateContainer = + liparam.view.findViewById( + liparam.res.getIdentifier( + "jr_date_container", + "id", + mContext.packageName + ) + ) + val jrDate = jrDateContainer.getChildAt(0) as TextView + jrDate.layoutParams.height = 0 + jrDate.layoutParams.width = 0 + jrDate.setTextAppearance(0) + jrDate.setTextColor(0) + jrDate.visibility = View.GONE + } catch (ignored: Throwable) { + } + } + }) + } catch (ignored: Throwable) { + } + + try { + resParam.res.hookLayout( + SYSTEMUI_PACKAGE, + "layout", + "quick_status_bar_header_date_privacy", + object : XC_LayoutInflated() { + override fun handleLayoutInflated(liparam: LayoutInflatedParam) { + if (!showHeaderClock) return + + try { + val date = + liparam.view.findViewById( + liparam.res.getIdentifier( + "date", + "id", + mContext.packageName + ) + ) + date.layoutParams.height = 0 + date.layoutParams.width = 0 + date.setTextAppearance(0) + date.setTextColor(0) + date.visibility = View.GONE + } catch (ignored: Throwable) { + } + } + }) + } catch (ignored: Throwable) { + } + } + + companion object { + private val TAG = "Iconify - ${HeaderClockA14::class.java.simpleName}: " + } +} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/xposed/modules/HeaderImage.kt b/app/src/main/java/com/drdisagree/iconify/xposed/modules/HeaderImage.kt index d9fb90b4e..2fd46e636 100644 --- a/app/src/main/java/com/drdisagree/iconify/xposed/modules/HeaderImage.kt +++ b/app/src/main/java/com/drdisagree/iconify/xposed/modules/HeaderImage.kt @@ -1,9 +1,14 @@ package com.drdisagree.iconify.xposed.modules +import android.annotation.SuppressLint +import android.content.BroadcastReceiver import android.content.Context +import android.content.Intent +import android.content.IntentFilter import android.content.res.Configuration import android.graphics.ImageDecoder import android.graphics.drawable.AnimatedImageDrawable +import android.os.Build import android.os.Environment import android.util.TypedValue import android.view.Gravity @@ -14,6 +19,7 @@ import android.widget.ImageView import android.widget.LinearLayout import android.widget.RelativeLayout import com.bosphere.fadingedgelayout.FadingEdgeLayout +import com.drdisagree.iconify.common.Const.ACTION_BOOT_COMPLETED import com.drdisagree.iconify.common.Const.SYSTEMUI_PACKAGE import com.drdisagree.iconify.common.Preferences.HEADER_IMAGE_ALPHA import com.drdisagree.iconify.common.Preferences.HEADER_IMAGE_BOTTOM_FADE_AMOUNT @@ -22,9 +28,11 @@ import com.drdisagree.iconify.common.Preferences.HEADER_IMAGE_LANDSCAPE_SWITCH import com.drdisagree.iconify.common.Preferences.HEADER_IMAGE_OVERLAP import com.drdisagree.iconify.common.Preferences.HEADER_IMAGE_SWITCH import com.drdisagree.iconify.common.Preferences.HEADER_IMAGE_ZOOMTOFIT -import com.drdisagree.iconify.config.XPrefs.Xprefs +import com.drdisagree.iconify.common.Preferences.ICONIFY_QS_HEADER_CONTAINER_TAG import com.drdisagree.iconify.xposed.ModPack import com.drdisagree.iconify.xposed.modules.utils.ViewHelper.toPx +import com.drdisagree.iconify.xposed.utils.XPrefs.Xprefs +import com.drdisagree.iconify.xposed.utils.XPrefs.XprefsIsInitialized import de.robv.android.xposed.XC_MethodHook import de.robv.android.xposed.XposedBridge.hookAllMethods import de.robv.android.xposed.XposedBridge.log @@ -49,17 +57,29 @@ class HeaderImage(context: Context?) : ModPack(context!!) { private var mQsHeaderLayout: FadingEdgeLayout? = null private var mQsHeaderImageView: ImageView? = null private var bottomFadeAmount = 0 + private var mBroadcastRegistered = false + private val mReceiver: BroadcastReceiver = object : BroadcastReceiver() { + override fun onReceive(context: Context?, intent: Intent?) { + if (intent != null && intent.action != null) { + if (intent.action == ACTION_BOOT_COMPLETED) { + updateQSHeaderImage() + } + } + } + } override fun updatePrefs(vararg key: String) { - if (Xprefs == null) return - - showHeaderImage = Xprefs!!.getBoolean(HEADER_IMAGE_SWITCH, false) - headerImageAlpha = Xprefs!!.getInt(HEADER_IMAGE_ALPHA, 100) - imageHeight = Xprefs!!.getInt(HEADER_IMAGE_HEIGHT, 140) - zoomToFit = Xprefs!!.getBoolean(HEADER_IMAGE_ZOOMTOFIT, false) - headerImageOverlap = Xprefs!!.getBoolean(HEADER_IMAGE_OVERLAP, false) - hideLandscapeHeaderImage = Xprefs!!.getBoolean(HEADER_IMAGE_LANDSCAPE_SWITCH, true) - bottomFadeAmount = mContext.toPx(Xprefs!!.getInt(HEADER_IMAGE_BOTTOM_FADE_AMOUNT, 40)) + if (!XprefsIsInitialized) return + + Xprefs.apply { + showHeaderImage = getBoolean(HEADER_IMAGE_SWITCH, false) + headerImageAlpha = getSliderInt(HEADER_IMAGE_ALPHA, 100) + imageHeight = getSliderInt(HEADER_IMAGE_HEIGHT, 140) + zoomToFit = getBoolean(HEADER_IMAGE_ZOOMTOFIT, false) + headerImageOverlap = getBoolean(HEADER_IMAGE_OVERLAP, false) + hideLandscapeHeaderImage = getBoolean(HEADER_IMAGE_LANDSCAPE_SWITCH, true) + bottomFadeAmount = mContext.toPx(getSliderInt(HEADER_IMAGE_BOTTOM_FADE_AMOUNT, 40)) + } if (key.isNotEmpty() && (key[0] == HEADER_IMAGE_SWITCH || @@ -73,7 +93,28 @@ class HeaderImage(context: Context?) : ModPack(context!!) { } } + @SuppressLint("UnspecifiedRegisterReceiverFlag") override fun handleLoadPackage(loadPackageParam: LoadPackageParam) { + if (!mBroadcastRegistered) { + val intentFilter = IntentFilter() + intentFilter.addAction(ACTION_BOOT_COMPLETED) + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + mContext.registerReceiver( + mReceiver, + intentFilter, + Context.RECEIVER_EXPORTED + ) + } else { + mContext.registerReceiver( + mReceiver, + intentFilter + ) + } + + mBroadcastRegistered = true + } + val quickStatusBarHeader = findClass( "$SYSTEMUI_PACKAGE.qs.QuickStatusBarHeader", loadPackageParam.classLoader @@ -83,94 +124,91 @@ class HeaderImage(context: Context?) : ModPack(context!!) { loadPackageParam.classLoader ) - try { - hookAllMethods(quickStatusBarHeader, "onFinishInflate", object : XC_MethodHook() { - override fun afterHookedMethod(param: MethodHookParam) { - val mQuickStatusBarHeader = param.thisObject as FrameLayout - mQsHeaderLayout = FadingEdgeLayout(mContext) - - val layoutParams = LinearLayout.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, TypedValue.applyDimension( - TypedValue.COMPLEX_UNIT_DIP, - imageHeight.toFloat(), - mContext.resources.displayMetrics - ).toInt() - ) - layoutParams.leftMargin = TypedValue.applyDimension( - TypedValue.COMPLEX_UNIT_DIP, - -16f, - mContext.resources.displayMetrics - ).toInt() - layoutParams.rightMargin = TypedValue.applyDimension( + hookAllMethods(quickStatusBarHeader, "onFinishInflate", object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + val mQuickStatusBarHeader = param.thisObject as FrameLayout + mQsHeaderLayout = FadingEdgeLayout(mContext).apply { + tag = ICONIFY_QS_HEADER_CONTAINER_TAG + } + + val layoutParams = LinearLayout.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, - -16f, + imageHeight.toFloat(), mContext.resources.displayMetrics ).toInt() + ) + layoutParams.leftMargin = TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_DIP, + -16f, + mContext.resources.displayMetrics + ).toInt() + layoutParams.rightMargin = TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_DIP, + -16f, + mContext.resources.displayMetrics + ).toInt() + + mQsHeaderLayout!!.layoutParams = layoutParams + mQsHeaderLayout!!.visibility = View.GONE + + mQsHeaderImageView = ImageView(mContext) + mQsHeaderImageView!!.layoutParams = LinearLayout.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT + ) + + mQsHeaderLayout!!.addView(mQsHeaderImageView) + mQuickStatusBarHeader.addView(mQsHeaderLayout, 0) + + updateQSHeaderImage() + } + }) - mQsHeaderLayout!!.setLayoutParams(layoutParams) - mQsHeaderLayout!!.visibility = View.GONE - - mQsHeaderImageView = ImageView(mContext) - mQsHeaderImageView!!.setLayoutParams( - LinearLayout.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT - ) - ) - - mQsHeaderLayout!!.addView(mQsHeaderImageView) - mQuickStatusBarHeader.addView(mQsHeaderLayout, 0) - - updateQSHeaderImage() - } - }) - - hookAllMethods(quickStatusBarHeader, "updateResources", object : XC_MethodHook() { - override fun afterHookedMethod(param: MethodHookParam) { - updateQSHeaderImage() - } - }) - - hookAllMethods(quickStatusBarHeader, "onMeasure", object : XC_MethodHook() { - override fun afterHookedMethod(param: MethodHookParam) { - val mDatePrivacyView = getObjectField( + hookAllMethods(quickStatusBarHeader, "updateResources", object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + updateQSHeaderImage() + } + }) + + hookAllMethods(quickStatusBarHeader, "onMeasure", object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + val mDatePrivacyView = getObjectField( + param.thisObject, + "mDatePrivacyView" + ) as View + val mTopViewMeasureHeight = + getIntField(param.thisObject, "mTopViewMeasureHeight") + + if (callMethod( + mDatePrivacyView, + "getMeasuredHeight" + ) as Int != mTopViewMeasureHeight + ) { + setObjectField( param.thisObject, - "mDatePrivacyView" - ) as View - val mTopViewMeasureHeight = - getIntField(param.thisObject, "mTopViewMeasureHeight") - - if (callMethod( - mDatePrivacyView, - "getMeasuredHeight" - ) as Int != mTopViewMeasureHeight - ) { - setObjectField( - param.thisObject, - "mTopViewMeasureHeight", - callMethod(mDatePrivacyView, "getMeasuredHeight") - ) + "mTopViewMeasureHeight", + callMethod(mDatePrivacyView, "getMeasuredHeight") + ) - callMethod(param.thisObject, "updateAnimators") - } + callMethod(param.thisObject, "updateAnimators") } - }) + } + }) - hookAllMethods(qsContainerImpl, "onFinishInflate", object : XC_MethodHook() { - override fun afterHookedMethod(param: MethodHookParam) { - if (headerImageOverlap) return + hookAllMethods(qsContainerImpl, "onFinishInflate", object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + if (headerImageOverlap) return - val mHeader = - getObjectField(param.thisObject, "mHeader") as FrameLayout + val mHeader = getObjectField(param.thisObject, "mHeader") as FrameLayout - (param.thisObject as FrameLayout).removeView(mHeader) - (param.thisObject as FrameLayout).addView(mHeader, 0) - (param.thisObject as FrameLayout).requestLayout() + (param.thisObject as FrameLayout).apply { + removeView(mHeader) + addView(mHeader, 0) + requestLayout() } - }) - } catch (throwable: Throwable) { - log(TAG + throwable) - } + } + }) } private fun updateQSHeaderImage() { @@ -232,10 +270,11 @@ class HeaderImage(context: Context?) : ModPack(context!!) { private fun loadImageOrGif(iv: ImageView) { try { val executor = Executors.newSingleThreadScheduledExecutor() - executor.scheduleAtFixedRate({ + executor.scheduleWithFixedDelay({ val androidDir = File(Environment.getExternalStorageDirectory().toString() + "/Android") - if (androidDir.isDirectory()) { + + if (androidDir.isDirectory) { try { val source = ImageDecoder.createSource( File( @@ -246,15 +285,15 @@ class HeaderImage(context: Context?) : ModPack(context!!) { val drawable = ImageDecoder.decodeDrawable(source) iv.setImageDrawable(drawable) - iv.setClipToOutline(true) + iv.clipToOutline = true if (!zoomToFit) { - iv.setScaleType(ImageView.ScaleType.FIT_XY) + iv.scaleType = ImageView.ScaleType.FIT_XY } else { - iv.setScaleType(ImageView.ScaleType.CENTER_CROP) - iv.setAdjustViewBounds(false) + iv.scaleType = ImageView.ScaleType.CENTER_CROP + iv.adjustViewBounds = false iv.cropToPadding = false - iv.setMinimumWidth(ViewGroup.LayoutParams.MATCH_PARENT) + iv.minimumWidth = ViewGroup.LayoutParams.MATCH_PARENT iv.addCenterProperty() } diff --git a/app/src/main/java/com/drdisagree/iconify/xposed/modules/LockscreenClock.kt b/app/src/main/java/com/drdisagree/iconify/xposed/modules/LockscreenClock.kt index 8038d41ad..7866c84d4 100644 --- a/app/src/main/java/com/drdisagree/iconify/xposed/modules/LockscreenClock.kt +++ b/app/src/main/java/com/drdisagree/iconify/xposed/modules/LockscreenClock.kt @@ -29,6 +29,7 @@ import android.widget.ImageView import android.widget.LinearLayout import android.widget.ProgressBar import android.widget.RelativeLayout +import android.widget.TextClock import android.widget.TextView import androidx.core.content.ContextCompat import androidx.core.content.res.ResourcesCompat @@ -46,23 +47,27 @@ import com.drdisagree.iconify.common.Preferences.LSCLOCK_COLOR_CODE_ACCENT3 import com.drdisagree.iconify.common.Preferences.LSCLOCK_COLOR_CODE_TEXT1 import com.drdisagree.iconify.common.Preferences.LSCLOCK_COLOR_CODE_TEXT2 import com.drdisagree.iconify.common.Preferences.LSCLOCK_COLOR_SWITCH +import com.drdisagree.iconify.common.Preferences.LSCLOCK_DEVICENAME import com.drdisagree.iconify.common.Preferences.LSCLOCK_FONT_LINEHEIGHT import com.drdisagree.iconify.common.Preferences.LSCLOCK_FONT_SWITCH import com.drdisagree.iconify.common.Preferences.LSCLOCK_FONT_TEXT_SCALING import com.drdisagree.iconify.common.Preferences.LSCLOCK_STYLE import com.drdisagree.iconify.common.Preferences.LSCLOCK_SWITCH import com.drdisagree.iconify.common.Preferences.LSCLOCK_TOPMARGIN +import com.drdisagree.iconify.common.Preferences.LSCLOCK_USERNAME import com.drdisagree.iconify.common.Resources.LOCKSCREEN_CLOCK_LAYOUT -import com.drdisagree.iconify.config.XPrefs.Xprefs -import com.drdisagree.iconify.utils.TextUtil +import com.drdisagree.iconify.utils.TextUtils import com.drdisagree.iconify.xposed.ModPack import com.drdisagree.iconify.xposed.modules.utils.ArcProgressWidget.generateBitmap +import com.drdisagree.iconify.xposed.modules.utils.TimeUtils import com.drdisagree.iconify.xposed.modules.utils.ViewHelper.applyFontRecursively import com.drdisagree.iconify.xposed.modules.utils.ViewHelper.applyTextMarginRecursively import com.drdisagree.iconify.xposed.modules.utils.ViewHelper.applyTextScalingRecursively import com.drdisagree.iconify.xposed.modules.utils.ViewHelper.findViewContainsTag import com.drdisagree.iconify.xposed.modules.utils.ViewHelper.findViewWithTagAndChangeColor import com.drdisagree.iconify.xposed.modules.utils.ViewHelper.setMargins +import com.drdisagree.iconify.xposed.utils.XPrefs.Xprefs +import com.drdisagree.iconify.xposed.utils.XPrefs.XprefsIsInitialized import de.robv.android.xposed.XC_MethodHook import de.robv.android.xposed.XposedBridge.hookAllMethods import de.robv.android.xposed.XposedBridge.log @@ -77,7 +82,7 @@ import java.util.concurrent.TimeUnit class LockscreenClock(context: Context?) : ModPack(context!!) { private var showLockscreenClock = false - private var showDepthWallpaper = false + private var showDepthWallpaper = false // was used in android 13 and below private var mClockViewContainer: ViewGroup? = null private var mStatusViewContainer: ViewGroup? = null private var mUserManager: UserManager? = null @@ -113,14 +118,17 @@ class LockscreenClock(context: Context?) : ModPack(context!!) { } override fun updatePrefs(vararg key: String) { - if (Xprefs == null) return + if (!XprefsIsInitialized) return - showLockscreenClock = Xprefs!!.getBoolean(LSCLOCK_SWITCH, false) - showDepthWallpaper = Xprefs!!.getBoolean(DEPTH_WALLPAPER_SWITCH, false) + val isAndroid13OrBelow = Build.VERSION.SDK_INT <= Build.VERSION_CODES.TIRAMISU + + Xprefs.apply { + showLockscreenClock = getBoolean(LSCLOCK_SWITCH, false) + showDepthWallpaper = isAndroid13OrBelow && getBoolean(DEPTH_WALLPAPER_SWITCH, false) + } if (key.isNotEmpty() && (key[0] == LSCLOCK_SWITCH || - key[0] == DEPTH_WALLPAPER_SWITCH || key[0] == LSCLOCK_COLOR_SWITCH || key[0] == LSCLOCK_COLOR_CODE_ACCENT1 || key[0] == LSCLOCK_COLOR_CODE_ACCENT2 || @@ -133,7 +141,13 @@ class LockscreenClock(context: Context?) : ModPack(context!!) { key[0] == LSCLOCK_FONT_LINEHEIGHT || key[0] == LSCLOCK_FONT_SWITCH || key[0] == LSCLOCK_FONT_TEXT_SCALING || - key[0] == DEPTH_WALLPAPER_FADE_ANIMATION) + key[0] == LSCLOCK_USERNAME || + key[0] == LSCLOCK_DEVICENAME || + (isAndroid13OrBelow && + (key[0] == DEPTH_WALLPAPER_SWITCH || + key[0] == DEPTH_WALLPAPER_FADE_ANIMATION) + ) + ) ) { updateClockView() } @@ -234,7 +248,7 @@ class LockscreenClock(context: Context?) : ModPack(context!!) { val androidDir = File(Environment.getExternalStorageDirectory().toString() + "/Android") - if (androidDir.isDirectory()) { + if (androidDir.isDirectory) { updateClockView() executor.shutdown() executor.shutdownNow() @@ -299,7 +313,8 @@ class LockscreenClock(context: Context?) : ModPack(context!!) { val currentTime = System.currentTimeMillis() val isClockAdded = mClockViewContainer!!.findViewWithTag(ICONIFY_LOCKSCREEN_CLOCK_TAG) != null - val isDepthClock = mClockViewContainer!!.tag === ICONIFY_DEPTH_WALLPAPER_TAG + val isDepthClock = mClockViewContainer!!.tag === ICONIFY_DEPTH_WALLPAPER_TAG && + Build.VERSION.SDK_INT <= Build.VERSION_CODES.TIRAMISU if (isClockAdded && currentTime - lastUpdated < THRESHOLD_TIME) { return @@ -338,11 +353,9 @@ class LockscreenClock(context: Context?) : ModPack(context!!) { if (dummyLayout == null) { dummyLayout = LinearLayout(mContext) - dummyLayout.setLayoutParams( - LinearLayout.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - 350 - ) + dummyLayout.layoutParams = LinearLayout.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + 350 ) dummyLayout.tag = dummyTag @@ -367,17 +380,17 @@ class LockscreenClock(context: Context?) : ModPack(context!!) { dummyParams.topMargin = clockParams.topMargin dummyParams.bottomMargin = clockParams.bottomMargin - dummyLayout.setLayoutParams(dummyParams) + dummyLayout.layoutParams = dummyParams } } } private val clockView: View? get() { - if (appContext == null || Xprefs == null) return null + if (appContext == null || !XprefsIsInitialized) return null val inflater = LayoutInflater.from(appContext) - val clockStyle: Int = Xprefs!!.getInt(LSCLOCK_STYLE, 0) + val clockStyle: Int = Xprefs.getInt(LSCLOCK_STYLE, 0) val view: View = inflater.inflate( appContext!!.resources.getIdentifier( @@ -392,18 +405,22 @@ class LockscreenClock(context: Context?) : ModPack(context!!) { } private fun modifyClockView(clockView: View) { - if (Xprefs == null) return + if (!XprefsIsInitialized) return - val clockStyle: Int = Xprefs!!.getInt(LSCLOCK_STYLE, 0) - val topMargin: Int = Xprefs!!.getInt(LSCLOCK_TOPMARGIN, 100) - val bottomMargin: Int = Xprefs!!.getInt(LSCLOCK_BOTTOMMARGIN, 40) - val clockScale: Float = (Xprefs!!.getInt(LSCLOCK_FONT_TEXT_SCALING, 10) / 10.0).toFloat() + val clockStyle: Int = Xprefs.getInt(LSCLOCK_STYLE, 0) + val topMargin: Int = Xprefs.getSliderInt(LSCLOCK_TOPMARGIN, 100) + val bottomMargin: Int = Xprefs.getSliderInt(LSCLOCK_BOTTOMMARGIN, 40) + val textScaleFactor: Float = + (Xprefs.getSliderInt(LSCLOCK_FONT_TEXT_SCALING, 10) / 10.0).toFloat() val customFont = Environment.getExternalStorageDirectory().toString() + "/.iconify_files/lsclock_font.ttf" - val lineHeight: Int = Xprefs!!.getInt(LSCLOCK_FONT_LINEHEIGHT, 0) - val customFontEnabled: Boolean = Xprefs!!.getBoolean(LSCLOCK_FONT_SWITCH, false) - val customColorEnabled: Boolean = Xprefs!!.getBoolean(LSCLOCK_COLOR_SWITCH, false) - val accent1: Int = Xprefs!!.getInt( + val lineHeight: Int = Xprefs.getSliderInt(LSCLOCK_FONT_LINEHEIGHT, 0) + val customFontEnabled: Boolean = Xprefs.getBoolean(LSCLOCK_FONT_SWITCH, false) + val customColorEnabled: Boolean = Xprefs.getBoolean(LSCLOCK_COLOR_SWITCH, false) + val customUserName: String = Xprefs.getString(LSCLOCK_USERNAME, "")!! + val customDeviceName: String = Xprefs.getString(LSCLOCK_DEVICENAME, "")!! + + val accent1: Int = Xprefs.getInt( LSCLOCK_COLOR_CODE_ACCENT1, mContext.resources.getColor( mContext.resources.getIdentifier( @@ -413,7 +430,7 @@ class LockscreenClock(context: Context?) : ModPack(context!!) { ), mContext.theme ) ) - val accent2: Int = Xprefs!!.getInt( + val accent2: Int = Xprefs.getInt( LSCLOCK_COLOR_CODE_ACCENT2, mContext.resources.getColor( mContext.resources.getIdentifier( @@ -423,7 +440,7 @@ class LockscreenClock(context: Context?) : ModPack(context!!) { ), mContext.theme ) ) - val accent3: Int = Xprefs!!.getInt( + val accent3: Int = Xprefs.getInt( LSCLOCK_COLOR_CODE_ACCENT3, mContext.resources.getColor( mContext.resources.getIdentifier( @@ -433,11 +450,11 @@ class LockscreenClock(context: Context?) : ModPack(context!!) { ), mContext.theme ) ) - val text1: Int = Xprefs!!.getInt( + val text1: Int = Xprefs.getInt( LSCLOCK_COLOR_CODE_TEXT1, Color.WHITE ) - val text2: Int = Xprefs!!.getInt( + val text2: Int = Xprefs.getInt( LSCLOCK_COLOR_CODE_TEXT2, Color.BLACK ) @@ -462,12 +479,8 @@ class LockscreenClock(context: Context?) : ModPack(context!!) { applyTextMarginRecursively(mContext, clockView, lineHeight) - if (clockScale != 1f) { - applyTextScalingRecursively(clockView, clockScale) - } - if (clockStyle != 10) { - TextUtil.convertTextViewsToTitleCase(clockView) + TextUtils.convertTextViewsToTitleCase(clockView) } when (clockStyle) { @@ -483,7 +496,7 @@ class LockscreenClock(context: Context?) : ModPack(context!!) { 7 -> { val usernameView = clockView.findViewContainsTag("summary") as TextView? - usernameView?.text = userName + usernameView?.text = customUserName.ifEmpty { userName } val imageView = clockView.findViewContainsTag("user_profile_image") as ImageView? userImage?.let { imageView?.setImageDrawable(it) } } @@ -495,7 +508,16 @@ class LockscreenClock(context: Context?) : ModPack(context!!) { mVolumeLevelArcProgress = clockView.findViewContainsTag("volume_progress") as ImageView? mRamUsageArcProgress = clockView.findViewContainsTag("ram_usage_info") as ImageView? - (clockView.findViewContainsTag("device_name") as TextView).text = Build.MODEL + val devName = clockView.findViewContainsTag("device_name") as TextView? + devName!!.text = customDeviceName.ifEmpty { Build.MODEL } + } + + 22 -> { + val hourView = clockView.findViewContainsTag("textHour") as TextView + val minuteView = clockView.findViewContainsTag("textMinute") as TextView + val tickIndicator = clockView.findViewContainsTag("tickIndicator") as TextClock + + TimeUtils.setCurrentTimeTextClock(mContext, tickIndicator, hourView, minuteView) } else -> { @@ -506,6 +528,29 @@ class LockscreenClock(context: Context?) : ModPack(context!!) { mVolumeProgress = null } } + + if (textScaleFactor != 1f) { + applyTextScalingRecursively(clockView, textScaleFactor) + + val reduceFactor = if (textScaleFactor > 1f) 0.91f else 1f + + mVolumeLevelArcProgress?.layoutParams?.apply { + width = (width * textScaleFactor * reduceFactor).toInt() + height = (height * textScaleFactor * reduceFactor).toInt() + } + + mRamUsageArcProgress?.layoutParams?.apply { + width = (width * textScaleFactor * reduceFactor).toInt() + height = (height * textScaleFactor * reduceFactor).toInt() + } + + (mBatteryProgress?.parent as ViewGroup?)?.apply { + layoutParams?.apply { + width = (width * textScaleFactor * reduceFactor).toInt() + } + requestLayout() + } + } } private fun initBatteryStatus() { @@ -545,28 +590,31 @@ class LockscreenClock(context: Context?) : ModPack(context!!) { val volLevel = mAudioManager!!.getStreamVolume(AudioManager.STREAM_MUSIC) val maxVolLevel = mAudioManager!!.getStreamMaxVolume(AudioManager.STREAM_MUSIC) val volPercent = (volLevel.toFloat() / maxVolLevel * 100).toInt() + val textScaleFactor: Float = + (Xprefs.getSliderInt(LSCLOCK_FONT_TEXT_SCALING, 10) / 10.0).toFloat() + val reduceFactor = if (textScaleFactor > 1f) 0.91f else 1f - if (mVolumeProgress != null) { - mVolumeProgress!!.progress = volPercent - } + mVolumeProgress?.progress = volPercent - if (mVolumeLevelView != null) { - mVolumeLevelView!!.text = - appContext!!.resources.getString(R.string.percentage_text, volPercent) - } + mVolumeLevelView?.text = + appContext!!.resources.getString(R.string.percentage_text, volPercent) - if (mVolumeLevelArcProgress != null) { - val widgetBitmap = generateBitmap( - mContext, - volPercent, - appContext!!.resources.getString(R.string.percentage_text, volPercent), - 40, - ContextCompat.getDrawable(appContext!!, R.drawable.ic_volume_up), - 36 + mVolumeLevelArcProgress?.setImageBitmap( + generateBitmap( + context = mContext, + percentage = volPercent, + textInside = appContext!!.resources.getString( + R.string.percentage_text, + volPercent + ), + textInsideSizePx = (40 * textScaleFactor * reduceFactor).toInt(), + iconDrawable = ContextCompat.getDrawable( + appContext!!, + R.drawable.ic_volume_up + ), + iconSizePx = 38 ) - - mVolumeLevelArcProgress!!.setImageBitmap(widgetBitmap) - } + ) } private fun initRamUsage() { @@ -576,22 +624,23 @@ class LockscreenClock(context: Context?) : ModPack(context!!) { mActivityManager!!.getMemoryInfo(memoryInfo) val usedMemory = memoryInfo.totalMem - memoryInfo.availMem val usedMemoryPercentage = (usedMemory * 100 / memoryInfo.totalMem).toInt() + val textScaleFactor: Float = + (Xprefs.getSliderInt(LSCLOCK_FONT_TEXT_SCALING, 10) / 10.0).toFloat() + val reduceFactor = if (textScaleFactor > 1f) 0.91f else 1f - if (mRamUsageArcProgress != null) { - val widgetBitmap = generateBitmap( + mRamUsageArcProgress?.setImageBitmap( + generateBitmap( context = mContext, percentage = usedMemoryPercentage, textInside = appContext!!.resources.getString( R.string.percentage_text, usedMemoryPercentage ), - textInsideSizePx = 40, + textInsideSizePx = (40 * textScaleFactor * reduceFactor).toInt(), textBottom = "RAM", textBottomSizePx = 28 ) - - mRamUsageArcProgress!!.setImageBitmap(widgetBitmap) - } + ) } @get:SuppressLint("MissingPermission") diff --git a/app/src/main/java/com/drdisagree/iconify/xposed/modules/LockscreenWeather.kt b/app/src/main/java/com/drdisagree/iconify/xposed/modules/LockscreenWeather.kt new file mode 100644 index 000000000..967540663 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/xposed/modules/LockscreenWeather.kt @@ -0,0 +1,236 @@ +package com.drdisagree.iconify.xposed.modules + +import android.content.Context +import android.content.Intent +import android.graphics.Color +import android.view.Gravity +import android.view.View +import android.view.ViewGroup +import android.widget.LinearLayout +import androidx.core.view.children +import com.drdisagree.iconify.common.Const.ACTION_WEATHER_INFLATED +import com.drdisagree.iconify.common.Preferences.LSCLOCK_SWITCH +import com.drdisagree.iconify.common.Preferences.WEATHER_CENTER_VIEW +import com.drdisagree.iconify.common.Preferences.WEATHER_CUSTOM_MARGINS_BOTTOM +import com.drdisagree.iconify.common.Preferences.WEATHER_CUSTOM_MARGINS_SIDE +import com.drdisagree.iconify.common.Preferences.WEATHER_CUSTOM_MARGINS_TOP +import com.drdisagree.iconify.common.Preferences.WEATHER_ICON_SIZE +import com.drdisagree.iconify.common.Preferences.WEATHER_SHOW_CONDITION +import com.drdisagree.iconify.common.Preferences.WEATHER_SHOW_HUMIDITY +import com.drdisagree.iconify.common.Preferences.WEATHER_SHOW_LOCATION +import com.drdisagree.iconify.common.Preferences.WEATHER_SHOW_WIND +import com.drdisagree.iconify.common.Preferences.WEATHER_STYLE +import com.drdisagree.iconify.common.Preferences.WEATHER_SWITCH +import com.drdisagree.iconify.common.Preferences.WEATHER_TEXT_COLOR +import com.drdisagree.iconify.common.Preferences.WEATHER_TEXT_COLOR_SWITCH +import com.drdisagree.iconify.common.Preferences.WEATHER_TEXT_SIZE +import com.drdisagree.iconify.xposed.ModPack +import com.drdisagree.iconify.xposed.modules.utils.ViewHelper.setMargins +import com.drdisagree.iconify.xposed.modules.views.CurrentWeatherView +import com.drdisagree.iconify.xposed.utils.XPrefs.Xprefs +import com.drdisagree.iconify.xposed.utils.XPrefs.XprefsIsInitialized +import de.robv.android.xposed.XC_MethodHook +import de.robv.android.xposed.XposedBridge.hookAllMethods +import de.robv.android.xposed.XposedHelpers.findClass +import de.robv.android.xposed.XposedHelpers.getObjectField +import de.robv.android.xposed.callbacks.XC_LoadPackage + +class LockscreenWeather(context: Context?) : ModPack(context!!) { + + private var customLockscreenClock = false + private var weatherEnabled = false + private var weatherShowLocation = true + private var weatherShowCondition = true + private var weatherShowHumidity = false + private var weatherShowWind = false + private var weatherCustomColor = false + private var weatherColor = Color.WHITE + private var weatherTextSize: Int = 16 + private var weatherImageSize: Int = 18 + private var mSideMargin: Int = 0 + private var mTopMargin: Int = 0 + private var mBottomMargin: Int = 0 + private var mWeatherBackground = 0 + private var mCenterWeather = false + private lateinit var mWeatherContainer: LinearLayout + private var mStatusViewContainer: ViewGroup? = null + private var mStatusArea: ViewGroup? = null + + override fun updatePrefs(vararg key: String) { + if (!XprefsIsInitialized) return + + Xprefs.apply { + customLockscreenClock = getBoolean(LSCLOCK_SWITCH, false) + weatherEnabled = getBoolean(WEATHER_SWITCH, false) + weatherShowLocation = getBoolean(WEATHER_SHOW_LOCATION, true) + weatherShowCondition = getBoolean(WEATHER_SHOW_CONDITION, true) + weatherShowHumidity = getBoolean(WEATHER_SHOW_HUMIDITY, false) + weatherShowWind = getBoolean(WEATHER_SHOW_WIND, false) + weatherCustomColor = getBoolean(WEATHER_TEXT_COLOR_SWITCH, false) + weatherColor = getInt(WEATHER_TEXT_COLOR, Color.WHITE) + weatherTextSize = getSliderInt(WEATHER_TEXT_SIZE, 16) + weatherImageSize = getSliderInt(WEATHER_ICON_SIZE, 18) + mSideMargin = getSliderInt(WEATHER_CUSTOM_MARGINS_SIDE, 32) + mTopMargin = getSliderInt(WEATHER_CUSTOM_MARGINS_TOP, 20) + mBottomMargin = getSliderInt(WEATHER_CUSTOM_MARGINS_BOTTOM, 20) + mWeatherBackground = Integer.parseInt(getString(WEATHER_STYLE, "0")!!) + mCenterWeather = getBoolean(WEATHER_CENTER_VIEW, false) + } + + if (key.isNotEmpty() && + (key[0] == WEATHER_SHOW_LOCATION || + key[0] == WEATHER_SHOW_CONDITION || + key[0] == WEATHER_SHOW_HUMIDITY || + key[0] == WEATHER_SHOW_WIND || + key[0] == WEATHER_TEXT_COLOR_SWITCH || + key[0] == WEATHER_TEXT_COLOR || + key[0] == WEATHER_TEXT_SIZE || + key[0] == WEATHER_ICON_SIZE || + key[0] == WEATHER_STYLE || + key[0] == WEATHER_CUSTOM_MARGINS_BOTTOM || + key[0] == WEATHER_CUSTOM_MARGINS_SIDE || + key[0] == WEATHER_CUSTOM_MARGINS_TOP || + key[0] == WEATHER_CENTER_VIEW) + ) { + updateWeatherView() + } + } + + override fun handleLoadPackage(loadPackageParam: XC_LoadPackage.LoadPackageParam) { + mWeatherContainer = LinearLayout(mContext) + mWeatherContainer.layoutParams = LinearLayout.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT + ) + + val keyguardStatusViewClass = findClass( + "com.android.keyguard.KeyguardStatusView", + loadPackageParam.classLoader + ) + + hookAllMethods(keyguardStatusViewClass, "onFinishInflate", object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + if (!weatherEnabled) return + + mStatusViewContainer = getObjectField( + param.thisObject, + "mStatusViewContainer" + ) as ViewGroup + + placeWeatherView() + + } + }) + + val keyguardClockSwitch = findClass( + "com.android.keyguard.KeyguardClockSwitch", + loadPackageParam.classLoader + ) + + hookAllMethods(keyguardClockSwitch, "onFinishInflate", object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + if (!weatherEnabled) return + + mStatusArea = getObjectField( + param.thisObject, + "mStatusArea" + ) as ViewGroup + + placeWeatherView() + + } + }) + } + + private fun placeWeatherView() { + try { + val currentWeatherView: CurrentWeatherView = CurrentWeatherView.getInstance( + mContext, + LOCKSCREEN_WEATHER + ) + + (currentWeatherView.parent as ViewGroup?)?.removeView(currentWeatherView) + (mWeatherContainer.parent as ViewGroup?)?.removeView(mWeatherContainer) + + mWeatherContainer.addView(currentWeatherView) + + if (customLockscreenClock) { + mStatusViewContainer!!.addView(mWeatherContainer) + } else { + // Put weather view inside the status area + // But before notifications + mStatusArea!!.addView(mWeatherContainer, mStatusArea!!.childCount - 1) + } + + refreshWeatherView(currentWeatherView) + + // Weather placed, now inflate widgets + val broadcast = Intent(ACTION_WEATHER_INFLATED) + broadcast.setFlags(Intent.FLAG_RECEIVER_FOREGROUND) + Thread { mContext.sendBroadcast(broadcast) }.start() + } catch (ignored: Throwable) { + } + } + + private fun updateMargins() { + setMargins( + mWeatherContainer, + mContext, + mSideMargin, + mTopMargin, + mSideMargin, + mBottomMargin + ) + + mWeatherContainer.gravity = if (mCenterWeather) { + Gravity.CENTER_HORIZONTAL + } else { + Gravity.START + } + (mWeatherContainer.getChildAt(0) as LinearLayout?)?.children?.forEach { + (it as LinearLayout).gravity = if (mCenterWeather) { + Gravity.CENTER_HORIZONTAL + } else { + Gravity.START or Gravity.CENTER_VERTICAL + } + } + } + + private fun refreshWeatherView(currentWeatherView: CurrentWeatherView?) { + if (currentWeatherView == null) return + + currentWeatherView.apply { + updateSizes( + weatherTextSize, + weatherImageSize, + LOCKSCREEN_WEATHER + ) + updateColors( + if (weatherCustomColor) weatherColor else Color.WHITE, + LOCKSCREEN_WEATHER + ) + updateWeatherSettings( + weatherShowLocation, + weatherShowCondition, + weatherShowHumidity, + weatherShowWind, + LOCKSCREEN_WEATHER + ) + visibility = if (weatherEnabled) View.VISIBLE else View.GONE + updateWeatherBg( + mWeatherBackground, + LOCKSCREEN_WEATHER + ) + } + + updateMargins() + } + + private fun updateWeatherView() { + refreshWeatherView(CurrentWeatherView.getInstance(LOCKSCREEN_WEATHER)) + } + + companion object { + const val LOCKSCREEN_WEATHER = "iconify_ls_weather" + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/xposed/modules/LockscreenWidgets.kt b/app/src/main/java/com/drdisagree/iconify/xposed/modules/LockscreenWidgets.kt new file mode 100644 index 000000000..cb12f9018 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/xposed/modules/LockscreenWidgets.kt @@ -0,0 +1,406 @@ +package com.drdisagree.iconify.xposed.modules + +import android.annotation.SuppressLint +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import android.content.IntentFilter +import android.graphics.Color +import android.os.Build +import android.view.ViewGroup +import android.widget.LinearLayout +import com.drdisagree.iconify.common.Const.ACTION_WEATHER_INFLATED +import com.drdisagree.iconify.common.Const.SYSTEMUI_PACKAGE +import com.drdisagree.iconify.common.Preferences.LOCKSCREEN_WIDGETS +import com.drdisagree.iconify.common.Preferences.LOCKSCREEN_WIDGETS_BIG_ACTIVE +import com.drdisagree.iconify.common.Preferences.LOCKSCREEN_WIDGETS_BIG_ICON_ACTIVE +import com.drdisagree.iconify.common.Preferences.LOCKSCREEN_WIDGETS_BIG_ICON_INACTIVE +import com.drdisagree.iconify.common.Preferences.LOCKSCREEN_WIDGETS_BIG_INACTIVE +import com.drdisagree.iconify.common.Preferences.LOCKSCREEN_WIDGETS_BOTTOM_MARGIN +import com.drdisagree.iconify.common.Preferences.LOCKSCREEN_WIDGETS_CUSTOM_COLOR +import com.drdisagree.iconify.common.Preferences.LOCKSCREEN_WIDGETS_DEVICE_WIDGET +import com.drdisagree.iconify.common.Preferences.LOCKSCREEN_WIDGETS_DEVICE_WIDGET_CIRCULAR_COLOR +import com.drdisagree.iconify.common.Preferences.LOCKSCREEN_WIDGETS_DEVICE_WIDGET_CUSTOM_COLOR_SWITCH +import com.drdisagree.iconify.common.Preferences.LOCKSCREEN_WIDGETS_DEVICE_WIDGET_DEVICE +import com.drdisagree.iconify.common.Preferences.LOCKSCREEN_WIDGETS_DEVICE_WIDGET_LINEAR_COLOR +import com.drdisagree.iconify.common.Preferences.LOCKSCREEN_WIDGETS_DEVICE_WIDGET_TEXT_COLOR +import com.drdisagree.iconify.common.Preferences.LOCKSCREEN_WIDGETS_ENABLED +import com.drdisagree.iconify.common.Preferences.LOCKSCREEN_WIDGETS_EXTRAS +import com.drdisagree.iconify.common.Preferences.LOCKSCREEN_WIDGETS_SCALE +import com.drdisagree.iconify.common.Preferences.LOCKSCREEN_WIDGETS_SMALL_ACTIVE +import com.drdisagree.iconify.common.Preferences.LOCKSCREEN_WIDGETS_SMALL_ICON_ACTIVE +import com.drdisagree.iconify.common.Preferences.LOCKSCREEN_WIDGETS_SMALL_ICON_INACTIVE +import com.drdisagree.iconify.common.Preferences.LOCKSCREEN_WIDGETS_SMALL_INACTIVE +import com.drdisagree.iconify.common.Preferences.LSCLOCK_SWITCH +import com.drdisagree.iconify.common.Preferences.WEATHER_SWITCH +import com.drdisagree.iconify.xposed.ModPack +import com.drdisagree.iconify.xposed.modules.utils.ViewHelper.setMargins +import com.drdisagree.iconify.xposed.modules.views.LockscreenWidgetsView +import com.drdisagree.iconify.xposed.utils.XPrefs.Xprefs +import com.drdisagree.iconify.xposed.utils.XPrefs.XprefsIsInitialized +import de.robv.android.xposed.XC_MethodHook +import de.robv.android.xposed.XposedBridge +import de.robv.android.xposed.XposedBridge.hookAllMethods +import de.robv.android.xposed.XposedBridge.log +import de.robv.android.xposed.XposedHelpers.findClass +import de.robv.android.xposed.XposedHelpers.findClassIfExists +import de.robv.android.xposed.XposedHelpers.getObjectField +import de.robv.android.xposed.callbacks.XC_LoadPackage + +class LockscreenWidgets(context: Context?) : ModPack(context!!) { + + // Parent + private var mStatusViewContainer: ViewGroup? = null + private var mStatusArea: ViewGroup? = null + + // Widgets Container + private lateinit var mWidgetsContainer: LinearLayout + + // Activity Starter + private var mActivityStarter: Any? = null + + // Ls custom clock + private var customLockscreenClock = false + + // Ls weather + private var lsWeather = false + private var lsWeatherInflated = false + + // Widgets Prefs + // Lockscreen Widgets + private var mWidgetsEnabled: Boolean = false + private var mDeviceWidgetEnabled = false + private var mDeviceCustomColor = false + private var mDeviceLinearColor = Color.WHITE + private var mDeviceCircularColor = Color.WHITE + private var mDeviceTextColor = Color.WHITE + private var mWidgetsCustomColor = false + private var mBigInactiveColor = Color.BLACK + private var mBigActiveColor = Color.WHITE + private var mSmallInactiveColor = Color.BLACK + private var mSmallActiveColor = Color.WHITE + private var mBigIconActiveColor = Color.WHITE + private var mBigIconInactiveColor = Color.BLACK + private var mSmallIconActiveColor = Color.WHITE + private var mSmallIconInactiveColor = Color.BLACK + private var mDeviceName = "" + private var mMainWidgets: String = "" + private var mExtraWidgets: String = "" + private var mBottomMargin = 0 + private var mWidgetsScale = 1.0f + + private var mBroadcastRegistered = false + private val mReceiver: BroadcastReceiver = object : BroadcastReceiver() { + override fun onReceive(context: Context?, intent: Intent?) { + if (intent != null && intent.action != null) { + if (intent.action == ACTION_WEATHER_INFLATED && mWidgetsEnabled) { + lsWeatherInflated = true + placeWidgets() + } + } + } + } + + override fun updatePrefs(vararg key: String) { + if (!XprefsIsInitialized) return + + Xprefs.apply { + // Ls custom clock + customLockscreenClock = getBoolean(LSCLOCK_SWITCH, false) + + // Ls weather + lsWeather = getBoolean(WEATHER_SWITCH, false) + + // Widgets + mWidgetsEnabled = getBoolean(LOCKSCREEN_WIDGETS_ENABLED, false) + mDeviceWidgetEnabled = getBoolean(LOCKSCREEN_WIDGETS_DEVICE_WIDGET, false) + mMainWidgets = getString(LOCKSCREEN_WIDGETS, "")!! + mExtraWidgets = getString(LOCKSCREEN_WIDGETS_EXTRAS, "")!! + mDeviceCustomColor = + getBoolean(LOCKSCREEN_WIDGETS_DEVICE_WIDGET_CUSTOM_COLOR_SWITCH, false) + mDeviceLinearColor = getInt(LOCKSCREEN_WIDGETS_DEVICE_WIDGET_LINEAR_COLOR, Color.WHITE) + mDeviceCircularColor = + getInt(LOCKSCREEN_WIDGETS_DEVICE_WIDGET_CIRCULAR_COLOR, Color.WHITE) + mDeviceTextColor = getInt(LOCKSCREEN_WIDGETS_DEVICE_WIDGET_TEXT_COLOR, Color.WHITE) + mDeviceName = getString(LOCKSCREEN_WIDGETS_DEVICE_WIDGET_DEVICE, "")!! + mWidgetsCustomColor = getBoolean(LOCKSCREEN_WIDGETS_CUSTOM_COLOR, false) + mBigInactiveColor = getInt(LOCKSCREEN_WIDGETS_BIG_INACTIVE, Color.BLACK) + mBigActiveColor = getInt(LOCKSCREEN_WIDGETS_BIG_ACTIVE, Color.WHITE) + mSmallInactiveColor = getInt(LOCKSCREEN_WIDGETS_SMALL_INACTIVE, Color.BLACK) + mSmallActiveColor = getInt(LOCKSCREEN_WIDGETS_SMALL_ACTIVE, Color.WHITE) + mBigIconActiveColor = getInt(LOCKSCREEN_WIDGETS_BIG_ICON_ACTIVE, Color.BLACK) + mBigIconInactiveColor = getInt(LOCKSCREEN_WIDGETS_BIG_ICON_INACTIVE, Color.WHITE) + mSmallIconActiveColor = getInt(LOCKSCREEN_WIDGETS_SMALL_ICON_ACTIVE, Color.BLACK) + mSmallIconInactiveColor = getInt(LOCKSCREEN_WIDGETS_SMALL_ICON_INACTIVE, Color.WHITE) + mBottomMargin = getSliderInt(LOCKSCREEN_WIDGETS_BOTTOM_MARGIN, 0) + mWidgetsScale = getSliderFloat(LOCKSCREEN_WIDGETS_SCALE, 1.0f) + } + + if (key.isNotEmpty()) { + if (key[0] == LOCKSCREEN_WIDGETS_ENABLED || + key[0] == LOCKSCREEN_WIDGETS_DEVICE_WIDGET || + key[0] == LOCKSCREEN_WIDGETS || + key[0] == LOCKSCREEN_WIDGETS_EXTRAS + ) { + updateLockscreenWidgets() + } + if (key[0] == LOCKSCREEN_WIDGETS_DEVICE_WIDGET_CUSTOM_COLOR_SWITCH || + key[0] == LOCKSCREEN_WIDGETS_DEVICE_WIDGET_LINEAR_COLOR || + key[0] == LOCKSCREEN_WIDGETS_DEVICE_WIDGET_CIRCULAR_COLOR || + key[0] == LOCKSCREEN_WIDGETS_DEVICE_WIDGET_TEXT_COLOR || + key[0] == LOCKSCREEN_WIDGETS_DEVICE_WIDGET_DEVICE + ) { + updateLsDeviceWidget() + } + if (key[0] == LOCKSCREEN_WIDGETS_CUSTOM_COLOR || + key[0] == LOCKSCREEN_WIDGETS_BIG_ACTIVE || + key[0] == LOCKSCREEN_WIDGETS_BIG_INACTIVE || + key[0] == LOCKSCREEN_WIDGETS_SMALL_ACTIVE || + key[0] == LOCKSCREEN_WIDGETS_SMALL_INACTIVE || + key[0] == LOCKSCREEN_WIDGETS_BIG_ICON_ACTIVE || + key[0] == LOCKSCREEN_WIDGETS_BIG_ICON_INACTIVE || + key[0] == LOCKSCREEN_WIDGETS_SMALL_ICON_ACTIVE || + key[0] == LOCKSCREEN_WIDGETS_SMALL_ICON_INACTIVE + ) { + updateLockscreenWidgetsColors() + } + if (key[0] == LOCKSCREEN_WIDGETS_BOTTOM_MARGIN) { + updateMargins() + } + if (key[0] == LOCKSCREEN_WIDGETS_SCALE) { + updateLockscreenWidgetsScale() + } + } + + } + + @SuppressLint("UnspecifiedRegisterReceiverFlag") + override fun handleLoadPackage(loadPackageParam: XC_LoadPackage.LoadPackageParam) { + // Receiver to handle weather inflated + if (!mBroadcastRegistered) { + val intentFilter = IntentFilter() + intentFilter.addAction(ACTION_WEATHER_INFLATED) + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + mContext.registerReceiver( + mReceiver, + intentFilter, + Context.RECEIVER_EXPORTED + ) + } else { + mContext.registerReceiver( + mReceiver, + intentFilter + ) + } + + mBroadcastRegistered = true + } + + mWidgetsContainer = LinearLayout(mContext) + mWidgetsContainer.layoutParams = LinearLayout.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT + ) + + LaunchableImageView = findClassIfExists( + "com.android.systemui.animation.view.LaunchableImageView", + loadPackageParam.classLoader + ) + + LaunchableLinearLayout = findClassIfExists( + "com.android.systemui.animation.view.LaunchableLinearLayout", + loadPackageParam.classLoader + ) + + try { + val keyguardQuickAffordanceInteractor = findClass( + "com.android.systemui.keyguard.domain.interactor.KeyguardQuickAffordanceInteractor", + loadPackageParam.classLoader + ) + XposedBridge.hookAllConstructors( + keyguardQuickAffordanceInteractor, + object : XC_MethodHook() { + @Throws(Throwable::class) + override fun afterHookedMethod(param: MethodHookParam) { + try { + mActivityStarter = getObjectField(param.thisObject, "activityStarter") + } catch (t: Throwable) { + log(TAG + "Failed to get ActivityStarter") + } + setActivityStarter() + } + }) + } catch (ignored: Throwable) { + } + + try { + val keyguardStatusViewClass = findClass( + "com.android.keyguard.KeyguardStatusView", + loadPackageParam.classLoader + ) + hookAllMethods(keyguardStatusViewClass, "onFinishInflate", object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + if (!mWidgetsEnabled) return + try { + mStatusViewContainer = getObjectField( + param.thisObject, + "mStatusViewContainer" + ) as ViewGroup + } catch (t: Throwable) { + log(TAG + "Failed to get mStatusViewContainer") + } + + placeWidgets() + } + }) + } catch (t: Throwable) { + log(TAG + "Failed to hook KeyguardStatusView") + } + + try { + val keyguardClockSwitch = findClass( + "com.android.keyguard.KeyguardClockSwitch", + loadPackageParam.classLoader + ) + + hookAllMethods(keyguardClockSwitch, "onFinishInflate", object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + if (!mWidgetsEnabled) return + + try { + mStatusArea = getObjectField( + param.thisObject, + "mStatusArea" + ) as ViewGroup + + } catch (t: Throwable) { + log(TAG + "Failed to get mStatusArea") + } + + placeWidgets() + + } + }) + + hookAllMethods(keyguardClockSwitch, "updateClockViews", object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + if (!mWidgetsEnabled) return + updateLockscreenWidgetsOnClock(param.args[0] as Boolean) + } + }) + } catch (t: Throwable) { + log(TAG + "Failed to hook KeyguardClockSwitch") + } + + try { + val dozeScrimControllerClass = findClass( + "$SYSTEMUI_PACKAGE.statusbar.phone.DozeScrimController", + loadPackageParam.classLoader + ) + hookAllMethods(dozeScrimControllerClass, "onDozingChanged", object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + updateDozingState(param.args[0] as Boolean) + } + }) + } catch (t: Throwable) { + log(TAG + "Failed to hook DozeScrimController") + } + } + + private fun placeWidgets() { + if (!mWidgetsEnabled) return + if (mStatusViewContainer == null || mStatusArea == null) return + if (lsWeather && !lsWeatherInflated) return + try { + val lsWidgets = LockscreenWidgetsView.getInstance(mContext, mActivityStarter) + (lsWidgets.parent as ViewGroup?)?.removeView(lsWidgets) + (mWidgetsContainer.parent as ViewGroup?)?.removeView(mWidgetsContainer) + + mWidgetsContainer.addView(lsWidgets) + + if (customLockscreenClock) { + mStatusViewContainer?.addView(mWidgetsContainer) + } else { + // Put widgets view inside the status area + // But before notifications + mStatusArea?.addView(mWidgetsContainer, mStatusArea!!.childCount - 1) + } + updateLockscreenWidgets() + updateLsDeviceWidget() + updateLockscreenWidgetsColors() + updateMargins() + updateLockscreenWidgetsScale() + } catch (ignored: Throwable) { + } + } + + private fun updateLockscreenWidgets() { + log(TAG + "Updating Lockscreen Widgets") + val lsWidgets = LockscreenWidgetsView.getInstance() ?: return + lsWidgets.setOptions(mWidgetsEnabled, mDeviceWidgetEnabled, mMainWidgets, mExtraWidgets) + } + + private fun updateLockscreenWidgetsOnClock(isLargeClock: Boolean) { + log(TAG + "Updating Lockscreen Widgets on Clock") + val lsWidgets = LockscreenWidgetsView.getInstance() ?: return + lsWidgets.setIsLargeClock(if (customLockscreenClock) false else isLargeClock) + } + + private fun updateLsDeviceWidget() { + log(TAG + "Updating Lockscreen Device Widget") + val lsWidgets = LockscreenWidgetsView.getInstance() ?: return + lsWidgets.setDeviceWidgetOptions( + mDeviceCustomColor, + mDeviceLinearColor, + mDeviceCircularColor, + mDeviceTextColor, + mDeviceName + ) + } + + private fun updateLockscreenWidgetsColors() { + log(TAG + "Updating Lockscreen Widgets Colors") + val lsWidgets = LockscreenWidgetsView.getInstance() ?: return + lsWidgets.setCustomColors( + mWidgetsCustomColor, + mBigInactiveColor, mBigActiveColor, + mSmallInactiveColor, mSmallActiveColor, + mBigIconInactiveColor, mBigIconActiveColor, + mSmallIconInactiveColor, mSmallIconActiveColor + ) + } + + private fun updateMargins() { + setMargins( + mWidgetsContainer, + mContext, + 0, + 0, + 0, + mBottomMargin + ) + } + + private fun updateLockscreenWidgetsScale() { + val lsWidgets = LockscreenWidgetsView.getInstance() ?: return + lsWidgets.setScale(mWidgetsScale) + } + + private fun updateDozingState(isDozing: Boolean) { + val lsWidgets = LockscreenWidgetsView.getInstance() ?: return + lsWidgets.setDozingState(isDozing) + } + + private fun setActivityStarter() { + val lsWidgets = LockscreenWidgetsView.getInstance() ?: return + if (mActivityStarter != null) lsWidgets.setActivityStarter(mActivityStarter) + } + + companion object { + private val TAG = "Iconify - ${LockscreenWidgets::class.java.simpleName}: " + + var LaunchableImageView: Class<*>? = null + var LaunchableLinearLayout: Class<*>? = null + } +} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/xposed/modules/Miscellaneous.kt b/app/src/main/java/com/drdisagree/iconify/xposed/modules/Miscellaneous.kt index 3cb8595a9..35a72eb9e 100644 --- a/app/src/main/java/com/drdisagree/iconify/xposed/modules/Miscellaneous.kt +++ b/app/src/main/java/com/drdisagree/iconify/xposed/modules/Miscellaneous.kt @@ -14,15 +14,15 @@ import com.drdisagree.iconify.common.Const.SYSTEMUI_PACKAGE import com.drdisagree.iconify.common.Preferences.FIXED_STATUS_ICONS_SIDEMARGIN import com.drdisagree.iconify.common.Preferences.FIXED_STATUS_ICONS_SWITCH import com.drdisagree.iconify.common.Preferences.FIXED_STATUS_ICONS_TOPMARGIN +import com.drdisagree.iconify.common.Preferences.HEADER_CLOCK_SWITCH import com.drdisagree.iconify.common.Preferences.HIDE_DATA_DISABLED_ICON -import com.drdisagree.iconify.common.Preferences.HIDE_LOCKSCREEN_CARRIER import com.drdisagree.iconify.common.Preferences.HIDE_LOCKSCREEN_LOCK_ICON -import com.drdisagree.iconify.common.Preferences.HIDE_LOCKSCREEN_STATUSBAR import com.drdisagree.iconify.common.Preferences.HIDE_STATUS_ICONS_SWITCH import com.drdisagree.iconify.common.Preferences.QSPANEL_HIDE_CARRIER -import com.drdisagree.iconify.config.XPrefs.Xprefs import com.drdisagree.iconify.xposed.HookRes.Companion.resParams import com.drdisagree.iconify.xposed.ModPack +import com.drdisagree.iconify.xposed.utils.XPrefs.Xprefs +import com.drdisagree.iconify.xposed.utils.XPrefs.XprefsIsInitialized import de.robv.android.xposed.XC_MethodHook import de.robv.android.xposed.XposedBridge.hookAllMethods import de.robv.android.xposed.XposedHelpers.callMethod @@ -37,11 +37,9 @@ import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam @SuppressLint("DiscouragedApi") class Miscellaneous(context: Context?) : ModPack(context!!) { - private var qsCarrierGroupHidden = false + private var hideQsCarrierGroup = false private var hideStatusIcons = false private var fixedStatusIcons = false - private var hideLockscreenCarrier = false - private var hideLockscreenStatusbar = false private var hideLockscreenLockIcon = false private var hideDataDisabledIcon = false private var sideMarginStatusIcons = 0 @@ -49,20 +47,21 @@ class Miscellaneous(context: Context?) : ModPack(context!!) { private var statusIcons: LinearLayout? = null private var statusIconContainer: LinearLayout? = null private var mobileSignalControllerParam: Any? = null + private var showHeaderClockA14 = false override fun updatePrefs(vararg key: String) { - if (Xprefs == null) return + if (!XprefsIsInitialized) return - Xprefs!!.apply { - qsCarrierGroupHidden = getBoolean(QSPANEL_HIDE_CARRIER, false) + Xprefs.apply { + hideQsCarrierGroup = getBoolean(QSPANEL_HIDE_CARRIER, false) hideStatusIcons = getBoolean(HIDE_STATUS_ICONS_SWITCH, false) fixedStatusIcons = getBoolean(FIXED_STATUS_ICONS_SWITCH, false) - topMarginStatusIcons = getInt(FIXED_STATUS_ICONS_TOPMARGIN, 8) - sideMarginStatusIcons = getInt(FIXED_STATUS_ICONS_SIDEMARGIN, 0) - hideLockscreenCarrier = getBoolean(HIDE_LOCKSCREEN_CARRIER, false) - hideLockscreenStatusbar = getBoolean(HIDE_LOCKSCREEN_STATUSBAR, false) + topMarginStatusIcons = getSliderInt(FIXED_STATUS_ICONS_TOPMARGIN, 8) + sideMarginStatusIcons = getSliderInt(FIXED_STATUS_ICONS_SIDEMARGIN, 0) hideLockscreenLockIcon = getBoolean(HIDE_LOCKSCREEN_LOCK_ICON, false) hideDataDisabledIcon = getBoolean(HIDE_DATA_DISABLED_ICON, false) + showHeaderClockA14 = getBoolean(HEADER_CLOCK_SWITCH, false) && + Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE } if (key.isNotEmpty()) { @@ -83,12 +82,6 @@ class Miscellaneous(context: Context?) : ModPack(context!!) { fixedStatusIconsA12() } - if (it == HIDE_LOCKSCREEN_CARRIER || - it == HIDE_LOCKSCREEN_STATUSBAR - ) { - hideLockscreenCarrierOrStatusbar() - } - if (it == HIDE_LOCKSCREEN_LOCK_ICON) { hideLockscreenLockIcon() } @@ -107,7 +100,6 @@ class Miscellaneous(context: Context?) : ModPack(context!!) { hideQSCarrierGroup() hideStatusIcons() fixedStatusIconsA12() - hideLockscreenCarrierOrStatusbar() hideLockscreenLockIcon() hideDataDisabledIcon(loadPackageParam) } @@ -158,7 +150,7 @@ class Miscellaneous(context: Context?) : ModPack(context!!) { } } - if (hideStatusIcons || qsCarrierGroupHidden) { + if (hideStatusIcons || hideQsCarrierGroup) { try { val mQSCarriers = getObjectField( param.thisObject, @@ -209,7 +201,7 @@ class Miscellaneous(context: Context?) : ModPack(context!!) { } } - if (hideStatusIcons || qsCarrierGroupHidden) { + if (hideStatusIcons || hideQsCarrierGroup) { try { val qsCarrierGroup = getObjectField( param.thisObject, @@ -317,20 +309,20 @@ class Miscellaneous(context: Context?) : ModPack(context!!) { "quick_qs_status_icons", object : XC_LayoutInflated() { override fun handleLayoutInflated(liparam: LayoutInflatedParam) { - if (!qsCarrierGroupHidden) return + if (!hideQsCarrierGroup || showHeaderClockA14) return - liparam.view.findViewById( - liparam.res.getIdentifier( - "carrier_group", - "id", - mContext.packageName - ) - ).apply { - layoutParams.height = 0 - layoutParams.width = 0 - setMinimumWidth(0) - visibility = View.INVISIBLE - } + liparam.view.findViewById( + liparam.res.getIdentifier( + "carrier_group", + "id", + mContext.packageName + ) + ).apply { + layoutParams.height = 0 + layoutParams.width = 0 + minimumWidth = 0 + visibility = View.INVISIBLE + } } }) } catch (ignored: Throwable) { @@ -350,38 +342,39 @@ class Miscellaneous(context: Context?) : ModPack(context!!) { if (!hideStatusIcons) return try { - liparam.view.findViewById( - liparam.res.getIdentifier( - "clock", - "id", - mContext.packageName - ) - ).apply { - layoutParams.height = 0 - layoutParams.width = 0 - setTextAppearance(0) - setTextColor(0) - } + liparam.view.findViewById( + liparam.res.getIdentifier( + "clock", + "id", + mContext.packageName + ) + ).apply { + layoutParams.height = 0 + layoutParams.width = 0 + setTextAppearance(0) + setTextColor(0) + } } catch (ignored: Throwable) { } try { - liparam.view.findViewById( - liparam.res.getIdentifier( - "date_clock", - "id", - mContext.packageName - ) - ).apply { - layoutParams.height = 0 - layoutParams.width = 0 - setTextAppearance(0) - setTextColor(0) - } + liparam.view.findViewById( + liparam.res.getIdentifier( + "date_clock", + "id", + mContext.packageName + ) + ).apply { + layoutParams.height = 0 + layoutParams.width = 0 + setTextAppearance(0) + setTextColor(0) + } } catch (ignored: Throwable) { } - try { + if (!showHeaderClockA14) { + try { liparam.view.findViewById( liparam.res.getIdentifier( "carrier_group", @@ -391,13 +384,13 @@ class Miscellaneous(context: Context?) : ModPack(context!!) { ).apply { layoutParams.height = 0 layoutParams.width = 0 - setMinimumWidth(0) + minimumWidth = 0 visibility = View.INVISIBLE } - } catch (ignored: Throwable) { - } + } catch (ignored: Throwable) { + } - try { + try { liparam.view.findViewById( liparam.res.getIdentifier( "statusIcons", @@ -408,10 +401,10 @@ class Miscellaneous(context: Context?) : ModPack(context!!) { layoutParams.height = 0 layoutParams.width = 0 } - } catch (ignored: Throwable) { - } + } catch (ignored: Throwable) { + } - try { + try { liparam.view.findViewById( liparam.res.getIdentifier( "batteryRemainingIcon", @@ -422,55 +415,56 @@ class Miscellaneous(context: Context?) : ModPack(context!!) { layoutParams.height = 0 layoutParams.width = 0 } - } catch (ignored: Throwable) { + } catch (ignored: Throwable) { + } } try { - liparam.view.findViewById( - liparam.res.getIdentifier( - "rightLayout", - "id", - mContext.packageName - ) - ).apply { - layoutParams.height = 0 - layoutParams.width = 0 - visibility = View.INVISIBLE - } + liparam.view.findViewById( + liparam.res.getIdentifier( + "rightLayout", + "id", + mContext.packageName + ) + ).apply { + layoutParams.height = 0 + layoutParams.width = 0 + visibility = View.INVISIBLE + } } catch (ignored: Throwable) { } // Ricedroid date try { - liparam.view.findViewById( - liparam.res.getIdentifier( - "date", - "id", - mContext.packageName - ) - ).apply { - layoutParams.height = 0 - layoutParams.width = 0 - setTextAppearance(0) - setTextColor(0) - } + liparam.view.findViewById( + liparam.res.getIdentifier( + "date", + "id", + mContext.packageName + ) + ).apply { + layoutParams.height = 0 + layoutParams.width = 0 + setTextAppearance(0) + setTextColor(0) + } } catch (ignored: Throwable) { } // Nusantara clock try { - liparam.view.findViewById( - liparam.res.getIdentifier( - "jr_clock", - "id", - mContext.packageName - ) - ).apply { - layoutParams.height = 0 - layoutParams.width = 0 - setTextAppearance(0) - setTextColor(0) - } + liparam.view.findViewById( + liparam.res.getIdentifier( + "jr_clock", + "id", + mContext.packageName + ) + ).apply { + layoutParams.height = 0 + layoutParams.width = 0 + setTextAppearance(0) + setTextColor(0) + } } catch (ignored: Throwable) { } @@ -508,11 +502,11 @@ class Miscellaneous(context: Context?) : ModPack(context!!) { try { liparam.view.findViewById( - liparam.res.getIdentifier( - "date", - "id", - mContext.packageName - ) + liparam.res.getIdentifier( + "date", + "id", + mContext.packageName + ) ).apply { setTextAppearance(0) layoutParams.height = 0 @@ -642,16 +636,14 @@ class Miscellaneous(context: Context?) : ModPack(context!!) { it.requestLayout() } - statusIconContainer!!.setLayoutParams( - FrameLayout.LayoutParams( - ViewGroup.LayoutParams.WRAP_CONTENT, - TypedValue.applyDimension( - TypedValue.COMPLEX_UNIT_DIP, - 28f, - mContext.resources.displayMetrics - ).toInt(), - Gravity.END - ) + statusIconContainer!!.layoutParams = FrameLayout.LayoutParams( + ViewGroup.LayoutParams.WRAP_CONTENT, + TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_DIP, + 28f, + mContext.resources.displayMetrics + ).toInt(), + Gravity.END ) statusIconContainer!!.gravity = Gravity.CENTER (statusIconContainer!!.layoutParams as FrameLayout.LayoutParams).setMargins( @@ -661,13 +653,12 @@ class Miscellaneous(context: Context?) : ModPack(context!!) { mContext.resources.displayMetrics ).toInt(), 0, 0 ) - (statusIconContainer!!.layoutParams as FrameLayout.LayoutParams).setMarginEnd( + (statusIconContainer!!.layoutParams as FrameLayout.LayoutParams).marginEnd = TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, sideMarginStatusIcons.toFloat(), mContext.resources.displayMetrics ).toInt() - ) statusIconContainer!!.requestLayout() privacyContainer.addView(statusIconContainer) @@ -680,70 +671,6 @@ class Miscellaneous(context: Context?) : ModPack(context!!) { } } - private fun hideLockscreenCarrierOrStatusbar() { - val resParam: InitPackageResourcesParam = resParams[SYSTEMUI_PACKAGE] ?: return - - try { - resParam.res.hookLayout( - SYSTEMUI_PACKAGE, - "layout", - "keyguard_status_bar", - object : XC_LayoutInflated() { - override fun handleLayoutInflated(liparam: LayoutInflatedParam) { - if (hideLockscreenCarrier) { - try { - liparam.view.findViewById( - liparam.res.getIdentifier( - "keyguard_carrier_text", - "id", - mContext.packageName - ) - ).apply { - layoutParams.height = 0 - visibility = View.INVISIBLE - requestLayout() - } - } catch (ignored: Throwable) { - } - } - - if (hideLockscreenStatusbar) { - try { - liparam.view.findViewById( - liparam.res.getIdentifier( - "status_icon_area", - "id", - mContext.packageName - ) - ).apply { - layoutParams.height = 0 - visibility = View.INVISIBLE - requestLayout() - } - } catch (ignored: Throwable) { - } - - try { - liparam.view.findViewById( - liparam.res.getIdentifier( - "keyguard_carrier_text", - "id", - mContext.packageName - ) - ).apply { - layoutParams.height = 0 - visibility = View.INVISIBLE - requestLayout() - } - } catch (ignored: Throwable) { - } - } - } - }) - } catch (ignored: Throwable) { - } - } - private fun hideLockscreenLockIcon() { val resParam: InitPackageResourcesParam = resParams[SYSTEMUI_PACKAGE] ?: return diff --git a/app/src/main/java/com/drdisagree/iconify/xposed/modules/OpQsHeader.kt b/app/src/main/java/com/drdisagree/iconify/xposed/modules/OpQsHeader.kt new file mode 100644 index 000000000..9535e5bb2 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/xposed/modules/OpQsHeader.kt @@ -0,0 +1,2255 @@ +package com.drdisagree.iconify.xposed.modules + +import android.annotation.SuppressLint +import android.bluetooth.BluetoothDevice +import android.bluetooth.BluetoothManager +import android.content.Context +import android.content.Intent +import android.content.pm.PackageManager +import android.content.res.Configuration +import android.content.res.Resources +import android.graphics.Bitmap +import android.graphics.BitmapShader +import android.graphics.Canvas +import android.graphics.Color +import android.graphics.LinearGradient +import android.graphics.Paint +import android.graphics.PorterDuff +import android.graphics.PorterDuffXfermode +import android.graphics.Rect +import android.graphics.RectF +import android.graphics.Shader +import android.graphics.drawable.BitmapDrawable +import android.graphics.drawable.Drawable +import android.graphics.drawable.GradientDrawable +import android.graphics.drawable.TransitionDrawable +import android.media.MediaMetadata +import android.media.session.MediaController +import android.media.session.MediaSessionManager +import android.media.session.PlaybackState +import android.net.ConnectivityManager +import android.net.Network +import android.net.NetworkCapabilities +import android.net.wifi.WifiManager +import android.os.Handler +import android.os.Looper +import android.provider.Settings +import android.telephony.SubscriptionManager +import android.telephony.TelephonyManager +import android.view.Gravity +import android.view.View +import android.view.View.OnLongClickListener +import android.view.ViewGroup +import android.view.ViewGroup.MarginLayoutParams +import android.widget.FrameLayout +import android.widget.ImageView +import android.widget.LinearLayout +import android.widget.RelativeLayout +import androidx.core.content.ContextCompat +import androidx.core.graphics.ColorUtils +import androidx.core.graphics.drawable.DrawableCompat +import androidx.core.graphics.drawable.toBitmap +import androidx.palette.graphics.Palette +import com.drdisagree.iconify.BuildConfig +import com.drdisagree.iconify.common.Const.FRAMEWORK_PACKAGE +import com.drdisagree.iconify.common.Const.SYSTEMUI_PACKAGE +import com.drdisagree.iconify.common.Preferences.ICONIFY_QS_HEADER_CONTAINER_SHADE_TAG +import com.drdisagree.iconify.common.Preferences.ICONIFY_QS_HEADER_CONTAINER_TAG +import com.drdisagree.iconify.common.Preferences.OP_QS_HEADER_BLUR_LEVEL +import com.drdisagree.iconify.common.Preferences.OP_QS_HEADER_EXPANSION_Y +import com.drdisagree.iconify.common.Preferences.OP_QS_HEADER_GAP_EXPANDED +import com.drdisagree.iconify.common.Preferences.OP_QS_HEADER_HIDE_STOCK_MEDIA +import com.drdisagree.iconify.common.Preferences.OP_QS_HEADER_SWITCH +import com.drdisagree.iconify.common.Preferences.OP_QS_HEADER_TOP_MARGIN +import com.drdisagree.iconify.common.Preferences.OP_QS_HEADER_VIBRATE +import com.drdisagree.iconify.common.Preferences.QS_TEXT_ALWAYS_WHITE +import com.drdisagree.iconify.common.Preferences.QS_TEXT_FOLLOW_ACCENT +import com.drdisagree.iconify.utils.color.monet.quantize.QuantizerCelebi +import com.drdisagree.iconify.utils.color.monet.score.Score +import com.drdisagree.iconify.xposed.ModPack +import com.drdisagree.iconify.xposed.modules.utils.ActivityLauncherUtils +import com.drdisagree.iconify.xposed.modules.utils.Helpers.findClassInArray +import com.drdisagree.iconify.xposed.modules.utils.Helpers.isMethodAvailable +import com.drdisagree.iconify.xposed.modules.utils.Helpers.isQsTileOverlayEnabled +import com.drdisagree.iconify.xposed.modules.utils.SettingsLibUtils.Companion.getColorAttr +import com.drdisagree.iconify.xposed.modules.utils.TouchAnimator +import com.drdisagree.iconify.xposed.modules.utils.VibrationUtils +import com.drdisagree.iconify.xposed.modules.utils.ViewHelper.applyBlur +import com.drdisagree.iconify.xposed.modules.utils.ViewHelper.toPx +import com.drdisagree.iconify.xposed.modules.views.MediaPlayerPagerAdapter +import com.drdisagree.iconify.xposed.modules.views.OpQsHeaderView +import com.drdisagree.iconify.xposed.modules.views.OpQsMediaPlayerView +import com.drdisagree.iconify.xposed.modules.views.OpQsMediaPlayerView.Companion.opMediaDefaultBackground +import com.drdisagree.iconify.xposed.utils.XPrefs.Xprefs +import com.drdisagree.iconify.xposed.utils.XPrefs.XprefsIsInitialized +import de.robv.android.xposed.XC_MethodHook +import de.robv.android.xposed.XC_MethodReplacement +import de.robv.android.xposed.XposedBridge.hookAllConstructors +import de.robv.android.xposed.XposedBridge.hookAllMethods +import de.robv.android.xposed.XposedBridge.log +import de.robv.android.xposed.XposedHelpers.callMethod +import de.robv.android.xposed.XposedHelpers.callStaticMethod +import de.robv.android.xposed.XposedHelpers.findAndHookMethod +import de.robv.android.xposed.XposedHelpers.findClass +import de.robv.android.xposed.XposedHelpers.findClassIfExists +import de.robv.android.xposed.XposedHelpers.getObjectField +import de.robv.android.xposed.XposedHelpers.setObjectField +import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import kotlinx.coroutines.delay +import kotlinx.coroutines.isActive +import kotlinx.coroutines.launch +import kotlinx.coroutines.suspendCancellableCoroutine +import kotlinx.coroutines.withContext +import java.lang.reflect.Method +import java.nio.ByteBuffer +import kotlin.coroutines.resume +import kotlin.math.pow +import kotlin.math.sqrt +import kotlin.properties.Delegates +import kotlin.random.Random + +@Suppress("DiscouragedApi") +class OpQsHeader(context: Context?) : ModPack(context!!) { + + // Preferences + private var showOpQsHeaderView = false + private var vibrateOnClick = false + private var hideStockMediaPlayer = false + private var mediaBlurLevel = 10f + private var topMarginValue = 0 + private var expansionAmount = 0 + private var qsTextAlwaysWhite = false + private var qsTextFollowAccent = false + private var expandedQsGap = 0 + + // Views + private var mQsHeaderContainer: LinearLayout = LinearLayout(mContext) + private var mQsHeaderContainerShade: LinearLayout = LinearLayout(mContext).apply { + tag = ICONIFY_QS_HEADER_CONTAINER_SHADE_TAG + } + private var mQsPanelView: ViewGroup? = null + private var mQuickStatusBarHeader: FrameLayout? = null + private var mQQSContainerAnimator: TouchAnimator? = null + private lateinit var mHeaderQsPanel: LinearLayout + private var mOpQsHeaderView: OpQsHeaderView? = null + + // Colors + private var colorActive: Int? = null + private var colorInactive: Int? = null + private var colorLabelActive: Int? = null + private var colorLabelInactive: Int? = null + private var colorAccent by Delegates.notNull() + private var colorPrimary by Delegates.notNull() + + // Media data + private val mActiveMediaControllers = mutableListOf>() + private val mPrevMediaPlayingState = mutableMapOf() + private val mMediaControllerMetadataMap = mutableMapOf() + private val mPrevMediaControllerMetadataMap = mutableMapOf() + private val mPrevMediaArtworkMap = mutableMapOf() + private val mPrevMediaProcessedArtworkMap = mutableMapOf() + private val mMediaPlayerViews = mutableListOf>().also { + it.add(null to OpQsMediaPlayerView(mContext)) + } + private var mMediaPlayerAdapter: MediaPlayerPagerAdapter? = null + + // Tile and media state + private var mInternetEnabled = false + private var mBluetoothEnabled = false + + // Misc + private lateinit var appContext: Context + private var mHandler: Handler = Handler(Looper.getMainLooper()) + private val artworkExtractorScope = CoroutineScope(Dispatchers.IO + Job()) + private var mMediaUpdater = CoroutineScope(Dispatchers.Main) + private var mMediaUpdaterJob: Job? = null + private var mActivityStarter: Any? = null + private var mMediaOutputDialogFactory: Any? = null + private var mNotificationMediaManager: Any? = null + private var mBluetoothController: Any? = null + private var qsTileViewImplInstance: Any? = null + private lateinit var mConnectivityManager: ConnectivityManager + private lateinit var mTelephonyManager: TelephonyManager + private lateinit var mWifiManager: WifiManager + private lateinit var mBluetoothManager: BluetoothManager + private lateinit var mMediaSessionManager: MediaSessionManager + private lateinit var mSubscriptionManager: SubscriptionManager + private lateinit var mActivityLauncherUtils: ActivityLauncherUtils + + // Resources + private var qqsTileHeight by Delegates.notNull() + private var qsTileMarginVertical by Delegates.notNull() + private var qsTileCornerRadius by Delegates.notNull() + private lateinit var opMediaBackgroundDrawable: Drawable + private var previousBlurLevel = 10f + + override fun updatePrefs(vararg key: String) { + if (!XprefsIsInitialized) return + + Xprefs.apply { + showOpQsHeaderView = getBoolean(OP_QS_HEADER_SWITCH, false) + vibrateOnClick = getBoolean(OP_QS_HEADER_VIBRATE, false) + hideStockMediaPlayer = getBoolean(OP_QS_HEADER_HIDE_STOCK_MEDIA, false) + mediaBlurLevel = getSliderInt(OP_QS_HEADER_BLUR_LEVEL, 10).toFloat() + topMarginValue = getSliderInt(OP_QS_HEADER_TOP_MARGIN, 0) + expansionAmount = getSliderInt(OP_QS_HEADER_EXPANSION_Y, 0) + expandedQsGap = getInt(OP_QS_HEADER_GAP_EXPANDED, 0) + qsTextAlwaysWhite = getBoolean(QS_TEXT_ALWAYS_WHITE, false) + qsTextFollowAccent = getBoolean(QS_TEXT_FOLLOW_ACCENT, false) + } + + if (key.isNotEmpty() && + (key[0] == OP_QS_HEADER_VIBRATE || + key[0] == OP_QS_HEADER_BLUR_LEVEL) + ) { + updateMediaPlayers(force = true) + } + } + + override fun handleLoadPackage(loadPackageParam: LoadPackageParam) { + val qsPanelClass = findClass( + "$SYSTEMUI_PACKAGE.qs.QSPanel", + loadPackageParam.classLoader + ) + val quickQsPanelClass = findClass( + "$SYSTEMUI_PACKAGE.qs.QuickQSPanel", + loadPackageParam.classLoader + ) + val qsImplClass = findClassInArray( + loadPackageParam.classLoader, + "$SYSTEMUI_PACKAGE.qs.QSImpl", + "$SYSTEMUI_PACKAGE.qs.QSFragment" + ) + val qsContainerImplClass = findClass( + "$SYSTEMUI_PACKAGE.qs.QSContainerImpl", + loadPackageParam.classLoader + ) + val qsTileViewImplClass = findClass( + "$SYSTEMUI_PACKAGE.qs.tileimpl.QSTileViewImpl", + loadPackageParam.classLoader + ) + val tileLayoutClass = findClassInArray( + loadPackageParam.classLoader, + "$SYSTEMUI_PACKAGE.qs.TileLayout", + "$SYSTEMUI_PACKAGE.qs.PagedTileLayout" + ) + val qsPanelControllerBaseClass = findClassIfExists( + "$SYSTEMUI_PACKAGE.qs.QSPanelControllerBase", + loadPackageParam.classLoader + ) + val qsSecurityFooterUtilsClass = findClassIfExists( + "$SYSTEMUI_PACKAGE.qs.QSSecurityFooterUtils", + loadPackageParam.classLoader + ) + val quickStatusBarHeaderClass = findClass( + "$SYSTEMUI_PACKAGE.qs.QuickStatusBarHeader", + loadPackageParam.classLoader + ) + val shadeHeaderControllerClass = findClassInArray( + loadPackageParam.classLoader, + "$SYSTEMUI_PACKAGE.shade.ShadeHeaderController", + "$SYSTEMUI_PACKAGE.shade.LargeScreenShadeHeaderController", + ) + val dependencyClass = findClass( + "$SYSTEMUI_PACKAGE.Dependency", + loadPackageParam.classLoader + ) + val activityStarterClass = findClass( + "$SYSTEMUI_PACKAGE.plugins.ActivityStarter", + loadPackageParam.classLoader + ) + val bluetoothControllerImplClass = findClass( + "$SYSTEMUI_PACKAGE.statusbar.policy.BluetoothControllerImpl", + loadPackageParam.classLoader + ) + val notificationMediaManagerClass = findClass( + "$SYSTEMUI_PACKAGE.statusbar.NotificationMediaManager", + loadPackageParam.classLoader + ) + val mediaControlPanelClass = findClassInArray( + loadPackageParam.classLoader, + "$SYSTEMUI_PACKAGE.media.controls.ui.controller.MediaControlPanel", + "$SYSTEMUI_PACKAGE.media.controls.ui.MediaControlPanel" + ) + launchableImageView = findClassIfExists( + "$SYSTEMUI_PACKAGE.animation.view.LaunchableImageView", + loadPackageParam.classLoader + ) + launchableLinearLayout = findClassIfExists( + "$SYSTEMUI_PACKAGE.animation.view.LaunchableLinearLayout", + loadPackageParam.classLoader + ) + + initResources() + + if (qsSecurityFooterUtilsClass == null) { + hookAllConstructors(quickStatusBarHeaderClass, object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + mActivityStarter = callStaticMethod( + dependencyClass, + "get", + activityStarterClass + ) + mActivityLauncherUtils = ActivityLauncherUtils(mContext, mActivityStarter) + } + }) + } else { + hookAllConstructors(qsSecurityFooterUtilsClass, object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + mActivityStarter = getObjectField( + param.thisObject, + "mActivityStarter" + ) + mActivityLauncherUtils = ActivityLauncherUtils(mContext, mActivityStarter) + } + }) + } + + hookAllConstructors(bluetoothControllerImplClass, object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + mBluetoothController = param.thisObject + } + }) + + hookAllConstructors(notificationMediaManagerClass, object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + mNotificationMediaManager = param.thisObject + } + }) + + hookAllConstructors(mediaControlPanelClass, object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + mMediaOutputDialogFactory = + getObjectField(param.thisObject, "mMediaOutputDialogFactory") + } + }) + + hookAllMethods(qsTileViewImplClass, "init", object : XC_MethodHook() { + override fun beforeHookedMethod(param: MethodHookParam) { + qsTileViewImplInstance = param.thisObject + } + }) + + hookAllConstructors(tileLayoutClass, object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + if (!showOpQsHeaderView) return + + updateOpHeaderView() + } + }) + + // Update colors when device theme changes + hookAllMethods(shadeHeaderControllerClass, "onInit", object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + if (!showOpQsHeaderView) return + + val configurationControllerListener = getObjectField( + param.thisObject, + "configurationControllerListener" + ) + + val updateColors = object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + if (!showOpQsHeaderView || qsTileViewImplInstance == null) return + + updateOpHeaderView() + } + } + + val methods = listOf( + "onConfigChanged", + "onDensityOrFontScaleChanged", + "onUiModeChanged", + "onThemeChanged" + ) + + for (method in methods) { + try { + hookAllMethods( + configurationControllerListener.javaClass, + method, + updateColors + ) + } catch (ignored: Throwable) { + } + } + } + }) + + hookAllMethods(quickStatusBarHeaderClass, "onFinishInflate", object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + if (!showOpQsHeaderView) return + + mQuickStatusBarHeader = param.thisObject as FrameLayout + + mHeaderQsPanel = (param.thisObject as FrameLayout).findViewById( + mContext.resources.getIdentifier( + "quick_qs_panel", + "id", + SYSTEMUI_PACKAGE + ) + ) + + mQsHeaderContainer.apply { + layoutParams = LinearLayout.LayoutParams( + LinearLayout.LayoutParams.MATCH_PARENT, + LinearLayout.LayoutParams.WRAP_CONTENT + ) + orientation = LinearLayout.HORIZONTAL + } + + mQsHeaderContainerShade.apply { + layoutParams = LinearLayout.LayoutParams( + LinearLayout.LayoutParams.MATCH_PARENT, + LinearLayout.LayoutParams.WRAP_CONTENT + ) + orientation = LinearLayout.VERTICAL + } + + (mQsHeaderContainer.parent as? ViewGroup)?.removeView(mQsHeaderContainer) + val headerImageAvailable = mQuickStatusBarHeader!!.findViewWithTag( + ICONIFY_QS_HEADER_CONTAINER_TAG + ) + mQuickStatusBarHeader!!.addView( + mQsHeaderContainer, + if (headerImageAvailable == null) { + -1 + } else { + mQuickStatusBarHeader!!.indexOfChild(headerImageAvailable) + 1 + } + ) + + val relativeLayout = RelativeLayout(mContext).apply { + layoutParams = RelativeLayout.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT + ).apply { + gravity = Gravity.TOP + } + clipChildren = false + clipToPadding = false + + (mOpQsHeaderView?.parent as? ViewGroup)?.removeView(mOpQsHeaderView) + mOpQsHeaderView = OpQsHeaderView(mContext).apply { + setOnAttachListener { + ControllersProvider.getInstance().apply { + registerWifiCallback(mWifiCallback) + registerMobileDataCallback(mMobileDataCallback) + registerBluetoothCallback(mBluetoothCallback) + } + } + setOnDetachListener { + ControllersProvider.getInstance().apply { + unRegisterWifiCallback(mWifiCallback) + unRegisterMobileDataCallback(mMobileDataCallback) + unRegisterBluetoothCallback(mBluetoothCallback) + } + } + setOnClickListeners( + onClickListener = mOnClickListener, + onLongClickListener = mOnLongClickListener + ) + mMediaPlayerAdapter = MediaPlayerPagerAdapter(mMediaPlayerViews) + mediaPlayerContainer.adapter = mMediaPlayerAdapter + } + + mQsHeaderContainer.addView(mOpQsHeaderView) + updateOpHeaderView() + + (mQsHeaderContainer.parent as? ViewGroup)?.removeView(mQsHeaderContainer) + addView(mQsHeaderContainer) + + (mHeaderQsPanel.parent as? ViewGroup)?.removeView(mHeaderQsPanel) + addView(mHeaderQsPanel) + + (mHeaderQsPanel.layoutParams as RelativeLayout.LayoutParams).apply { + addRule(RelativeLayout.BELOW, mOpQsHeaderView!!.id) + } + } + + mQuickStatusBarHeader!!.addView( + relativeLayout, + mQuickStatusBarHeader!!.childCount + ) + + buildHeaderViewExpansion() + } + }) + + // Move view to different parent when rotation changes + hookAllMethods(quickStatusBarHeaderClass, "updateResources", object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + mQuickStatusBarHeader = param.thisObject as FrameLayout + + mHeaderQsPanel = (param.thisObject as FrameLayout).findViewById( + mContext.resources.getIdentifier( + "quick_qs_panel", + "id", + SYSTEMUI_PACKAGE + ) + ) + + if (!showOpQsHeaderView) return + + buildHeaderViewExpansion() + + if (isLandscape) { + if (mQsHeaderContainer.parent != mQsHeaderContainerShade) { + (mQsHeaderContainer.parent as? ViewGroup)?.removeView(mQsHeaderContainer) + mQsHeaderContainerShade.addView(mQsHeaderContainer, -1) + } + mQsHeaderContainerShade.visibility = View.VISIBLE + } else { + if (mQsHeaderContainer.parent != mQuickStatusBarHeader) { + val headerImageAvailable = + mQuickStatusBarHeader!!.findViewWithTag( + ICONIFY_QS_HEADER_CONTAINER_TAG + ) + (mQsHeaderContainer.parent as? ViewGroup)?.removeView(mQsHeaderContainer) + mQuickStatusBarHeader?.addView( + mQsHeaderContainer, + if (headerImageAvailable == null) { + 0 + } else { + mQuickStatusBarHeader!!.indexOfChild(headerImageAvailable) + 1 + } + ) + } + mQsHeaderContainerShade.visibility = View.GONE + } + } + }) + + val updateQsTopMargin = object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + if (!showOpQsHeaderView) return + + val mQsPanel = try { + getObjectField(param.thisObject, "mQSPanel") + } catch (ignored: Throwable) { + (param.thisObject as FrameLayout).findViewById( + mContext.resources.getIdentifier( + "quick_settings_panel", + "id", + SYSTEMUI_PACKAGE + ) + ) + } as LinearLayout + + (mQsPanel.layoutParams as MarginLayoutParams).topMargin = + if (isLandscape) { + 0 + } else { + (qqsTileHeight * 2) + (qsTileMarginVertical * 2) + + mContext.toPx(topMarginValue + expansionAmount + expandedQsGap) + } + } + } + + // Update qs top margin + hookAllMethods(qsContainerImplClass, "onFinishInflate", updateQsTopMargin) + hookAllMethods(qsContainerImplClass, "updateResources", updateQsTopMargin) + + // Hide stock media player + val reAttachMediaHostAvailable = qsPanelClass.declaredMethods.any { + it.name == "reAttachMediaHost" + } + + if (showOpQsHeaderView && hideStockMediaPlayer && reAttachMediaHostAvailable) { + hookAllMethods(qsPanelClass, "reAttachMediaHost", object : XC_MethodReplacement() { + override fun replaceHookedMethod(param: MethodHookParam): Any? { + return null + } + }) + + // Ensure stock media player is hidden + hookAllMethods(qsImplClass, "onComponentCreated", object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + if (!showOpQsHeaderView) return + + try { + val mQSPanelController = + getObjectField(param.thisObject, "mQSPanelController") + + val listener = Runnable { + val mediaHost = callMethod(mQSPanelController, "getMediaHost") + val hostView = callMethod(mediaHost, "getHostView") + + callMethod(hostView, "setAlpha", 0.0f) + + try { + callMethod(mQSPanelController, "requestAnimatorUpdate") + } catch (ignored: Throwable) { + val mQSAnimator = getObjectField(param.thisObject, "mQSAnimator") + callMethod(mQSAnimator, "requestAnimatorUpdate") + } + } + + callMethod( + mQSPanelController, + "setUsingHorizontalLayoutChangeListener", + listener + ) + } catch (ignored: Throwable) { + } + } + }) + } else if (hideStockMediaPlayer) { // If reAttachMediaHost is not available, we need to hook switchTileLayout() + hookAllMethods( + qsPanelControllerBaseClass, + "switchTileLayout", + object : XC_MethodHook() { + override fun beforeHookedMethod(param: MethodHookParam) { + if (!showOpQsHeaderView) return + + val force = param.args[0] as Boolean + val horizontal = callMethod( + param.thisObject, + "shouldUseHorizontalLayout" + ) as Boolean + val mUsingHorizontalLayout = getObjectField( + param.thisObject, + "mUsingHorizontalLayout" + ) as Boolean + + if (horizontal != mUsingHorizontalLayout || force) { + val mQSLogger = getObjectField(param.thisObject, "mQSLogger") + val qsPanel = getObjectField(param.thisObject, "mView") + val qsPanelTag = callMethod(qsPanel, "getDumpableTag") + + callMethod( + mQSLogger, + "logSwitchTileLayout", + horizontal, + mUsingHorizontalLayout, + force, + qsPanelTag + ) + + setObjectField( + param.thisObject, + "mUsingHorizontalLayout", + horizontal + ) + + val mUsingHorizontalLayout2 = getObjectField( + qsPanel, + "mUsingHorizontalLayout" + ) as Boolean + + if (horizontal != mUsingHorizontalLayout2 || force) { + setObjectField( + qsPanel, + "mUsingHorizontalLayout", + horizontal + ) + + val mHorizontalContentContainer = getObjectField( + qsPanel, + "mHorizontalContentContainer" + ) as LinearLayout + + val newParent: ViewGroup = if (horizontal) { + mHorizontalContentContainer + } else { + qsPanel as ViewGroup + } + val mTileLayout = getObjectField(qsPanel, "mTileLayout") + val index = if (!horizontal) { + getObjectField(qsPanel, "mMovableContentStartIndex") + } else { + 0 + } as Int + + callStaticMethod( + qsPanelClass, + "switchToParent", + mTileLayout, + newParent, + index, + qsPanelTag + ) + + val mFooter = getObjectField(qsPanel, "mFooter") as? View + + if (mFooter != null) { + callStaticMethod( + qsPanelClass, + "switchToParent", + mFooter, + newParent, + index + 1, + qsPanelTag + ) + } + + callMethod( + mTileLayout, + "setMinRows", + if (horizontal) 2 else 1 + ) + callMethod( + mTileLayout, + "setMaxColumns", + if (horizontal) 2 else 4 + ) + + val mHorizontalLinearLayout = getObjectField( + qsPanel, + "mHorizontalLinearLayout" + ) as? LinearLayout + + if (mHorizontalLinearLayout != null && + quickQsPanelClass.isInstance(qsPanel) + ) { + val mMediaTotalBottomMargin = getObjectField( + qsPanel, + "mMediaTotalBottomMargin" + ) as Int + val mQsPanelBottomPadding = + (qsPanel as LinearLayout).paddingBottom + + val layoutParams = + mHorizontalLinearLayout.layoutParams as LinearLayout.LayoutParams + layoutParams.bottomMargin = + (mMediaTotalBottomMargin - mQsPanelBottomPadding) + .coerceAtLeast(0) + mHorizontalLinearLayout.layoutParams = layoutParams + } + + callMethod(qsPanel, "updatePadding") + + mHorizontalLinearLayout?.visibility = if (!horizontal) { + View.GONE + } else { + View.VISIBLE + } + } + + (getObjectField( + param.thisObject, + "mUsingHorizontalLayoutChangedListener" + ) as? Runnable)?.run() + } + + param.result = true + } + } + ) + } + + val hasSwitchAllContentToParent = qsPanelClass.declaredMethods.any { + it.name == "switchAllContentToParent" + } + val hasSwitchToParentMethod = qsPanelClass.declaredMethods.any { method -> + method.name == "switchToParent" && + method.parameterTypes.contentEquals( + arrayOf(View::class.java, ViewGroup::class.java, Int::class.java) + ) + } + + if (hasSwitchAllContentToParent && hasSwitchToParentMethod) { + hookAllMethods(qsPanelClass, "switchAllContentToParent", object : XC_MethodHook() { + override fun beforeHookedMethod(param: MethodHookParam) { + if (!showOpQsHeaderView) return + + val parent = param.args[0] as ViewGroup + val mMovableContentStartIndex = getObjectField( + param.thisObject, "mMovableContentStartIndex" + ) as Int + val index = if (parent === param.thisObject) mMovableContentStartIndex else 0 + val targetParentId = mContext.resources.getIdentifier( + "quick_settings_panel", + "id", + SYSTEMUI_PACKAGE + ) + + if (parent.id == targetParentId) { + val checkExistingView = + parent.findViewWithTag(ICONIFY_QS_HEADER_CONTAINER_SHADE_TAG) + if (checkExistingView != null) { + mQsHeaderContainerShade = checkExistingView as LinearLayout + if (parent.indexOfChild(mQsHeaderContainerShade) == index) { + return + } + } + + callMethod( + param.thisObject, + "switchToParent", + mQsHeaderContainerShade, + parent, + index + ) + } + } + }) + + if (showOpQsHeaderView) { + findAndHookMethod( + qsPanelClass, + "switchToParent", + View::class.java, + ViewGroup::class.java, + Int::class.java, + String::class.java, + object : XC_MethodReplacement() { + override fun replaceHookedMethod(param: MethodHookParam): Any? { + val view = param.args[0] as View + val newParent = param.args[1] as? ViewGroup + val tempIndex = param.args[2] as Int + + if (newParent == null) { + return null + } + + val index = if (view.tag == ICONIFY_QS_HEADER_CONTAINER_SHADE_TAG) { + tempIndex + } else { + tempIndex + 1 + } + + val currentParent = view.parent as? ViewGroup + + if (currentParent != newParent) { + currentParent?.removeView(view) + newParent.addView(view, index.coerceAtMost(newParent.childCount)) + } else if (newParent.indexOfChild(view) == index) { + return null + } else { + newParent.removeView(view) + newParent.addView(view, index.coerceAtMost(newParent.childCount)) + } + + return null + } + } + ) + } + } else { // Some ROMs don't have this method switchAllContentToParent() + hookAllMethods( + qsPanelControllerBaseClass, + "onInit", + object : XC_MethodHook() { + override fun beforeHookedMethod(param: MethodHookParam) { + mQsPanelView = getObjectField( + param.thisObject, + "mView" + ) as ViewGroup + } + } + ) + + findAndHookMethod( + qsPanelClass, + "switchToParent", + View::class.java, + ViewGroup::class.java, + Int::class.java, + String::class.java, + object : XC_MethodHook() { + override fun beforeHookedMethod(param: MethodHookParam) { + if (!showOpQsHeaderView || + mQsPanelView == null || + (param.args[1] as? ViewGroup) == null + ) return + + val parent = param.args[1] as ViewGroup + val mMovableContentStartIndex = getObjectField( + mQsPanelView, "mMovableContentStartIndex" + ) as Int + val index = if (parent === mQsPanelView) mMovableContentStartIndex else 0 + val targetParentId = mContext.resources.getIdentifier( + "quick_settings_panel", + "id", + SYSTEMUI_PACKAGE + ) + + if (parent.id == targetParentId) { + val mQsHeaderContainerShadeParent = + mQsHeaderContainerShade.parent as? ViewGroup + if (mQsHeaderContainerShadeParent != parent || + mQsHeaderContainerShadeParent.indexOfChild(mQsHeaderContainerShade) != index + ) { + mQsHeaderContainerShadeParent?.removeView(mQsHeaderContainerShade) + parent.addView(mQsHeaderContainerShade, index) + } + } + + param.args[2] = ((param.args[2] as Int) + 1).coerceAtMost(parent.childCount) + } + } + ) + } + + hookAllMethods(qsImplClass, "setQsExpansion", object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + if (!showOpQsHeaderView) return + + val onKeyguard = callMethod( + param.thisObject, + "isKeyguardState" + ) as Boolean + val mShowCollapsedOnKeyguard = getObjectField( + param.thisObject, + "mShowCollapsedOnKeyguard" + ) as Boolean + + val onKeyguardAndExpanded = onKeyguard && !mShowCollapsedOnKeyguard + val expansion = param.args[0] as Float + + setExpansion(onKeyguardAndExpanded, expansion); + } + }) + + hookResources() + } + + private fun hookResources() { + hookAllMethods( + Resources::class.java, + "getBoolean", + object : XC_MethodHook() { + override fun beforeHookedMethod(param: MethodHookParam) { + if (!showOpQsHeaderView) return + + val resId1 = mContext.resources.getIdentifier( + "config_use_split_notification_shade", + "bool", + SYSTEMUI_PACKAGE + ) + + val resId2 = mContext.resources.getIdentifier( + "config_skinnyNotifsInLandscape", + "bool", + SYSTEMUI_PACKAGE + ) + + if (param.args[0] == resId1) { + param.result = isLandscape + } else if (param.args[0] == resId2) { + param.result = false + } + } + } + ) + + hookAllMethods( + Resources::class.java, + "getInteger", + object : XC_MethodHook() { + override fun beforeHookedMethod(param: MethodHookParam) { + if (!showOpQsHeaderView) return + + val resId1 = mContext.resources.getIdentifier( + "quick_settings_max_rows", + "integer", + SYSTEMUI_PACKAGE + ) + + if (param.args[0] == resId1) { + param.result = 3 + } + } + } + ) + + hookAllMethods( + Resources::class.java, + "getDimensionPixelSize", + object : XC_MethodHook() { + override fun beforeHookedMethod(param: MethodHookParam) { + if (!showOpQsHeaderView) return + + val res1 = mContext.resources.getIdentifier( + "qs_brightness_margin_top", + "dimen", + SYSTEMUI_PACKAGE + ) + + if (res1 != 0 && param.args[0] == res1) { + param.result = 0 + } + } + } + ) + } + + private fun updateOpHeaderView() { + if (mOpQsHeaderView == null) return + + initResources() + startMediaUpdater() + updateInternetState() + updateBluetoothState() + updateMediaPlayers(force = true) + } + + private fun buildHeaderViewExpansion() { + if (!showOpQsHeaderView || + mOpQsHeaderView == null || + !::mHeaderQsPanel.isInitialized + ) return + + val resources = mContext.resources + val largeScreenHeaderActive = resources.getBoolean( + resources.getIdentifier( + "config_use_large_screen_shade_header", + "bool", + SYSTEMUI_PACKAGE + ) + ) + val derivedTopMargin = if (isLandscape) 0 else topMarginValue + + val params = mQsHeaderContainer.layoutParams as MarginLayoutParams + val qqsHeaderResId = if (largeScreenHeaderActive) resources.getIdentifier( + "qqs_layout_margin_top", + "dimen", + SYSTEMUI_PACKAGE + ) + else resources.getIdentifier( + "large_screen_shade_header_min_height", + "dimen", + SYSTEMUI_PACKAGE + ) + val topMargin = resources.getDimensionPixelSize(qqsHeaderResId) + params.topMargin = topMargin + mContext.toPx(derivedTopMargin) + mQsHeaderContainer.layoutParams = params + + (mHeaderQsPanel.layoutParams as MarginLayoutParams).topMargin = topMargin + + (qqsTileHeight * 2) + (qsTileMarginVertical * 2) + mContext.toPx(derivedTopMargin) + + val qsHeaderHeight = resources.getDimensionPixelOffset( + resources.getIdentifier( + "qs_header_height", + "dimen", + SYSTEMUI_PACKAGE + ) + ) - resources.getDimensionPixelOffset(qqsHeaderResId) + + val mQQSExpansionY = if (isLandscape) { + 0 + } else { + qsHeaderHeight + 16 - topMargin + expansionAmount + } + + val builderP: TouchAnimator.Builder = TouchAnimator.Builder() + .addFloat( + mQsHeaderContainer, + "translationY", + 0F, + mContext.toPx(mQQSExpansionY).toFloat() + ) + + mQQSContainerAnimator = builderP.build() + } + + private fun setExpansion(forceExpanded: Boolean, expansionFraction: Float) { + val keyguardExpansionFraction = if (forceExpanded) 1f else expansionFraction + mQQSContainerAnimator?.setPosition(keyguardExpansionFraction) + + mQsHeaderContainer.alpha = if (forceExpanded) expansionFraction else 1f + } + + private val mWifiCallback: ControllersProvider.OnWifiChanged = + object : ControllersProvider.OnWifiChanged { + override fun onWifiChanged(mWifiIndicators: Any?) { + updateInternetState() + } + } + + private val mMobileDataCallback: ControllersProvider.OnMobileDataChanged = + object : ControllersProvider.OnMobileDataChanged { + override fun setMobileDataIndicators(mMobileDataIndicators: Any?) { + updateInternetState() + } + + override fun setNoSims(show: Boolean, simDetected: Boolean) { + updateInternetState() + } + + override fun setIsAirplaneMode(mIconState: Any?) { + updateInternetState() + } + } + + private val mBluetoothCallback: ControllersProvider.OnBluetoothChanged = + object : ControllersProvider.OnBluetoothChanged { + override fun onBluetoothChanged(enabled: Boolean) { + updateBluetoothState(enabled) + } + } + + private val mMediaCallback: MediaController.Callback = object : MediaController.Callback() { + override fun onPlaybackStateChanged(state: PlaybackState?) { + super.onPlaybackStateChanged(state) + updateMediaControllers() + } + + override fun onMetadataChanged(metadata: MediaMetadata?) { + super.onMetadataChanged(metadata) + updateMediaControllers() + } + } + + private fun startMediaUpdater() { + mMediaUpdaterJob?.cancel() + + mMediaUpdaterJob = mMediaUpdater.launch { + while (isActive) { + updateMediaControllers() + delay(1000) + } + } + } + + private fun stopMediaUpdater() { + mMediaUpdaterJob?.cancel() + } + + private fun toggleInternetState(v: View) { + mHandler.post { + if (!ControllersProvider.showInternetDialog(v)) { + mActivityLauncherUtils.launchApp(Intent(Settings.ACTION_WIFI_SETTINGS), true) + } + } + + mHandler.postDelayed({ + updateInternetState() + }, 250) + } + + private fun updateInternetState() { + val isWiFiConnected = isWiFiConnected + val isMobileDataConnected = isMobileDataConnected + mInternetEnabled = isWiFiConnected || isMobileDataConnected + + val internetLabel: CharSequence = mContext.getString( + mContext.resources.getIdentifier( + "quick_settings_internet_label", + "string", + SYSTEMUI_PACKAGE + ) + ) + val noInternetIconDrawable = ContextCompat.getDrawable( + mContext, + mContext.resources.getIdentifier( + "ic_qs_no_internet_available", + "drawable", + SYSTEMUI_PACKAGE + ) + )!! + colorLabelInactive?.let { DrawableCompat.setTint(noInternetIconDrawable, it) } + + if (mInternetEnabled) { + if (isWiFiConnected) { + val wifiInfo = getWiFiInfo() + val wifiIconResId = when (wifiInfo.signalStrengthLevel) { + 4 -> "ic_wifi_signal_4" + 3 -> "ic_wifi_signal_3" + 2 -> "ic_wifi_signal_2" + 1 -> "ic_wifi_signal_1" + else -> "ic_wifi_signal_0" + } + val wifiIconDrawable = ContextCompat.getDrawable( + mContext, + mContext.resources.getIdentifier( + wifiIconResId, + "drawable", + FRAMEWORK_PACKAGE + ) + )!! + colorLabelActive?.let { DrawableCompat.setTint(wifiIconDrawable, it) } + + mOpQsHeaderView?.setInternetText(wifiInfo.ssid) + mOpQsHeaderView?.setInternetIcon(wifiIconDrawable) + } else { + val carrierInfo = getConnectedCarrierInfo() + val maxBars = 4 + + val mobileDataIconDrawable = ContextCompat.getDrawable( + mContext, + mContext.resources.getIdentifier( + "ic_signal_cellular_${carrierInfo.signalStrengthLevel}_${maxBars}_bar", + "drawable", + FRAMEWORK_PACKAGE + ) + )!! + colorLabelActive?.let { DrawableCompat.setTint(mobileDataIconDrawable, it) } + + if (carrierInfo.networkType == null) { + mOpQsHeaderView?.setInternetText(carrierInfo.name) + } else { + mOpQsHeaderView?.setInternetText( + String.format( + "%s, %s", + carrierInfo.name, + carrierInfo.networkType + ) + ) + } + mOpQsHeaderView?.setInternetIcon(mobileDataIconDrawable) + } + } else { + mOpQsHeaderView?.setInternetText(internetLabel) + mOpQsHeaderView?.setInternetIcon(noInternetIconDrawable) + } + + updateInternetTileColors() + } + + private val isWiFiConnected: Boolean + get() { + val network: Network? = mConnectivityManager.activeNetwork + return if (network != null) { + val capabilities = mConnectivityManager.getNetworkCapabilities(network) + capabilities != null && capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) + } else { + false + } + } + + data class WiFiInfo( + val ssid: String, + val signalStrengthLevel: Int + ) + + @Suppress("deprecation") + private fun getWiFiInfo(): WiFiInfo { + val internetLabel = mContext.getString( + mContext.resources.getIdentifier( + "quick_settings_internet_label", + "string", + SYSTEMUI_PACKAGE + ) + ) + val defaultInfo = WiFiInfo(internetLabel, 0) + + val wifiInfo = mWifiManager.connectionInfo ?: return defaultInfo + + val ssid = if (wifiInfo.hiddenSSID || wifiInfo.ssid == WifiManager.UNKNOWN_SSID) { + internetLabel + } else { + wifiInfo.ssid?.replace("\"", "") ?: internetLabel + } + val signalStrengthLevel = WifiManager.calculateSignalLevel(wifiInfo.rssi, 5).coerceIn(0, 4) + + return WiFiInfo(ssid, signalStrengthLevel) + } + + private val isMobileDataConnected: Boolean + get() { + val network: Network? = mConnectivityManager.activeNetwork + if (network != null) { + val capabilities = mConnectivityManager.getNetworkCapabilities(network) + return capabilities != null && + capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) && + capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) + } + return false + } + + data class CarrierInfo( + val name: String, + val signalStrengthLevel: Int?, + val networkType: String? + ) + + @Suppress("deprecation") + @SuppressLint("MissingPermission") + fun getConnectedCarrierInfo(): CarrierInfo { + val internetLabel = mContext.getString( + mContext.resources.getIdentifier( + "quick_settings_internet_label", + "string", + SYSTEMUI_PACKAGE + ) + ) + val defaultInfo = CarrierInfo(internetLabel, null, null) + + val activeSubscriptionInfoList = mSubscriptionManager.activeSubscriptionInfoList + if (activeSubscriptionInfoList.isNullOrEmpty()) { + return defaultInfo + } + + val network: Network = mConnectivityManager.activeNetwork ?: return defaultInfo + val networkCapabilities = + mConnectivityManager.getNetworkCapabilities(network) ?: return defaultInfo + + if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) { + for (subscriptionInfo in activeSubscriptionInfoList) { + val subId = subscriptionInfo.subscriptionId + val subTelephonyManager = mTelephonyManager.createForSubscriptionId(subId) + + if (subTelephonyManager.simState == TelephonyManager.SIM_STATE_READY && + networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) + ) { + val carrierName = subscriptionInfo.carrierName.toString() + val signalStrength = subTelephonyManager.signalStrength + val signalStrengthLevel = signalStrength?.level?.coerceIn(0, 4) ?: 0 + + val networkType = when (subTelephonyManager.networkType) { + TelephonyManager.NETWORK_TYPE_NR -> "5G" + TelephonyManager.NETWORK_TYPE_LTE -> "LTE" + TelephonyManager.NETWORK_TYPE_HSDPA, + TelephonyManager.NETWORK_TYPE_HSPA, + TelephonyManager.NETWORK_TYPE_HSUPA, + TelephonyManager.NETWORK_TYPE_UMTS -> "3G" + + TelephonyManager.NETWORK_TYPE_EDGE, + TelephonyManager.NETWORK_TYPE_GPRS -> "2G" + + TelephonyManager.NETWORK_TYPE_CDMA, + TelephonyManager.NETWORK_TYPE_EVDO_0, + TelephonyManager.NETWORK_TYPE_EVDO_A, + TelephonyManager.NETWORK_TYPE_EVDO_B, + TelephonyManager.NETWORK_TYPE_1xRTT -> "CDMA" + + TelephonyManager.NETWORK_TYPE_GSM -> "GSM" + else -> null + } + + return CarrierInfo(carrierName, signalStrengthLevel, networkType) + } + } + } + + return defaultInfo + } + + private val isBluetoothEnabled: Boolean + get() { + return mBluetoothManager.adapter != null && mBluetoothManager.adapter.isEnabled + } + + @SuppressLint("MissingPermission") + private fun getBluetoothConnectedDevice(): String { + val bluetoothLabel = mContext.resources.getString( + mContext.resources.getIdentifier( + "quick_settings_bluetooth_label", + "string", + SYSTEMUI_PACKAGE + ) + ) + + val bluetoothAdapter = mBluetoothManager.adapter + + if (bluetoothAdapter != null) { + val bondedDevices = bluetoothAdapter.bondedDevices + + for (device in bondedDevices) { + if (isBluetoothDeviceConnected(device)) { + return device.name.ifEmpty { bluetoothLabel } + } + } + } + + return bluetoothLabel + } + + private fun isBluetoothDeviceConnected(device: BluetoothDevice): Boolean { + return try { + val m: Method = device.javaClass.getMethod("isConnected") + m.invoke(device) as Boolean + } catch (e: Exception) { + throw IllegalStateException(e) + } + } + + private fun toggleBluetoothState(v: View) { + mHandler.post { + if (!ControllersProvider.showBluetoothDialog(mContext, v)) { + callMethod(mBluetoothController, "setBluetoothEnabled", !isBluetoothEnabled) + } + } + + mHandler.postDelayed({ + updateBluetoothState() + }, 250) + } + + private fun updateBluetoothState(enabled: Boolean = isBluetoothEnabled) { + mBluetoothEnabled = enabled + + val connectedIconResId = mContext.resources.getIdentifier( + "ic_bluetooth_connected", + "drawable", + SYSTEMUI_PACKAGE + ) + val connectedIcon = if (connectedIconResId != 0) { + ContextCompat.getDrawable(mContext, connectedIconResId) + } else { + ContextCompat.getDrawable( + appContext, + appContext.resources.getIdentifier( + "ic_bluetooth_connected", + "drawable", + appContext.packageName + ) + ) + }!! + colorLabelActive?.let { DrawableCompat.setTint(connectedIcon, it) } + + val disconnectedIconResId = mContext.resources.getIdentifier( + "ic_qs_bluetooth", + "drawable", + FRAMEWORK_PACKAGE + ) + val disconnectedIcon = if (disconnectedIconResId != 0) { + ContextCompat.getDrawable(mContext, disconnectedIconResId) + } else { + ContextCompat.getDrawable( + appContext, + appContext.resources.getIdentifier( + "ic_bluetooth_disconnected", + "drawable", + appContext.packageName + ) + ) + }!! + colorLabelInactive?.let { DrawableCompat.setTint(disconnectedIcon, it) } + + if (enabled) { + val defaultLabel = mContext.resources.getString( + mContext.resources.getIdentifier( + "quick_settings_bluetooth_label", + "string", + SYSTEMUI_PACKAGE + ) + ) + val bluetoothLabel = getBluetoothConnectedDevice() + val deviceConnected = bluetoothLabel != defaultLabel + + mOpQsHeaderView?.setBlueToothText(bluetoothLabel) + mOpQsHeaderView?.setBlueToothIcon(if (deviceConnected) connectedIcon else disconnectedIcon) + } else { + mOpQsHeaderView?.setBlueToothText( + mContext.resources.getIdentifier( + "quick_settings_bluetooth_label", + "string", + SYSTEMUI_PACKAGE + ) + ) + mOpQsHeaderView?.setBlueToothIcon(disconnectedIcon) + } + + updateBluetoothTileColors() + } + + private enum class MediaAction { + TOGGLE_PLAYBACK, + PLAY_PREVIOUS, + PLAY_NEXT + } + + private fun performMediaAction(packageName: String, action: MediaAction) { + val controller = mActiveMediaControllers.find { it.first == packageName }?.second ?: return + + when (action) { + MediaAction.TOGGLE_PLAYBACK -> { + if (controller.playbackState?.state == PlaybackState.STATE_PLAYING) { + controller.transportControls.pause() + } else { + controller.transportControls.play() + } + } + + MediaAction.PLAY_PREVIOUS -> { + controller.transportControls.skipToPrevious() + } + + MediaAction.PLAY_NEXT -> { + controller.transportControls.skipToNext() + } + } + + updateMediaPlayers() + } + + private fun updateMediaControllers() { + val currentControllers = mMediaSessionManager.getActiveSessions(null) + .map { controller -> controller.packageName to controller } + .toMutableList() + + val currentPackageNames = currentControllers.map { it.first }.toSet() + + mActiveMediaControllers.removeAll { (packageName, controller) -> + if (!currentPackageNames.contains(packageName)) { + controller.unregisterCallback(mMediaCallback) + + mMediaControllerMetadataMap.remove(packageName) + mPrevMediaControllerMetadataMap.remove(packageName) + mPrevMediaPlayingState.remove(packageName) + mPrevMediaArtworkMap.remove(packageName) + mPrevMediaProcessedArtworkMap.remove(packageName) + removeMediaPlayerView(packageName) + + true + } else { + false + } + } + + currentControllers.forEach { (packageName, controller) -> + val existingController = mActiveMediaControllers.find { it.first == packageName } + + if (existingController == null) { + controller.registerCallback(mMediaCallback) + mMediaControllerMetadataMap[packageName] = controller.metadata + mActiveMediaControllers.add(packageName to controller) + } else if (existingController.second != controller) { + val oldController = existingController.second + + oldController.unregisterCallback(mMediaCallback) + controller.registerCallback(mMediaCallback) + mMediaControllerMetadataMap[packageName] = controller.metadata + + mActiveMediaControllers.remove(existingController) + mActiveMediaControllers.add(packageName to controller) + } + } + + updateMediaPlayers() + } + + private fun updateMediaPlayers(force: Boolean = false) { + updateMediaPlayer(null, null, force) + + mActiveMediaControllers.forEach { (packageName, controller) -> + updateMediaPlayer(packageName, controller, force) + } + } + + private fun updateMediaPlayer( + packageName: String?, + controller: MediaController?, + force: Boolean = false + ) { + if (mOpQsHeaderView == null || !::opMediaBackgroundDrawable.isInitialized) return + + val mMediaPlayer = getOrCreateMediaPlayer(packageName) ?: return + val mInactiveBackground = opMediaBackgroundDrawable.constantState?.newDrawable()?.mutate() + ?.apply { + if (isQsTileOverlayEnabled) { + setTint(Color.TRANSPARENT) + } else { + colorInactive?.let { setTint(it) } + } + } + + mMediaPlayer.apply { + if (packageName == null || + mediaPlayerBackground.drawable == null || + mediaPlayerBackground.drawable == opMediaDefaultBackground + ) { + setMediaPlayerBackground(mInactiveBackground) + colorLabelActive?.let { + setMediaAppIconColor( + backgroundColor = colorAccent, + iconColor = it + ) + } + colorLabelInactive?.let { setMediaPlayerItemsColor(it) } + } + } + + if (packageName == null || controller == null) return + + artworkExtractorScope.launch { + val mMediaMetadata = controller.metadata + val mPreviousMediaMetadata = mPrevMediaControllerMetadataMap[packageName] + + val (areBitmapsEqual, areMetadataEqual) = areDataEqual( + mPreviousMediaMetadata, + mMediaMetadata + ) + val isSamePlayingState = + controller.playbackState?.state == PlaybackState.STATE_PLAYING == + mPrevMediaPlayingState[packageName] + + val requireUpdate = !areBitmapsEqual || !areMetadataEqual || !isSamePlayingState + + if (!requireUpdate && !force) return@launch + + val mMediaArtwork = mMediaMetadata?.getBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART) + ?: mMediaMetadata?.getBitmap(MediaMetadata.METADATA_KEY_ART) + val processedArtwork = processArtwork(mMediaArtwork, mMediaPlayer.mediaPlayerBackground) + val dominantColor: Int? = extractDominantColor(processedArtwork) + val filteredArtwork: Bitmap? = processedArtwork?.let { + applyColorFilterToBitmap(it, dominantColor) + it.applyBlur(mContext, mediaBlurLevel) + } + val newArtworkDrawable = when { + filteredArtwork != null -> BitmapDrawable(mContext.resources, filteredArtwork) + else -> mInactiveBackground + } + + val finalArtworkDrawable: Drawable? = when { + mPrevMediaArtworkMap[packageName] == null && filteredArtwork != null -> { + TransitionDrawable( + arrayOf( + mInactiveBackground, + newArtworkDrawable + ) + ) + } + + mPrevMediaArtworkMap[packageName] != null && filteredArtwork != null -> { + TransitionDrawable( + arrayOf( + BitmapDrawable( + mContext.resources, + mPrevMediaProcessedArtworkMap[packageName] + ), + newArtworkDrawable + ) + ) + } + + mPrevMediaArtworkMap[packageName] != null && filteredArtwork == null -> { + TransitionDrawable( + arrayOf( + BitmapDrawable( + mContext.resources, + mPrevMediaProcessedArtworkMap[packageName] + ), + newArtworkDrawable + ) + ) + } + + else -> { + mInactiveBackground + } + } + + val mMediaTitle = mMediaMetadata?.getString(MediaMetadata.METADATA_KEY_TITLE) + val mMediaArtist = mMediaMetadata?.getString(MediaMetadata.METADATA_KEY_ARTIST) + val mIsMediaPlaying = controller.playbackState?.state == PlaybackState.STATE_PLAYING + + val appIconDrawable = runCatching { + controller.packageName?.let { packageName -> + mContext.packageManager.getApplicationIcon(packageName) + }?.toCircularDrawable() + }.getOrNull() + + withContext(Dispatchers.Main) { + mMediaPlayer.apply { + setMediaTitle( + mMediaTitle + ?: appContext.getString( + appContext.resources.getIdentifier( + "media_player_not_playing", + "string", + appContext.packageName + ) + ) + ) + setMediaArtist(mMediaArtist) + setMediaPlayingIcon(mIsMediaPlaying) + } + + val requireIconTint = when { + appIconDrawable != null && mMediaTitle != null -> { + mMediaPlayer.setMediaAppIconDrawable(appIconDrawable) + false + } + + else -> { + mMediaPlayer.resetMediaAppIcon() + true + } + } + + withContext(Dispatchers.IO) { + previousBlurLevel = mediaBlurLevel + mPrevMediaPlayingState[packageName] = mIsMediaPlaying + mPrevMediaControllerMetadataMap[packageName] = mMediaMetadata + mPrevMediaArtworkMap[packageName] = mMediaArtwork + mPrevMediaProcessedArtworkMap[packageName] = filteredArtwork + } + + val onDominantColor: Int? + + withContext(Dispatchers.IO) { + val bitmap = filteredArtwork ?: mMediaArtwork + val scaledBitmap = bitmap?.let { scaleBitmap(it, 0.1f) } + val mostUsedColor = scaledBitmap?.let { getMostUsedColor(it) } ?: dominantColor + onDominantColor = getContrastingTextColor(mostUsedColor) + } + + if (requireIconTint) { + mMediaPlayer.setMediaAppIconColor( + backgroundColor = dominantColor ?: colorActive ?: colorAccent, + iconColor = onDominantColor ?: colorLabelActive ?: colorPrimary + ) + } else { + mMediaPlayer.resetMediaAppIconColor( + backgroundColor = dominantColor ?: colorActive ?: colorAccent + ) + } + + if (processedArtwork == null || onDominantColor == null) { + mMediaPlayer.setMediaPlayerItemsColor(colorLabelInactive) + } else { + mMediaPlayer.setMediaPlayerItemsColor(onDominantColor) + } + + mMediaPlayer.post { + mMediaPlayer.setMediaPlayerBackground(finalArtworkDrawable) + if (finalArtworkDrawable is TransitionDrawable) { + finalArtworkDrawable.isCrossFadeEnabled = true + finalArtworkDrawable.startTransition(250) + } + } + } + } + } + + private fun getOrCreateMediaPlayer(packageName: String?): OpQsMediaPlayerView? { + if (!mMediaPlayerViews.any { it.first == packageName }) { + val mediaPlayerView = OpQsMediaPlayerView(mContext) + + if (packageName != null) { + mediaPlayerView.setOnClickListeners { v -> + when (v) { + mediaPlayerView.mediaPlayerPrevBtn -> { + performMediaAction(packageName, MediaAction.PLAY_PREVIOUS) + } + + mediaPlayerView.mediaPlayerPlayPauseBtn -> { + performMediaAction(packageName, MediaAction.TOGGLE_PLAYBACK) + } + + mediaPlayerView.mediaPlayerNextBtn -> { + performMediaAction(packageName, MediaAction.PLAY_NEXT) + } + + mediaPlayerView.mediaPlayerBackground -> { + launchMediaPlayer(packageName) + } + + mediaPlayerView.mediaOutputSwitcher -> { + launchMediaOutputSwitcher(packageName, v) + } + } + } + } + + addMediaPlayerView(packageName, mediaPlayerView) + } + + return mMediaPlayerViews.find { it.first == packageName }?.second + } + + private fun addMediaPlayerView(packageName: String?, view: OpQsMediaPlayerView) { + if (packageName == null && mMediaPlayerViews.isNotEmpty()) return + + val position = mMediaPlayerViews.indexOfFirst { it.first == packageName } + if (position != -1) return + + mMediaPlayerViews.removeAll { it.first == null } + mMediaPlayerAdapter?.notifyDataSetChanged() + + mMediaPlayerViews.add(0, packageName to view) + mMediaPlayerAdapter?.notifyDataSetChanged() + + mOpQsHeaderView?.mediaPlayerContainer?.post { + mOpQsHeaderView?.mediaPlayerContainer?.setCurrentItem(0, false) + } + + updateAdapter() + } + + private fun removeMediaPlayerView(packageName: String) { + val position = mMediaPlayerViews.indexOfFirst { it.first == packageName } + if (position == -1) return + + mMediaPlayerViews.removeAt(position) + mMediaPlayerAdapter?.notifyDataSetChanged() + + if (mMediaPlayerViews.isEmpty()) { + mMediaPlayerViews.add(null to OpQsMediaPlayerView(mContext)) + mMediaPlayerAdapter?.notifyDataSetChanged() + } + + updateAdapter() + } + + private fun updateAdapter() { + mMediaPlayerAdapter = MediaPlayerPagerAdapter(mMediaPlayerViews) + mOpQsHeaderView?.mediaPlayerContainer?.adapter = mMediaPlayerAdapter + } + + private fun updateInternetTileColors() { + if (mInternetEnabled) { + mOpQsHeaderView?.setInternetTileColor( + tileColor = colorActive, + labelColor = colorLabelActive + ) + } else { + mOpQsHeaderView?.setInternetTileColor( + tileColor = colorInactive, + labelColor = colorLabelInactive + ) + } + } + + private fun updateBluetoothTileColors() { + if (mBluetoothEnabled) { + mOpQsHeaderView?.setBluetoothTileColor( + tileColor = colorActive, + labelColor = colorLabelActive + ) + } else { + mOpQsHeaderView?.setBluetoothTileColor( + tileColor = colorInactive, + labelColor = colorLabelInactive + ) + } + } + + private suspend fun processArtwork( + bitmap: Bitmap?, + mMediaAlbumArtBg: ImageView + ): Bitmap? { + return withContext(Dispatchers.IO) { + if (bitmap == null) return@withContext null + + val width = mMediaAlbumArtBg.width + val height = mMediaAlbumArtBg.height + + getScaledRoundedBitmap(bitmap, width, height) + } + } + + private fun getScaledRoundedBitmap( + bitmap: Bitmap, + width: Int, + height: Int + ): Bitmap? { + if (width <= 0 || height <= 0) return null + + val widthScale = width.toFloat() / bitmap.width + val heightScale = height.toFloat() / bitmap.height + val scaleFactor = maxOf(widthScale, heightScale) + + val scaledWidth = (bitmap.width * scaleFactor).toInt() + val scaledHeight = (bitmap.height * scaleFactor).toInt() + + val scaledBitmap = Bitmap.createScaledBitmap(bitmap, scaledWidth, scaledHeight, true) + + val xOffset = (scaledWidth - width) / 2 + val yOffset = (scaledHeight - height) / 2 + + val validWidth = + if (xOffset + width > scaledBitmap.width) scaledBitmap.width - xOffset else width + val validHeight = + if (yOffset + height > scaledBitmap.height) scaledBitmap.height - yOffset else height + + val croppedBitmap = Bitmap.createBitmap( + scaledBitmap, + xOffset, + yOffset, + validWidth, + validHeight + ) + + val output = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888) + + val paint = Paint().apply { + isAntiAlias = true + shader = BitmapShader(croppedBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP) + } + + val rect = RectF(0f, 0f, width.toFloat(), height.toFloat()) + + Canvas(output).drawRoundRect(rect, qsTileCornerRadius, qsTileCornerRadius, paint) + + return output + } + + private fun applyColorFilterToBitmap(bitmap: Bitmap, color: Int?): Bitmap { + val colorFilteredBitmap = Bitmap.createBitmap(bitmap.width, bitmap.height, bitmap.config) + + val paint = Paint().apply { + isAntiAlias = true + shader = LinearGradient( + 0f, 0f, bitmap.width.toFloat(), 0f, // Horizontal gradient + intArrayOf( + ColorUtils.blendARGB(color ?: Color.BLACK, Color.TRANSPARENT, 0.4f), + ColorUtils.blendARGB(color ?: Color.BLACK, Color.TRANSPARENT, 0.6f), + ColorUtils.blendARGB(color ?: Color.BLACK, Color.TRANSPARENT, 0.8f), + ColorUtils.blendARGB(color ?: Color.BLACK, Color.TRANSPARENT, 0.6f), + ColorUtils.blendARGB(color ?: Color.BLACK, Color.TRANSPARENT, 0.4f) + ), + floatArrayOf(0f, 0.2f, 0.5f, 0.8f, 1f), // Positions for the colors + Shader.TileMode.CLAMP + ) + } + + Canvas(colorFilteredBitmap).apply { + drawBitmap(bitmap, 0f, 0f, null) + drawRect(0f, 0f, bitmap.width.toFloat(), bitmap.height.toFloat(), paint) + } + + return colorFilteredBitmap + } + + private suspend fun extractDominantColor(bitmap: Bitmap?): Int? = + suspendCancellableCoroutine { cont -> + if (bitmap == null) { + cont.resume(null) + return@suspendCancellableCoroutine + } + + Palette.from(bitmap).generate { palette -> + val pixels = IntArray(bitmap.width * bitmap.height) + bitmap.getPixels(pixels, 0, bitmap.width, 0, 0, bitmap.width, bitmap.height) + val fallbackColor = Score.score(QuantizerCelebi.quantize(pixels, 128)).firstOrNull() + val dominantColor = palette?.getDominantColor(fallbackColor ?: Color.BLACK) + cont.resume(dominantColor) + } + } + + private fun Bitmap.toCircularBitmap(): Bitmap { + val width = this.width + val height = this.height + val diameter = width.coerceAtMost(height) + val output = Bitmap.createBitmap(diameter, diameter, Bitmap.Config.ARGB_8888) + + val paint = Paint() + paint.isAntiAlias = true + + val canvas = Canvas(output) + val rect = Rect(0, 0, diameter, diameter) + val rectF = RectF(rect) + + canvas.drawARGB(0, 0, 0, 0) + canvas.drawOval(rectF, paint) + + paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_IN) + val left = (width - diameter) / 2 + val top = (height - diameter) / 2 + canvas.drawBitmap(this, Rect(left, top, left + diameter, top + diameter), rect, paint) + + return output + } + + private fun Drawable.toCircularDrawable(): Drawable { + val bitmap = this.toBitmap() + val circularBitmap = bitmap.toCircularBitmap() + return BitmapDrawable(mContext.resources, circularBitmap) + } + + @Suppress("SameParameterValue") + private fun scaleBitmap(bitmap: Bitmap, scaleFactor: Float): Bitmap { + val width = (bitmap.width * scaleFactor).toInt() + val height = (bitmap.height * scaleFactor).toInt() + return Bitmap.createScaledBitmap(bitmap, width, height, true) + } + + private data class ColorRGB(val r: Int, val g: Int, val b: Int) { + fun toInt() = (r shl 16) or (g shl 8) or b + } + + private fun colorDistance(c1: ColorRGB, c2: ColorRGB): Double { + return sqrt( + ((c1.r - c2.r).toDouble().pow(2)) + + ((c1.g - c2.g).toDouble().pow(2)) + + ((c1.b - c2.b).toDouble().pow(2)) + ) + } + + private fun getMostUsedColor(bitmap: Bitmap, k: Int = 5, iterations: Int = 10): Int { + val width = bitmap.width + val height = bitmap.height + val colors = mutableListOf() + + for (x in 0 until width) { + for (y in 0 until height) { + val pixel = bitmap.getPixel(x, y) + val color = ColorRGB( + r = (pixel shr 16) and 0xFF, + g = (pixel shr 8) and 0xFF, + b = pixel and 0xFF + ) + colors.add(color) + } + } + + val centroids = List(k) { + ColorRGB( + r = Random.nextInt(256), + g = Random.nextInt(256), + b = Random.nextInt(256) + ) + }.toMutableList() + + repeat(iterations) { + val clusters = Array(k) { mutableListOf() } + + for (color in colors) { + val distances = centroids.map { centroid -> colorDistance(color, centroid) } + val closestCentroidIndex = distances.indexOf(distances.minOrNull()) + clusters[closestCentroidIndex].add(color) + } + + for (i in centroids.indices) { + val clusterColors = clusters[i] + if (clusterColors.isNotEmpty()) { + val r = clusterColors.map { it.r }.average().toInt() + val g = clusterColors.map { it.g }.average().toInt() + val b = clusterColors.map { it.b }.average().toInt() + centroids[i] = ColorRGB(r, g, b) + } + } + } + + val dominantColor = centroids.maxByOrNull { centroid -> + colors.count { color -> + colorDistance(color, centroid) < 50 + } + } ?: ColorRGB(0, 0, 0) + + return dominantColor.toInt() + } + + private fun getContrastingTextColor(color: Int?): Int? { + if (color == null) return null + + val luminance = (0.299 * Color.red(color) + + 0.587 * Color.green(color) + + 0.114 * Color.blue(color)) / 255 + + return if (luminance > 0.5) Color.BLACK else Color.WHITE + } + + private val mOnClickListener = View.OnClickListener { v -> + if (v === mOpQsHeaderView?.internetTile) { + toggleInternetState(v) + vibrate() + } else if (v === mOpQsHeaderView?.bluetoothTile) { + toggleBluetoothState(v) + vibrate() + } + } + + private val mOnLongClickListener = OnLongClickListener { v -> + if (v === mOpQsHeaderView?.internetTile) { + mActivityLauncherUtils.launchApp(Intent(Settings.ACTION_WIFI_SETTINGS), true) + vibrate() + return@OnLongClickListener true + } else if (v === mOpQsHeaderView?.bluetoothTile) { + mActivityLauncherUtils.launchApp(Intent(Settings.ACTION_BLUETOOTH_SETTINGS), true) + vibrate() + return@OnLongClickListener true + } else { + return@OnLongClickListener false + } + } + + private fun launchMediaOutputSwitcher(packageName: String?, v: View) { + if (packageName != null && mMediaOutputDialogFactory != null) { + if (isMethodAvailable( + mMediaOutputDialogFactory, + "create", + String::class.java, + Boolean::class.java, + View::class.java + ) + ) { + callMethod(mMediaOutputDialogFactory, "create", packageName, true, v) + } else if (isMethodAvailable( + mMediaOutputDialogFactory, + "create", + View::class.java, + String::class.java, + Boolean::class.java, + Boolean::class.java + ) + ) { + callMethod(mMediaOutputDialogFactory, "create", v, packageName, true, true) + } else { + log(TAG + "MediaOutputDialogFactory is not available") + } + } + } + + private fun launchMediaPlayer(packageName: String?) { + val appIntent = if (packageName != null) Intent( + mContext.packageManager.getLaunchIntentForPackage(packageName) + ) + else null + + if (appIntent != null) { + appIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + appIntent.setPackage(packageName) + mActivityLauncherUtils.launchApp(appIntent, true) + vibrate() + return + } + } + + private fun areDataEqual( + metadata1: MediaMetadata?, + metadata2: MediaMetadata? + ): Pair { + val bitmap1 = metadata1?.getBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART) + ?: metadata1?.getBitmap(MediaMetadata.METADATA_KEY_ART) + val bitmap2 = metadata2?.getBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART) + ?: metadata2?.getBitmap(MediaMetadata.METADATA_KEY_ART) + + return areBitmapsEqual(bitmap1, bitmap2) to + (metadata1?.getString(MediaMetadata.METADATA_KEY_TITLE) == + metadata2?.getString(MediaMetadata.METADATA_KEY_TITLE) && + metadata1?.getString(MediaMetadata.METADATA_KEY_ARTIST) == + metadata2?.getString(MediaMetadata.METADATA_KEY_ARTIST)) + } + + private fun areBitmapsEqual(bitmap1: Bitmap?, bitmap2: Bitmap?): Boolean { + if (bitmap1 == null && bitmap2 == null) { + return true + } + if (bitmap1 == null || bitmap2 == null) { + return false + } + if (bitmap1.width != bitmap2.width || bitmap1.height != bitmap2.height) { + return false + } + + val buffer1 = ByteBuffer.allocate(bitmap1.byteCount) + val buffer2 = ByteBuffer.allocate(bitmap2.byteCount) + + bitmap1.copyPixelsToBuffer(buffer1) + bitmap2.copyPixelsToBuffer(buffer2) + + return buffer1.array().contentEquals(buffer2.array()) + } + + private fun vibrate() { + if (vibrateOnClick) { + VibrationUtils.triggerVibration(mContext, 2) + } + } + + private fun initResources() { + try { + appContext = mContext.createPackageContext( + BuildConfig.APPLICATION_ID, + Context.CONTEXT_IGNORE_SECURITY + ) + } catch (ignored: PackageManager.NameNotFoundException) { + } + + mContext.apply { + colorAccent = getColorAttr( + this, + resources.getIdentifier( + "colorAccent", + "attr", + FRAMEWORK_PACKAGE + ) + ).defaultColor + colorPrimary = getColorAttr( + this, + resources.getIdentifier( + "colorPrimary", + "attr", + FRAMEWORK_PACKAGE + ) + ).defaultColor + + qsTileCornerRadius = resources.getDimensionPixelSize( + resources.getIdentifier( + "qs_corner_radius", + "dimen", + SYSTEMUI_PACKAGE + ) + ).toFloat() + qqsTileHeight = resources.getDimensionPixelSize( + resources.getIdentifier( + "qs_quick_tile_size", + "dimen", + SYSTEMUI_PACKAGE + ) + ) + qsTileMarginVertical = resources.getDimensionPixelSize( + resources.getIdentifier( + "qs_tile_margin_vertical", + "dimen", + SYSTEMUI_PACKAGE + ) + ) + } + + qsTileViewImplInstance?.let { thisObject -> + val qsTileOverlayEnabled = isQsTileOverlayEnabled + + colorActive = if (qsTileOverlayEnabled) Color.WHITE + else getObjectField( + thisObject, + "colorActive" + ) as Int + colorInactive = if (qsTileOverlayEnabled) Color.TRANSPARENT + else getObjectField( + thisObject, + "colorInactive" + ) as Int + colorLabelActive = if (qsTextAlwaysWhite) Color.WHITE + else if (qsTextFollowAccent) colorAccent + else getObjectField( + thisObject, + "colorLabelActive" + ) as Int + colorLabelInactive = getObjectField( + thisObject, + "colorLabelInactive" + ) as Int + } + + opMediaBackgroundDrawable = if (colorInactive != null && colorInactive != 0) { + GradientDrawable().apply { + setColor(colorInactive!!) + shape = GradientDrawable.RECTANGLE + cornerRadius = qsTileCornerRadius + } + } else { + ContextCompat.getDrawable( + mContext, + mContext.resources.getIdentifier( + "qs_tile_background_shape", + "drawable", + SYSTEMUI_PACKAGE + ) + )!! + } + + mContext.apply { + mWifiManager = getSystemService(WifiManager::class.java) + mTelephonyManager = getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager + mBluetoothManager = getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager + mMediaSessionManager = mContext.getSystemService(MediaSessionManager::class.java) + mConnectivityManager = + getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager + mSubscriptionManager = + getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE) as SubscriptionManager + } + + mInternetEnabled = isWiFiConnected || isMobileDataConnected + mBluetoothEnabled = isBluetoothEnabled + } + + private val isLandscape: Boolean + get() = mContext.resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE + + companion object { + private val TAG = "Iconify - ${OpQsHeader::class.java.simpleName}: " + + var launchableImageView: Class<*>? = null + var launchableLinearLayout: Class<*>? = null + } +} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/xposed/modules/QSTransparency.kt b/app/src/main/java/com/drdisagree/iconify/xposed/modules/QSTransparency.kt index 80b74f580..75fbc336f 100644 --- a/app/src/main/java/com/drdisagree/iconify/xposed/modules/QSTransparency.kt +++ b/app/src/main/java/com/drdisagree/iconify/xposed/modules/QSTransparency.kt @@ -12,8 +12,9 @@ import com.drdisagree.iconify.common.Preferences.NOTIF_TRANSPARENCY_SWITCH import com.drdisagree.iconify.common.Preferences.QSALPHA_LEVEL import com.drdisagree.iconify.common.Preferences.QSPANEL_BLUR_SWITCH import com.drdisagree.iconify.common.Preferences.QS_TRANSPARENCY_SWITCH -import com.drdisagree.iconify.config.XPrefs.Xprefs import com.drdisagree.iconify.xposed.ModPack +import com.drdisagree.iconify.xposed.utils.XPrefs.Xprefs +import com.drdisagree.iconify.xposed.utils.XPrefs.XprefsIsInitialized import de.robv.android.xposed.XC_MethodHook import de.robv.android.xposed.XposedBridge.hookAllMethods import de.robv.android.xposed.XposedBridge.log @@ -34,14 +35,16 @@ class QSTransparency(context: Context?) : ModPack(context!!) { private var blurRadius = 23 override fun updatePrefs(vararg key: String) { - if (Xprefs == null) return - - qsTransparencyActive = Xprefs!!.getBoolean(QS_TRANSPARENCY_SWITCH, false) - onlyNotifTransparencyActive = Xprefs!!.getBoolean(NOTIF_TRANSPARENCY_SWITCH, false) - keepLockScreenShade = Xprefs!!.getBoolean(LOCKSCREEN_SHADE_SWITCH, false) - alpha = (Xprefs!!.getInt(QSALPHA_LEVEL, 60).toFloat() / 100.0).toFloat() - blurEnabled = Xprefs!!.getBoolean(QSPANEL_BLUR_SWITCH, false) - blurRadius = Xprefs!!.getInt(BLUR_RADIUS_VALUE, 23) + if (!XprefsIsInitialized) return + + Xprefs.apply { + qsTransparencyActive = getBoolean(QS_TRANSPARENCY_SWITCH, false) + onlyNotifTransparencyActive = getBoolean(NOTIF_TRANSPARENCY_SWITCH, false) + keepLockScreenShade = getBoolean(LOCKSCREEN_SHADE_SWITCH, false) + alpha = (getSliderInt(QSALPHA_LEVEL, 60).toFloat() / 100.0).toFloat() + blurEnabled = getBoolean(QSPANEL_BLUR_SWITCH, false) + blurRadius = getSliderInt(BLUR_RADIUS_VALUE, 23) + } } override fun handleLoadPackage(loadPackageParam: LoadPackageParam) { diff --git a/app/src/main/java/com/drdisagree/iconify/xposed/modules/QuickSettings.kt b/app/src/main/java/com/drdisagree/iconify/xposed/modules/QuickSettings.kt index 2c29900fe..a6f7bbad4 100644 --- a/app/src/main/java/com/drdisagree/iconify/xposed/modules/QuickSettings.kt +++ b/app/src/main/java/com/drdisagree/iconify/xposed/modules/QuickSettings.kt @@ -3,10 +3,15 @@ package com.drdisagree.iconify.xposed.modules import android.annotation.SuppressLint import android.content.Context import android.content.res.ColorStateList +import android.content.res.Configuration import android.content.res.Resources import android.graphics.Color import android.graphics.PorterDuff +import android.graphics.drawable.Drawable +import android.graphics.drawable.LayerDrawable import android.os.Build +import android.os.Handler +import android.os.Looper import android.service.quicksettings.Tile import android.view.Gravity import android.view.View @@ -19,22 +24,30 @@ import android.widget.LinearLayout import android.widget.TextView import androidx.annotation.ColorInt import com.drdisagree.iconify.common.Const.SYSTEMUI_PACKAGE +import com.drdisagree.iconify.common.Preferences.CUSTOM_QS_MARGIN import com.drdisagree.iconify.common.Preferences.FIX_NOTIFICATION_COLOR +import com.drdisagree.iconify.common.Preferences.FIX_NOTIFICATION_FOOTER_BUTTON_COLOR import com.drdisagree.iconify.common.Preferences.FIX_QS_TILE_COLOR +import com.drdisagree.iconify.common.Preferences.HEADER_CLOCK_SWITCH import com.drdisagree.iconify.common.Preferences.HIDE_QSLABEL_SWITCH import com.drdisagree.iconify.common.Preferences.HIDE_QS_FOOTER_BUTTONS +import com.drdisagree.iconify.common.Preferences.HIDE_QS_ON_LOCKSCREEN import com.drdisagree.iconify.common.Preferences.HIDE_QS_SILENT_TEXT import com.drdisagree.iconify.common.Preferences.QQS_TOPMARGIN import com.drdisagree.iconify.common.Preferences.QS_TEXT_ALWAYS_WHITE import com.drdisagree.iconify.common.Preferences.QS_TEXT_FOLLOW_ACCENT import com.drdisagree.iconify.common.Preferences.QS_TOPMARGIN import com.drdisagree.iconify.common.Preferences.VERTICAL_QSTILE_SWITCH -import com.drdisagree.iconify.config.XPrefs.Xprefs import com.drdisagree.iconify.xposed.ModPack +import com.drdisagree.iconify.xposed.modules.utils.Helpers.findClassInArray +import com.drdisagree.iconify.xposed.modules.utils.Helpers.hookAllMethodsMatchPattern import com.drdisagree.iconify.xposed.modules.utils.Helpers.isPixelVariant import com.drdisagree.iconify.xposed.modules.utils.ViewHelper.toPx +import com.drdisagree.iconify.xposed.utils.XPrefs.Xprefs +import com.drdisagree.iconify.xposed.utils.XPrefs.XprefsIsInitialized import de.robv.android.xposed.XC_MethodHook import de.robv.android.xposed.XC_MethodHook.MethodHookParam +import de.robv.android.xposed.XC_MethodReplacement import de.robv.android.xposed.XposedBridge.hookAllConstructors import de.robv.android.xposed.XposedBridge.hookAllMethods import de.robv.android.xposed.XposedBridge.log @@ -51,10 +64,12 @@ class QuickSettings(context: Context?) : ModPack(context!!) { private var fixQsTileColor = true private var fixNotificationColor = true + private var fixNotificationFooterButtonsColor = true private var qsTextAlwaysWhite = false private var qsTextFollowAccent = false - private var hideFooterButtons = false + private var hideQsOnLockscreen = false private var hideSilentText = false + private var hideFooterButtons = false private var qqsTopMargin = 100 private var qsTopMargin = 100 private var mParam: Any? = null @@ -62,24 +77,37 @@ class QuickSettings(context: Context?) : ModPack(context!!) { private var mFooterButtonsOnDrawListener: OnDrawListener? = null private var mSilentTextContainer: ViewGroup? = null private var mSilentTextOnDrawListener: OnDrawListener? = null + private var mKeyguardStateController: Any? = null + private val isAtLeastAndroid14 = Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE + private var isVerticalQSTileActive = false + private var isHideLabelActive = false + private var customQsMarginsEnabled = false + private var qsTilePrimaryTextSize: Float? = null + private var qsTileSecondaryTextSize: Float? = null + private var showHeaderClock = false override fun updatePrefs(vararg key: String) { - if (Xprefs == null) return - - isVerticalQSTileActive = Xprefs!!.getBoolean(VERTICAL_QSTILE_SWITCH, false) - isHideLabelActive = Xprefs!!.getBoolean(HIDE_QSLABEL_SWITCH, false) - qqsTopMarginEnabled = Xprefs!!.getInt(QQS_TOPMARGIN, -1) != -1 - qsTopMarginEnabled = Xprefs!!.getInt(QS_TOPMARGIN, -1) != -1 - qqsTopMargin = Xprefs!!.getInt(QQS_TOPMARGIN, 100) - qsTopMargin = Xprefs!!.getInt(QS_TOPMARGIN, 100) - fixQsTileColor = Build.VERSION.SDK_INT >= 34 && - Xprefs!!.getBoolean(FIX_QS_TILE_COLOR, false) - fixNotificationColor = Build.VERSION.SDK_INT >= 34 && - Xprefs!!.getBoolean(FIX_NOTIFICATION_COLOR, false) - qsTextAlwaysWhite = Xprefs!!.getBoolean(QS_TEXT_ALWAYS_WHITE, false) - qsTextFollowAccent = Xprefs!!.getBoolean(QS_TEXT_FOLLOW_ACCENT, false) - hideSilentText = Xprefs!!.getBoolean(HIDE_QS_SILENT_TEXT, false) - hideFooterButtons = Xprefs!!.getBoolean(HIDE_QS_FOOTER_BUTTONS, false) + if (!XprefsIsInitialized) return + + Xprefs.apply { + isVerticalQSTileActive = getBoolean(VERTICAL_QSTILE_SWITCH, false) + isHideLabelActive = getBoolean(HIDE_QSLABEL_SWITCH, false) + customQsMarginsEnabled = getBoolean(CUSTOM_QS_MARGIN, false) + qqsTopMargin = getSliderInt(QQS_TOPMARGIN, 100) + qsTopMargin = getSliderInt(QS_TOPMARGIN, 100) + fixQsTileColor = isAtLeastAndroid14 && + getBoolean(FIX_QS_TILE_COLOR, false) + fixNotificationColor = isAtLeastAndroid14 && + getBoolean(FIX_NOTIFICATION_COLOR, false) + fixNotificationFooterButtonsColor = isAtLeastAndroid14 && + getBoolean(FIX_NOTIFICATION_FOOTER_BUTTON_COLOR, false) + qsTextAlwaysWhite = getBoolean(QS_TEXT_ALWAYS_WHITE, false) + qsTextFollowAccent = getBoolean(QS_TEXT_FOLLOW_ACCENT, false) + hideQsOnLockscreen = getBoolean(HIDE_QS_ON_LOCKSCREEN, false) + hideSilentText = getBoolean(HIDE_QS_SILENT_TEXT, false) + hideFooterButtons = getBoolean(HIDE_QS_FOOTER_BUTTONS, false) + showHeaderClock = getBoolean(HEADER_CLOCK_SWITCH, false) + } triggerQsElementVisibility() } @@ -90,6 +118,7 @@ class QuickSettings(context: Context?) : ModPack(context!!) { fixQsTileAndLabelColorA14(loadPackageParam) fixNotificationColorA14(loadPackageParam) manageQsElementVisibility(loadPackageParam) + disableQsOnSecureLockScreen(loadPackageParam) } private fun setVerticalTiles(loadPackageParam: LoadPackageParam) { @@ -109,55 +138,53 @@ class QuickSettings(context: Context?) : ModPack(context!!) { mParam = param.thisObject try { - (param.thisObject as LinearLayout).gravity = Gravity.CENTER - (param.thisObject as LinearLayout).orientation = LinearLayout.VERTICAL + (mParam as LinearLayout).gravity = Gravity.CENTER + (mParam as LinearLayout).orientation = LinearLayout.VERTICAL (getObjectField( - param.thisObject, + mParam, "label" - ) as TextView).setGravity(Gravity.CENTER_HORIZONTAL) + ) as TextView).gravity = Gravity.CENTER_HORIZONTAL (getObjectField( - param.thisObject, + mParam, "secondaryLabel" - ) as TextView).setGravity(Gravity.CENTER_HORIZONTAL) + ) as TextView).gravity = Gravity.CENTER_HORIZONTAL (getObjectField( - param.thisObject, + mParam, "labelContainer" - ) as LinearLayout).setLayoutParams( - MarginLayoutParams( - MarginLayoutParams.MATCH_PARENT, MarginLayoutParams.WRAP_CONTENT - ) + ) as LinearLayout).layoutParams = MarginLayoutParams( + MarginLayoutParams.MATCH_PARENT, MarginLayoutParams.WRAP_CONTENT ) (getObjectField( - param.thisObject, + mParam, "sideView" ) as View).visibility = View.GONE - (param.thisObject as LinearLayout).removeView( + (mParam as LinearLayout).removeView( getObjectField( - param.thisObject, + mParam, "labelContainer" ) as LinearLayout ) if (!isHideLabelActive) { (getObjectField( - param.thisObject, + mParam, "labelContainer" ) as LinearLayout).gravity = Gravity.CENTER_HORIZONTAL - (param.thisObject as LinearLayout).addView( + (mParam as LinearLayout).addView( getObjectField( - param.thisObject, + mParam, "labelContainer" ) as LinearLayout ) } - fixTileLayout(param.thisObject as LinearLayout, mParam) + fixTileLayout(mParam as LinearLayout, mParam) if (qsTilePrimaryTextSize == null || qsTileSecondaryTextSize == null) { try { @@ -169,7 +196,7 @@ class QuickSettings(context: Context?) : ModPack(context!!) { "dimen", mContext.packageName ), - getObjectField(param.thisObject, "label") + getObjectField(mParam, "label") ) callStaticMethod( @@ -180,25 +207,20 @@ class QuickSettings(context: Context?) : ModPack(context!!) { "dimen", mContext.packageName ), - getObjectField(param.thisObject, "secondaryLabel") + getObjectField(mParam, "secondaryLabel") ) } catch (ignored: Throwable) { } - val primaryText = getObjectField( - param.thisObject, + qsTilePrimaryTextSize = (getObjectField( + mParam, "label" - ) as TextView - val secondaryText = getObjectField( - param.thisObject, - "secondaryLabel" - ) as TextView - - qsTilePrimaryTextSize = primaryText.textSize - qsTilePrimaryTextSizeUnit = primaryText.textSizeUnit + ) as TextView).textSize - qsTileSecondaryTextSize = secondaryText.textSize - qsTileSecondaryTextSizeUnit = secondaryText.textSizeUnit + qsTileSecondaryTextSize = (getObjectField( + mParam, + "secondaryLabel" + ) as TextView).textSize } } catch (throwable: Throwable) { log(TAG + throwable) @@ -213,65 +235,60 @@ class QuickSettings(context: Context?) : ModPack(context!!) { fixTileLayout(param.thisObject as LinearLayout, mParam) } }) - - hookAllMethods(qsTileViewImplClass, "onLayout", object : XC_MethodHook() { - override fun beforeHookedMethod(param: MethodHookParam) { - if (!isVerticalQSTileActive) return - - setLabelSizes(param.thisObject) - } - }) } private fun setQsMargin(loadPackageParam: LoadPackageParam) { hookAllMethods(Resources::class.java, "getDimensionPixelSize", object : XC_MethodHook() { override fun beforeHookedMethod(param: MethodHookParam) { - if (qqsTopMarginEnabled) { - val qqsHeaderResNames = arrayOf( - "qs_header_system_icons_area_height", - "qqs_layout_margin_top", - "qs_header_row_min_height", - "large_screen_shade_header_min_height" - ) + if (!customQsMarginsEnabled) return - for (resName in qqsHeaderResNames) { - try { - val resId = mContext.resources.getIdentifier( - resName, - "dimen", - mContext.packageName - ) + val qqsHeaderResNames = arrayOf( + "qs_header_system_icons_area_height", + "qqs_layout_margin_top", + "qs_header_row_min_height", + "large_screen_shade_header_min_height" + ) - if (param.args[0] == resId) { - param.result = - (qqsTopMargin * mContext.resources.displayMetrics.density).toInt() - } - } catch (ignored: Throwable) { + qqsHeaderResNames.forEach { resName -> + try { + val resId = mContext.resources.getIdentifier( + resName, + "dimen", + mContext.packageName + ) + + if (param.args[0] == resId) { + param.result = mContext.toPx(qqsTopMargin) } + } catch (ignored: Throwable) { } } - if (qsTopMarginEnabled) { - val qsHeaderResNames = arrayOf( - "qs_panel_padding_top", - "qs_panel_padding_top_combined_headers", - "qs_header_height" - ) + val qsHeaderResNames = arrayOf( + "qs_panel_padding_top", + "qs_panel_padding_top_combined_headers", + "qs_header_height" + ) - for (resName in qsHeaderResNames) { - try { - val resId = mContext.resources.getIdentifier( - resName, - "dimen", - mContext.packageName - ) + qsHeaderResNames.forEach { resName -> + try { + val resId = mContext.resources.getIdentifier( + resName, + "dimen", + mContext.packageName + ) - if (param.args[0] == resId) { - param.result = - (qsTopMargin * mContext.resources.displayMetrics.density).toInt() + if (param.args[0] == resId) { + if (showHeaderClock && Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { + val isLandscape = + mContext.resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE + + param.result = if (isLandscape) 0 else mContext.toPx(qsTopMargin) + } else { + param.result = mContext.toPx(qsTopMargin) } - } catch (ignored: Throwable) { } + } catch (ignored: Throwable) { } } } @@ -284,9 +301,9 @@ class QuickSettings(context: Context?) : ModPack(context!!) { hookAllMethods(quickStatusBarHeader, "updateResources", object : XC_MethodHook() { override fun afterHookedMethod(param: MethodHookParam) { - if (!qqsTopMarginEnabled) return + if (!customQsMarginsEnabled) return - if (Build.VERSION.SDK_INT >= 33) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { try { val res = mContext.resources @@ -322,6 +339,8 @@ class QuickSettings(context: Context?) : ModPack(context!!) { } private fun fixQsTileAndLabelColorA14(loadPackageParam: LoadPackageParam) { + if (!isAtLeastAndroid14) return + try { val qsTileViewImplClass = findClass( "$SYSTEMUI_PACKAGE.qs.tileimpl.QSTileViewImpl", @@ -330,28 +349,58 @@ class QuickSettings(context: Context?) : ModPack(context!!) { val removeQsTileTint: XC_MethodHook = object : XC_MethodHook() { override fun afterHookedMethod(param: MethodHookParam) { - if (fixQsTileColor && Build.VERSION.SDK_INT >= 34) { - try { - setObjectField( - param.thisObject, - "colorActive", - Color.WHITE - ) - setObjectField( + if (!fixQsTileColor) return + + try { + setObjectField( + param.thisObject, + "colorActive", + Color.WHITE + ) + setObjectField( + param.thisObject, + "colorInactive", + Color.TRANSPARENT + ) + setObjectField( + param.thisObject, + "colorUnavailable", + Color.TRANSPARENT + ) + } catch (throwable: Throwable) { + log(TAG + throwable) + } + } + } + + if (fixQsTileColor && qsTileViewImplClass.declaredMethods.find { it.name == "setStateLayer" } != null) { + hookAllMethods( + qsTileViewImplClass, + "setStateLayer", + object : XC_MethodReplacement() { + override fun replaceHookedMethod(param: MethodHookParam): Any? { + val currentState = getObjectField( param.thisObject, - "colorInactive", - Color.TRANSPARENT - ) - setObjectField( + "currentState" + ) as Int + + val ld: LayerDrawable = (getObjectField( param.thisObject, - "colorUnavailable", - Color.TRANSPARENT - ) - } catch (throwable: Throwable) { - log(TAG + throwable) + "backgroundDrawable" + ) as LayerDrawable).mutate() as LayerDrawable + + when (currentState) { + Tile.STATE_ACTIVE -> ld.setTint(Color.WHITE) + + Tile.STATE_INACTIVE -> ld.setTint(Color.TRANSPARENT) + + else -> ld.setTint(Color.TRANSPARENT) + } + + return null } } - } + ) } hookAllConstructors(qsTileViewImplClass, removeQsTileTint) @@ -422,7 +471,7 @@ class QuickSettings(context: Context?) : ModPack(context!!) { override fun afterHookedMethod(param: MethodHookParam) { if (isQsIconLabelStateActive(param, 1)) { val mIcon = param.args[0] as ImageView - mIcon.setImageTintList(ColorStateList.valueOf(qsIconLabelColor)) + mIcon.imageTintList = ColorStateList.valueOf(qsIconLabelColor) } } }) @@ -474,7 +523,7 @@ class QuickSettings(context: Context?) : ModPack(context!!) { mContext.packageName ) ) - pmButton.setImageTintList(ColorStateList.valueOf(color)) + pmButton.imageTintList = ColorStateList.valueOf(color) } } catch (ignored: Throwable) { } @@ -523,8 +572,8 @@ class QuickSettings(context: Context?) : ModPack(context!!) { @ColorInt val color: Int = qsIconLabelColor try { - (getObjectField(param.thisObject, "mIcon") as ImageView) - .setImageTintList(ColorStateList.valueOf(color)) + (getObjectField(param.thisObject, "mIcon") as ImageView).imageTintList = + ColorStateList.valueOf(color) } catch (throwable: Throwable) { log(TAG + throwable) } @@ -539,12 +588,15 @@ class QuickSettings(context: Context?) : ModPack(context!!) { @ColorInt val color: Int = qsIconLabelColor try { - (getObjectField(param.thisObject, "mIcon") as ImageView) - .setImageTintList(ColorStateList.valueOf(color)) + (getObjectField(param.thisObject, "mIcon") as ImageView).imageTintList = + ColorStateList.valueOf(color) } catch (throwable: Throwable) { try { - (getObjectField(param.thisObject, "mIconView") as ImageView) - .setImageTintList(ColorStateList.valueOf(color)) + (getObjectField( + param.thisObject, + "mIconView" + ) as ImageView).imageTintList = + ColorStateList.valueOf(color) } catch (ignored: Throwable) { } } @@ -559,8 +611,8 @@ class QuickSettings(context: Context?) : ModPack(context!!) { @ColorInt val color: Int = qsIconLabelColor try { - (getObjectField(param.thisObject, "mIcon") as ImageView) - .setImageTintList(ColorStateList.valueOf(color)) + (getObjectField(param.thisObject, "mIcon") as ImageView).imageTintList = + ColorStateList.valueOf(color) } catch (throwable: Throwable) { log(TAG + throwable) } @@ -569,7 +621,7 @@ class QuickSettings(context: Context?) : ModPack(context!!) { } private fun fixNotificationColorA14(loadPackageParam: LoadPackageParam) { - if (Build.VERSION.SDK_INT < 34) return + if (!isAtLeastAndroid14) return try { val activatableNotificationViewClass = findClass( @@ -592,11 +644,13 @@ class QuickSettings(context: Context?) : ModPack(context!!) { } val removeNotificationTint: XC_MethodHook = object : XC_MethodHook() { - override fun afterHookedMethod(param: MethodHookParam) { + override fun beforeHookedMethod(param: MethodHookParam) { if (!fixNotificationColor) return - val notificationBackgroundView = - getObjectField(param.thisObject, "mBackgroundNormal") as View + val notificationBackgroundView = getObjectField( + param.thisObject, + "mBackgroundNormal" + ) as View try { setObjectField( @@ -608,23 +662,40 @@ class QuickSettings(context: Context?) : ModPack(context!!) { } try { - callMethod( - getObjectField( - notificationBackgroundView, - "mBackground" - ), "clearColorFilter" - ) + setObjectField(notificationBackgroundView, "mTintColor", 0) } catch (ignored: Throwable) { } + } + + override fun afterHookedMethod(param: MethodHookParam) { + if (!fixNotificationColor) return + + val notificationBackgroundView = getObjectField( + param.thisObject, + "mBackgroundNormal" + ) as View try { callMethod(notificationBackgroundView, "setColorFilter", 0) } catch (ignored: Throwable) { } - setObjectField(notificationBackgroundView, "mTintColor", 0) + try { + (getObjectField( + notificationBackgroundView, + "mBackground" + ) as Drawable).colorFilter = null + } catch (ignored: Throwable) { + } + + try { + setObjectField(notificationBackgroundView, "mTintColor", 0) + } catch (ignored: Throwable) { + } - notificationBackgroundView.invalidate() + Handler(Looper.getMainLooper()).post { + notificationBackgroundView.invalidate() + } } } @@ -639,64 +710,64 @@ class QuickSettings(context: Context?) : ModPack(context!!) { removeNotificationTint ) - val replaceTintColor: XC_MethodHook = object : XC_MethodHook() { - override fun beforeHookedMethod(param: MethodHookParam) { - if (!fixNotificationColor) return + hookAllMethods(activatableNotificationViewClass, + "calculateBgColor", + object : XC_MethodHook() { + override fun beforeHookedMethod(param: MethodHookParam) { + if (!fixNotificationColor) return - setObjectField(param.thisObject, "mTintColor", 0) + try { + param.result = getObjectField( + param.thisObject, + "mCurrentBackgroundTint" + ) + } catch (ignored: Throwable) { + } + } } - } + ) - try { - hookAllMethods( - notificationBackgroundViewClass, - "setCustomBackground$1", - replaceTintColor - ) - } catch (ignored: Throwable) { - } + hookAllMethodsMatchPattern(notificationBackgroundViewClass, + "setCustomBackground.*", + object : XC_MethodHook() { + override fun beforeHookedMethod(param: MethodHookParam) { + if (!fixNotificationColor) return - try { - hookAllMethods( - notificationBackgroundViewClass, - "setCustomBackground", - replaceTintColor - ) - } catch (ignored: Throwable) { - } + setObjectField(param.thisObject, "mTintColor", 0) + } + } + ) - val removeButtonTint: XC_MethodHook = object : XC_MethodHook() { - override fun afterHookedMethod(param: MethodHookParam) { - if (!fixNotificationColor) return + hookAllMethodsMatchPattern(footerViewClass, + "updateColors.*", + object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + if (!fixNotificationFooterButtonsColor) return - try { - val mManageButton = - getObjectField(param.thisObject, "mManageButton") as Button - val mClearAllButton = try { - getObjectField(param.thisObject, "mClearAllButton") + try { + val mManageButton = try { + getObjectField(param.thisObject, "mManageButton") + } catch (ignored: Throwable) { + getObjectField(param.thisObject, "mManageOrHistoryButton") + } as Button + val mClearAllButton = try { + getObjectField(param.thisObject, "mClearAllButton") + } catch (ignored: Throwable) { + getObjectField(param.thisObject, "mDismissButton") + } as Button + + mManageButton.background?.colorFilter = null + mClearAllButton.background?.colorFilter = null + + Handler(Looper.getMainLooper()).post { + mManageButton.invalidate() + mClearAllButton.invalidate() + } } catch (ignored: Throwable) { - getObjectField(param.thisObject, "mDismissButton") - } as Button - - mManageButton.background?.clearColorFilter() - mClearAllButton.background?.clearColorFilter() - - mManageButton.invalidate() - mClearAllButton.invalidate() - } catch (ignored: Throwable) { + } } } - } - - try { - hookAllMethods(footerViewClass, "updateColors", removeButtonTint) - } catch (ignored: Throwable) { - } - - try { - hookAllMethods(footerViewClass, "updateColors$3", removeButtonTint) - } catch (ignored: Throwable) { - } + ) } catch (throwable: Throwable) { log(TAG + throwable) } @@ -704,16 +775,11 @@ class QuickSettings(context: Context?) : ModPack(context!!) { private fun manageQsElementVisibility(loadPackageParam: LoadPackageParam) { try { - var footerViewClass = findClassIfExists( + val footerViewClass = findClassInArray( + loadPackageParam.classLoader, "$SYSTEMUI_PACKAGE.statusbar.notification.footer.ui.view.FooterView", - loadPackageParam.classLoader + "$SYSTEMUI_PACKAGE.statusbar.notification.row.FooterView" ) - if (footerViewClass == null) { - footerViewClass = findClass( - "$SYSTEMUI_PACKAGE.statusbar.notification.row.FooterView", - loadPackageParam.classLoader - ) - } hookAllMethods(footerViewClass, "onFinishInflate", object : XC_MethodHook() { override fun afterHookedMethod(param: MethodHookParam) { @@ -764,6 +830,56 @@ class QuickSettings(context: Context?) : ModPack(context!!) { } } + private fun disableQsOnSecureLockScreen(loadPackageParam: LoadPackageParam) { + val remoteInputQuickSettingsDisablerClass = findClass( + "$SYSTEMUI_PACKAGE.statusbar.policy.RemoteInputQuickSettingsDisabler", + loadPackageParam.classLoader + ) + val phoneStatusBarPolicyClass = findClass( + "$SYSTEMUI_PACKAGE.statusbar.phone.PhoneStatusBarPolicy", + loadPackageParam.classLoader + ) + + hookAllConstructors(phoneStatusBarPolicyClass, object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + mKeyguardStateController = getObjectField( + param.thisObject, + "mKeyguardStateController" + ) + + if (mKeyguardStateController == null) { + log(TAG + "mKeyguardStateController is null") + } + } + }) + + hookAllMethods(remoteInputQuickSettingsDisablerClass, + "adjustDisableFlags", + object : XC_MethodHook() { + override fun beforeHookedMethod(param: MethodHookParam) { + if (!hideQsOnLockscreen || mKeyguardStateController == null) return + + val isUnlocked = !(getObjectField( + mKeyguardStateController, + "mShowing" + ) as Boolean) || getObjectField( + mKeyguardStateController, + "mCanDismissLockScreen" + ) as Boolean + + /* + * Location: frameworks/base/core/java/android/app/StatusBarManager.java + * public static final int DISABLE2_QUICK_SETTINGS = 1; + */ + param.result = if (hideQsOnLockscreen && !isUnlocked) { + param.args[0] as Int or 1 // DISABLE2_QUICK_SETTINGS + } else { + param.args[0] + } + } + }) + } + private fun isQsIconLabelStateActive(param: MethodHookParam?, stateIndex: Int): Boolean { if (param?.args == null) return false @@ -825,10 +941,10 @@ class QuickSettings(context: Context?) : ModPack(context!!) { try { if (hideFooterButtons) { mFooterButtonsContainer!!.visibility = View.INVISIBLE - mFooterButtonsContainer!!.getViewTreeObserver() + mFooterButtonsContainer!!.viewTreeObserver .addOnDrawListener(mFooterButtonsOnDrawListener) } else { - mFooterButtonsContainer!!.getViewTreeObserver() + mFooterButtonsContainer!!.viewTreeObserver .removeOnDrawListener(mFooterButtonsOnDrawListener) mFooterButtonsContainer!!.visibility = View.VISIBLE } @@ -845,10 +961,10 @@ class QuickSettings(context: Context?) : ModPack(context!!) { try { if (hideSilentText) { mSilentTextContainer!!.visibility = View.GONE - mSilentTextContainer!!.getViewTreeObserver() + mSilentTextContainer!!.viewTreeObserver .addOnDrawListener(mSilentTextOnDrawListener) } else { - mSilentTextContainer!!.getViewTreeObserver() + mSilentTextContainer!!.viewTreeObserver .removeOnDrawListener(mSilentTextOnDrawListener) mSilentTextContainer!!.visibility = View.VISIBLE } @@ -876,7 +992,7 @@ class QuickSettings(context: Context?) : ModPack(context!!) { ((getObjectField( tile, "labelContainer" - ) as LinearLayout).layoutParams as MarginLayoutParams).setMarginStart(0) + ) as LinearLayout).layoutParams as MarginLayoutParams).marginStart = 0 ((getObjectField( tile, @@ -888,50 +1004,14 @@ class QuickSettings(context: Context?) : ModPack(context!!) { } if (param != null) { - (getObjectField(param, "label") as TextView) - .setGravity(Gravity.CENTER_HORIZONTAL) + (getObjectField(param, "label") as TextView).gravity = Gravity.CENTER_HORIZONTAL - (getObjectField(param, "secondaryLabel") as TextView) - .setGravity(Gravity.CENTER_HORIZONTAL) - } - } - - private fun setLabelSizes(paramThisObject: Any) { - try { - val textSize = mContext.resources.getDimensionPixelSize( - mContext.resources.getIdentifier( - "qs_tile_text_size", - "dimen", - mContext.packageName - ) - ) - - if (qsTilePrimaryTextSize != null && qsTilePrimaryTextSizeUnit != -1) { - (getObjectField(paramThisObject, "label") as TextView).setTextSize( - qsTilePrimaryTextSizeUnit, - textSize.toFloat() - ) - } - - if (qsTileSecondaryTextSize != null && qsTileSecondaryTextSizeUnit != -1) { - (getObjectField(paramThisObject, "secondaryLabel") as TextView).setTextSize( - qsTileSecondaryTextSizeUnit, - (textSize * 0.92).toFloat() - ) - } - } catch (ignored: Throwable) { + (getObjectField(param, "secondaryLabel") as TextView).gravity = + Gravity.CENTER_HORIZONTAL } } companion object { private val TAG = "Iconify - ${QuickSettings::class.java.simpleName}: " - private var isVerticalQSTileActive = false - private var isHideLabelActive = false - private var qsTilePrimaryTextSize: Float? = null - private var qsTilePrimaryTextSizeUnit: Int = -1 - private var qsTileSecondaryTextSize: Float? = null - private var qsTileSecondaryTextSizeUnit: Int = -1 - private var qqsTopMarginEnabled = false - private var qsTopMarginEnabled = false } } \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/xposed/modules/Statusbar.kt b/app/src/main/java/com/drdisagree/iconify/xposed/modules/Statusbar.kt new file mode 100644 index 000000000..ab8f4ece2 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/xposed/modules/Statusbar.kt @@ -0,0 +1,529 @@ +package com.drdisagree.iconify.xposed.modules + +import android.annotation.SuppressLint +import android.app.ActivityManager +import android.content.Context +import android.graphics.Color +import android.graphics.drawable.Drawable +import android.os.Build +import android.os.Bundle +import android.text.Editable +import android.text.TextWatcher +import android.util.TypedValue +import android.view.Gravity +import android.view.View +import android.widget.LinearLayout +import android.widget.TextView +import com.drdisagree.iconify.common.Const.FRAMEWORK_PACKAGE +import com.drdisagree.iconify.common.Const.SYSTEMUI_PACKAGE +import com.drdisagree.iconify.common.Preferences.COLORED_STATUSBAR_ICON +import com.drdisagree.iconify.common.Preferences.HIDE_LOCKSCREEN_CARRIER +import com.drdisagree.iconify.common.Preferences.HIDE_LOCKSCREEN_STATUSBAR +import com.drdisagree.iconify.common.Preferences.SB_CLOCK_SIZE +import com.drdisagree.iconify.common.Preferences.SB_CLOCK_SIZE_SWITCH +import com.drdisagree.iconify.xposed.HookRes.Companion.resParams +import com.drdisagree.iconify.xposed.ModPack +import com.drdisagree.iconify.xposed.modules.utils.Helpers.findClassInArray +import com.drdisagree.iconify.xposed.modules.utils.StatusBarClock.getCenterClockView +import com.drdisagree.iconify.xposed.modules.utils.StatusBarClock.getLeftClockView +import com.drdisagree.iconify.xposed.modules.utils.StatusBarClock.getRightClockView +import com.drdisagree.iconify.xposed.modules.utils.StatusBarClock.setClockGravity +import com.drdisagree.iconify.xposed.utils.XPrefs.Xprefs +import com.drdisagree.iconify.xposed.utils.XPrefs.XprefsIsInitialized +import de.robv.android.xposed.XC_MethodHook +import de.robv.android.xposed.XC_MethodReplacement +import de.robv.android.xposed.XposedBridge.hookAllMethods +import de.robv.android.xposed.XposedBridge.log +import de.robv.android.xposed.XposedHelpers.callMethod +import de.robv.android.xposed.XposedHelpers.callStaticMethod +import de.robv.android.xposed.XposedHelpers.findAndHookMethod +import de.robv.android.xposed.XposedHelpers.findClass +import de.robv.android.xposed.XposedHelpers.findClassIfExists +import de.robv.android.xposed.XposedHelpers.getObjectField +import de.robv.android.xposed.XposedHelpers.setObjectField +import de.robv.android.xposed.callbacks.XC_InitPackageResources.InitPackageResourcesParam +import de.robv.android.xposed.callbacks.XC_LayoutInflated +import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam + +@SuppressLint("DiscouragedApi") +class Statusbar(context: Context?) : ModPack(context!!) { + + private var mColoredStatusbarIcon = false + private var sbClockSizeSwitch = false + private var sbClockSize = 14 + private var mClockView: TextView? = null + private var mCenterClockView: TextView? = null + private var mRightClockView: TextView? = null + private var mLeftClockSize = 14 + private var mCenterClockSize = 14 + private var mRightClockSize = 14 + private var hideLockscreenCarrier = false + private var hideLockscreenStatusbar = false + + override fun updatePrefs(vararg key: String) { + if (!XprefsIsInitialized) return + + Xprefs.apply { + mColoredStatusbarIcon = getBoolean(COLORED_STATUSBAR_ICON, false) + sbClockSizeSwitch = getBoolean(SB_CLOCK_SIZE_SWITCH, false) + sbClockSize = getSliderInt(SB_CLOCK_SIZE, 14) + hideLockscreenCarrier = getBoolean(HIDE_LOCKSCREEN_CARRIER, false) + hideLockscreenStatusbar = getBoolean(HIDE_LOCKSCREEN_STATUSBAR, false) + } + + if (key.isNotEmpty()) { + key[0].let { + if (it == SB_CLOCK_SIZE_SWITCH || + it == SB_CLOCK_SIZE + ) { + setClockSize() + } + + if (it == HIDE_LOCKSCREEN_CARRIER || + it == HIDE_LOCKSCREEN_STATUSBAR + ) { + hideLockscreenCarrierOrStatusbar() + } + } + } + } + + override fun handleLoadPackage(loadPackageParam: LoadPackageParam) { + setColoredNotificationIcons(loadPackageParam) + hideLockscreenCarrierOrStatusbar() + applyClockSize(loadPackageParam) + } + + private fun setColoredNotificationIcons(loadPackageParam: LoadPackageParam) { + if (!mColoredStatusbarIcon) return + + val notificationIconContainerClass = findClass( + "$SYSTEMUI_PACKAGE.statusbar.phone.NotificationIconContainer", + loadPackageParam.classLoader + ) + val iconStateClass = findClass( + "$SYSTEMUI_PACKAGE.statusbar.phone.NotificationIconContainer\$IconState", + loadPackageParam.classLoader + ) + val legacyNotificationIconAreaControllerImplClass = findClassIfExists( + "$SYSTEMUI_PACKAGE.statusbar.phone.LegacyNotificationIconAreaControllerImpl", + loadPackageParam.classLoader + ) + val drawableSizeClass = findClassIfExists( + "$SYSTEMUI_PACKAGE.util.drawable.DrawableSize", + loadPackageParam.classLoader + ) + val scalingDrawableWrapperClass = findClass( + "$SYSTEMUI_PACKAGE.statusbar.ScalingDrawableWrapper", + loadPackageParam.classLoader + ) + val statusBarIconViewClass = findClass( + "$SYSTEMUI_PACKAGE.statusbar.StatusBarIconView", + loadPackageParam.classLoader + ) + + findAndHookMethod( + notificationIconContainerClass, + "applyIconStates", + @Suppress("UNCHECKED_CAST") + object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + val mIconStates: HashMap = getObjectField( + param.thisObject, + "mIconStates" + ) as HashMap + + for (icon in mIconStates.keys) { + removeTintForStatusbarIcon(icon) + } + } + } + ) + + findAndHookMethod( + iconStateClass, + "initFrom", + View::class.java, + object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + removeTintForStatusbarIcon(param) + } + } + ) + + findAndHookMethod( + iconStateClass, + "applyToView", + View::class.java, + object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + removeTintForStatusbarIcon(param) + } + } + ) + + hookAllMethods( + statusBarIconViewClass, + "updateIconColor", + object : XC_MethodReplacement() { + override fun replaceHookedMethod(param: MethodHookParam): Any? { + return null + } + } + ) + + legacyNotificationIconAreaControllerImplClass?.let { thisClass -> + hookAllMethods( + thisClass, + "updateTintForIcon", + object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + removeTintForStatusbarIcon(param) + + try { + val view = param.args[0] as View + callMethod( + view, + "setStaticDrawableColor", + 0 // StatusBarIconView.NO_COLOR + ) + callMethod( + view, + "setDecorColor", + Color.WHITE + ) + } catch (ignored: Throwable) { + } + } + } + ) + } + + try { + findAndHookMethod( + statusBarIconViewClass, + "getIcon", + Context::class.java, + Context::class.java, + "com.android.internal.statusbar.StatusBarIcon", + object : XC_MethodHook() { + override fun beforeHookedMethod(param: MethodHookParam) { + val sysuiContext = param.args[0] as Context + val context = param.args[1] as Context + val statusBarIcon = param.args[2] + + setNotificationIcon( + statusBarIcon, + context, + sysuiContext, + drawableSizeClass, + param, + scalingDrawableWrapperClass + ) + } + } + ) + } catch (ignored: Throwable) { + findAndHookMethod( + statusBarIconViewClass, + "getIcon", + "com.android.internal.statusbar.StatusBarIcon", + object : XC_MethodHook() { + override fun beforeHookedMethod(param: MethodHookParam) { + val sysuiContext = mContext + var context: Context? = null + val statusBarIcon = param.args[0] + val statusBarNotification = getObjectField( + param.thisObject, + "mNotification" + ) + + if (statusBarNotification != null) { + context = callMethod( + statusBarNotification, + "getPackageContext", + mContext + ) as Context? + } + + if (context == null) { + context = mContext + } + + setNotificationIcon( + statusBarIcon, + context, + sysuiContext, + drawableSizeClass, + param, + scalingDrawableWrapperClass + ) + } + } + ) + } + } + + private fun removeTintForStatusbarIcon(param: XC_MethodHook.MethodHookParam) { + val icon = param.args[0] as View + removeTintForStatusbarIcon(icon) + } + + private fun removeTintForStatusbarIcon(icon: View) { + try { + val pkgName = getObjectField( + getObjectField( + icon, + "mIcon" + ), + "pkg" + ) as String + + if (!pkgName.contains("systemui")) { + setObjectField( + icon, + "mCurrentSetColor", + 0 // StatusBarIconView.NO_COLOR + ) + callMethod( + icon, + "updateIconColor" + ) + } + } catch (ignored: Throwable) { + log(TAG + ignored) + } + } + + private fun setNotificationIcon( + statusBarIcon: Any?, + context: Context, + sysuiContext: Context, + drawableSize: Class<*>?, + param: XC_MethodHook.MethodHookParam, + scalingDrawableWrapper: Class<*> + ) { + var icon: Drawable + val res = sysuiContext.resources + val pkgName = getObjectField(statusBarIcon, "pkg") as String + + if (listOf("com.android", "systemui").any { pkgName.contains(it) }) { + return + } + + try { + icon = context.packageManager.getApplicationIcon(pkgName) + } catch (e: Throwable) { + return + } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + val isLowRamDevice = callStaticMethod( + ActivityManager::class.java, + "isLowRamDeviceStatic" + ) as Boolean + + val maxIconSize = res.getDimensionPixelSize( + res.getIdentifier( + if (isLowRamDevice) { + "notification_small_icon_size_low_ram" + } else { + "notification_small_icon_size" + }, + "dimen", + FRAMEWORK_PACKAGE + ) + ) + + if (drawableSize != null) { + icon = callStaticMethod( + drawableSize, + "downscaleToSize", + res, + icon, + maxIconSize, + maxIconSize + ) as Drawable + } + } + + val typedValue = TypedValue() + res.getValue( + res.getIdentifier( + "status_bar_icon_scale_factor", + "dimen", + SYSTEMUI_PACKAGE + ), + typedValue, + true + ) + val scaleFactor = typedValue.float + + if (scaleFactor == 1f) { + param.result = icon + } else { + param.result = scalingDrawableWrapper.getConstructor( + Drawable::class.java, + Float::class.javaPrimitiveType + ).newInstance(icon, scaleFactor) + } + } + + private fun hideLockscreenCarrierOrStatusbar() { + val resParam: InitPackageResourcesParam = resParams[SYSTEMUI_PACKAGE] ?: return + + try { + resParam.res.hookLayout( + SYSTEMUI_PACKAGE, + "layout", + "keyguard_status_bar", + object : XC_LayoutInflated() { + override fun handleLayoutInflated(liparam: LayoutInflatedParam) { + if (hideLockscreenCarrier) { + try { + liparam.view.findViewById( + liparam.res.getIdentifier( + "keyguard_carrier_text", + "id", + mContext.packageName + ) + ).apply { + layoutParams.height = 0 + visibility = View.INVISIBLE + requestLayout() + } + } catch (ignored: Throwable) { + } + } + + if (hideLockscreenStatusbar) { + try { + liparam.view.findViewById( + liparam.res.getIdentifier( + "status_icon_area", + "id", + mContext.packageName + ) + ).apply { + layoutParams.height = 0 + visibility = View.INVISIBLE + requestLayout() + } + } catch (ignored: Throwable) { + } + + try { + liparam.view.findViewById( + liparam.res.getIdentifier( + "keyguard_carrier_text", + "id", + mContext.packageName + ) + ).apply { + layoutParams.height = 0 + visibility = View.INVISIBLE + requestLayout() + } + } catch (ignored: Throwable) { + } + } + } + }) + } catch (ignored: Throwable) { + } + } + + private fun applyClockSize(loadPackageParam: LoadPackageParam) { + val collapsedStatusBarFragment = findClassInArray( + loadPackageParam.classLoader, + "$SYSTEMUI_PACKAGE.statusbar.phone.CollapsedStatusBarFragment", + "$SYSTEMUI_PACKAGE.statusbar.phone.fragment.CollapsedStatusBarFragment" + ) + + if (collapsedStatusBarFragment == null) { + log(TAG + "CollapsedStatusBarFragment not found") + return + } + + findAndHookMethod(collapsedStatusBarFragment, + "onViewCreated", + View::class.java, + Bundle::class.java, + object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + mClockView = getLeftClockView(mContext, param) as? TextView + mCenterClockView = getCenterClockView(mContext, param) as? TextView + mRightClockView = getRightClockView(mContext, param) as? TextView + + mLeftClockSize = mClockView?.textSize?.toInt() ?: 14 + mCenterClockSize = mCenterClockView?.textSize?.toInt() ?: 14 + mRightClockSize = mRightClockView?.textSize?.toInt() ?: 14 + + setClockSize() + + val textChangeListener = object : TextWatcher { + override fun beforeTextChanged( + s: CharSequence, + start: Int, + count: Int, + after: Int + ) { + } + + override fun onTextChanged( + s: CharSequence, + start: Int, + before: Int, + count: Int + ) { + } + + override fun afterTextChanged(s: Editable) { + setClockSize() + } + } + + mClockView?.addTextChangedListener(textChangeListener) + mCenterClockView?.addTextChangedListener(textChangeListener) + mRightClockView?.addTextChangedListener(textChangeListener) + } + }) + + } + + @SuppressLint("RtlHardcoded") + private fun setClockSize() { + val leftClockSize = if (sbClockSizeSwitch) sbClockSize else mLeftClockSize + val centerClockSize = if (sbClockSizeSwitch) sbClockSize else mCenterClockSize + val rightClockSize = if (sbClockSizeSwitch) sbClockSize else mRightClockSize + val unit = if (sbClockSizeSwitch) TypedValue.COMPLEX_UNIT_SP else TypedValue.COMPLEX_UNIT_PX + + mClockView?.let { + it.setTextSize(unit, leftClockSize.toFloat()) + + if (sbClockSizeSwitch) { + setClockGravity(it, Gravity.LEFT or Gravity.CENTER) + } + } + + mCenterClockView?.let { + it.setTextSize(unit, centerClockSize.toFloat()) + + if (sbClockSizeSwitch) { + setClockGravity(it, Gravity.CENTER) + } + } + + mRightClockView?.let { + it.setTextSize(unit, rightClockSize.toFloat()) + + if (sbClockSizeSwitch) { + setClockGravity(it, Gravity.RIGHT or Gravity.CENTER) + } + } + } + + companion object { + private val TAG = "Iconify - ${Statusbar::class.java.simpleName}: " + } +} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/xposed/modules/VolumePanel.kt b/app/src/main/java/com/drdisagree/iconify/xposed/modules/VolumePanel.kt index 2291f8c27..eac2d6a8c 100644 --- a/app/src/main/java/com/drdisagree/iconify/xposed/modules/VolumePanel.kt +++ b/app/src/main/java/com/drdisagree/iconify/xposed/modules/VolumePanel.kt @@ -2,17 +2,22 @@ package com.drdisagree.iconify.xposed.modules import android.annotation.SuppressLint import android.content.Context +import android.content.res.ColorStateList import android.view.Gravity import android.view.View import android.view.ViewGroup +import android.widget.ImageView import android.widget.LinearLayout import android.widget.TextView import com.drdisagree.iconify.common.Const.SYSTEMUI_PACKAGE +import com.drdisagree.iconify.common.Preferences.VOLUME_COLORED_RINGER_ICON import com.drdisagree.iconify.common.Preferences.VOLUME_PANEL_PERCENTAGE import com.drdisagree.iconify.common.Preferences.VOLUME_PANEL_SAFETY_WARNING -import com.drdisagree.iconify.config.XPrefs.Xprefs import com.drdisagree.iconify.xposed.ModPack +import com.drdisagree.iconify.xposed.modules.utils.SettingsLibUtils import com.drdisagree.iconify.xposed.modules.utils.ViewHelper.toPx +import com.drdisagree.iconify.xposed.utils.XPrefs.Xprefs +import com.drdisagree.iconify.xposed.utils.XPrefs.XprefsIsInitialized import de.robv.android.xposed.XC_MethodHook import de.robv.android.xposed.XposedBridge.hookAllMethods import de.robv.android.xposed.XposedHelpers.callMethod @@ -21,24 +26,75 @@ import de.robv.android.xposed.XposedHelpers.getObjectField import de.robv.android.xposed.XposedHelpers.setObjectField import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam import kotlin.math.ceil +import kotlin.properties.Delegates @SuppressLint("DiscouragedApi", "DefaultLocale") class VolumePanel(context: Context?) : ModPack(context!!) { private var showPercentage = false private var showWarning = true + private var coloredRingerIcon = false + private lateinit var mSelectedRingerIcon: ImageView; + private var ringerIconDefaultColor by Delegates.notNull(); + private var ringerIconTextColor by Delegates.notNull(); override fun updatePrefs(vararg key: String) { - if (Xprefs == null) return + if (!XprefsIsInitialized) return - showPercentage = Xprefs!!.getBoolean(VOLUME_PANEL_PERCENTAGE, false) - showWarning = Xprefs!!.getBoolean(VOLUME_PANEL_SAFETY_WARNING, true) + Xprefs.apply { + showPercentage = getBoolean(VOLUME_PANEL_PERCENTAGE, false) + showWarning = getBoolean(VOLUME_PANEL_SAFETY_WARNING, true) + coloredRingerIcon = getBoolean(VOLUME_COLORED_RINGER_ICON, false) + } + + if (key.isNotEmpty()) { + key[0].let { + if (it == VOLUME_COLORED_RINGER_ICON) { + setRingerIconColor() + } + } + } } override fun handleLoadPackage(loadPackageParam: LoadPackageParam) { + coloredSelectedRingerIcon(loadPackageParam) showVolumePercentage(loadPackageParam) } + private fun coloredSelectedRingerIcon(loadPackageParam: LoadPackageParam) { + val volumeDialogImplClass = findClass( + "$SYSTEMUI_PACKAGE.volume.VolumeDialogImpl", + loadPackageParam.classLoader + ) + + hookAllMethods(volumeDialogImplClass, "initDialog", object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + mSelectedRingerIcon = getObjectField( + param.thisObject, + "mSelectedRingerIcon" + ) as ImageView + + ringerIconDefaultColor = mSelectedRingerIcon.imageTintList!!.defaultColor + ringerIconTextColor = SettingsLibUtils.getColorAttrDefaultColor( + mSelectedRingerIcon.context, + android.R.attr.textColorPrimary + ) + + setRingerIconColor() + } + }) + } + + private fun setRingerIconColor() { + mSelectedRingerIcon.imageTintList = ColorStateList.valueOf( + if (coloredRingerIcon) { + ringerIconTextColor + } else { + ringerIconDefaultColor + } + ) + } + private fun showVolumePercentage(loadPackageParam: LoadPackageParam) { val volumeDialogImplClass = findClass( "$SYSTEMUI_PACKAGE.volume.VolumeDialogImpl", diff --git a/app/src/main/java/com/drdisagree/iconify/xposed/modules/batterystyles/CircleBattery.kt b/app/src/main/java/com/drdisagree/iconify/xposed/modules/batterystyles/CircleBattery.kt index c0d9a859e..96d607581 100644 --- a/app/src/main/java/com/drdisagree/iconify/xposed/modules/batterystyles/CircleBattery.kt +++ b/app/src/main/java/com/drdisagree/iconify/xposed/modules/batterystyles/CircleBattery.kt @@ -22,8 +22,8 @@ import androidx.core.graphics.PathParser import androidx.interpolator.view.animation.FastOutSlowInInterpolator import com.drdisagree.iconify.common.Preferences import com.drdisagree.iconify.config.RPrefs.getBoolean -import com.drdisagree.iconify.config.XPrefs.Xprefs import com.drdisagree.iconify.xposed.modules.utils.AlphaRefreshedPaint +import com.drdisagree.iconify.xposed.utils.XPrefs.Xprefs @Suppress("UNUSED_PARAMETER") open class CircleBattery(private val mContext: Context, frameColor: Int) : BatteryDrawable() { @@ -91,7 +91,7 @@ open class CircleBattery(private val mContext: Context, frameColor: Int) : Batte private fun initColors() { customBlendColor = try { - Xprefs?.getBoolean(Preferences.CUSTOM_BATTERY_BLEND_COLOR, false) ?: false + Xprefs.getBoolean(Preferences.CUSTOM_BATTERY_BLEND_COLOR, false) ?: false } catch (ignored: Throwable) { getBoolean(Preferences.CUSTOM_BATTERY_BLEND_COLOR, false) } @@ -319,7 +319,7 @@ open class CircleBattery(private val mContext: Context, frameColor: Int) : Batte mBatteryPaint.style = Paint.Style.STROKE try { - Xprefs?.let { setMeterStyle(it.getInt(Preferences.CUSTOM_BATTERY_STYLE, 0)) } + setMeterStyle(Xprefs.getInt(Preferences.CUSTOM_BATTERY_STYLE, 0)) } catch (ignored: Throwable) { setMeterStyle(Preferences.BATTERY_STYLE_CIRCLE) } diff --git a/app/src/main/java/com/drdisagree/iconify/xposed/modules/batterystyles/CircleFilledBattery.kt b/app/src/main/java/com/drdisagree/iconify/xposed/modules/batterystyles/CircleFilledBattery.kt index 54fb029b7..19b159d13 100644 --- a/app/src/main/java/com/drdisagree/iconify/xposed/modules/batterystyles/CircleFilledBattery.kt +++ b/app/src/main/java/com/drdisagree/iconify/xposed/modules/batterystyles/CircleFilledBattery.kt @@ -15,7 +15,7 @@ import androidx.core.graphics.ColorUtils import androidx.interpolator.view.animation.FastOutSlowInInterpolator import com.drdisagree.iconify.common.Preferences import com.drdisagree.iconify.config.RPrefs -import com.drdisagree.iconify.config.XPrefs +import com.drdisagree.iconify.xposed.utils.XPrefs.Xprefs import kotlin.math.max @Suppress("UNUSED_PARAMETER") @@ -188,7 +188,7 @@ open class CircleFilledBattery(private val mContext: Context, frameColor: Int) : private fun initColors() { customBlendColor = try { - XPrefs.Xprefs?.getBoolean(Preferences.CUSTOM_BATTERY_BLEND_COLOR, false) ?: false + Xprefs.getBoolean(Preferences.CUSTOM_BATTERY_BLEND_COLOR, false) ?: false } catch (ignored: Throwable) { RPrefs.getBoolean(Preferences.CUSTOM_BATTERY_BLEND_COLOR, false) } diff --git a/app/src/main/java/com/drdisagree/iconify/xposed/modules/themes/QSBlackThemeA13.kt b/app/src/main/java/com/drdisagree/iconify/xposed/modules/themes/QSBlackThemeA13.kt index a2ac17278..eb16616f1 100644 --- a/app/src/main/java/com/drdisagree/iconify/xposed/modules/themes/QSBlackThemeA13.kt +++ b/app/src/main/java/com/drdisagree/iconify/xposed/modules/themes/QSBlackThemeA13.kt @@ -12,10 +12,11 @@ import android.widget.TextView import androidx.core.graphics.ColorUtils import com.drdisagree.iconify.common.Const.SYSTEMUI_PACKAGE import com.drdisagree.iconify.common.Preferences -import com.drdisagree.iconify.config.XPrefs.Xprefs import com.drdisagree.iconify.xposed.ModPack import com.drdisagree.iconify.xposed.modules.utils.SettingsLibUtils.Companion.getColorAttr -import com.drdisagree.iconify.xposed.utils.SystemUtil +import com.drdisagree.iconify.xposed.utils.SystemUtils +import com.drdisagree.iconify.xposed.utils.XPrefs.Xprefs +import com.drdisagree.iconify.xposed.utils.XPrefs.XprefsIsInitialized import de.robv.android.xposed.XC_MethodHook import de.robv.android.xposed.XposedBridge.hookAllConstructors import de.robv.android.xposed.XposedBridge.hookAllMethods @@ -41,15 +42,17 @@ class QSBlackThemeA13(context: Context?) : ModPack(context!!) { private var qsTextFollowAccent = false init { - isDark = SystemUtil.isDarkMode + isDark = SystemUtils.isDarkMode } override fun updatePrefs(vararg key: String) { - if (Xprefs == null) return + if (!XprefsIsInitialized) return - blackQSHeaderEnabled = Xprefs!!.getBoolean(Preferences.BLACK_QSPANEL, false) - qsTextAlwaysWhite = Xprefs!!.getBoolean(Preferences.QS_TEXT_ALWAYS_WHITE, false) - qsTextFollowAccent = Xprefs!!.getBoolean(Preferences.QS_TEXT_FOLLOW_ACCENT, false) + Xprefs.apply { + blackQSHeaderEnabled = getBoolean(Preferences.BLACK_QSPANEL, false) + qsTextAlwaysWhite = getBoolean(Preferences.QS_TEXT_ALWAYS_WHITE, false) + qsTextFollowAccent = getBoolean(Preferences.QS_TEXT_FOLLOW_ACCENT, false) + } initColors(true) } @@ -168,18 +171,29 @@ class QSBlackThemeA13(context: Context?) : ModPack(context!!) { "configurationControllerListener" ) - hookAllMethods( - configurationControllerListener.javaClass, + val applyComponentColors = object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + setHeaderComponentsColor(mView, iconManager, batteryIcon) + } + } + + val methods = listOf( "onConfigChanged", - object : XC_MethodHook() { - override fun afterHookedMethod(param: MethodHookParam) { - setHeaderComponentsColor( - mView, - iconManager, - batteryIcon - ) - } - }) + "onDensityOrFontScaleChanged", + "onUiModeChanged", + "onThemeChanged" + ) + + for (method in methods) { + try { + hookAllMethods( + configurationControllerListener.javaClass, + method, + applyComponentColors + ) + } catch (ignored: Throwable) { + } + } setHeaderComponentsColor(mView, iconManager, batteryIcon) } catch (throwable: Throwable) { @@ -211,7 +225,7 @@ class QSBlackThemeA13(context: Context?) : ModPack(context!!) { ) ) - icon.setImageTintList(ColorStateList.valueOf(Color.WHITE)) + icon.imageTintList = ColorStateList.valueOf(Color.WHITE) } catch (throwable: Throwable) { log(TAG + throwable) } @@ -258,8 +272,8 @@ class QSBlackThemeA13(context: Context?) : ModPack(context!!) { if (!blackQSHeaderEnabled) return try { - (getObjectField(param.thisObject, "mIcon") as ImageView) - .setImageTintList(ColorStateList.valueOf(colorText!!)) + (getObjectField(param.thisObject, "mIcon") as ImageView).imageTintList = + ColorStateList.valueOf(colorText!!) } catch (throwable: Throwable) { log(TAG + throwable) } @@ -272,12 +286,15 @@ class QSBlackThemeA13(context: Context?) : ModPack(context!!) { if (!blackQSHeaderEnabled) return try { - (getObjectField(param.thisObject, "mIcon") as ImageView) - .setImageTintList(ColorStateList.valueOf(colorText!!)) + (getObjectField(param.thisObject, "mIcon") as ImageView).imageTintList = + ColorStateList.valueOf(colorText!!) } catch (throwable: Throwable) { try { - (getObjectField(param.thisObject, "mIconView") as ImageView) - .setImageTintList(ColorStateList.valueOf(colorText!!)) + (getObjectField( + param.thisObject, + "mIconView" + ) as ImageView).imageTintList = + ColorStateList.valueOf(colorText!!) } catch (throwable1: Throwable) { log(TAG + throwable1) } @@ -291,8 +308,8 @@ class QSBlackThemeA13(context: Context?) : ModPack(context!!) { if (!blackQSHeaderEnabled) return try { - (getObjectField(param.thisObject, "mIcon") as ImageView) - .setImageTintList(ColorStateList.valueOf(colorText!!)) + (getObjectField(param.thisObject, "mIcon") as ImageView).imageTintList = + ColorStateList.valueOf(colorText!!) } catch (throwable: Throwable) { log(TAG + throwable) } @@ -305,8 +322,8 @@ class QSBlackThemeA13(context: Context?) : ModPack(context!!) { try { if (getIntField(param.args[1], "state") == Tile.STATE_ACTIVE ) { - (param.args[0] as ImageView) - .setImageTintList(ColorStateList.valueOf(colorText!!)) + (param.args[0] as ImageView).imageTintList = + ColorStateList.valueOf(colorText!!) } } catch (throwable: Throwable) { log(TAG + throwable) @@ -418,7 +435,7 @@ class QSBlackThemeA13(context: Context?) : ModPack(context!!) { mContext.packageName ) ) - customDrawable.setImageTintList(ColorStateList.valueOf(colorText!!)) + customDrawable.imageTintList = ColorStateList.valueOf(colorText!!) val chevron = sideView.findViewById( mContext.resources.getIdentifier( @@ -427,7 +444,7 @@ class QSBlackThemeA13(context: Context?) : ModPack(context!!) { mContext.packageName ) ) - chevron.setImageTintList(ColorStateList.valueOf(colorText!!)) + chevron.imageTintList = ColorStateList.valueOf(colorText!!) } catch (throwable: Throwable) { log(TAG + throwable) } @@ -436,7 +453,8 @@ class QSBlackThemeA13(context: Context?) : ModPack(context!!) { hookAllMethods(qsIconViewImplClass, "getIconColorForState", object : XC_MethodHook() { override fun beforeHookedMethod(param: MethodHookParam) { - val (isDisabledState: Boolean, isActiveState: Boolean) = getTileState(param) + val (isDisabledState: Boolean, + isActiveState: Boolean) = Utils.getTileState(param) if (blackQSHeaderEnabled) { if (isDisabledState) { @@ -455,17 +473,18 @@ class QSBlackThemeA13(context: Context?) : ModPack(context!!) { override fun afterHookedMethod(param: MethodHookParam) { if (qsTextAlwaysWhite || qsTextFollowAccent) return - val (isDisabledState: Boolean, isActiveState: Boolean) = getTileState(param) + val (isDisabledState: Boolean, + isActiveState: Boolean) = Utils.getTileState(param) if (blackQSHeaderEnabled) { val mIcon = param.args[0] as ImageView if (isDisabledState) { - mIcon.setImageTintList(ColorStateList.valueOf(-0x7f000001)) + mIcon.imageTintList = ColorStateList.valueOf(-0x7f000001) } else if (isActiveState && !qsTextAlwaysWhite && !qsTextFollowAccent) { - mIcon.setImageTintList(ColorStateList.valueOf(colorText!!)) + mIcon.imageTintList = ColorStateList.valueOf(colorText!!) } else if (!isActiveState) { - mIcon.setImageTintList(ColorStateList.valueOf(Color.WHITE)) + mIcon.imageTintList = ColorStateList.valueOf(Color.WHITE) } } } @@ -569,7 +588,7 @@ class QSBlackThemeA13(context: Context?) : ModPack(context!!) { }) try { - val constants: Array? = scrimStateEnum.getEnumConstants() + val constants: Array? = scrimStateEnum.enumConstants if (constants != null) { for (constant in constants) { when (constant.toString()) { @@ -736,45 +755,8 @@ class QSBlackThemeA13(context: Context?) : ModPack(context!!) { }) } - private fun getTileState(param: XC_MethodHook.MethodHookParam): Pair { - val isDisabledState: Boolean = try { - getObjectField( - param.args[1], - "disabledByPolicy" - ) as Boolean || - getObjectField( - param.args[1], - "state" - ) as Int == Tile.STATE_UNAVAILABLE - } catch (throwable: Throwable) { - getObjectField( - param.args[1], - "state" - ) as Int == Tile.STATE_UNAVAILABLE - } - - val isActiveState: Boolean = try { - getObjectField( - param.args[1], - "state" - ) as Int == QSLightThemeA13.STATE_ACTIVE - } catch (throwable: Throwable) { - try { - param.args[1] as Int == QSLightThemeA13.STATE_ACTIVE - } catch (throwable1: Throwable) { - try { - param.args[1] as Boolean - } catch (throwable2: Throwable) { - false - } - } - } - - return Pair(isDisabledState, isActiveState) - } - private fun initColors(force: Boolean) { - val isDark: Boolean = SystemUtil.isDarkMode + val isDark: Boolean = SystemUtils.isDarkMode if (isDark == this.isDark && !force) return this.isDark = isDark @@ -851,7 +833,7 @@ class QSBlackThemeA13(context: Context?) : ModPack(context!!) { mContext.packageName ) ), "mMobileSignal" - ) as ImageView).setImageTintList(ColorStateList.valueOf(textColor)) + ) as ImageView).imageTintList = ColorStateList.valueOf(textColor) (getObjectField( mView.findViewById( @@ -861,7 +843,7 @@ class QSBlackThemeA13(context: Context?) : ModPack(context!!) { mContext.packageName ) ), "mMobileRoaming" - ) as ImageView).setImageTintList(ColorStateList.valueOf(textColor)) + ) as ImageView).imageTintList = ColorStateList.valueOf(textColor) } catch (ignored: Throwable) { } } diff --git a/app/src/main/java/com/drdisagree/iconify/xposed/modules/themes/QSBlackThemeA14.kt b/app/src/main/java/com/drdisagree/iconify/xposed/modules/themes/QSBlackThemeA14.kt index 565ffdd78..88f76f0e9 100644 --- a/app/src/main/java/com/drdisagree/iconify/xposed/modules/themes/QSBlackThemeA14.kt +++ b/app/src/main/java/com/drdisagree/iconify/xposed/modules/themes/QSBlackThemeA14.kt @@ -17,10 +17,12 @@ import com.drdisagree.iconify.common.Const.SYSTEMUI_PACKAGE import com.drdisagree.iconify.common.Preferences.BLACK_QSPANEL import com.drdisagree.iconify.common.Preferences.QS_TEXT_ALWAYS_WHITE import com.drdisagree.iconify.common.Preferences.QS_TEXT_FOLLOW_ACCENT -import com.drdisagree.iconify.config.XPrefs.Xprefs import com.drdisagree.iconify.xposed.ModPack +import com.drdisagree.iconify.xposed.modules.utils.Helpers.findClassInArray import com.drdisagree.iconify.xposed.modules.utils.SettingsLibUtils.Companion.getColorAttr -import com.drdisagree.iconify.xposed.utils.SystemUtil +import com.drdisagree.iconify.xposed.utils.SystemUtils +import com.drdisagree.iconify.xposed.utils.XPrefs.Xprefs +import com.drdisagree.iconify.xposed.utils.XPrefs.XprefsIsInitialized import de.robv.android.xposed.XC_MethodHook import de.robv.android.xposed.XposedBridge.hookAllConstructors import de.robv.android.xposed.XposedBridge.hookAllMethods @@ -34,7 +36,7 @@ import de.robv.android.xposed.XposedHelpers.getIntField import de.robv.android.xposed.XposedHelpers.getObjectField import de.robv.android.xposed.XposedHelpers.setObjectField import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam -import java.util.function.Consumer + @SuppressLint("DiscouragedApi") class QSBlackThemeA14(context: Context?) : ModPack(context!!) { @@ -48,17 +50,21 @@ class QSBlackThemeA14(context: Context?) : ModPack(context!!) { private var qsTextFollowAccent = false private var shadeCarrierGroupController: Any? = null private val modernShadeCarrierGroupMobileViews = ArrayList() + private var colorActive: Int? = null + private var colorInactive: Int? = null init { - isDark = SystemUtil.isDarkMode + isDark = SystemUtils.isDarkMode } override fun updatePrefs(vararg key: String) { - if (Xprefs == null) return + if (!XprefsIsInitialized) return - blackQSHeaderEnabled = Xprefs!!.getBoolean(BLACK_QSPANEL, false) - qsTextAlwaysWhite = Xprefs!!.getBoolean(QS_TEXT_ALWAYS_WHITE, false) - qsTextFollowAccent = Xprefs!!.getBoolean(QS_TEXT_FOLLOW_ACCENT, false) + Xprefs.apply { + blackQSHeaderEnabled = getBoolean(BLACK_QSPANEL, false) + qsTextAlwaysWhite = getBoolean(QS_TEXT_ALWAYS_WHITE, false) + qsTextFollowAccent = getBoolean(QS_TEXT_FOLLOW_ACCENT, false) + } initColors(true) } @@ -164,16 +170,11 @@ class QSBlackThemeA14(context: Context?) : ModPack(context!!) { "$SYSTEMUI_PACKAGE.qs.footer.ui.binder.FooterActionsViewBinder", loadPackageParam.classLoader ) - var shadeHeaderControllerClass = findClassIfExists( + val shadeHeaderControllerClass = findClassInArray( + loadPackageParam.classLoader, "$SYSTEMUI_PACKAGE.shade.ShadeHeaderController", - loadPackageParam.classLoader + "$SYSTEMUI_PACKAGE.shade.LargeScreenShadeHeaderController" ) - if (shadeHeaderControllerClass == null) { - shadeHeaderControllerClass = findClass( - "$SYSTEMUI_PACKAGE.shade.LargeScreenShadeHeaderController", - loadPackageParam.classLoader - ) - } // Background color of android 14's charging chip. Fix for light QS theme situation val batteryStatusChipColorHook: XC_MethodHook = object : XC_MethodHook() { @@ -213,14 +214,29 @@ class QSBlackThemeA14(context: Context?) : ModPack(context!!) { "configurationControllerListener" ) - hookAllMethods( - configurationControllerListener.javaClass, + val applyComponentColors = object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + setHeaderComponentsColor(mView, iconManager, batteryIcon) + } + } + + val methods = listOf( "onConfigChanged", - object : XC_MethodHook() { - override fun afterHookedMethod(param: MethodHookParam) { - setHeaderComponentsColor(mView, iconManager, batteryIcon) - } - }) + "onDensityOrFontScaleChanged", + "onUiModeChanged", + "onThemeChanged" + ) + + for (method in methods) { + try { + hookAllMethods( + configurationControllerListener.javaClass, + method, + applyComponentColors + ) + } catch (ignored: Throwable) { + } + } setHeaderComponentsColor(mView, iconManager, batteryIcon) } catch (throwable: Throwable) { @@ -247,7 +263,7 @@ class QSBlackThemeA14(context: Context?) : ModPack(context!!) { hookAllMethods(mobileIconBinderClass, "bind", object : XC_MethodHook() { override fun afterHookedMethod(param: MethodHookParam) { - if (param.args[1].javaClass.getName() + if (param.args[1].javaClass.name .contains("ShadeCarrierGroupMobileIconViewModel") ) { modernShadeCarrierGroupMobileViews.add(param.result) @@ -265,102 +281,111 @@ class QSBlackThemeA14(context: Context?) : ModPack(context!!) { override fun afterHookedMethod(param: MethodHookParam) { if (!blackQSHeaderEnabled) return - val view = (param.thisObject as ViewGroup).findViewById( - mContext.resources.getIdentifier( - "qs_footer_actions", - "id", - mContext.packageName - ) - ).also { - it.background?.setTint(Color.BLACK) - it.elevation = 0f - } - - // Settings button - view.findViewById( - mContext.resources.getIdentifier( - "settings_button_container", - "id", - mContext.packageName - ) - ).findViewById( - mContext.resources.getIdentifier( - "icon", - "id", - mContext.packageName - ) - ).setImageTintList(ColorStateList.valueOf(Color.WHITE)) - - // Power menu button try { - view.findViewById( + val view = (param.thisObject as ViewGroup).findViewById( mContext.resources.getIdentifier( - "pm_lite", + "qs_footer_actions", "id", mContext.packageName ) - ) - } catch (ignored: ClassCastException) { - view.findViewById( + ).also { + it.background?.setTint(Color.BLACK) + it.elevation = 0f + } + + // Settings button + view.findViewById( mContext.resources.getIdentifier( - "pm_lite", + "settings_button_container", "id", mContext.packageName ) - ) - }?.apply { - if (this is ImageView) { - setImageTintList(ColorStateList.valueOf(Color.BLACK)) - } else if (this is ViewGroup) { - (getChildAt(0) as ImageView).setColorFilter( - Color.WHITE, - PorterDuff.Mode.SRC_IN + ).findViewById( + mContext.resources.getIdentifier( + "icon", + "id", + mContext.packageName + ) + ).imageTintList = ColorStateList.valueOf(Color.WHITE) + + // Power menu button + try { + view.findViewById( + mContext.resources.getIdentifier( + "pm_lite", + "id", + mContext.packageName + ) + ) + } catch (ignored: ClassCastException) { + view.findViewById( + mContext.resources.getIdentifier( + "pm_lite", + "id", + mContext.packageName + ) ) + }?.apply { + if (this is ImageView) { + imageTintList = ColorStateList.valueOf(Color.BLACK) + } else if (this is ViewGroup) { + (getChildAt(0) as ImageView).setColorFilter( + Color.WHITE, + PorterDuff.Mode.SRC_IN + ) + } } + } catch (ignored: Throwable) { + // it will fail on compose implementation } } }) // QS Customize panel - hookAllConstructors(qsCustomizerClass, object : XC_MethodHook() { - override fun afterHookedMethod(param: MethodHookParam) { - if (blackQSHeaderEnabled) { - val mainView = param.thisObject as ViewGroup + hookAllConstructors(qsCustomizerClass, + object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + if (blackQSHeaderEnabled) { + val mainView = param.thisObject as ViewGroup - for (i in 0 until mainView.childCount) { - mainView.getChildAt(i).setBackgroundColor(Color.BLACK) + for (i in 0 until mainView.childCount) { + mainView.getChildAt(i).setBackgroundColor(Color.BLACK) + } } } - } - }) + }) // Mobile signal icons - this is the legacy model. new model uses viewmodels - hookAllMethods(shadeCarrierClass, "updateState", object : XC_MethodHook() { - override fun afterHookedMethod(param: MethodHookParam) { - if (!blackQSHeaderEnabled) return + hookAllMethods(shadeCarrierClass, "updateState", + object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + if (!blackQSHeaderEnabled) return - (getObjectField(param.thisObject, "mMobileSignal") as ImageView) - .setImageTintList(ColorStateList.valueOf(Color.WHITE)) - } - }) + (getObjectField(param.thisObject, "mMobileSignal") as ImageView).imageTintList = + ColorStateList.valueOf(Color.WHITE) + } + }) // QS security footer count circle - hookAllConstructors(numberButtonViewHolderClass, object : XC_MethodHook() { - override fun afterHookedMethod(param: MethodHookParam) { - if (blackQSHeaderEnabled) { - (getObjectField(param.thisObject, "newDot") as ImageView) - .setColorFilter(Color.WHITE) + hookAllConstructors(numberButtonViewHolderClass, + object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + if (blackQSHeaderEnabled) { + (getObjectField(param.thisObject, "newDot") as ImageView) + .setColorFilter(Color.WHITE) - (getObjectField(param.thisObject, "number") as TextView) - .setTextColor(Color.WHITE) + (getObjectField(param.thisObject, "number") as TextView) + .setTextColor(Color.WHITE) + } } - } - }) + }) // QS security footer - hookAllConstructors(textButtonViewHolderClass, object : XC_MethodHook() { - override fun afterHookedMethod(param: MethodHookParam) { - if (blackQSHeaderEnabled) { + hookAllConstructors(textButtonViewHolderClass, + object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + if (!blackQSHeaderEnabled) return + (getObjectField(param.thisObject, "chevron") as ImageView) .setColorFilter(Color.WHITE) @@ -373,8 +398,8 @@ class QSBlackThemeA14(context: Context?) : ModPack(context!!) { (getObjectField(param.thisObject, "text") as TextView) .setTextColor(Color.WHITE) } - } - }) + }) + try { //QS Footer built text row hookAllMethods(qsFooterViewClass, "onFinishInflate", object : XC_MethodHook() { @@ -407,19 +432,20 @@ class QSBlackThemeA14(context: Context?) : ModPack(context!!) { } // QS tile primary label color - hookAllMethods(qsTileViewImplClass, "getLabelColorForState", object : XC_MethodHook() { - override fun beforeHookedMethod(param: MethodHookParam) { - if (!blackQSHeaderEnabled) return + hookAllMethods(qsTileViewImplClass, "getLabelColorForState", + object : XC_MethodHook() { + override fun beforeHookedMethod(param: MethodHookParam) { + if (!blackQSHeaderEnabled) return - try { - if (param.args[0] as Int == Tile.STATE_ACTIVE) { - param.result = colorText + try { + if (param.args[0] as Int == Tile.STATE_ACTIVE) { + param.result = colorText + } + } catch (throwable: Throwable) { + log(TAG + throwable) } - } catch (throwable: Throwable) { - log(TAG + throwable) } - } - }) + }) // QS tile secondary label color hookAllMethods( @@ -440,18 +466,25 @@ class QSBlackThemeA14(context: Context?) : ModPack(context!!) { }) // Auto Brightness Icon Color - hookAllMethods(brightnessControllerClass, "updateIcon", object : XC_MethodHook() { - override fun afterHookedMethod(param: MethodHookParam) { - if (!blackQSHeaderEnabled) return + hookAllMethods(brightnessControllerClass, "updateIcon", + object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + if (!blackQSHeaderEnabled) return - try { - (getObjectField(param.thisObject, "mIcon") as ImageView) - .setImageTintList(ColorStateList.valueOf(colorText!!)) - } catch (throwable: Throwable) { - log(TAG + throwable) + try { + val iconColor = if ((param.args?.get(0) ?: false) as Boolean) { + Color.BLACK + } else { + Color.WHITE + } + val mIcon = getObjectField(param.thisObject, "mIcon") as ImageView + + mIcon.imageTintList = ColorStateList.valueOf(iconColor) + } catch (throwable: Throwable) { + log(TAG + throwable) + } } - } - }) + }) if (brightnessSliderControllerClass != null) { hookAllConstructors(brightnessSliderControllerClass, object : XC_MethodHook() { @@ -459,12 +492,15 @@ class QSBlackThemeA14(context: Context?) : ModPack(context!!) { if (!blackQSHeaderEnabled) return try { - (getObjectField(param.thisObject, "mIcon") as ImageView) - .setImageTintList(ColorStateList.valueOf(colorText!!)) + (getObjectField(param.thisObject, "mIcon") as ImageView).imageTintList = + ColorStateList.valueOf(colorText!!) } catch (throwable: Throwable) { try { - (getObjectField(param.thisObject, "mIconView") as ImageView) - .setImageTintList(ColorStateList.valueOf(colorText!!)) + (getObjectField( + param.thisObject, + "mIconView" + ) as ImageView).imageTintList = + ColorStateList.valueOf(colorText!!) } catch (ignored: Throwable) { } } @@ -472,63 +508,47 @@ class QSBlackThemeA14(context: Context?) : ModPack(context!!) { }) } - hookAllMethods(brightnessMirrorControllerClass, "updateIcon", object : XC_MethodHook() { - override fun afterHookedMethod(param: MethodHookParam) { - if (!blackQSHeaderEnabled) return - - try { - (getObjectField(param.thisObject, "mIcon") as ImageView) - .setImageTintList(ColorStateList.valueOf(colorText!!)) - } catch (throwable: Throwable) { - log(TAG + throwable) - } - } - }) + hookAllMethods(brightnessMirrorControllerClass, "updateIcon", + object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + if (!blackQSHeaderEnabled) return - hookAllMethods(qsIconViewImplClass, "updateIcon", object : XC_MethodHook() { - override fun afterHookedMethod(param: MethodHookParam) { - if (blackQSHeaderEnabled) { try { - if (getIntField(param.args[1], "state") == Tile.STATE_ACTIVE - ) { - (param.args[0] as ImageView) - .setImageTintList(ColorStateList.valueOf(colorText!!)) - } + val mIcon = getObjectField(param.thisObject, "mIcon") as ImageView + mIcon.imageTintList = ColorStateList.valueOf(colorText!!) } catch (throwable: Throwable) { log(TAG + throwable) } } - } - }) + }) - hookAllMethods(qsIconViewImplClass, "setIcon", object : XC_MethodHook() { - override fun beforeHookedMethod(param: MethodHookParam) { - if (blackQSHeaderEnabled) { - try { - if (param.args[0] is ImageView && - getIntField(param.args[1], "state") == Tile.STATE_ACTIVE - ) { - setObjectField(param.thisObject, "mTint", colorText) + hookAllMethods(qsIconViewImplClass, "updateIcon", + object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + if (blackQSHeaderEnabled) { + try { + if (getIntField(param.args[1], "state") == Tile.STATE_ACTIVE + ) { + (param.args[0] as ImageView).imageTintList = + ColorStateList.valueOf(colorText!!) + } + } catch (throwable: Throwable) { + log(TAG + throwable) } - } catch (throwable: Throwable) { - log(TAG + throwable) } } - } - }) - - try { - // White QS Clock bug - hookAllMethods(quickStatusBarHeaderClass, "onFinishInflate", object : XC_MethodHook() { - override fun afterHookedMethod(param: MethodHookParam) { - try { - mClockViewQSHeader = getObjectField(param.thisObject, "mClockView") - } catch (ignored: Throwable) { - } + }) - if (blackQSHeaderEnabled && mClockViewQSHeader != null) { + hookAllMethods(qsIconViewImplClass, "setIcon", + object : XC_MethodHook() { + override fun beforeHookedMethod(param: MethodHookParam) { + if (blackQSHeaderEnabled) { try { - (mClockViewQSHeader as TextView).setTextColor(Color.WHITE) + if (param.args[0] is ImageView && + getIntField(param.args[1], "state") == Tile.STATE_ACTIVE + ) { + setObjectField(param.thisObject, "mTint", colorText) + } } catch (throwable: Throwable) { log(TAG + throwable) } @@ -536,7 +556,29 @@ class QSBlackThemeA14(context: Context?) : ModPack(context!!) { } }) - // White QS Clock bug + try { + // Black QS Clock bug + hookAllMethods( + quickStatusBarHeaderClass, + "onFinishInflate", + object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + try { + mClockViewQSHeader = getObjectField(param.thisObject, "mClockView") + } catch (ignored: Throwable) { + } + + if (blackQSHeaderEnabled && mClockViewQSHeader != null) { + try { + (mClockViewQSHeader as TextView).setTextColor(Color.WHITE) + } catch (throwable: Throwable) { + log(TAG + throwable) + } + } + } + }) + + // Black QS Clock bug hookAllMethods(clockClass, "onColorsChanged", object : XC_MethodHook() { override fun afterHookedMethod(param: MethodHookParam) { if (blackQSHeaderEnabled && mClockViewQSHeader != null) { @@ -558,86 +600,98 @@ class QSBlackThemeA14(context: Context?) : ModPack(context!!) { } }) - hookAllMethods(centralSurfacesImplClass, "updateTheme", object : XC_MethodHook() { - override fun afterHookedMethod(param: MethodHookParam) { - initColors(false) - } - }) + hookAllMethods( + centralSurfacesImplClass, + "updateTheme", + object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + initColors(false) + } + }) } - hookAllConstructors(qsTileViewImplClass, object : XC_MethodHook() { - override fun afterHookedMethod(param: MethodHookParam) { - if (!blackQSHeaderEnabled) return - try { - if (!qsTextAlwaysWhite && !qsTextFollowAccent) { - setObjectField(param.thisObject, "colorLabelActive", colorText) + hookAllConstructors(qsTileViewImplClass, + object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + if (!blackQSHeaderEnabled) return + + try { + if (!qsTextAlwaysWhite && !qsTextFollowAccent) { + setObjectField(param.thisObject, "colorLabelActive", colorText) + setObjectField( + param.thisObject, + "colorSecondaryLabelActive", + colorTextAlpha + ) + } + + setObjectField(param.thisObject, "colorLabelInactive", Color.WHITE) setObjectField( param.thisObject, - "colorSecondaryLabelActive", - colorTextAlpha + "colorSecondaryLabelInactive", + -0x7f000001 ) - } - - setObjectField(param.thisObject, "colorLabelInactive", Color.WHITE) - setObjectField(param.thisObject, "colorSecondaryLabelInactive", -0x7f000001) - val sideView = getObjectField(param.thisObject, "sideView") as ViewGroup + val sideView = getObjectField(param.thisObject, "sideView") as ViewGroup - val customDrawable = sideView.findViewById( - mContext.resources.getIdentifier( - "customDrawable", - "id", - mContext.packageName + val customDrawable = sideView.findViewById( + mContext.resources.getIdentifier( + "customDrawable", + "id", + mContext.packageName + ) ) - ) - customDrawable.setImageTintList(ColorStateList.valueOf(colorText!!)) + customDrawable.imageTintList = ColorStateList.valueOf(colorText!!) - val chevron = sideView.findViewById( - mContext.resources.getIdentifier( - "chevron", - "id", - mContext.packageName + val chevron = sideView.findViewById( + mContext.resources.getIdentifier( + "chevron", + "id", + mContext.packageName + ) ) - ) - chevron.setImageTintList(ColorStateList.valueOf(colorText!!)) - } catch (throwable: Throwable) { - log(TAG + throwable) + chevron.imageTintList = ColorStateList.valueOf(colorText!!) + } catch (throwable: Throwable) { + log(TAG + throwable) + } } - } - }) + }) - hookAllMethods(qsIconViewImplClass, "getIconColorForState", object : XC_MethodHook() { - override fun beforeHookedMethod(param: MethodHookParam) { - val (isDisabledState: Boolean, isActiveState: Boolean) = getTileState(param) + hookAllMethods(qsIconViewImplClass, "getIconColorForState", + object : XC_MethodHook() { + override fun beforeHookedMethod(param: MethodHookParam) { + val (isDisabledState: Boolean, + isActiveState: Boolean) = Utils.getTileState(param) - if (blackQSHeaderEnabled) { - if (isDisabledState) { - param.result = -0x7f000001 - } else if (isActiveState && !qsTextAlwaysWhite && !qsTextFollowAccent) { - param.result = colorText - } else if (!isActiveState) { - param.result = Color.WHITE + if (blackQSHeaderEnabled) { + if (isDisabledState) { + param.result = -0x7f000001 + } else if (isActiveState && !qsTextAlwaysWhite && !qsTextFollowAccent) { + param.result = colorText + } else if (!isActiveState) { + param.result = Color.WHITE + } } } - } - }) + }) try { hookAllMethods(qsIconViewImplClass, "updateIcon", object : XC_MethodHook() { override fun afterHookedMethod(param: MethodHookParam) { if (qsTextAlwaysWhite || qsTextFollowAccent) return - val (isDisabledState: Boolean, isActiveState: Boolean) = getTileState(param) + val (isDisabledState: Boolean, + isActiveState: Boolean) = Utils.getTileState(param) if (blackQSHeaderEnabled) { val mIcon = param.args[0] as ImageView if (isDisabledState) { - mIcon.setImageTintList(ColorStateList.valueOf(-0x7f000001)) + mIcon.imageTintList = ColorStateList.valueOf(-0x7f000001) } else if (isActiveState && !qsTextAlwaysWhite && !qsTextFollowAccent) { - mIcon.setImageTintList(ColorStateList.valueOf(colorText!!)) + mIcon.imageTintList = ColorStateList.valueOf(colorText!!) } else if (!isActiveState) { - mIcon.setImageTintList(ColorStateList.valueOf(Color.WHITE)) + mIcon.imageTintList = ColorStateList.valueOf(Color.WHITE) } } } @@ -646,48 +700,51 @@ class QSBlackThemeA14(context: Context?) : ModPack(context!!) { } try { - hookAllMethods(qsContainerImplClass, "updateResources", object : XC_MethodHook() { - override fun afterHookedMethod(param: MethodHookParam) { - if (!blackQSHeaderEnabled) return - - try { - val res = mContext.resources - val view = (param.thisObject as ViewGroup).findViewById( - res.getIdentifier( - "qs_footer_actions", - "id", - mContext.packageName - ) - ) + hookAllMethods( + qsContainerImplClass, + "updateResources", + object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + if (!blackQSHeaderEnabled) return try { - val pmButtonContainer = view.findViewById( + val res = mContext.resources + val view = (param.thisObject as ViewGroup).findViewById( res.getIdentifier( - "pm_lite", + "qs_footer_actions", "id", mContext.packageName ) ) - (pmButtonContainer.getChildAt(0) as ImageView).setColorFilter( - Color.BLACK, - PorterDuff.Mode.SRC_IN - ) - } catch (ignored: Throwable) { - val pmButton = view.findViewById( - res.getIdentifier( - "pm_lite", - "id", - mContext.packageName + try { + val pmButtonContainer = view.findViewById( + res.getIdentifier( + "pm_lite", + "id", + mContext.packageName + ) + ) + + (pmButtonContainer.getChildAt(0) as ImageView).setColorFilter( + Color.BLACK, + PorterDuff.Mode.SRC_IN + ) + } catch (ignored: Throwable) { + val pmButton = view.findViewById( + res.getIdentifier( + "pm_lite", + "id", + mContext.packageName + ) ) - ) - pmButton.setImageTintList(ColorStateList.valueOf(Color.BLACK)) + pmButton.imageTintList = ColorStateList.valueOf(Color.BLACK) + } + } catch (ignored: Throwable) { } - } catch (ignored: Throwable) { } - } - }) + }) } catch (ignored: Throwable) { } @@ -712,13 +769,22 @@ class QSBlackThemeA14(context: Context?) : ModPack(context!!) { val code = param.args[0] as Int var result = 0 - if (code != PM_LITE_BACKGROUND_CODE) { + if (code == PM_LITE_BACKGROUND_CODE) { + if (colorActive != null) { + result = colorActive!! + } + } else { try { - if (mContext.resources.getResourceName(code).split("/".toRegex()) - .dropLastWhile { it.isEmpty() } - .toTypedArray()[1] == "onShadeInactiveVariant" - ) { - result = Color.WHITE // number button text + when (mContext.resources.getResourceName(code).split("/")[1]) { + "underSurface", "onShadeActive", "shadeInactive" -> { + if (colorInactive != null) { + result = colorInactive!! // button backgrounds + } + } + + "onShadeInactiveVariant" -> { + result = Color.WHITE // "number button" text + } } } catch (ignored: Throwable) { } @@ -737,6 +803,7 @@ class QSBlackThemeA14(context: Context?) : ModPack(context!!) { // Power button val power = getObjectField(param.thisObject, "power") setObjectField(power, "iconTint", Color.BLACK) + setObjectField(power, "backgroundColor", PM_LITE_BACKGROUND_CODE) // Settings button val settings = getObjectField(param.thisObject, "settings") @@ -753,12 +820,20 @@ class QSBlackThemeA14(context: Context?) : ModPack(context!!) { ) try { - val zeroAlphaFlow = - stateFlowImplClass.getConstructor(Any::class.java).newInstance(0f) + val zeroAlphaFlow = stateFlowImplClass + .getConstructor(Any::class.java) + .newInstance(0f) + + val readonlyStateFlowInstance = try { + readonlyStateFlowClass.constructors[0].newInstance(zeroAlphaFlow) + } catch (ignored: Throwable) { + readonlyStateFlowClass.constructors[0].newInstance(zeroAlphaFlow, null) + } + setObjectField( param.thisObject, "backgroundAlpha", - readonlyStateFlowClass.constructors[0].newInstance(zeroAlphaFlow) + readonlyStateFlowInstance ) } catch (throwable: Throwable) { log(TAG + throwable) @@ -784,94 +859,98 @@ class QSBlackThemeA14(context: Context?) : ModPack(context!!) { log(TAG + throwable) } - hookAllMethods(scrimControllerClass, "updateScrims", object : XC_MethodHook() { - override fun afterHookedMethod(param: MethodHookParam) { - if (!blackQSHeaderEnabled) return + hookAllMethods(scrimControllerClass, "updateScrims", + object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + if (!blackQSHeaderEnabled) return - try { - val mScrimBehind = - getObjectField(param.thisObject, "mScrimBehind") - val mBlankScreen = - getObjectField(param.thisObject, "mBlankScreen") as Boolean - val alpha = getFloatField(mScrimBehind, "mViewAlpha") - val animateBehindScrim = alpha != 0f && !mBlankScreen + try { + val mScrimBehind = + getObjectField(param.thisObject, "mScrimBehind") + val mBlankScreen = + getObjectField(param.thisObject, "mBlankScreen") as Boolean + val alpha = getFloatField(mScrimBehind, "mViewAlpha") + val animateBehindScrim = alpha != 0f && !mBlankScreen - callMethod( - mScrimBehind, - "setColors", - mBehindColors, - animateBehindScrim - ) - } catch (throwable: Throwable) { - log(TAG + throwable) + callMethod( + mScrimBehind, + "setColors", + mBehindColors, + animateBehindScrim + ) + } catch (throwable: Throwable) { + log(TAG + throwable) + } } - } - }) + }) - hookAllMethods(scrimControllerClass, "updateThemeColors", object : XC_MethodHook() { - override fun afterHookedMethod(param: MethodHookParam) { - calculateColors() - } - }) + hookAllMethods(scrimControllerClass, "updateThemeColors", + object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + calculateColors() + } + }) - hookAllMethods(scrimControllerClass, "updateThemeColors", object : XC_MethodHook() { - override fun afterHookedMethod(param: MethodHookParam) { - if (!blackQSHeaderEnabled) return + hookAllMethods(scrimControllerClass, "updateThemeColors", + object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + if (!blackQSHeaderEnabled) return - try { - val states: ColorStateList = getColorAttr( - mContext.resources.getIdentifier( - "android:attr/colorBackgroundFloating", - "attr", - mContext.packageName - ), mContext - ) - val surfaceBackground = states.defaultColor - val accentStates: ColorStateList = - getColorAttr( + try { + val states: ColorStateList = getColorAttr( mContext.resources.getIdentifier( - "colorAccent", + "android:attr/colorBackgroundFloating", "attr", - "android" + mContext.packageName ), mContext ) - val accent = accentStates.defaultColor + val surfaceBackground = states.defaultColor + val accentStates: ColorStateList = + getColorAttr( + mContext.resources.getIdentifier( + "colorAccent", + "attr", + "android" + ), mContext + ) + val accent = accentStates.defaultColor - callMethod(mBehindColors, "setMainColor", surfaceBackground) - callMethod(mBehindColors, "setSecondaryColor", accent) + callMethod(mBehindColors, "setMainColor", surfaceBackground) + callMethod(mBehindColors, "setSecondaryColor", accent) - val contrast = ColorUtils.calculateContrast( - callMethod( - mBehindColors, - "getMainColor" - ) as Int, Color.WHITE - ) + val contrast = ColorUtils.calculateContrast( + callMethod( + mBehindColors, + "getMainColor" + ) as Int, Color.WHITE + ) - callMethod(mBehindColors, "setSupportsDarkText", contrast > 4.5) - } catch (throwable: Throwable) { - log(TAG + throwable) + callMethod(mBehindColors, "setSupportsDarkText", contrast > 4.5) + } catch (throwable: Throwable) { + log(TAG + throwable) + } } - } - }) + }) - hookAllMethods(scrimControllerClass, "applyState", object : XC_MethodHook() { - override fun afterHookedMethod(param: MethodHookParam) { - if (!blackQSHeaderEnabled) return + hookAllMethods(scrimControllerClass, "applyState", + object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + if (!blackQSHeaderEnabled) return - try { - val mClipsQsScrim = - getObjectField(param.thisObject, "mClipsQsScrim") as Boolean - if (mClipsQsScrim) { - setObjectField(param.thisObject, "mBehindTint", Color.BLACK) + try { + val mClipsQsScrim = + getObjectField(param.thisObject, "mClipsQsScrim") as Boolean + if (mClipsQsScrim) { + setObjectField(param.thisObject, "mBehindTint", Color.BLACK) + } + } catch (throwable: Throwable) { + log(TAG + throwable) } - } catch (throwable: Throwable) { - log(TAG + throwable) } - } - }) + }) try { - val constants: Array? = scrimStateEnum.getEnumConstants() + val constants: Array? = scrimStateEnum.enumConstants if (constants != null) { for (constant in constants) { when (constant.toString()) { @@ -1025,63 +1104,26 @@ class QSBlackThemeA14(context: Context?) : ModPack(context!!) { log(TAG + throwable) } - hookAllConstructors(fragmentHostManagerClass, object : XC_MethodHook() { - override fun beforeHookedMethod(param: MethodHookParam) { - try { - setObjectField( - param.thisObject, - "mConfigChanges", - interestingConfigChangesClass.getDeclaredConstructor( - Int::class.javaPrimitiveType - ).newInstance(0x40000000 or 0x0004 or 0x0100 or -0x80000000 or 0x0200) - ) - } catch (throwable: Throwable) { - log(TAG + throwable) - } - } - }) - } - - private fun getTileState(param: XC_MethodHook.MethodHookParam): Pair { - val isDisabledState: Boolean = try { - getObjectField( - param.args[1], - "disabledByPolicy" - ) as Boolean || - getObjectField( - param.args[1], - "state" - ) as Int == Tile.STATE_UNAVAILABLE - } catch (throwable: Throwable) { - getObjectField( - param.args[1], - "state" - ) as Int == Tile.STATE_UNAVAILABLE - } - - val isActiveState: Boolean = try { - getObjectField( - param.args[1], - "state" - ) as Int == Tile.STATE_ACTIVE - } catch (throwable: Throwable) { - try { - param.args[1] as Int == Tile.STATE_ACTIVE - } catch (throwable1: Throwable) { - try { - param.args[1] as Boolean - } catch (throwable2: Throwable) { - log(TAG + throwable2) - false + hookAllConstructors(fragmentHostManagerClass, + object : XC_MethodHook() { + override fun beforeHookedMethod(param: MethodHookParam) { + try { + setObjectField( + param.thisObject, + "mConfigChanges", + interestingConfigChangesClass.getDeclaredConstructor( + Int::class.javaPrimitiveType + ).newInstance(0x40000000 or 0x0004 or 0x0100 or -0x80000000 or 0x0200) + ) + } catch (throwable: Throwable) { + log(TAG + throwable) + } } - } - } - - return Pair(isDisabledState, isActiveState) + }) } private fun initColors(force: Boolean) { - val isDark: Boolean = SystemUtil.isDarkMode + val isDark: Boolean = SystemUtils.isDarkMode if (isDark == this.isDark && !force) return this.isDark = isDark @@ -1091,6 +1133,22 @@ class QSBlackThemeA14(context: Context?) : ModPack(context!!) { private fun calculateColors() { try { + colorActive = mContext.resources.getColor( + mContext.resources.getIdentifier( + "android:color/system_accent1_100", + "color", + mContext.packageName + ), mContext.theme + ) + + colorInactive = mContext.resources.getColor( + mContext.resources.getIdentifier( + "android:color/system_neutral2_800", + "color", + mContext.packageName + ), mContext.theme + ) + colorText = mContext.resources.getColor( mContext.resources.getIdentifier( "android:color/system_neutral1_900", @@ -1109,7 +1167,11 @@ class QSBlackThemeA14(context: Context?) : ModPack(context!!) { } } - private fun setHeaderComponentsColor(mView: View, iconManager: Any, batteryIcon: Any) { + private fun setHeaderComponentsColor( + mView: View, + iconManager: Any, + batteryIcon: Any + ) { if (!blackQSHeaderEnabled) return val textColor = Color.WHITE @@ -1137,12 +1199,12 @@ class QSBlackThemeA14(context: Context?) : ModPack(context!!) { try { // A14 ap11 callMethod(iconManager, "setTint", textColor, textColor) - modernShadeCarrierGroupMobileViews.forEach(Consumer { view: Any -> + modernShadeCarrierGroupMobileViews.forEach { view -> setMobileIconTint( view, textColor ) - }) + } setModernSignalTextColor(textColor) } catch (ignored: Throwable) { // A14 older @@ -1150,13 +1212,11 @@ class QSBlackThemeA14(context: Context?) : ModPack(context!!) { } for (i in 1..3) { - val id = String.format("carrier%s", i) - try { (getObjectField( mView.findViewById( mContext.resources.getIdentifier( - id, + "carrier$i", "id", mContext.packageName ) @@ -1166,22 +1226,22 @@ class QSBlackThemeA14(context: Context?) : ModPack(context!!) { (getObjectField( mView.findViewById( mContext.resources.getIdentifier( - id, + "carrier$i", "id", mContext.packageName ) ), "mMobileSignal" - ) as ImageView).setImageTintList(ColorStateList.valueOf(textColor)) + ) as ImageView).imageTintList = ColorStateList.valueOf(textColor) (getObjectField( mView.findViewById( mContext.resources.getIdentifier( - id, + "carrier$i", "id", mContext.packageName ) ), "mMobileRoaming" - ) as ImageView).setImageTintList(ColorStateList.valueOf(textColor)) + ) as ImageView).imageTintList = ColorStateList.valueOf(textColor) } catch (ignored: Throwable) { } } @@ -1201,7 +1261,7 @@ class QSBlackThemeA14(context: Context?) : ModPack(context!!) { ) } - @Suppress("UNCHECKED_CAST") + @Suppress("UNCHECKED_CAST", "SameParameterValue") private fun setModernSignalTextColor(textColor: Int) { val res: Resources = mContext.resources if (shadeCarrierGroupController == null) return diff --git a/app/src/main/java/com/drdisagree/iconify/xposed/modules/themes/QSFluidThemeA13.kt b/app/src/main/java/com/drdisagree/iconify/xposed/modules/themes/QSFluidThemeA13.kt index 5da15e9b9..919d44654 100644 --- a/app/src/main/java/com/drdisagree/iconify/xposed/modules/themes/QSFluidThemeA13.kt +++ b/app/src/main/java/com/drdisagree/iconify/xposed/modules/themes/QSFluidThemeA13.kt @@ -26,13 +26,14 @@ import com.drdisagree.iconify.common.Const.SYSTEMUI_PACKAGE import com.drdisagree.iconify.common.Preferences.FLUID_NOTIF_TRANSPARENCY import com.drdisagree.iconify.common.Preferences.FLUID_POWERMENU_TRANSPARENCY import com.drdisagree.iconify.common.Preferences.FLUID_QSPANEL -import com.drdisagree.iconify.config.XPrefs.Xprefs import com.drdisagree.iconify.xposed.HookRes import com.drdisagree.iconify.xposed.ModPack import com.drdisagree.iconify.xposed.modules.utils.RoundedCornerProgressDrawable import com.drdisagree.iconify.xposed.modules.utils.SettingsLibUtils import com.drdisagree.iconify.xposed.modules.utils.ViewHelper.toPx -import com.drdisagree.iconify.xposed.utils.SystemUtil +import com.drdisagree.iconify.xposed.utils.SystemUtils +import com.drdisagree.iconify.xposed.utils.XPrefs.Xprefs +import com.drdisagree.iconify.xposed.utils.XPrefs.XprefsIsInitialized import de.robv.android.xposed.XC_MethodHook import de.robv.android.xposed.XposedBridge.hookAllConstructors import de.robv.android.xposed.XposedBridge.hookAllMethods @@ -72,16 +73,18 @@ class QSFluidThemeA13(context: Context?) : ModPack(context!!) { ) ) val colorInactiveAlpha = intArrayOf(changeAlpha(colorInactive[0], INACTIVE_ALPHA)) - private var wasDark: Boolean = SystemUtil.isDarkMode + private var wasDark: Boolean = SystemUtils.isDarkMode private var mSlider: SeekBar? = null override fun updatePrefs(vararg key: String) { - if (Xprefs == null) return - - fluidQsThemeEnabled = Xprefs!!.getBoolean(FLUID_QSPANEL, false) - fluidNotifEnabled = fluidQsThemeEnabled && - Xprefs!!.getBoolean(FLUID_NOTIF_TRANSPARENCY, false) - fluidPowerMenuEnabled = fluidQsThemeEnabled && - Xprefs!!.getBoolean(FLUID_POWERMENU_TRANSPARENCY, false) + if (!XprefsIsInitialized) return + + Xprefs.apply { + fluidQsThemeEnabled = getBoolean(FLUID_QSPANEL, false) + fluidNotifEnabled = fluidQsThemeEnabled && + getBoolean(FLUID_NOTIF_TRANSPARENCY, false) + fluidPowerMenuEnabled = fluidQsThemeEnabled && + getBoolean(FLUID_POWERMENU_TRANSPARENCY, false) + } initResources() } @@ -214,8 +217,8 @@ class QSFluidThemeA13(context: Context?) : ModPack(context!!) { if (param.args[0] is ImageView && getIntField(param.args[1], "state") == Tile.STATE_ACTIVE ) { - (param.args[0] as ImageView) - .setImageTintList(ColorStateList.valueOf(colorActive[0])) + (param.args[0] as ImageView).imageTintList = + ColorStateList.valueOf(colorActive[0]) } } catch (ignored: Throwable) { } @@ -312,7 +315,7 @@ class QSFluidThemeA13(context: Context?) : ModPack(context!!) { pmButton.background.alpha = (ACTIVE_ALPHA * 255).toInt() pmButton.background.setTint(colorActive[0]) - pmButton.setImageTintList(ColorStateList.valueOf(colorActive[0])) + pmButton.imageTintList = ColorStateList.valueOf(colorActive[0]) } } catch (ignored: Throwable) { } @@ -360,11 +363,11 @@ class QSFluidThemeA13(context: Context?) : ModPack(context!!) { if (!fluidQsThemeEnabled) return try { - (getObjectField(param.thisObject, "mIcon") as ImageView) - .setImageTintList(ColorStateList.valueOf(colorActive[0])) + (getObjectField(param.thisObject, "mIcon") as ImageView).imageTintList = + ColorStateList.valueOf(colorActive[0]) - (getObjectField(param.thisObject, "mIcon") as ImageView) - .setBackgroundTintList(ColorStateList.valueOf(colorActiveAlpha[0])) + (getObjectField(param.thisObject, "mIcon") as ImageView).backgroundTintList = + ColorStateList.valueOf(colorActiveAlpha[0]) } catch (throwable: Throwable) { log(TAG + throwable) } @@ -377,18 +380,27 @@ class QSFluidThemeA13(context: Context?) : ModPack(context!!) { if (!fluidQsThemeEnabled) return try { - (getObjectField(param.thisObject, "mIcon") as ImageView) - .setImageTintList(ColorStateList.valueOf(colorActive[0])) + (getObjectField(param.thisObject, "mIcon") as ImageView).imageTintList = + ColorStateList.valueOf(colorActive[0]) - (getObjectField(param.thisObject, "mIcon") as ImageView) - .setBackgroundTintList(ColorStateList.valueOf(colorActiveAlpha[0])) + (getObjectField( + param.thisObject, + "mIcon" + ) as ImageView).backgroundTintList = + ColorStateList.valueOf(colorActiveAlpha[0]) } catch (throwable: Throwable) { try { - (getObjectField(param.thisObject, "mIconView") as ImageView) - .setImageTintList(ColorStateList.valueOf(colorActive[0])) - - (getObjectField(param.thisObject, "mIconView") as ImageView) - .setBackgroundTintList(ColorStateList.valueOf(colorActiveAlpha[0])) + (getObjectField( + param.thisObject, + "mIconView" + ) as ImageView).imageTintList = + ColorStateList.valueOf(colorActive[0]) + + (getObjectField( + param.thisObject, + "mIconView" + ) as ImageView).backgroundTintList = + ColorStateList.valueOf(colorActiveAlpha[0]) } catch (ignored: Throwable) { } } @@ -401,11 +413,11 @@ class QSFluidThemeA13(context: Context?) : ModPack(context!!) { if (!fluidQsThemeEnabled) return try { - (getObjectField(param.thisObject, "mIcon") as ImageView) - .setImageTintList(ColorStateList.valueOf(colorActive[0])) + (getObjectField(param.thisObject, "mIcon") as ImageView).imageTintList = + ColorStateList.valueOf(colorActive[0]) - (getObjectField(param.thisObject, "mIcon") as ImageView) - .setBackgroundTintList(ColorStateList.valueOf(colorActiveAlpha[0])) + (getObjectField(param.thisObject, "mIcon") as ImageView).backgroundTintList = + ColorStateList.valueOf(colorActiveAlpha[0]) } catch (throwable: Throwable) { log(TAG + throwable) } @@ -625,7 +637,7 @@ class QSFluidThemeA13(context: Context?) : ModPack(context!!) { val mBackgroundNormal = getObjectField(param.thisObject, "mBackgroundNormal") as View? - mBackgroundNormal?.setAlpha(INACTIVE_ALPHA) + mBackgroundNormal?.alpha = INACTIVE_ALPHA } }) @@ -720,8 +732,8 @@ class QSFluidThemeA13(context: Context?) : ModPack(context!!) { val childCount = parent.childCount for (i in 0 until childCount) { val childView = parent.getChildAt(i) - childView.background.setTint(colorInactive[0]) - childView.background.alpha = (INACTIVE_ALPHA * 255).toInt() + childView.background?.setTint(colorInactive[0]) + childView.background?.alpha = (INACTIVE_ALPHA * 255).toInt() } } } @@ -734,7 +746,7 @@ class QSFluidThemeA13(context: Context?) : ModPack(context!!) { } private fun initResources() { - val isDark: Boolean = SystemUtil.isDarkMode + val isDark: Boolean = SystemUtils.isDarkMode if (isDark != wasDark) { wasDark = isDark @@ -797,8 +809,8 @@ class QSFluidThemeA13(context: Context?) : ModPack(context!!) { } val backgroundShape = ShapeDrawable(RoundRectShape(radiusF, null, null)) - backgroundShape.setIntrinsicHeight(height) - backgroundShape.paint.setColor(changeAlpha(colorInactiveAlpha[0], UNAVAILABLE_ALPHA)) + backgroundShape.intrinsicHeight = height + backgroundShape.paint.color = changeAlpha(colorInactiveAlpha[0], UNAVAILABLE_ALPHA) // Create the progress drawable var progressDrawable: RoundedCornerProgressDrawable? = null @@ -811,20 +823,16 @@ class QSFluidThemeA13(context: Context?) : ModPack(context!!) { } // Create the start and end drawables - val startDrawable = HookRes.modRes?.let { - ResourcesCompat.getDrawable( - it, - R.drawable.ic_brightness_low, - context.theme - ) - } - val endDrawable = HookRes.modRes?.let { - ResourcesCompat.getDrawable( - it, - R.drawable.ic_brightness_full, - context.theme - ) - } + val startDrawable = ResourcesCompat.getDrawable( + HookRes.modRes, + R.drawable.ic_brightness_low, + context.theme + ) + val endDrawable = ResourcesCompat.getDrawable( + HookRes.modRes, + R.drawable.ic_brightness_full, + context.theme + ) if (startDrawable != null && endDrawable != null) { startDrawable.setTint(colorActive[0]) endDrawable.setTint(colorActive[0]) @@ -854,7 +862,7 @@ class QSFluidThemeA13(context: Context?) : ModPack(context!!) { ) ) - rectangleDrawable.setCornerRadius(cornerRadius.toFloat()) + rectangleDrawable.cornerRadius = cornerRadius.toFloat() rectangleDrawable.setColor(colorActive[0]) val layerDrawable = LayerDrawable(arrayOf(rectangleDrawable)) diff --git a/app/src/main/java/com/drdisagree/iconify/xposed/modules/themes/QSFluidThemeA14.kt b/app/src/main/java/com/drdisagree/iconify/xposed/modules/themes/QSFluidThemeA14.kt index a6383a1c8..08b1520a7 100644 --- a/app/src/main/java/com/drdisagree/iconify/xposed/modules/themes/QSFluidThemeA14.kt +++ b/app/src/main/java/com/drdisagree/iconify/xposed/modules/themes/QSFluidThemeA14.kt @@ -26,13 +26,14 @@ import com.drdisagree.iconify.common.Const.SYSTEMUI_PACKAGE import com.drdisagree.iconify.common.Preferences.FLUID_NOTIF_TRANSPARENCY import com.drdisagree.iconify.common.Preferences.FLUID_POWERMENU_TRANSPARENCY import com.drdisagree.iconify.common.Preferences.FLUID_QSPANEL -import com.drdisagree.iconify.config.XPrefs.Xprefs import com.drdisagree.iconify.xposed.HookRes import com.drdisagree.iconify.xposed.ModPack import com.drdisagree.iconify.xposed.modules.utils.RoundedCornerProgressDrawable import com.drdisagree.iconify.xposed.modules.utils.SettingsLibUtils import com.drdisagree.iconify.xposed.modules.utils.ViewHelper.toPx -import com.drdisagree.iconify.xposed.utils.SystemUtil +import com.drdisagree.iconify.xposed.utils.SystemUtils +import com.drdisagree.iconify.xposed.utils.XPrefs.Xprefs +import com.drdisagree.iconify.xposed.utils.XPrefs.XprefsIsInitialized import de.robv.android.xposed.XC_MethodHook import de.robv.android.xposed.XposedBridge.hookAllConstructors import de.robv.android.xposed.XposedBridge.hookAllMethods @@ -49,7 +50,7 @@ import kotlin.math.min @SuppressLint("DiscouragedApi") class QSFluidThemeA14(context: Context?) : ModPack(context!!) { - private var wasDark: Boolean = SystemUtil.isDarkMode + private var wasDark: Boolean = SystemUtils.isDarkMode private var mSlider: SeekBar? = null val colorActive = intArrayOf( mContext.resources.getColor( @@ -78,13 +79,15 @@ class QSFluidThemeA14(context: Context?) : ModPack(context!!) { ) override fun updatePrefs(vararg key: String) { - if (Xprefs == null) return - - fluidQsThemeEnabled = Xprefs!!.getBoolean(FLUID_QSPANEL, false) - fluidNotifEnabled = fluidQsThemeEnabled && - Xprefs!!.getBoolean(FLUID_NOTIF_TRANSPARENCY, false) - fluidPowerMenuEnabled = fluidQsThemeEnabled && - Xprefs!!.getBoolean(FLUID_POWERMENU_TRANSPARENCY, false) + if (!XprefsIsInitialized) return + + Xprefs.apply { + fluidQsThemeEnabled = getBoolean(FLUID_QSPANEL, false) + fluidNotifEnabled = fluidQsThemeEnabled && + getBoolean(FLUID_NOTIF_TRANSPARENCY, false) + fluidPowerMenuEnabled = fluidQsThemeEnabled && + getBoolean(FLUID_POWERMENU_TRANSPARENCY, false) + } initResources() } @@ -229,10 +232,8 @@ class QSFluidThemeA14(context: Context?) : ModPack(context!!) { if (param.args[0] is ImageView && getIntField(param.args[1], "state") == Tile.STATE_ACTIVE ) { - (param.args[0] as ImageView).setImageTintList( - ColorStateList.valueOf( - colorActive[0] - ) + (param.args[0] as ImageView).imageTintList = ColorStateList.valueOf( + colorActive[0] ) } } catch (ignored: Throwable) { @@ -279,12 +280,12 @@ class QSFluidThemeA14(context: Context?) : ModPack(context!!) { // Security footer view.let { it.getChildAt(0)?.apply { - background.setTint(colorInactiveAlpha[0]) - background.alpha = (INACTIVE_ALPHA * 255).toInt() + background?.setTint(colorInactiveAlpha[0]) + background?.alpha = (INACTIVE_ALPHA * 255).toInt() } it.getChildAt(1)?.apply { - background.setTint(colorInactiveAlpha[0]) - background.alpha = (INACTIVE_ALPHA * 255).toInt() + background?.setTint(colorInactiveAlpha[0]) + background?.alpha = (INACTIVE_ALPHA * 255).toInt() } } @@ -332,7 +333,7 @@ class QSFluidThemeA14(context: Context?) : ModPack(context!!) { background.alpha = (ACTIVE_ALPHA * 255).toInt() if (this is ImageView) { - setImageTintList(ColorStateList.valueOf(colorActive[0])) + imageTintList = ColorStateList.valueOf(colorActive[0]) } else if (this is ViewGroup) { (getChildAt(0) as ImageView).setColorFilter( colorActive[0], @@ -374,12 +375,20 @@ class QSFluidThemeA14(context: Context?) : ModPack(context!!) { ) try { - val zeroAlphaFlow = - stateFlowImplClass.getConstructor(Any::class.java).newInstance(0f) + val zeroAlphaFlow = stateFlowImplClass + .getConstructor(Any::class.java) + .newInstance(0f) + + val readonlyStateFlowInstance = try { + readonlyStateFlowClass.constructors[0].newInstance(zeroAlphaFlow) + } catch (ignored: Throwable) { + readonlyStateFlowClass.constructors[0].newInstance(zeroAlphaFlow, null) + } + setObjectField( param.thisObject, "backgroundAlpha", - readonlyStateFlowClass.constructors[0].newInstance(zeroAlphaFlow) + readonlyStateFlowInstance ) } catch (throwable: Throwable) { log(TAG + throwable) @@ -429,8 +438,8 @@ class QSFluidThemeA14(context: Context?) : ModPack(context!!) { mSlider!!.progressDrawable = createBrightnessDrawable(mContext) val progress = mSlider!!.progressDrawable as LayerDrawable - val progressSlider = - progress.findDrawableByLayerId(android.R.id.progress) as DrawableWrapper + val progressSlider = progress + .findDrawableByLayerId(android.R.id.progress) as DrawableWrapper try { val actualProgressSlider = progressSlider.drawable as LayerDrawable? @@ -461,19 +470,15 @@ class QSFluidThemeA14(context: Context?) : ModPack(context!!) { (getObjectField( param.thisObject, "mIcon" - ) as ImageView).setImageTintList( - ColorStateList.valueOf( - colorActive[0] - ) + ) as ImageView).imageTintList = ColorStateList.valueOf( + colorActive[0] ) (getObjectField( param.thisObject, "mIcon" - ) as ImageView).setBackgroundTintList( - ColorStateList.valueOf( - colorActiveAlpha[0] - ) + ) as ImageView).backgroundTintList = ColorStateList.valueOf( + colorActiveAlpha[0] ) } catch (throwable: Throwable) { log(TAG + throwable) @@ -490,38 +495,30 @@ class QSFluidThemeA14(context: Context?) : ModPack(context!!) { (getObjectField( param.thisObject, "mIcon" - ) as ImageView).setImageTintList( - ColorStateList.valueOf( - colorActive[0] - ) + ) as ImageView).imageTintList = ColorStateList.valueOf( + colorActive[0] ) (getObjectField( param.thisObject, "mIcon" - ) as ImageView).setBackgroundTintList( - ColorStateList.valueOf( - colorActiveAlpha[0] - ) + ) as ImageView).backgroundTintList = ColorStateList.valueOf( + colorActiveAlpha[0] ) } catch (throwable: Throwable) { try { (getObjectField( param.thisObject, "mIconView" - ) as ImageView).setImageTintList( - ColorStateList.valueOf( - colorActive[0] - ) + ) as ImageView).imageTintList = ColorStateList.valueOf( + colorActive[0] ) (getObjectField( param.thisObject, "mIconView" - ) as ImageView).setBackgroundTintList( - ColorStateList.valueOf( - colorActiveAlpha[0] - ) + ) as ImageView).backgroundTintList = ColorStateList.valueOf( + colorActiveAlpha[0] ) } catch (ignored: Throwable) { } @@ -541,19 +538,15 @@ class QSFluidThemeA14(context: Context?) : ModPack(context!!) { (getObjectField( param.thisObject, "mIcon" - ) as ImageView).setImageTintList( - ColorStateList.valueOf( - colorActive[0] - ) + ) as ImageView).imageTintList = ColorStateList.valueOf( + colorActive[0] ) (getObjectField( param.thisObject, "mIcon" - ) as ImageView).setBackgroundTintList( - ColorStateList.valueOf( - colorActiveAlpha[0] - ) + ) as ImageView).backgroundTintList = ColorStateList.valueOf( + colorActiveAlpha[0] ) } catch (throwable: Throwable) { log(TAG + throwable) @@ -773,7 +766,7 @@ class QSFluidThemeA14(context: Context?) : ModPack(context!!) { val mBackgroundNormal = getObjectField(param.thisObject, "mBackgroundNormal") as View? - mBackgroundNormal?.setAlpha(INACTIVE_ALPHA) + mBackgroundNormal?.alpha = INACTIVE_ALPHA } }) @@ -804,8 +797,11 @@ class QSFluidThemeA14(context: Context?) : ModPack(context!!) { if (!fluidQsThemeEnabled || !fluidNotifEnabled) return try { - val mManageButton = - getObjectField(param.thisObject, "mManageButton") as Button + val mManageButton: Button = try { + getObjectField(param.thisObject, "mManageButton") + } catch (ignored: Throwable) { + getObjectField(param.thisObject, "mManageOrHistoryButton") + } as Button val mClearAllButton: Button = try { getObjectField(param.thisObject, "mClearAllButton") } catch (ignored: Throwable) { @@ -814,7 +810,8 @@ class QSFluidThemeA14(context: Context?) : ModPack(context!!) { mManageButton.background?.alpha = (INACTIVE_ALPHA * 255).toInt() mClearAllButton.background?.alpha = (INACTIVE_ALPHA * 255).toInt() - } catch (ignored: Throwable) { + } catch (throwable: Throwable) { + log(TAG + throwable) } } } @@ -826,9 +823,15 @@ class QSFluidThemeA14(context: Context?) : ModPack(context!!) { } catch (ignored: Throwable) { } - try { - hookAllMethods(footerViewClass, "updateColors$3", updateNotificationFooterButtons) - } catch (ignored: Throwable) { + for (i in 1..3) { + try { + hookAllMethods( + footerViewClass, + "updateColors$${i}", + updateNotificationFooterButtons + ) + } catch (ignored: Throwable) { + } } // Power menu @@ -870,7 +873,7 @@ class QSFluidThemeA14(context: Context?) : ModPack(context!!) { } private fun initResources() { - val isDark: Boolean = SystemUtil.isDarkMode + val isDark: Boolean = SystemUtils.isDarkMode if (isDark != wasDark) { wasDark = isDark @@ -933,34 +936,32 @@ class QSFluidThemeA14(context: Context?) : ModPack(context!!) { } val backgroundShape = ShapeDrawable(RoundRectShape(radiusF, null, null)) - backgroundShape.setIntrinsicHeight(height) - backgroundShape.paint.setColor(changeAlpha(colorInactiveAlpha[0], UNAVAILABLE_ALPHA)) + backgroundShape.intrinsicHeight = height + backgroundShape.paint.color = changeAlpha(colorInactiveAlpha[0], INACTIVE_ALPHA) + backgroundShape.setTint(colorInactiveAlpha[0]) // Create the progress drawable var progressDrawable: RoundedCornerProgressDrawable? = null try { - progressDrawable = - RoundedCornerProgressDrawable(createBrightnessForegroundDrawable(context)) + progressDrawable = RoundedCornerProgressDrawable( + createBrightnessForegroundDrawable(context) + ) progressDrawable.alpha = (ACTIVE_ALPHA * 255).toInt() progressDrawable.setTint(colorActive[0]) } catch (ignored: Throwable) { } // Create the start and end drawables - val startDrawable = HookRes.modRes?.let { - ResourcesCompat.getDrawable( - it, - R.drawable.ic_brightness_low, - context.theme - ) - } - val endDrawable = HookRes.modRes?.let { - ResourcesCompat.getDrawable( - it, - R.drawable.ic_brightness_full, - context.theme - ) - } + val startDrawable = ResourcesCompat.getDrawable( + HookRes.modRes, + R.drawable.ic_brightness_low, + context.theme + ) + val endDrawable = ResourcesCompat.getDrawable( + HookRes.modRes, + R.drawable.ic_brightness_full, + context.theme + ) if (startDrawable != null && endDrawable != null) { startDrawable.setTint(colorActive[0]) @@ -991,7 +992,7 @@ class QSFluidThemeA14(context: Context?) : ModPack(context!!) { ) ) - rectangleDrawable.setCornerRadius(cornerRadius.toFloat()) + rectangleDrawable.cornerRadius = cornerRadius.toFloat() rectangleDrawable.setColor(colorActive[0]) val layerDrawable = LayerDrawable(arrayOf(rectangleDrawable)) diff --git a/app/src/main/java/com/drdisagree/iconify/xposed/modules/themes/QSLightThemeA12.kt b/app/src/main/java/com/drdisagree/iconify/xposed/modules/themes/QSLightThemeA12.kt index 8aead579d..c1e54c9d1 100644 --- a/app/src/main/java/com/drdisagree/iconify/xposed/modules/themes/QSLightThemeA12.kt +++ b/app/src/main/java/com/drdisagree/iconify/xposed/modules/themes/QSLightThemeA12.kt @@ -8,11 +8,10 @@ import androidx.core.graphics.ColorUtils import com.drdisagree.iconify.common.Const.SYSTEMUI_PACKAGE import com.drdisagree.iconify.common.Preferences.DUALTONE_QSPANEL import com.drdisagree.iconify.common.Preferences.LIGHT_QSPANEL -import com.drdisagree.iconify.config.XPrefs.Xprefs import com.drdisagree.iconify.xposed.ModPack -import com.drdisagree.iconify.xposed.modules.utils.Helpers.disableOverlays -import com.drdisagree.iconify.xposed.modules.utils.Helpers.enableOverlay -import com.drdisagree.iconify.xposed.utils.SystemUtil +import com.drdisagree.iconify.xposed.utils.SystemUtils +import com.drdisagree.iconify.xposed.utils.XPrefs.Xprefs +import com.drdisagree.iconify.xposed.utils.XPrefs.XprefsIsInitialized import de.robv.android.xposed.XC_MethodHook import de.robv.android.xposed.XposedBridge.hookAllConstructors import de.robv.android.xposed.XposedBridge.hookAllMethods @@ -37,17 +36,24 @@ class QSLightThemeA12(context: Context?) : ModPack(context!!) { private val qsDualToneOverlay = "IconifyComponentQSDT.overlay" init { - isDark = SystemUtil.isDarkMode + isDark = SystemUtils.isDarkMode } override fun updatePrefs(vararg key: String) { - if (Xprefs == null) return + if (!XprefsIsInitialized) return - lightQSHeaderEnabled = Xprefs!!.getBoolean(LIGHT_QSPANEL, false) - dualToneQSEnabled = lightQSHeaderEnabled && - Xprefs!!.getBoolean(DUALTONE_QSPANEL, false) + Xprefs.apply { + lightQSHeaderEnabled = getBoolean(LIGHT_QSPANEL, false) + dualToneQSEnabled = lightQSHeaderEnabled && getBoolean(DUALTONE_QSPANEL, false) + } - applyOverlays(true) + if (key.isNotEmpty()) { + key[0].let { + if (it == LIGHT_QSPANEL || it == DUALTONE_QSPANEL) { + applyOverlays(true) + } + } + } } override fun handleLoadPackage(loadPackageParam: LoadPackageParam) { @@ -205,7 +211,7 @@ class QSLightThemeA12(context: Context?) : ModPack(context!!) { "$SYSTEMUI_PACKAGE.statusbar.phone.ScrimState", loadPackageParam.classLoader ) - val constants: Array? = scrimStateEnum.getEnumConstants() + val constants: Array? = scrimStateEnum.enumConstants if (constants != null) { for (constant in constants) { @@ -358,27 +364,27 @@ class QSLightThemeA12(context: Context?) : ModPack(context!!) { }) } + @Suppress("SameParameterValue") private fun applyOverlays(force: Boolean) { - val isCurrentlyDark: Boolean = SystemUtil.isDarkMode + val isCurrentlyDark: Boolean = SystemUtils.isDarkMode if (isCurrentlyDark == isDark && !force) return isDark = isCurrentlyDark - disableOverlays(qsLightThemeOverlay, qsDualToneOverlay) + Utils.disableOverlays(qsLightThemeOverlay, qsDualToneOverlay) try { Thread.sleep(50) } catch (ignored: Throwable) { } - if (lightQSHeaderEnabled) { - if (!isCurrentlyDark) enableOverlay(qsLightThemeOverlay) - if (dualToneQSEnabled) enableOverlay(qsDualToneOverlay) + if (lightQSHeaderEnabled && !isCurrentlyDark) { + Utils.enableOverlay(qsLightThemeOverlay) + if (dualToneQSEnabled) Utils.enableOverlay(qsDualToneOverlay) } } companion object { - const val STATE_ACTIVE = 2 private val TAG = "Iconify - ${QSLightThemeA12::class.java.simpleName}: " private var lightQSHeaderEnabled = false private var dualToneQSEnabled = false diff --git a/app/src/main/java/com/drdisagree/iconify/xposed/modules/themes/QSLightThemeA13.kt b/app/src/main/java/com/drdisagree/iconify/xposed/modules/themes/QSLightThemeA13.kt index 77ee8f062..e14fa04c3 100644 --- a/app/src/main/java/com/drdisagree/iconify/xposed/modules/themes/QSLightThemeA13.kt +++ b/app/src/main/java/com/drdisagree/iconify/xposed/modules/themes/QSLightThemeA13.kt @@ -16,13 +16,12 @@ import com.drdisagree.iconify.common.Preferences.DUALTONE_QSPANEL import com.drdisagree.iconify.common.Preferences.LIGHT_QSPANEL import com.drdisagree.iconify.common.Preferences.QS_TEXT_ALWAYS_WHITE import com.drdisagree.iconify.common.Preferences.QS_TEXT_FOLLOW_ACCENT -import com.drdisagree.iconify.config.XPrefs.Xprefs import com.drdisagree.iconify.xposed.ModPack -import com.drdisagree.iconify.xposed.modules.utils.Helpers.disableOverlays -import com.drdisagree.iconify.xposed.modules.utils.Helpers.enableOverlay import com.drdisagree.iconify.xposed.modules.utils.SettingsLibUtils.Companion.getColorAttr import com.drdisagree.iconify.xposed.modules.utils.SettingsLibUtils.Companion.getColorAttrDefaultColor -import com.drdisagree.iconify.xposed.utils.SystemUtil +import com.drdisagree.iconify.xposed.utils.SystemUtils +import com.drdisagree.iconify.xposed.utils.XPrefs.Xprefs +import com.drdisagree.iconify.xposed.utils.XPrefs.XprefsIsInitialized import de.robv.android.xposed.XC_MethodHook import de.robv.android.xposed.XposedBridge.hookAllConstructors import de.robv.android.xposed.XposedBridge.hookAllMethods @@ -52,19 +51,26 @@ class QSLightThemeA13(context: Context?) : ModPack(context!!) { private val qsDualToneOverlay = "IconifyComponentQSDT.overlay" init { - isDark = SystemUtil.isDarkMode + isDark = SystemUtils.isDarkMode } override fun updatePrefs(vararg key: String) { - if (Xprefs == null) return + if (!XprefsIsInitialized) return - lightQSHeaderEnabled = Xprefs!!.getBoolean(LIGHT_QSPANEL, false) - dualToneQSEnabled = lightQSHeaderEnabled && - Xprefs!!.getBoolean(DUALTONE_QSPANEL, false) - qsTextAlwaysWhite = Xprefs!!.getBoolean(QS_TEXT_ALWAYS_WHITE, false) - qsTextFollowAccent = Xprefs!!.getBoolean(QS_TEXT_FOLLOW_ACCENT, false) + Xprefs.apply { + lightQSHeaderEnabled = getBoolean(LIGHT_QSPANEL, false) + dualToneQSEnabled = lightQSHeaderEnabled && getBoolean(DUALTONE_QSPANEL, false) + qsTextAlwaysWhite = getBoolean(QS_TEXT_ALWAYS_WHITE, false) + qsTextFollowAccent = getBoolean(QS_TEXT_FOLLOW_ACCENT, false) + } - applyOverlays(true) + if (key.isNotEmpty()) { + key[0].let { + if (it == LIGHT_QSPANEL || it == DUALTONE_QSPANEL) { + applyOverlays(true) + } + } + } } override fun handleLoadPackage(loadPackageParam: LoadPackageParam) { @@ -148,7 +154,7 @@ class QSLightThemeA13(context: Context?) : ModPack(context!!) { } catch (ignored: Throwable) { } - unlockedScrimState = scrimStateEnum.getEnumConstants()?.let { + unlockedScrimState = scrimStateEnum.enumConstants?.let { Arrays.stream(it) .filter { c: Any -> c.toString() == "UNLOCKED" } .findFirst().get() @@ -298,14 +304,29 @@ class QSLightThemeA13(context: Context?) : ModPack(context!!) { "configurationControllerListener" ) - hookAllMethods( - configurationControllerListener.javaClass, + val applyComponentColors = object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + setHeaderComponentsColor(mView, iconManager, batteryIcon) + } + } + + val methods = listOf( "onConfigChanged", - object : XC_MethodHook() { - override fun afterHookedMethod(param: MethodHookParam) { - setHeaderComponentsColor(mView, iconManager, batteryIcon) - } - }) + "onDensityOrFontScaleChanged", + "onUiModeChanged", + "onThemeChanged" + ) + + for (method in methods) { + try { + hookAllMethods( + configurationControllerListener.javaClass, + method, + applyComponentColors + ) + } catch (ignored: Throwable) { + } + } setHeaderComponentsColor(mView, iconManager, batteryIcon) } catch (throwable: Throwable) { @@ -338,7 +359,7 @@ class QSLightThemeA13(context: Context?) : ModPack(context!!) { mContext.packageName ) ) - settingsIcon.setImageTintList(ColorStateList.valueOf(Color.BLACK)) + settingsIcon.imageTintList = ColorStateList.valueOf(Color.BLACK) val pmButtonContainer = view.findViewById( res.getIdentifier( @@ -355,7 +376,7 @@ class QSLightThemeA13(context: Context?) : ModPack(context!!) { mContext.packageName ) ) - pmIcon.setImageTintList(ColorStateList.valueOf(Color.WHITE)) + pmIcon.imageTintList = ColorStateList.valueOf(Color.WHITE) } catch (throwable: Throwable) { log(TAG + throwable) } @@ -367,11 +388,11 @@ class QSLightThemeA13(context: Context?) : ModPack(context!!) { hookAllMethods(qsIconViewImplClass, "updateIcon", object : XC_MethodHook() { override fun afterHookedMethod(param: MethodHookParam) { if (lightQSHeaderEnabled && !isDark && - getIntField(param.args[1], "state") == STATE_ACTIVE + getIntField(param.args[1], "state") == Tile.STATE_ACTIVE ) { try { - (param.args[0] as ImageView) - .setImageTintList(ColorStateList.valueOf(colorInactive!!)) + (param.args[0] as ImageView).imageTintList = + ColorStateList.valueOf(colorInactive!!) } catch (throwable: Throwable) { log(TAG + throwable) } @@ -384,7 +405,7 @@ class QSLightThemeA13(context: Context?) : ModPack(context!!) { if (lightQSHeaderEnabled && !isDark) { try { if (param.args[0] is ImageView && - getIntField(param.args[1], "state") == STATE_ACTIVE + getIntField(param.args[1], "state") == Tile.STATE_ACTIVE ) { setObjectField(param.thisObject, "mTint", colorInactive) } @@ -428,7 +449,8 @@ class QSLightThemeA13(context: Context?) : ModPack(context!!) { }) hookAllMethods(qsIconViewImplClass, "getIconColorForState", object : XC_MethodHook() { override fun beforeHookedMethod(param: MethodHookParam) { - val (isDisabledState: Boolean, isActiveState: Boolean) = getTileState(param) + val (isDisabledState: Boolean, + isActiveState: Boolean) = Utils.getTileState(param) if (!isDark && lightQSHeaderEnabled) { if (isDisabledState) { @@ -446,7 +468,8 @@ class QSLightThemeA13(context: Context?) : ModPack(context!!) { try { hookAllMethods(qsIconViewImplClass, "updateIcon", object : XC_MethodHook() { override fun afterHookedMethod(param: MethodHookParam) { - val (isDisabledState: Boolean, isActiveState: Boolean) = getTileState(param) + val (isDisabledState: Boolean, + isActiveState: Boolean) = Utils.getTileState(param) if (!isDark && lightQSHeaderEnabled) { val mIcon = param.args[0] as ImageView @@ -455,9 +478,9 @@ class QSLightThemeA13(context: Context?) : ModPack(context!!) { param.result = -0x80000000 } else { if (isActiveState && !qsTextAlwaysWhite && !qsTextFollowAccent) { - mIcon.setImageTintList(ColorStateList.valueOf(Color.WHITE)) + mIcon.imageTintList = ColorStateList.valueOf(Color.WHITE) } else if (!isActiveState) { - mIcon.setImageTintList(ColorStateList.valueOf(Color.BLACK)) + mIcon.imageTintList = ColorStateList.valueOf(Color.BLACK) } } } @@ -555,7 +578,7 @@ class QSLightThemeA13(context: Context?) : ModPack(context!!) { }) try { - val constants: Array? = scrimStateEnum.getEnumConstants() + val constants: Array? = scrimStateEnum.enumConstants if (constants != null) { for (constant in constants) { when (constant.toString()) { @@ -730,60 +753,24 @@ class QSLightThemeA13(context: Context?) : ModPack(context!!) { }) } - private fun getTileState(param: XC_MethodHook.MethodHookParam): Pair { - val isDisabledState: Boolean = try { - getObjectField( - param.args[1], - "disabledByPolicy" - ) as Boolean || - getObjectField( - param.args[1], - "state" - ) as Int == Tile.STATE_UNAVAILABLE - } catch (throwable: Throwable) { - getObjectField( - param.args[1], - "state" - ) as Int == Tile.STATE_UNAVAILABLE - } - - val isActiveState: Boolean = try { - getObjectField( - param.args[1], - "state" - ) as Int == STATE_ACTIVE - } catch (throwable: Throwable) { - try { - param.args[1] as Int == STATE_ACTIVE - } catch (throwable1: Throwable) { - try { - param.args[1] as Boolean - } catch (throwable2: Throwable) { - false - } - } - } - - return Pair(isDisabledState, isActiveState) - } - private fun applyOverlays(force: Boolean) { - val isCurrentlyDark: Boolean = SystemUtil.isDarkMode + val isCurrentlyDark: Boolean = SystemUtils.isDarkMode if (isCurrentlyDark == isDark && !force) return isDark = isCurrentlyDark calculateColors() - disableOverlays(qsLightThemeOverlay, qsDualToneOverlay) + + Utils.disableOverlays(qsLightThemeOverlay, qsDualToneOverlay) try { Thread.sleep(50) } catch (ignored: Throwable) { } - if (lightQSHeaderEnabled) { - if (!isCurrentlyDark) enableOverlay(qsLightThemeOverlay) - if (dualToneQSEnabled) enableOverlay(qsDualToneOverlay) + if (lightQSHeaderEnabled && !isCurrentlyDark) { + Utils.enableOverlay(qsLightThemeOverlay) + if (dualToneQSEnabled) Utils.enableOverlay(qsDualToneOverlay) } } @@ -867,7 +854,7 @@ class QSLightThemeA13(context: Context?) : ModPack(context!!) { mContext.packageName ) ), "mMobileSignal" - ) as ImageView).setImageTintList(ColorStateList.valueOf(textColorPrimary)) + ) as ImageView).imageTintList = ColorStateList.valueOf(textColorPrimary) (getObjectField( mView.findViewById( @@ -877,7 +864,7 @@ class QSLightThemeA13(context: Context?) : ModPack(context!!) { mContext.packageName ) ), "mMobileRoaming" - ) as ImageView).setImageTintList(ColorStateList.valueOf(textColorPrimary)) + ) as ImageView).imageTintList = ColorStateList.valueOf(textColorPrimary) } catch (ignored: Throwable) { } } @@ -895,7 +882,6 @@ class QSLightThemeA13(context: Context?) : ModPack(context!!) { } companion object { - const val STATE_ACTIVE = 2 private val TAG = "Iconify - ${QSLightThemeA13::class.java.simpleName}: " private var lightQSHeaderEnabled = false private var dualToneQSEnabled = false diff --git a/app/src/main/java/com/drdisagree/iconify/xposed/modules/themes/QSLightThemeA14.kt b/app/src/main/java/com/drdisagree/iconify/xposed/modules/themes/QSLightThemeA14.kt index 6800a0e8a..e48214795 100644 --- a/app/src/main/java/com/drdisagree/iconify/xposed/modules/themes/QSLightThemeA14.kt +++ b/app/src/main/java/com/drdisagree/iconify/xposed/modules/themes/QSLightThemeA14.kt @@ -18,13 +18,13 @@ import com.drdisagree.iconify.common.Preferences.DUALTONE_QSPANEL import com.drdisagree.iconify.common.Preferences.LIGHT_QSPANEL import com.drdisagree.iconify.common.Preferences.QS_TEXT_ALWAYS_WHITE import com.drdisagree.iconify.common.Preferences.QS_TEXT_FOLLOW_ACCENT -import com.drdisagree.iconify.config.XPrefs.Xprefs import com.drdisagree.iconify.xposed.ModPack -import com.drdisagree.iconify.xposed.modules.utils.Helpers.disableOverlays -import com.drdisagree.iconify.xposed.modules.utils.Helpers.enableOverlay +import com.drdisagree.iconify.xposed.modules.utils.Helpers.findClassInArray import com.drdisagree.iconify.xposed.modules.utils.SettingsLibUtils.Companion.getColorAttr import com.drdisagree.iconify.xposed.modules.utils.SettingsLibUtils.Companion.getColorAttrDefaultColor -import com.drdisagree.iconify.xposed.utils.SystemUtil +import com.drdisagree.iconify.xposed.utils.SystemUtils +import com.drdisagree.iconify.xposed.utils.XPrefs.Xprefs +import com.drdisagree.iconify.xposed.utils.XPrefs.XprefsIsInitialized import de.robv.android.xposed.XC_MethodHook import de.robv.android.xposed.XposedBridge.hookAllConstructors import de.robv.android.xposed.XposedBridge.hookAllMethods @@ -58,19 +58,26 @@ class QSLightThemeA14(context: Context?) : ModPack(context!!) { private val qsDualToneOverlay = "IconifyComponentQSDT.overlay" init { - isDark = SystemUtil.isDarkMode + isDark = SystemUtils.isDarkMode } override fun updatePrefs(vararg key: String) { - if (Xprefs == null) return + if (!XprefsIsInitialized) return - lightQSHeaderEnabled = Xprefs!!.getBoolean(LIGHT_QSPANEL, false) - dualToneQSEnabled = lightQSHeaderEnabled && - Xprefs!!.getBoolean(DUALTONE_QSPANEL, false) - qsTextAlwaysWhite = Xprefs!!.getBoolean(QS_TEXT_ALWAYS_WHITE, false) - qsTextFollowAccent = Xprefs!!.getBoolean(QS_TEXT_FOLLOW_ACCENT, false) + Xprefs.apply { + lightQSHeaderEnabled = getBoolean(LIGHT_QSPANEL, false) + dualToneQSEnabled = lightQSHeaderEnabled && getBoolean(DUALTONE_QSPANEL, false) + qsTextAlwaysWhite = getBoolean(QS_TEXT_ALWAYS_WHITE, false) + qsTextFollowAccent = getBoolean(QS_TEXT_FOLLOW_ACCENT, false) + } - applyOverlays(true) + if (key.isNotEmpty()) { + key[0].let { + if (it == LIGHT_QSPANEL || it == DUALTONE_QSPANEL) { + applyOverlays(true) + } + } + } } override fun handleLoadPackage(loadPackageParam: LoadPackageParam) { @@ -166,44 +173,39 @@ class QSLightThemeA14(context: Context?) : ModPack(context!!) { "$SYSTEMUI_PACKAGE.qs.footer.ui.binder.FooterActionsViewBinder", loadPackageParam.classLoader ) - var shadeHeaderControllerClass = findClassIfExists( + val shadeHeaderControllerClass = findClassInArray( + loadPackageParam.classLoader, "$SYSTEMUI_PACKAGE.shade.ShadeHeaderController", - loadPackageParam.classLoader + "$SYSTEMUI_PACKAGE.shade.LargeScreenShadeHeaderController", ) - if (shadeHeaderControllerClass == null) { - shadeHeaderControllerClass = findClass( - "$SYSTEMUI_PACKAGE.shade.LargeScreenShadeHeaderController", - loadPackageParam.classLoader - ) - } // Background color of android 14's charging chip. Fix for light QS theme situation val batteryStatusChipColorHook: XC_MethodHook = object : XC_MethodHook() { override fun afterHookedMethod(param: MethodHookParam) { - if (lightQSHeaderEnabled && !isDark) { - (getObjectField(param.thisObject, "roundedContainer") as LinearLayout) - .background.setTint(colorInactive!!) + if (isDark || !lightQSHeaderEnabled) return - val colorPrimary: Int = - getColorAttrDefaultColor(mContext, android.R.attr.textColorPrimaryInverse) - val textColorSecondary: Int = - getColorAttrDefaultColor(mContext, android.R.attr.textColorSecondaryInverse) + (getObjectField(param.thisObject, "roundedContainer") as LinearLayout) + .background.setTint(colorInactive!!) - callMethod( - getObjectField(param.thisObject, "batteryMeterView"), - "updateColors", - colorPrimary, - textColorSecondary, - colorPrimary - ) - } + val colorPrimary: Int = + getColorAttrDefaultColor(mContext, android.R.attr.textColorPrimaryInverse) + val textColorSecondary: Int = + getColorAttrDefaultColor(mContext, android.R.attr.textColorSecondaryInverse) + + callMethod( + getObjectField(param.thisObject, "batteryMeterView"), + "updateColors", + colorPrimary, + textColorSecondary, + colorPrimary + ) } } hookAllConstructors(batteryStatusChipClass, batteryStatusChipColorHook) hookAllMethods(batteryStatusChipClass, "onConfigurationChanged", batteryStatusChipColorHook) - unlockedScrimState = scrimStateEnum.getEnumConstants()?.let { + unlockedScrimState = scrimStateEnum.enumConstants?.let { Arrays.stream(it) .filter { c: Any -> c.toString() == "UNLOCKED" } .findFirst().get() @@ -234,15 +236,29 @@ class QSLightThemeA14(context: Context?) : ModPack(context!!) { "configurationControllerListener" ) - hookAllMethods( - configurationControllerListener.javaClass, + val applyComponentColors = object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { + setHeaderComponentsColor(mView, iconManager, batteryIcon) + } + } + + val methods = listOf( "onConfigChanged", - object : XC_MethodHook() { - @Throws(Throwable::class) - override fun afterHookedMethod(param: MethodHookParam) { - setHeaderComponentsColor(mView, iconManager, batteryIcon) - } - }) + "onDensityOrFontScaleChanged", + "onUiModeChanged", + "onThemeChanged" + ) + + for (method in methods) { + try { + hookAllMethods( + configurationControllerListener.javaClass, + method, + applyComponentColors + ) + } catch (ignored: Throwable) { + } + } setHeaderComponentsColor(mView, iconManager, batteryIcon) } catch (throwable: Throwable) { @@ -269,7 +285,7 @@ class QSLightThemeA14(context: Context?) : ModPack(context!!) { hookAllMethods(mobileIconBinderClass, "bind", object : XC_MethodHook() { override fun afterHookedMethod(param: MethodHookParam) { - if (param.args[1].javaClass.getName() + if (param.args[1].javaClass.name .contains("ShadeCarrierGroupMobileIconViewModel") ) { modernShadeCarrierGroupMobileViews.add(param.result) @@ -291,58 +307,62 @@ class QSLightThemeA14(context: Context?) : ModPack(context!!) { override fun afterHookedMethod(param: MethodHookParam) { if (isDark || !lightQSHeaderEnabled) return - val view = (param.thisObject as ViewGroup).findViewById( - mContext.resources.getIdentifier( - "qs_footer_actions", - "id", - mContext.packageName - ) - ).also { - it.background?.setTint(Color.TRANSPARENT) - it.elevation = 0f - } - - // Settings button - view.findViewById( - mContext.resources.getIdentifier( - "settings_button_container", - "id", - mContext.packageName - ) - ).findViewById( - mContext.resources.getIdentifier( - "icon", - "id", - mContext.packageName - ) - ).setImageTintList(ColorStateList.valueOf(Color.BLACK)) - - // Power menu button try { - view.findViewById( + val view = (param.thisObject as ViewGroup).findViewById( mContext.resources.getIdentifier( - "pm_lite", + "qs_footer_actions", "id", mContext.packageName ) - ) - } catch (ignored: ClassCastException) { - view.findViewById( + ).also { + it.background?.setTint(Color.TRANSPARENT) + it.elevation = 0f + } + + // Settings button + view.findViewById( mContext.resources.getIdentifier( - "pm_lite", + "settings_button_container", "id", mContext.packageName ) - ) - }?.apply { - if (this is ImageView) { - setImageTintList(ColorStateList.valueOf(Color.WHITE)) - } else if (this is ViewGroup) { - (getChildAt(0) as ImageView).setColorFilter( - Color.WHITE, - PorterDuff.Mode.SRC_IN + ).findViewById( + mContext.resources.getIdentifier( + "icon", + "id", + mContext.packageName + ) + ).imageTintList = ColorStateList.valueOf(Color.BLACK) + + // Power menu button + try { + view.findViewById( + mContext.resources.getIdentifier( + "pm_lite", + "id", + mContext.packageName + ) + ) + } catch (ignored: ClassCastException) { + view.findViewById( + mContext.resources.getIdentifier( + "pm_lite", + "id", + mContext.packageName + ) ) + }?.apply { + if (this is ImageView) { + imageTintList = ColorStateList.valueOf(Color.WHITE) + } else if (this is ViewGroup) { + (getChildAt(0) as ImageView).setColorFilter( + Color.WHITE, + PorterDuff.Mode.SRC_IN + ) + } } + } catch (ignored: Throwable) { + // it will fail on compose implementation } } }) @@ -350,12 +370,12 @@ class QSLightThemeA14(context: Context?) : ModPack(context!!) { // QS Customize panel hookAllConstructors(qsCustomizerClass, object : XC_MethodHook() { override fun afterHookedMethod(param: MethodHookParam) { - if (!isDark && lightQSHeaderEnabled) { - val mainView = param.thisObject as ViewGroup + if (isDark || !lightQSHeaderEnabled) return - for (i in 0 until mainView.childCount) { - mainView.getChildAt(i).setBackgroundColor(mScrimBehindTint) - } + val mainView = param.thisObject as ViewGroup + + for (i in 0 until mainView.childCount) { + mainView.getChildAt(i).setBackgroundColor(mScrimBehindTint) } } }) @@ -365,40 +385,40 @@ class QSLightThemeA14(context: Context?) : ModPack(context!!) { override fun afterHookedMethod(param: MethodHookParam) { if (isDark || !lightQSHeaderEnabled) return - (getObjectField(param.thisObject, "mMobileSignal") as ImageView) - .setImageTintList(ColorStateList.valueOf(Color.BLACK)) + (getObjectField(param.thisObject, "mMobileSignal") as ImageView).imageTintList = + ColorStateList.valueOf(Color.BLACK) } }) // QS security footer count circle hookAllConstructors(numberButtonViewHolderClass, object : XC_MethodHook() { override fun afterHookedMethod(param: MethodHookParam) { - if (!isDark && lightQSHeaderEnabled) { - (getObjectField(param.thisObject, "newDot") as ImageView) - .setColorFilter(Color.BLACK) + if (isDark || !lightQSHeaderEnabled) return - (getObjectField(param.thisObject, "number") as TextView) - .setTextColor(Color.BLACK) - } + (getObjectField(param.thisObject, "newDot") as ImageView) + .setColorFilter(Color.BLACK) + + (getObjectField(param.thisObject, "number") as TextView) + .setTextColor(Color.BLACK) } }) // QS security footer hookAllConstructors(textButtonViewHolderClass, object : XC_MethodHook() { override fun afterHookedMethod(param: MethodHookParam) { - if (!isDark && lightQSHeaderEnabled) { - (getObjectField(param.thisObject, "chevron") as ImageView) - .setColorFilter(Color.BLACK) + if (isDark || !lightQSHeaderEnabled) return - (getObjectField(param.thisObject, "icon") as ImageView) - .setColorFilter(Color.BLACK) + (getObjectField(param.thisObject, "chevron") as ImageView) + .setColorFilter(Color.BLACK) - (getObjectField(param.thisObject, "newDot") as ImageView) - .setColorFilter(Color.BLACK) + (getObjectField(param.thisObject, "icon") as ImageView) + .setColorFilter(Color.BLACK) - (getObjectField(param.thisObject, "text") as TextView) - .setTextColor(Color.BLACK) - } + (getObjectField(param.thisObject, "newDot") as ImageView) + .setColorFilter(Color.BLACK) + + (getObjectField(param.thisObject, "text") as TextView) + .setTextColor(Color.BLACK) } }) @@ -406,27 +426,27 @@ class QSLightThemeA14(context: Context?) : ModPack(context!!) { hookAllMethods(qsFooterViewClass, "onFinishInflate", object : XC_MethodHook() { // QS Footer built text row override fun afterHookedMethod(param: MethodHookParam) { - if (!isDark && lightQSHeaderEnabled) { - try { - (getObjectField(param.thisObject, "mBuildText") as TextView) - .setTextColor(Color.BLACK) - } catch (ignored: Throwable) { - } + if (isDark || !lightQSHeaderEnabled) return - try { - (getObjectField(param.thisObject, "mEditButton") as ImageView) - .setColorFilter(Color.BLACK) - } catch (ignored: Throwable) { - } + try { + (getObjectField(param.thisObject, "mBuildText") as TextView) + .setTextColor(Color.BLACK) + } catch (ignored: Throwable) { + } - try { - setObjectField( - getObjectField(param.thisObject, "mPageIndicator"), - "mTint", - ColorStateList.valueOf(Color.BLACK) - ) - } catch (ignored: Throwable) { - } + try { + (getObjectField(param.thisObject, "mEditButton") as ImageView) + .setColorFilter(Color.BLACK) + } catch (ignored: Throwable) { + } + + try { + setObjectField( + getObjectField(param.thisObject, "mPageIndicator"), + "mTint", + ColorStateList.valueOf(Color.BLACK) + ) + } catch (ignored: Throwable) { } } }) @@ -439,8 +459,8 @@ class QSLightThemeA14(context: Context?) : ModPack(context!!) { if (isDark || !lightQSHeaderEnabled) return try { - (getObjectField(param.thisObject, "mIcon") as ImageView) - .setImageTintList(ColorStateList.valueOf(Color.BLACK)) + (getObjectField(param.thisObject, "mIcon") as ImageView).imageTintList = + ColorStateList.valueOf(Color.BLACK) } catch (throwable: Throwable) { log(TAG + throwable) } @@ -453,12 +473,15 @@ class QSLightThemeA14(context: Context?) : ModPack(context!!) { if (isDark || !lightQSHeaderEnabled) return try { - (getObjectField(param.thisObject, "mIcon") as ImageView) - .setImageTintList(ColorStateList.valueOf(Color.BLACK)) + (getObjectField(param.thisObject, "mIcon") as ImageView).imageTintList = + ColorStateList.valueOf(Color.BLACK) } catch (throwable: Throwable) { try { - (getObjectField(param.thisObject, "mIconView") as ImageView) - .setImageTintList(ColorStateList.valueOf(Color.BLACK)) + (getObjectField( + param.thisObject, + "mIconView" + ) as ImageView).imageTintList = + ColorStateList.valueOf(Color.BLACK) } catch (ignored: Throwable) { } } @@ -471,8 +494,14 @@ class QSLightThemeA14(context: Context?) : ModPack(context!!) { if (isDark || !lightQSHeaderEnabled) return try { - (getObjectField(param.thisObject, "mIcon") as ImageView) - .setImageTintList(ColorStateList.valueOf(Color.BLACK)) + val iconColor = if ((param.args?.get(0) ?: false) as Boolean) { + Color.WHITE + } else { + Color.BLACK + } + val mIcon = getObjectField(param.thisObject, "mIcon") as ImageView + + mIcon.imageTintList = ColorStateList.valueOf(iconColor) } catch (throwable: Throwable) { log(TAG + throwable) } @@ -482,11 +511,11 @@ class QSLightThemeA14(context: Context?) : ModPack(context!!) { hookAllMethods(qsIconViewImplClass, "updateIcon", object : XC_MethodHook() { override fun afterHookedMethod(param: MethodHookParam) { if (lightQSHeaderEnabled && !isDark && - getIntField(param.args[1], "state") == STATE_ACTIVE + getIntField(param.args[1], "state") == Tile.STATE_ACTIVE ) { try { - (param.args[0] as ImageView) - .setImageTintList(ColorStateList.valueOf(colorInactive!!)) + (param.args[0] as ImageView).imageTintList = + ColorStateList.valueOf(colorInactive!!) } catch (throwable: Throwable) { log(TAG + throwable) } @@ -499,7 +528,7 @@ class QSLightThemeA14(context: Context?) : ModPack(context!!) { if (lightQSHeaderEnabled && !isDark) { try { if (param.args[0] is ImageView && - getIntField(param.args[1], "state") == STATE_ACTIVE + getIntField(param.args[1], "state") == Tile.STATE_ACTIVE ) { setObjectField(param.thisObject, "mTint", colorInactive) } @@ -512,22 +541,25 @@ class QSLightThemeA14(context: Context?) : ModPack(context!!) { try { // White QS Clock bug - hookAllMethods(quickStatusBarHeaderClass, "onFinishInflate", object : XC_MethodHook() { - override fun afterHookedMethod(param: MethodHookParam) { - try { - mClockViewQSHeader = getObjectField(param.thisObject, "mClockView") - } catch (ignored: Throwable) { - } - - if (!isDark && lightQSHeaderEnabled && mClockViewQSHeader != null) { + hookAllMethods( + quickStatusBarHeaderClass, + "onFinishInflate", + object : XC_MethodHook() { + override fun afterHookedMethod(param: MethodHookParam) { try { - (mClockViewQSHeader as TextView).setTextColor(Color.WHITE) - } catch (throwable: Throwable) { - log(TAG + throwable) + mClockViewQSHeader = getObjectField(param.thisObject, "mClockView") + } catch (ignored: Throwable) { + } + + if (!isDark && lightQSHeaderEnabled && mClockViewQSHeader != null) { + try { + (mClockViewQSHeader as TextView).setTextColor(Color.WHITE) + } catch (throwable: Throwable) { + log(TAG + throwable) + } } } - } - }) + }) // White QS Clock bug hookAllMethods(clockClass, "onColorsChanged", object : XC_MethodHook() { @@ -570,6 +602,26 @@ class QSLightThemeA14(context: Context?) : ModPack(context!!) { setObjectField(param.thisObject, "colorLabelInactive", Color.BLACK) setObjectField(param.thisObject, "colorSecondaryLabelInactive", -0x80000000) + + val sideView = getObjectField(param.thisObject, "sideView") as ViewGroup + + val customDrawable = sideView.findViewById( + mContext.resources.getIdentifier( + "customDrawable", + "id", + mContext.packageName + ) + ) + customDrawable.imageTintList = ColorStateList.valueOf(Color.WHITE) + + val chevron = sideView.findViewById( + mContext.resources.getIdentifier( + "chevron", + "id", + mContext.packageName + ) + ) + chevron.imageTintList = ColorStateList.valueOf(Color.WHITE) } catch (throwable: Throwable) { log(TAG + throwable) } @@ -578,7 +630,8 @@ class QSLightThemeA14(context: Context?) : ModPack(context!!) { hookAllMethods(qsIconViewImplClass, "getIconColorForState", object : XC_MethodHook() { override fun beforeHookedMethod(param: MethodHookParam) { - val (isDisabledState: Boolean, isActiveState: Boolean) = getTileState(param) + val (isDisabledState: Boolean, + isActiveState: Boolean) = Utils.getTileState(param) if (!isDark && lightQSHeaderEnabled) { if (isDisabledState) { @@ -597,7 +650,8 @@ class QSLightThemeA14(context: Context?) : ModPack(context!!) { try { hookAllMethods(qsIconViewImplClass, "updateIcon", object : XC_MethodHook() { override fun afterHookedMethod(param: MethodHookParam) { - val (isDisabledState: Boolean, isActiveState: Boolean) = getTileState(param) + val (isDisabledState: Boolean, + isActiveState: Boolean) = Utils.getTileState(param) if (!isDark && lightQSHeaderEnabled) { val mIcon = param.args[0] as ImageView @@ -605,9 +659,9 @@ class QSLightThemeA14(context: Context?) : ModPack(context!!) { param.result = -0x80000000 } else { if (isActiveState && !qsTextAlwaysWhite && !qsTextFollowAccent) { - mIcon.setImageTintList(ColorStateList.valueOf(Color.WHITE)) + mIcon.imageTintList = ColorStateList.valueOf(Color.WHITE) } else if (!isActiveState) { - mIcon.setImageTintList(ColorStateList.valueOf(Color.BLACK)) + mIcon.imageTintList = ColorStateList.valueOf(Color.BLACK) } } } @@ -654,7 +708,7 @@ class QSLightThemeA14(context: Context?) : ModPack(context!!) { ) ) - pmButton.setImageTintList(ColorStateList.valueOf(Color.WHITE)) + pmButton.imageTintList = ColorStateList.valueOf(Color.WHITE) } } catch (ignored: Throwable) { } @@ -686,11 +740,14 @@ class QSLightThemeA14(context: Context?) : ModPack(context!!) { if (code != PM_LITE_BACKGROUND_CODE) { try { - if (mContext.resources.getResourceName(code).split("/".toRegex()) - .dropLastWhile { it.isEmpty() } - .toTypedArray()[1] == "onShadeInactiveVariant" - ) { - result = Color.BLACK // number button text + when (mContext.resources.getResourceName(code).split("/")[1]) { + "underSurface", "onShadeActive", "shadeInactive" -> { + result = colorInactive!! // button backgrounds + } + + "onShadeInactiveVariant" -> { + result = Color.BLACK // "number button" text + } } } catch (ignored: Throwable) { } @@ -709,11 +766,11 @@ class QSLightThemeA14(context: Context?) : ModPack(context!!) { // Power button val power = getObjectField(param.thisObject, "power") setObjectField(power, "iconTint", Color.WHITE) + setObjectField(power, "backgroundColor", PM_LITE_BACKGROUND_CODE) // Settings button val settings = getObjectField(param.thisObject, "settings") setObjectField(settings, "iconTint", Color.BLACK) - // setObjectField(settings, "backgroundColor", colorInactive); // We must use the classes defined in the apk. Using our own will fail. val stateFlowImplClass = findClass( @@ -726,13 +783,20 @@ class QSLightThemeA14(context: Context?) : ModPack(context!!) { ) try { - val zeroAlphaFlow = - stateFlowImplClass.getConstructor(Any::class.java).newInstance(0f) + val zeroAlphaFlow = stateFlowImplClass + .getConstructor(Any::class.java) + .newInstance(0f) + + val readonlyStateFlowInstance = try { + readonlyStateFlowClass.constructors[0].newInstance(zeroAlphaFlow) + } catch (ignored: Throwable) { + readonlyStateFlowClass.constructors[0].newInstance(zeroAlphaFlow, null) + } setObjectField( param.thisObject, "backgroundAlpha", - readonlyStateFlowClass.constructors[0].newInstance(zeroAlphaFlow) + readonlyStateFlowInstance ) } catch (throwable: Throwable) { log(TAG + throwable) @@ -797,18 +861,16 @@ class QSLightThemeA14(context: Context?) : ModPack(context!!) { ), mContext ) val surfaceBackground = states.defaultColor - val accentStates: ColorStateList = - getColorAttr( - mContext.resources.getIdentifier( - "colorAccent", - "attr", - "android" - ), mContext - ) - val accent = accentStates.defaultColor + val accentColor = getColorAttr( + mContext.resources.getIdentifier( + "colorAccent", + "attr", + "android" + ), mContext + ).defaultColor callMethod(mBehindColors, "setMainColor", surfaceBackground) - callMethod(mBehindColors, "setSecondaryColor", accent) + callMethod(mBehindColors, "setSecondaryColor", accentColor) val contrast = ColorUtils.calculateContrast( callMethod( @@ -842,7 +904,7 @@ class QSLightThemeA14(context: Context?) : ModPack(context!!) { }) try { - val constants: Array? = scrimStateEnum.getEnumConstants() + val constants: Array? = scrimStateEnum.enumConstants if (constants != null) { for (constant in constants) { when (constant.toString()) { @@ -1012,61 +1074,24 @@ class QSLightThemeA14(context: Context?) : ModPack(context!!) { } } - private fun getTileState(param: XC_MethodHook.MethodHookParam): Pair { - val isDisabledState: Boolean = try { - getObjectField( - param.args[1], - "disabledByPolicy" - ) as Boolean || - getObjectField( - param.args[1], - "state" - ) as Int == Tile.STATE_UNAVAILABLE - } catch (throwable: Throwable) { - getObjectField( - param.args[1], - "state" - ) as Int == Tile.STATE_UNAVAILABLE - } - - val isActiveState: Boolean = try { - getObjectField( - param.args[1], - "state" - ) as Int == STATE_ACTIVE - } catch (throwable: Throwable) { - try { - param.args[1] as Int == STATE_ACTIVE - } catch (throwable1: Throwable) { - try { - param.args[1] as Boolean - } catch (throwable2: Throwable) { - log(TAG + throwable2) - false - } - } - } - - return Pair(isDisabledState, isActiveState) - } - private fun applyOverlays(force: Boolean) { - val isCurrentlyDark: Boolean = SystemUtil.isDarkMode + val isCurrentlyDark: Boolean = SystemUtils.isDarkMode if (isCurrentlyDark == isDark && !force) return isDark = isCurrentlyDark calculateColors() - disableOverlays(qsLightThemeOverlay, qsDualToneOverlay) + + Utils.disableOverlays(qsLightThemeOverlay, qsDualToneOverlay) try { Thread.sleep(50) } catch (ignored: Throwable) { } - if (lightQSHeaderEnabled) { - if (!isCurrentlyDark) enableOverlay(qsLightThemeOverlay) - if (dualToneQSEnabled) enableOverlay(qsDualToneOverlay) + if (lightQSHeaderEnabled && !isCurrentlyDark) { + Utils.enableOverlay(qsLightThemeOverlay) + if (dualToneQSEnabled) Utils.enableOverlay(qsDualToneOverlay) } } @@ -1154,13 +1179,11 @@ class QSLightThemeA14(context: Context?) : ModPack(context!!) { } for (i in 1..3) { - val id = String.format("carrier%s", i) - try { (getObjectField( mView.findViewById( mContext.resources.getIdentifier( - id, + "carrier$i", "id", mContext.packageName ) @@ -1170,22 +1193,22 @@ class QSLightThemeA14(context: Context?) : ModPack(context!!) { (getObjectField( mView.findViewById( mContext.resources.getIdentifier( - id, + "carrier$i", "id", mContext.packageName ) ), "mMobileSignal" - ) as ImageView).setImageTintList(ColorStateList.valueOf(textColorPrimary)) + ) as ImageView).imageTintList = ColorStateList.valueOf(textColorPrimary) (getObjectField( mView.findViewById( mContext.resources.getIdentifier( - id, + "carrier$i", "id", mContext.packageName ) ), "mMobileRoaming" - ) as ImageView).setImageTintList(ColorStateList.valueOf(textColorPrimary)) + ) as ImageView).imageTintList = ColorStateList.valueOf(textColorPrimary) } catch (ignored: Throwable) { } } @@ -1242,7 +1265,6 @@ class QSLightThemeA14(context: Context?) : ModPack(context!!) { } companion object { - const val STATE_ACTIVE = 2 private val TAG = "Iconify - ${QSLightThemeA14::class.java.simpleName}: " private var lightQSHeaderEnabled = false private var dualToneQSEnabled = false diff --git a/app/src/main/java/com/drdisagree/iconify/xposed/modules/themes/Utils.kt b/app/src/main/java/com/drdisagree/iconify/xposed/modules/themes/Utils.kt new file mode 100644 index 000000000..19f23409f --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/xposed/modules/themes/Utils.kt @@ -0,0 +1,93 @@ +package com.drdisagree.iconify.xposed.modules.themes + +import android.service.quicksettings.Tile +import com.topjohnwu.superuser.Shell +import de.robv.android.xposed.XC_MethodHook +import de.robv.android.xposed.XposedHelpers.getObjectField + +object Utils { + + fun getTileState(param: XC_MethodHook.MethodHookParam): Pair { + var isDisabledState: Boolean + var isActiveState: Boolean + + try { + isDisabledState = try { + getObjectField( + param.args[1], + "disabledByPolicy" + ) as Boolean || + getObjectField( + param.args[1], + "state" + ) as Int == Tile.STATE_UNAVAILABLE + } catch (throwable: Throwable) { + getObjectField( + param.args[1], + "state" + ) as Int == Tile.STATE_UNAVAILABLE + } + + isActiveState = try { + getObjectField( + param.args[1], + "state" + ) as Int == Tile.STATE_ACTIVE + } catch (throwable: Throwable) { + try { + param.args[1] as Int == Tile.STATE_ACTIVE + } catch (throwable1: Throwable) { + try { + param.args[1] as Boolean + } catch (throwable2: Throwable) { + false + } + } + } + } catch (ignored: Throwable) { + isDisabledState = param.args[1] == Tile.STATE_UNAVAILABLE + isActiveState = param.args[1] == Tile.STATE_ACTIVE + } + + return Pair(isDisabledState, isActiveState) + } + + fun enableOverlay(pkgName: String) { + Shell.cmd( + "cmd overlay enable --user current $pkgName", + "cmd overlay set-priority $pkgName highest" + ).submit() + } + + fun enableOverlay(pkgName: String, priority: String) { + Shell.cmd( + "cmd overlay enable --user current $pkgName", + "cmd overlay set-priority $pkgName $priority" + ).submit() + } + + fun enableOverlays(vararg pkgNames: String?) { + val command = StringBuilder() + + for (pkgName in pkgNames) { + command.append("cmd overlay enable --user current ").append(pkgName) + .append("; cmd overlay set-priority ").append(pkgName).append(" highest; ") + } + + Shell.cmd(command.toString().trim { it <= ' ' }).submit() + } + + fun disableOverlay(pkgName: String) { + Shell.cmd("cmd overlay disable --user current $pkgName").submit() + } + + fun disableOverlays(vararg pkgNames: String?) { + val command = StringBuilder() + + for (pkgName in pkgNames) { + command.append("cmd overlay disable --user current ").append(pkgName).append("; ") + } + + Shell.cmd(command.toString().trim { it <= ' ' }).submit() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/xposed/modules/utils/ActivityLauncherUtils.kt b/app/src/main/java/com/drdisagree/iconify/xposed/modules/utils/ActivityLauncherUtils.kt new file mode 100644 index 000000000..ebba25c64 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/xposed/modules/utils/ActivityLauncherUtils.kt @@ -0,0 +1,99 @@ +package com.drdisagree.iconify.xposed.modules.utils + +import android.content.ComponentName +import android.content.Context +import android.content.Intent +import android.content.pm.PackageManager +import android.provider.MediaStore +import android.provider.Settings +import android.widget.Toast +import androidx.annotation.StringRes +import com.drdisagree.iconify.R +import com.drdisagree.iconify.xposed.HookRes.Companion.modRes +import com.drdisagree.iconify.xposed.modules.ControllersProvider +import de.robv.android.xposed.XposedBridge.log +import de.robv.android.xposed.XposedHelpers +import de.robv.android.xposed.XposedHelpers.callMethod + +class ActivityLauncherUtils(private val mContext: Context, private val mActivityStarter: Any?) { + private val mPackageManager: PackageManager = mContext.packageManager + + private fun launchAppIfAvailable(launchIntent: Intent?, @StringRes appTypeResId: Int) { + val apps = + mPackageManager.queryIntentActivities(launchIntent!!, PackageManager.MATCH_DEFAULT_ONLY) + if (apps.isNotEmpty()) { + if (mActivityStarter == null) { + log("ActivityStarter is null") + return + } + callMethod(mActivityStarter, "startActivity", launchIntent, true) + } else { + if (appTypeResId != 0) showNoDefaultAppFoundToast(appTypeResId) + } + } + + fun launchApp(launchIntent: Intent?, fromQs: Boolean = false) { + if (launchIntent == null) return + if (mActivityStarter == null) { + log("ActivityStarter is null") + return + } + callMethod(mActivityStarter, "postStartActivityDismissingKeyguard", launchIntent, /* dismissShade */ 0) + } + + fun launchCamera() { + val launchIntent = Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE) + launchAppIfAvailable(launchIntent, R.string.camera) + } + + fun launchTimer() { + val intent = Intent() + intent.setAction("android.intent.action.SHOW_ALARMS") + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP + Intent.FLAG_ACTIVITY_SINGLE_TOP) + launchAppIfAvailable(intent, R.string.clock_timer) + } + + fun launchCalculator() { + val launchIntent = Intent(Intent.ACTION_MAIN) + launchIntent.addCategory(Intent.CATEGORY_APP_CALCULATOR) + launchIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP + Intent.FLAG_ACTIVITY_SINGLE_TOP) + launchAppIfAvailable(launchIntent, R.string.calculator) + } + + fun launchWallet() { + val launchIntent = + mContext.packageManager.getLaunchIntentForPackage("com.google.android.apps.walletnfcrel") + launchIntent?.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP + Intent.FLAG_ACTIVITY_SINGLE_TOP) + launchAppIfAvailable(launchIntent, R.string.wallet) + } + + fun launchSettingsComponent(className: String) { + if (mActivityStarter == null) return + val intent = Intent() + intent.setComponent(ComponentName("com.android.settings", className)) + callMethod(mActivityStarter, "startActivity", intent, true) + } + + fun launchBluetoothSettings() { + val launchIntent = Intent(Settings.ACTION_BLUETOOTH_SETTINGS) + launchIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP + Intent.FLAG_ACTIVITY_SINGLE_TOP) + launchAppIfAvailable(launchIntent, 0) + } + + fun launchAudioSettings() { + val launchIntent = Intent(Settings.ACTION_SOUND_SETTINGS) + launchIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP + Intent.FLAG_ACTIVITY_SINGLE_TOP) + launchAppIfAvailable(launchIntent, 0) + } + + fun launchInternetSettings() { + val launchIntent = Intent(Settings.ACTION_NETWORK_OPERATOR_SETTINGS) + launchIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP + Intent.FLAG_ACTIVITY_SINGLE_TOP) + launchAppIfAvailable(launchIntent, 0) + } + + private fun showNoDefaultAppFoundToast(@StringRes appTypeResId: Int) { + Toast.makeText(mContext, modRes.getString(appTypeResId) + " not found", Toast.LENGTH_SHORT) + .show() + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/xposed/modules/utils/BitmapSubjectSegmenter.kt b/app/src/main/java/com/drdisagree/iconify/xposed/modules/utils/BitmapSubjectSegmenter.kt new file mode 100644 index 000000000..546ce60de --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/xposed/modules/utils/BitmapSubjectSegmenter.kt @@ -0,0 +1,122 @@ +package com.drdisagree.iconify.xposed.modules.utils + +import android.content.Context +import android.graphics.Bitmap +import android.graphics.Color +import android.util.Log +import com.google.android.gms.common.moduleinstall.ModuleAvailabilityResponse +import com.google.android.gms.common.moduleinstall.ModuleInstall +import com.google.android.gms.common.moduleinstall.ModuleInstallClient +import com.google.android.gms.common.moduleinstall.ModuleInstallRequest +import com.google.android.gms.tasks.OnSuccessListener +import com.google.mlkit.common.MlKit +import com.google.mlkit.vision.common.InputImage; +import com.google.mlkit.vision.segmentation.subject.SubjectSegmentation +import com.google.mlkit.vision.segmentation.subject.SubjectSegmenter +import com.google.mlkit.vision.segmentation.subject.SubjectSegmenterOptions +import java.nio.FloatBuffer + +class BitmapSubjectSegmenter(context: Context) { + + private var mSegmenter: SubjectSegmenter? = null + private val mContext: Context = context + + init { + try { + MlKit.initialize(context) + } catch (ignored: Throwable) { + } + + mSegmenter = try { + SubjectSegmentation.getClient( + SubjectSegmenterOptions + .Builder() + .enableForegroundConfidenceMask() + .build() + ) + } catch (ignored: Throwable) { + null + } + + downloadModelIfNeeded() + } + + private fun downloadModelIfNeeded() { + if (mSegmenter == null) return + + val moduleInstallClient: ModuleInstallClient = ModuleInstall.getClient(mContext) + + moduleInstallClient + .areModulesAvailable(mSegmenter!!) + .addOnSuccessListener { response -> + if (!response.areModulesAvailable()) { + moduleInstallClient + .installModules( + ModuleInstallRequest + .newBuilder() + .addApi(mSegmenter!!) + .build() + ) + } + } + } + + fun checkModelAvailability(resultListener: OnSuccessListener?) { + if (mSegmenter == null) { + resultListener?.onSuccess(ModuleAvailabilityResponse(false, 0)) + return + } + + val moduleInstallClient: ModuleInstallClient = ModuleInstall.getClient(mContext) + + if (resultListener != null) { + moduleInstallClient.areModulesAvailable(mSegmenter!!) + .addOnSuccessListener(resultListener) + } + } + + fun segmentSubject(inputBitmap: Bitmap, listener: SegmentResultListener) { + if (mSegmenter == null) return + + val transparentColor = Color.alpha(Color.TRANSPARENT) + val resultBitmap = inputBitmap.copy(Bitmap.Config.ARGB_8888, true) + + listener.onStart() + + mSegmenter!! + .process(InputImage.fromBitmap(inputBitmap, 0)) + .addOnSuccessListener { subjectSegmentationResult -> + val mSubjectMask: FloatBuffer? = subjectSegmentationResult.foregroundConfidenceMask + resultBitmap.setHasAlpha(true) + + for (y in 0 until inputBitmap.height) { + for (x in 0 until inputBitmap.width) { + if (mSubjectMask != null) { + if (mSubjectMask.get() < .5f) { + resultBitmap.setPixel(x, y, transparentColor) + } + } + } + } + + inputBitmap.recycle() + listener.onSuccess(resultBitmap) + } + .addOnFailureListener { e -> + Log.e(TAG, "onFail:", e) + + inputBitmap.recycle() + listener.onFail() + } + } + + interface SegmentResultListener { + fun onStart() + fun onSuccess(result: Bitmap?) + fun onFail() + } + + companion object { + private val TAG = "Iconify - ${BitmapSubjectSegmenter::class.java.simpleName}: " + } +} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/xposed/modules/utils/ExtendedFAB.kt b/app/src/main/java/com/drdisagree/iconify/xposed/modules/utils/ExtendedFAB.kt new file mode 100644 index 000000000..0620298ef --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/xposed/modules/utils/ExtendedFAB.kt @@ -0,0 +1,21 @@ +package com.drdisagree.iconify.xposed.modules.utils + +import android.content.Context +import android.content.ContextWrapper +import android.content.res.Resources +import android.util.AttributeSet +import android.view.ContextThemeWrapper +import com.drdisagree.iconify.R +import com.drdisagree.iconify.xposed.HookRes.Companion.modRes +import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton + +class ExtendedFAB @JvmOverloads constructor( + context: Context?, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0 +) : + ExtendedFloatingActionButton(ContextThemeWrapper(object : ContextWrapper(context) { + override fun getResources(): Resources { + return modRes + } + }, R.style.Theme_MaterialComponents_DayNight), attrs, defStyleAttr) \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/xposed/modules/utils/Helpers.kt b/app/src/main/java/com/drdisagree/iconify/xposed/modules/utils/Helpers.kt index d3a07f577..eb806cb56 100644 --- a/app/src/main/java/com/drdisagree/iconify/xposed/modules/utils/Helpers.kt +++ b/app/src/main/java/com/drdisagree/iconify/xposed/modules/utils/Helpers.kt @@ -1,6 +1,7 @@ package com.drdisagree.iconify.xposed.modules.utils import android.content.Context +import android.util.ArraySet import android.util.TypedValue import android.view.View import android.view.ViewGroup @@ -10,50 +11,36 @@ import com.topjohnwu.superuser.Shell import de.robv.android.xposed.XC_MethodHook import de.robv.android.xposed.XposedBridge.hookAllConstructors import de.robv.android.xposed.XposedBridge.hookAllMethods +import de.robv.android.xposed.XposedBridge.hookMethod import de.robv.android.xposed.XposedBridge.log -import de.robv.android.xposed.XposedHelpers +import de.robv.android.xposed.XposedHelpers.findClass +import de.robv.android.xposed.XposedHelpers.findClassIfExists +import java.lang.reflect.Method +import java.util.regex.Pattern @Suppress("unused") object Helpers { - fun enableOverlay(pkgName: String) { - Shell.cmd( - "cmd overlay enable --user current $pkgName", - "cmd overlay set-priority $pkgName highest" - ).exec() - } - - fun disableOverlay(pkgName: String) { - Shell.cmd("cmd overlay disable --user current $pkgName").exec() - } - - fun enableOverlays(vararg pkgNames: String?) { - val command = StringBuilder() - for (pkgName in pkgNames) { - command.append("cmd overlay enable --user current $pkgName; cmd overlay set-priority $pkgName highest; ") - } - Shell.cmd(command.toString().trim()).submit() - } - - fun disableOverlays(vararg pkgNames: String?) { - val command = StringBuilder() - for (pkgName in pkgNames) { - command.append("cmd overlay disable --user current $pkgName; ") - } - Shell.cmd(command.toString().trim()).submit() - } fun findAndDumpClass(className: String, classLoader: ClassLoader?): Class<*> { dumpClass(className, classLoader) - return XposedHelpers.findClass(className, classLoader) + return findClass(className, classLoader) } fun findAndDumpClassIfExists(className: String, classLoader: ClassLoader?): Class<*> { dumpClass(className, classLoader) - return XposedHelpers.findClassIfExists(className, classLoader) + return findClassIfExists(className, classLoader) + } + + fun dumpClassObj(classObj: Class<*>?) { + if (classObj == null) { + log("Class: null not found") + return + } + dumpClass(classObj) } - fun dumpClass(className: String, classLoader: ClassLoader?) { - val ourClass = XposedHelpers.findClassIfExists(className, classLoader) + private fun dumpClass(className: String, classLoader: ClassLoader?) { + val ourClass = findClassIfExists(className, classLoader) if (ourClass == null) { log("Class: $className not found") return @@ -61,38 +48,38 @@ object Helpers { dumpClass(ourClass) } - fun dumpClass(ourClass: Class<*>) { - val ms = ourClass.getDeclaredMethods() - log("\n\nClass: ${ourClass.getName()}") - log("extends: ${ourClass.superclass.getName()}") + private fun dumpClass(ourClass: Class<*>) { + val ms = ourClass.declaredMethods + log("\n\nClass: ${ourClass.name}") + log("extends: ${ourClass.superclass.name}") log("Subclasses:") - val scs = ourClass.getClasses() + val scs = ourClass.classes for (c in scs) { - log(c.getName()) + log(c.name) } log("Methods:") val cons = ourClass.declaredConstructors for (m in cons) { log(m.name + " - " + " - " + m.parameterCount) - val cs = m.getParameterTypes() + val cs = m.parameterTypes for (c in cs) { - log("\t\t" + c.getTypeName()) + log("\t\t" + c.typeName) } } for (m in ms) { log(m.name + " - " + m.returnType + " - " + m.parameterCount) - val cs = m.getParameterTypes() + val cs = m.parameterTypes for (c in cs) { - log("\t\t" + c.getTypeName()) + log("\t\t" + c.typeName) } } log("Fields:") val fs = ourClass.declaredFields for (f in fs) { - log("\t\t" + f.getName() + "-" + f.type.getName()) + log("\t\t" + f.name + "-" + f.type.name) } log("End dump\n\n") } @@ -111,6 +98,45 @@ object Helpers { } } + fun hookAllMethodsMatchPattern( + clazz: Class<*>, + namePattern: String, + callback: XC_MethodHook + ): Set { + val result: MutableSet = ArraySet() + + for (method in findMethods(clazz, namePattern)) { + result.add(hookMethod(method, callback)) + } + + return result + } + + private fun findMethods(clazz: Class<*>, namePattern: String): Set { + val result: MutableSet = ArraySet() + val methods: Array = clazz.methods + + for (method in methods) { + if (Pattern.matches(namePattern, method.name)) { + result.add(method) + } + } + + return result + } + + fun findMethod(clazz: Class<*>, namePattern: String): Method? { + val methods: Array = clazz.methods + + for (method in methods) { + if (Pattern.matches(namePattern, method.name)) { + return method + } + } + + return null + } + fun dumpChildViews(context: Context, view: View) { if (view is ViewGroup) { logViewInfo(context, view, 0) @@ -155,6 +181,15 @@ object Helpers { } } + fun findClassInArray(classLoader: ClassLoader, vararg classNames: String): Class<*>? { + for (className in classNames) { + val clazz = findClassIfExists(className, classLoader) + if (clazz != null) return clazz + } + return null + } + + @Suppress("SameParameterValue") private fun repeatString(str: String, times: Int): String { val result = StringBuilder() for (i in 0 until times) { @@ -173,7 +208,34 @@ object Helpers { return color } + fun isMethodAvailable( + target: Any?, + methodName: String, + vararg parameterTypes: Class<*> + ): Boolean { + if (target == null) return false + + return try { + target::class.java.getMethod(methodName, *parameterTypes) + true + } catch (ignored: NoSuchMethodException) { + false + } + } + + val isQsTileOverlayEnabled: Boolean + get() { + val output = Shell.cmd( + "[[ $(cmd overlay list | grep -oE '\\[x\\] IconifyComponentQSS[N|P][0-9]+.overlay') ]] && echo 1 || echo 0" + ).exec().out + return output.isNotEmpty() && output[0] == "1" + } + val isPixelVariant: Boolean - get() = Shell.cmd("[[ $(cmd overlay list | grep -oE '\\[x\\] IconifyComponentQSSP[0-9]+.overlay') ]] && echo 1 || echo 0") - .exec().out[0] == "1" + get() { + val output = Shell.cmd( + "[[ $(cmd overlay list | grep -oE '\\[x\\] IconifyComponentQSSP[0-9]+.overlay') ]] && echo 1 || echo 0" + ).exec().out + return output.isNotEmpty() && output[0] == "1" + } } diff --git a/app/src/main/java/com/drdisagree/iconify/xposed/modules/utils/SettingsLibUtils.kt b/app/src/main/java/com/drdisagree/iconify/xposed/modules/utils/SettingsLibUtils.kt index 8935dd327..5b67b4019 100644 --- a/app/src/main/java/com/drdisagree/iconify/xposed/modules/utils/SettingsLibUtils.kt +++ b/app/src/main/java/com/drdisagree/iconify/xposed/modules/utils/SettingsLibUtils.kt @@ -3,10 +3,12 @@ package com.drdisagree.iconify.xposed.modules.utils import android.content.Context import android.content.res.ColorStateList import com.drdisagree.iconify.xposed.ModPack +import de.robv.android.xposed.XposedBridge.log import de.robv.android.xposed.XposedHelpers +import de.robv.android.xposed.XposedHelpers.callStaticMethod import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam -class SettingsLibUtils(context: Context?) : ModPack(context!!) { +class SettingsLibUtils(context: Context) : ModPack(context) { override fun updatePrefs(vararg key: String) {} @@ -21,84 +23,125 @@ class SettingsLibUtils(context: Context?) : ModPack(context!!) { } companion object { + private val TAG = SettingsLibUtils::class.java.simpleName private var UtilsClass: Class<*>? = null - fun getColorAttr(context: Context?, resID: Int): ColorStateList { - return getColorAttr(resID, context) + fun getColorAttr(resID: Int, context: Context): ColorStateList { + return getColorAttr( + context, + resID + ) } - fun getColorAttr(resID: Int, context: Context?): ColorStateList { - return if (UtilsClass == null) ColorStateList.valueOf(0) else try { - XposedHelpers.callStaticMethod( - UtilsClass, - "getColorAttr", - resID, - context - ) as ColorStateList - } catch (throwable: Throwable) { - XposedHelpers.callStaticMethod( - UtilsClass, - "getColorAttr", - context, - resID - ) as ColorStateList - } + fun getColorAttr(context: Context, resID: Int): ColorStateList { + return getColorStateListFromUtils( + "getColorAttr", + context, + resID + ) } - fun getColorAttrDefaultColor(resID: Int, context: Context?): Int { - return getColorAttrDefaultColor(context, resID) + fun getColorAttrDefaultColor(resID: Int, context: Context, defValue: Int = 0): Int { + return getColorFromUtils( + "getColorAttrDefaultColor", + context, + resID, + defValue + ) } - fun getColorAttrDefaultColor(context: Context?, resID: Int): Int { - return getColorAttrDefaultColor(resID, context, 0) + fun getColorAttrDefaultColor(context: Context, resID: Int, defValue: Int = 0): Int { + return getColorFromUtils( + "getColorAttrDefaultColor", + context, + resID, + defValue + ) } - fun getColorAttrDefaultColor(resID: Int, context: Context?, defValue: Int): Int { - return if (UtilsClass == null) 0 else try { - XposedHelpers.callStaticMethod( + fun getColorStateListDefaultColor(context: Context, resID: Int): Int { + return getColorStateListFromUtils( + "getColorStateListDefaultColor", + context, + resID + ).defaultColor + } + + private fun getColorFromUtils( + methodName: String, + context: Context, + resID: Int, + defValue: Int = 0 + ): Int { + if (UtilsClass == null) return defValue + + return try { + callStaticMethod( UtilsClass, - "getColorAttrDefaultColor", + methodName, resID, context ) as Int - } catch (throwable: Throwable) { + } catch (ignored: Throwable) { try { - XposedHelpers.callStaticMethod( + callStaticMethod( UtilsClass, - "getColorAttrDefaultColor", + methodName, context, resID ) as Int - } catch (throwable1: Throwable) { - XposedHelpers.callStaticMethod( - UtilsClass, - "getColorAttrDefaultColor", - context, - resID, - defValue - ) as Int + } catch (ignored: Throwable) { + try { + callStaticMethod( + UtilsClass, + methodName, + context, + resID, + defValue + ) as Int + } catch (ignored: Throwable) { + try { + callStaticMethod( + UtilsClass, + methodName, + resID, + defValue, + context + ) as Int + } catch (throwable: Throwable) { + log(TAG + throwable) + defValue + } + } } } } - fun getColorStateListDefaultColor(context: Context?, resID: Int): Int { - return if (UtilsClass == null) 0 else try { - (XposedHelpers.callStaticMethod( + private fun getColorStateListFromUtils( + methodName: String, + context: Context, + resID: Int + ): ColorStateList { + if (UtilsClass == null) return ColorStateList.valueOf(0) + + return try { + callStaticMethod( UtilsClass, - "getColorStateListDefaultColor", - context, - resID - ) as ColorStateList).defaultColor - } catch (throwable: Throwable) { + methodName, + resID, + context + ) as ColorStateList + } catch (ignored: Throwable) { try { - (XposedHelpers.callStaticMethod( + callStaticMethod( UtilsClass, - "getColorStateListDefaultColor", - resID, - context - ) as ColorStateList).defaultColor - } catch (throwable1: Throwable) { - 0 + methodName, + context, + resID + ) as ColorStateList + } catch (throwable: Throwable) { + log(TAG + throwable) + ColorStateList.valueOf(0) } } } diff --git a/app/src/main/java/com/drdisagree/iconify/xposed/modules/utils/StatusBarClock.kt b/app/src/main/java/com/drdisagree/iconify/xposed/modules/utils/StatusBarClock.kt new file mode 100644 index 000000000..2c8c46bb1 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/xposed/modules/utils/StatusBarClock.kt @@ -0,0 +1,210 @@ +package com.drdisagree.iconify.xposed.modules.utils + +import android.annotation.SuppressLint +import android.content.Context +import android.util.Log +import android.view.Gravity +import android.view.View +import android.view.ViewGroup +import android.widget.FrameLayout +import android.widget.LinearLayout +import android.widget.RelativeLayout +import android.widget.TextView +import de.robv.android.xposed.XC_MethodHook +import de.robv.android.xposed.XposedBridge.log +import de.robv.android.xposed.XposedHelpers.callMethod +import de.robv.android.xposed.XposedHelpers.getObjectField + +object StatusBarClock { + + private val TAG = "Iconify - ${StatusBarClock::class.java.simpleName}: " + + fun getLeftClockView(mContext: Context, param: XC_MethodHook.MethodHookParam) = try { + getObjectField(param.thisObject, "mClockView") as View + } catch (throwable1: Throwable) { + try { + getObjectField(param.thisObject, "mLeftClock") as View + } catch (throwable2: Throwable) { + try { + callMethod( + getObjectField( + param.thisObject, + "mClockController" + ), + "getClock" + ) as View + } catch (throwable3: Throwable) { + try { + val mActiveClock = getObjectField( + getObjectField( + param.thisObject, + "mClockController" + ), + "mActiveClock" + ) as View + val mLeftClockId = mContext.resources.getIdentifier( + "clock", + "id", + mContext.packageName + ) + + if (mActiveClock.id == mLeftClockId) { + mActiveClock + } else { + null + } + } catch (throwable4: Throwable) { + log(TAG + throwable4) + null + } + } + } + } + + fun getCenterClockView(mContext: Context, param: XC_MethodHook.MethodHookParam) = try { + getObjectField(param.thisObject, "mCenterClockView") as View + } catch (throwable1: Throwable) { + try { + getObjectField( + param.thisObject, + "mCenterClock" + ) as View + } catch (throwable2: Throwable) { + try { + callMethod( + getObjectField( + param.thisObject, + "mClockController" + ), + "mCenterClockView" + ) as View + } catch (throwable3: Throwable) { + try { + val mActiveClock = getObjectField( + getObjectField( + param.thisObject, + "mClockController" + ), + "mActiveClock" + ) as View + val mCenterClockId = mContext.resources.getIdentifier( + "clock_center", + "id", + mContext.packageName + ) + + if (mActiveClock.id == mCenterClockId) { + mActiveClock + } else { + null + } + } catch (throwable4: Throwable) { + try { + (getObjectField( + param.thisObject, + "mCenterClockLayout" + ) as LinearLayout).getChildAt(0) + } catch (throwable5: Throwable) { + null + } + } + } + } + } + + fun getRightClockView(mContext: Context, param: XC_MethodHook.MethodHookParam) = try { + getObjectField(param.thisObject, "mRightClockView") as View + } catch (throwable1: Throwable) { + try { + getObjectField(param.thisObject, "mRightClock") as View + } catch (throwable2: Throwable) { + try { + callMethod( + getObjectField( + param.thisObject, + "mClockController" + ), + "mRightClockView" + ) as View + } catch (throwable3: Throwable) { + try { + val mActiveClock = getObjectField( + getObjectField( + param.thisObject, + "mClockController" + ), + "mActiveClock" + ) as View + val mRightClockId = mContext.resources.getIdentifier( + "clock_right", + "id", + mContext.packageName + ) + + if (mActiveClock.id == mRightClockId) { + mActiveClock + } else { + null + } + } catch (throwable4: Throwable) { + null + } + } + } + } + + @SuppressLint("RtlHardcoded") + fun setClockGravity(clockView: View?, gravity: Int) { + if (clockView == null) return + + val layoutParams = clockView.layoutParams + when (layoutParams) { + is LinearLayout.LayoutParams -> { + layoutParams.gravity = gravity + } + + is FrameLayout.LayoutParams -> { + layoutParams.gravity = gravity + } + + is RelativeLayout.LayoutParams -> { + when (gravity) { + Gravity.LEFT or Gravity.CENTER -> { + layoutParams.addRule(RelativeLayout.CENTER_VERTICAL) + layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT) + } + + Gravity.CENTER -> { + layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT) + } + + Gravity.RIGHT or Gravity.CENTER -> { + layoutParams.addRule(RelativeLayout.CENTER_VERTICAL) + layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT) + } + + else -> { + Log.w( + "$TAG LayoutParamsCheck", + "Unsupported gravity type for RelativeLayout: $gravity" + ) + } + } + } + + else -> { + Log.w( + "$TAG LayoutParamsCheck", + "Unknown LayoutParams type: ${layoutParams.javaClass.name}" + ) + } + } + clockView.layoutParams = layoutParams + + (clockView as TextView).includeFontPadding = false + clockView.getLayoutParams().height = ViewGroup.LayoutParams.WRAP_CONTENT + clockView.setGravity(Gravity.CENTER) + clockView.setTextAlignment(View.TEXT_ALIGNMENT_CENTER) + clockView.requestLayout() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/xposed/modules/utils/TimeUtils.kt b/app/src/main/java/com/drdisagree/iconify/xposed/modules/utils/TimeUtils.kt index 5a56c2ab1..68224088c 100644 --- a/app/src/main/java/com/drdisagree/iconify/xposed/modules/utils/TimeUtils.kt +++ b/app/src/main/java/com/drdisagree/iconify/xposed/modules/utils/TimeUtils.kt @@ -1,82 +1,90 @@ package com.drdisagree.iconify.xposed.modules.utils import android.content.Context +import android.text.Editable +import android.text.TextWatcher import android.text.format.DateFormat +import android.widget.TextClock +import android.widget.TextView import de.robv.android.xposed.XposedBridge import java.text.SimpleDateFormat +import java.util.Calendar import java.util.Date import java.util.Locale object TimeUtils { private val TAG = "Iconify - ${TimeUtils::class.java.simpleName}: " + private val numbers = arrayOf( + "Zero", + "One", + "Two", + "Three", + "Four", + "Five", + "Six", + "Seven", + "Eight", + "Nine", + "Ten", + "Eleven", + "Twelve", + "Thirteen", + "Fourteen", + "Fifteen", + "Sixteen", + "Seventeen", + "Eighteen", + "Nineteen", + "Twenty", + "Twenty One", + "Twenty Two", + "Twenty Three", + "Twenty Four", + "Twenty Five", + "Twenty Six", + "Twenty Seven", + "Twenty Eight", + "Twenty Nine", + "Thirty", + "Thirty One", + "Thirty Two", + "Thirty Three", + "Thirty Four", + "Thirty Five", + "Thirty Six", + "Thirty Seven", + "Thirty Eight", + "Thirty Nine", + "Forty", + "Forty One", + "Forty Two", + "Forty Three", + "Forty Four", + "Forty Five", + "Forty Six", + "Forty Seven", + "Forty Eight", + "Forty Nine", + "Fifty", + "Fifty One", + "Fifty Two", + "Fifty Three", + "Fifty Four", + "Fifty Five", + "Fifty Six", + "Fifty Seven", + "Fifty Eight", + "Fifty Nine", + "Sixty" + ) - fun getNumericToText(number: String): String { - val num = number.toInt() - val numbers = arrayOf( - "Zero", - "One", - "Two", - "Three", - "Four", - "Five", - "Six", - "Seven", - "Eight", - "Nine", - "Ten", - "Eleven", - "Twelve", - "Thirteen", - "Fourteen", - "Fifteen", - "Sixteen", - "Seventeen", - "Eighteen", - "Nineteen", - "Twenty", - "Twenty One", - "Twenty Two", - "Twenty Three", - "Twenty Four", - "Twenty Five", - "Twenty Six", - "Twenty Seven", - "Twenty Eight", - "Twenty Nine", - "Thirty", - "Thirty One", - "Thirty Two", - "Thirty Three", - "Thirty Four", - "Thirty Five", - "Thirty Six", - "Thirty Seven", - "Thirty Eight", - "Thirty Nine", - "Forty", - "Forty One", - "Forty Two", - "Forty Three", - "Forty Four", - "Forty Five", - "Forty Six", - "Forty Seven", - "Forty Eight", - "Forty Nine", - "Fifty", - "Fifty One", - "Fifty Two", - "Fifty Three", - "Fifty Four", - "Fifty Five", - "Fifty Six", - "Fifty Seven", - "Fifty Eight", - "Fifty Nine", - "Sixty" - ) - return numbers[num] + private fun convertNumberToText(number: String): String { + return try { + numbers[number.toInt()] + } catch (throwable: Throwable) { + number + } } fun regionFormattedDate(usFormat: String?, euFormat: String?): String { @@ -96,11 +104,52 @@ object TimeUtils { return SimpleDateFormat(usFormat, Locale.getDefault()).format(Date()) } - fun formatTime(context: Context?, format24H: String?, format12H: String?): String { + fun formatTime(context: Context, format24H: String, format12H: String): String { return formatTime(if (DateFormat.is24HourFormat(context)) format24H else format12H) } - fun formatTime(format: String?): String { + fun formatTime(format: String): String { return SimpleDateFormat(format, Locale.getDefault()).format(Date()) } + + fun setCurrentTimeTextClock( + context: Context, + tickIndicator: TextClock, + hourView: TextView, + minuteView: TextView + ) { + setCurrentTimeHour(context, hourView) + setCurrentTimeMinute(minuteView) + + tickIndicator.addTextChangedListener(object : TextWatcher { + override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {} + + override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {} + + override fun afterTextChanged(s: Editable?) { + if (!s.isNullOrEmpty()) { + setCurrentTimeHour(context, hourView) + setCurrentTimeMinute(minuteView) + } + } + }) + } + + private fun setCurrentTimeHour(context: Context, hourView: TextView) { + val hourFormat = if (DateFormat.is24HourFormat(context)) "HH" else "hh" + val hour = SimpleDateFormat( + hourFormat, + Locale.getDefault() + ).format(Calendar.getInstance().time) + hourView.text = convertNumberToText(hour) + } + + private fun setCurrentTimeMinute(minuteView: TextView) { + val minuteFormat = "mm" + val minute = SimpleDateFormat( + minuteFormat, + Locale.getDefault() + ).format(Calendar.getInstance().time) + minuteView.text = convertNumberToText(minute) + } } diff --git a/app/src/main/java/com/drdisagree/iconify/xposed/modules/utils/TouchAnimator.java b/app/src/main/java/com/drdisagree/iconify/xposed/modules/utils/TouchAnimator.java new file mode 100644 index 000000000..d5be87b73 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/xposed/modules/utils/TouchAnimator.java @@ -0,0 +1,289 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package com.drdisagree.iconify.xposed.modules.utils; + +import android.util.FloatProperty; +import android.util.Property; +import android.view.View; +import android.view.animation.Interpolator; + +import androidx.annotation.Nullable; + +import java.util.ArrayList; +import java.util.List; + +/** + * Helper class, that handles similar properties as animators (delay, interpolators) + * but can have a float input as to the amount they should be in effect. This allows + * easier animation that tracks input. + *

+ * All "delays" and "times" are as fractions from 0-1. + */ +@SuppressWarnings("all") +public class TouchAnimator { + + private final Object[] mTargets; + private final KeyframeSet[] mKeyframeSets; + private final float mStartDelay; + private final float mEndDelay; + private final float mSpan; + @Nullable + private final Interpolator mInterpolator; + @Nullable + private final Listener mListener; + private float mLastT = -1; + + private TouchAnimator( + Object[] targets, + KeyframeSet[] keyframeSets, + float startDelay, + float endDelay, + @Nullable Interpolator interpolator, + @Nullable Listener listener) { + mTargets = targets; + mKeyframeSets = keyframeSets; + mStartDelay = startDelay; + mEndDelay = endDelay; + mSpan = (1 - mEndDelay - mStartDelay); + mInterpolator = interpolator; + mListener = listener; + } + + public void setPosition(float fraction) { + if (Float.isNaN(fraction)) return; + float t = constrain((fraction - mStartDelay) / mSpan, 0, 1); + if (mInterpolator != null) { + t = mInterpolator.getInterpolation(t); + } + if (t == mLastT) { + return; + } + if (mListener != null) { + if (t == 1) { + mListener.onAnimationAtEnd(); + } else if (t == 0) { + mListener.onAnimationAtStart(); + } else if (mLastT <= 0 || mLastT == 1) { + mListener.onAnimationStarted(); + } + mLastT = t; + } + for (int i = 0; i < mTargets.length; i++) { + mKeyframeSets[i].setValue(t, mTargets[i]); + } + } + + private static final FloatProperty POSITION = + new FloatProperty("position") { + @Override + public void setValue(TouchAnimator touchAnimator, float value) { + touchAnimator.setPosition(value); + } + + @Override + public Float get(TouchAnimator touchAnimator) { + return touchAnimator.mLastT; + } + }; + + public static class ListenerAdapter implements Listener { + @Override + public void onAnimationAtStart() { + } + + @Override + public void onAnimationAtEnd() { + } + + @Override + public void onAnimationStarted() { + } + } + + public interface Listener { + /** + * Called when the animator moves into a position of "0". Start and end delays are + * taken into account, so this position may cover a range of fractional inputs. + */ + void onAnimationAtStart(); + + /** + * Called when the animator moves into a position of "1". Start and end delays are + * taken into account, so this position may cover a range of fractional inputs. + */ + void onAnimationAtEnd(); + + /** + * Called when the animator moves out of the start or end position and is in a transient + * state. + */ + void onAnimationStarted(); + } + + public static class Builder { + private List mTargets = new ArrayList<>(); + private List mValues = new ArrayList<>(); + + private float mStartDelay; + private float mEndDelay; + @Nullable + private Interpolator mInterpolator; + @Nullable + private Listener mListener; + + public Builder addFloat(Object target, String property, float... values) { + add(target, KeyframeSet.ofFloat(getProperty(target, property, float.class), values)); + return this; + } + + public Builder addInt(Object target, String property, int... values) { + add(target, KeyframeSet.ofInt(getProperty(target, property, int.class), values)); + return this; + } + + private void add(Object target, KeyframeSet keyframeSet) { + mTargets.add(target); + mValues.add(keyframeSet); + } + + private static Property getProperty(Object target, String property, Class cls) { + if (target instanceof View) { + switch (property) { + case "translationX": + return View.TRANSLATION_X; + case "translationY": + return View.TRANSLATION_Y; + case "translationZ": + return View.TRANSLATION_Z; + case "alpha": + return View.ALPHA; + case "rotation": + return View.ROTATION; + case "x": + return View.X; + case "y": + return View.Y; + case "scaleX": + return View.SCALE_X; + case "scaleY": + return View.SCALE_Y; + } + } + if (target instanceof TouchAnimator && "position".equals(property)) { + return POSITION; + } + return Property.of(target.getClass(), cls, property); + } + + public Builder setStartDelay(float startDelay) { + mStartDelay = startDelay; + return this; + } + + public Builder setEndDelay(float endDelay) { + mEndDelay = endDelay; + return this; + } + + /** + * Sets interpolator. + */ + public Builder setInterpolator(@Nullable Interpolator intepolator) { + mInterpolator = intepolator; + return this; + } + + public Builder setListener(Listener listener) { + mListener = listener; + return this; + } + + public TouchAnimator build() { + return new TouchAnimator(mTargets.toArray(new Object[mTargets.size()]), + mValues.toArray(new KeyframeSet[mValues.size()]), + mStartDelay, mEndDelay, mInterpolator, mListener); + } + } + + private static abstract class KeyframeSet { + private final float mFrameWidth; + private final int mSize; + + public KeyframeSet(int size) { + mSize = size; + mFrameWidth = 1 / (float) (size - 1); + } + + void setValue(float fraction, Object target) { + int i = constrain((int) Math.ceil(fraction / mFrameWidth), 1, mSize - 1); + float amount = (fraction - mFrameWidth * (i - 1)) / mFrameWidth; + interpolate(i, amount, target); + } + + protected abstract void interpolate(int index, float amount, Object target); + + public static KeyframeSet ofInt(Property property, int... values) { + return new IntKeyframeSet((Property) property, values); + } + + public static KeyframeSet ofFloat(Property property, float... values) { + return new FloatKeyframeSet((Property) property, values); + } + } + + private static class FloatKeyframeSet extends KeyframeSet { + private final float[] mValues; + private final Property mProperty; + + public FloatKeyframeSet(Property property, float[] values) { + super(values.length); + mProperty = property; + mValues = values; + } + + @Override + protected void interpolate(int index, float amount, Object target) { + float firstFloat = mValues[index - 1]; + float secondFloat = mValues[index]; + mProperty.set((T) target, firstFloat + (secondFloat - firstFloat) * amount); + } + } + + private static class IntKeyframeSet extends KeyframeSet { + private final int[] mValues; + private final Property mProperty; + + public IntKeyframeSet(Property property, int[] values) { + super(values.length); + mProperty = property; + mValues = values; + } + + @Override + protected void interpolate(int index, float amount, Object target) { + int firstFloat = mValues[index - 1]; + int secondFloat = mValues[index]; + mProperty.set((T) target, (int) (firstFloat + (secondFloat - firstFloat) * amount)); + } + } + + private static int constrain(int amount, int low, int high) { + return amount < low ? low : (Math.min(amount, high)); + } + + private static float constrain(float amount, float low, float high) { + return amount < low ? low : (Math.min(amount, high)); + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/xposed/modules/utils/VibrationUtils.kt b/app/src/main/java/com/drdisagree/iconify/xposed/modules/utils/VibrationUtils.kt new file mode 100644 index 000000000..674dff4a4 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/xposed/modules/utils/VibrationUtils.kt @@ -0,0 +1,38 @@ +package com.drdisagree.iconify.xposed.modules.utils + +import android.annotation.SuppressLint +import android.content.Context +import android.os.VibrationEffect +import android.os.Vibrator +import java.util.concurrent.Executor +import java.util.concurrent.Executors + +object VibrationUtils { + + private val executor: Executor = Executors.newSingleThreadExecutor() + + @SuppressLint("MissingPermission") + @Suppress("deprecation") + fun triggerVibration(context: Context, intensity: Int) { + executor.execute(Runnable { + val vibrator = context.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator + if (intensity == 0) { + return@Runnable + } + + val effect = createVibrationEffect(intensity) ?: return@Runnable + vibrator.cancel() + vibrator.vibrate(effect) + }) + } + + private fun createVibrationEffect(intensity: Int): VibrationEffect? { + return when (intensity) { + 2 -> VibrationEffect.createPredefined(VibrationEffect.EFFECT_TICK) + 3 -> VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK) + 4 -> VibrationEffect.createPredefined(VibrationEffect.EFFECT_DOUBLE_CLICK) + 5 -> VibrationEffect.createPredefined(VibrationEffect.EFFECT_HEAVY_CLICK) + else -> null + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/xposed/modules/utils/ViewHelper.kt b/app/src/main/java/com/drdisagree/iconify/xposed/modules/utils/ViewHelper.kt index 7d67371b9..67d983cec 100644 --- a/app/src/main/java/com/drdisagree/iconify/xposed/modules/utils/ViewHelper.kt +++ b/app/src/main/java/com/drdisagree/iconify/xposed/modules/utils/ViewHelper.kt @@ -2,10 +2,18 @@ package com.drdisagree.iconify.xposed.modules.utils import android.content.Context import android.content.res.ColorStateList +import android.graphics.Bitmap +import android.graphics.Canvas import android.graphics.PorterDuff import android.graphics.PorterDuffColorFilter import android.graphics.Typeface +import android.graphics.drawable.BitmapDrawable import android.graphics.drawable.Drawable +import android.graphics.drawable.GradientDrawable +import android.renderscript.Allocation +import android.renderscript.Element +import android.renderscript.RenderScript +import android.renderscript.ScriptIntrinsicBlur import android.util.TypedValue import android.view.View import android.view.ViewGroup @@ -16,11 +24,14 @@ import android.widget.LinearLayout import android.widget.ProgressBar import android.widget.RelativeLayout import android.widget.TextView +import androidx.constraintlayout.widget.ConstraintLayout import de.robv.android.xposed.XposedBridge object ViewHelper { + private val TAG = "Iconify - ${ViewHelper::class.java.simpleName}: " + fun setMargins(viewGroup: Any, context: Context, left: Int, top: Int, right: Int, bottom: Int) { when (viewGroup) { is View -> { @@ -52,8 +63,19 @@ object ViewHelper { ) } + is ConstraintLayout.LayoutParams -> { + layoutParams.setMargins( + context.toPx(left), + context.toPx(top), + context.toPx(right), + context.toPx(bottom) + ) + } + else -> { - XposedBridge.log("Unsupported type: $layoutParams") + if (layoutParams != null) { + XposedBridge.log("Unsupported type: $layoutParams") + } } } } @@ -112,18 +134,53 @@ object ViewHelper { } } + fun findViewWithTagAndChangeColor( + view: View?, + tagContains: String, + color1: Int, + color2: Int, + cornerRadius: Int + ) { + if (view == null) return + + val drawable = GradientDrawable() + drawable.colors = intArrayOf(color1, color2) + drawable.orientation = GradientDrawable.Orientation.LEFT_RIGHT + drawable.cornerRadius = view.context.toPx(cornerRadius).toFloat() + + if (view is ViewGroup) { + for (i in 0 until view.childCount) { + val child: View = view.getChildAt(i) + checkTagAndChangeBackgroundColor(child, tagContains, drawable) + + if (child is ViewGroup) { + checkTagAndChangeBackgroundColor(child, tagContains, drawable) + } + } + } else { + checkTagAndChangeBackgroundColor(view, tagContains, drawable) + } + + } + private fun checkTagAndChangeColor(view: View, tag: String, color: Int) { if (view.tag?.toString()?.let { isTagMatch(tag, it) } == true) { changeViewColor(view, color) } } + private fun checkTagAndChangeBackgroundColor(view: View, tag: String, bkg: Drawable) { + if (view.tag?.toString()?.let { isTagMatch(tag, it) } == true) { + changeViewBackgroundColor(view, bkg) + } + } + private fun changeViewColor(view: View, color: Int) { when (view) { is TextView -> { view.setTextColor(color) - val drawablesRelative: Array = view.getCompoundDrawablesRelative() + val drawablesRelative: Array = view.compoundDrawablesRelative for (drawable in drawablesRelative) { drawable?.let { it.mutate() @@ -132,7 +189,7 @@ object ViewHelper { } } - val drawables: Array = view.getCompoundDrawables() + val drawables: Array = view.compoundDrawables for (drawable in drawables) { drawable?.let { it.mutate() @@ -151,8 +208,8 @@ object ViewHelper { } is ProgressBar -> { - view.setProgressTintList(ColorStateList.valueOf(color)) - view.setProgressBackgroundTintList(ColorStateList.valueOf(color)) + view.progressTintList = ColorStateList.valueOf(color) + view.progressBackgroundTintList = ColorStateList.valueOf(color) } else -> { @@ -161,6 +218,10 @@ object ViewHelper { } } + private fun changeViewBackgroundColor(view: View, bkg: Drawable) { + view.background = bkg + } + fun applyFontRecursively(view: View?, typeface: Typeface?) { if (view == null) return @@ -207,21 +268,21 @@ object ViewHelper { when (val params = child.layoutParams) { is LinearLayout.LayoutParams -> { params.topMargin += topMarginInDp - child.setLayoutParams(params) + child.layoutParams = params } is FrameLayout.LayoutParams -> { params.topMargin += topMarginInDp - child.setLayoutParams(params) + child.layoutParams = params } is RelativeLayout.LayoutParams -> { params.topMargin += topMarginInDp - child.setLayoutParams(params) + child.layoutParams = params } else -> { - XposedBridge.log("Invalid params: $params") + XposedBridge.log(TAG + "Invalid params: $params") } } } @@ -279,4 +340,87 @@ object ViewHelper { val parts = targetTag.split("|") return parts.any { it.trim() == tagToCheck } } + + fun Drawable.applyBlur(context: Context, radius: Float): Drawable { + if (radius == 0f) { + return this + } + + val bitmap = drawableToBitmap(this) + + val blurredBitmap = bitmap.applyBlur(context, radius.coerceIn(1f, 25f)) + + return BitmapDrawable(context.resources, blurredBitmap) + } + + private fun drawableToBitmap(drawable: Drawable): Bitmap { + if (drawable is BitmapDrawable) { + return drawable.bitmap + } + + val bitmap = Bitmap.createBitmap( + drawable.intrinsicWidth, + drawable.intrinsicHeight, + Bitmap.Config.ARGB_8888 + ) + + val canvas = Canvas(bitmap) + drawable.setBounds(0, 0, canvas.width, canvas.height) + drawable.draw(canvas) + + return bitmap + } + + @Suppress("deprecation") + fun Bitmap.applyBlur(context: Context?, radius: Float): Bitmap { + if (radius == 0f) { + return this + } + + var tempImage = this + + try { + tempImage = rgb565toArgb888() + } catch (e: Exception) { + e.printStackTrace() + } + + val bitmap = Bitmap.createBitmap( + tempImage.width, tempImage.height, + Bitmap.Config.ARGB_8888 + ) + val renderScript = RenderScript.create(context) + val blurInput = Allocation.createFromBitmap(renderScript, tempImage) + val blurOutput = Allocation.createFromBitmap(renderScript, bitmap) + + ScriptIntrinsicBlur.create( + renderScript, + Element.U8_4(renderScript) + ).apply { + setInput(blurInput) + setRadius(radius) // radius must be 0 < r <= 25 + forEach(blurOutput) + } + + blurOutput.copyTo(bitmap) + renderScript.destroy() + + return bitmap + } + + private fun Bitmap.rgb565toArgb888(): Bitmap { + val numPixels = width * height + val pixels = IntArray(numPixels) + + // Get JPEG pixels. Each int is the color values for one pixel. + getPixels(pixels, 0, width, 0, 0, width, height) + + // Create a Bitmap of the appropriate format. + val result = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888) + + // Set RGB pixels. + result.setPixels(pixels, 0, result.width, 0, 0, result.width, result.height) + + return result + } } diff --git a/app/src/main/java/com/drdisagree/iconify/xposed/modules/views/ChipDrawable.kt b/app/src/main/java/com/drdisagree/iconify/xposed/modules/views/ChipDrawable.kt new file mode 100644 index 000000000..75184e707 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/xposed/modules/views/ChipDrawable.kt @@ -0,0 +1,100 @@ +package com.drdisagree.iconify.xposed.modules.views + +import android.content.Context +import android.graphics.drawable.GradientDrawable +import android.graphics.drawable.LayerDrawable +import androidx.core.content.ContextCompat +import com.drdisagree.iconify.xposed.modules.utils.ViewHelper.toPx + +object ChipDrawable { + + enum class GradientDirection(val index: Int) { + TOP_BOTTOM(0), + BOTTOM_TOP(1), + LEFT_RIGHT(2), + RIGHT_LEFT(3), + TOP_LEFT_BOTTOM_RIGHT(4), + TOP_RIGHT_BOTTOM_LEFT(5), + BOTTOM_LEFT_TOP_RIGHT(6), + BOTTOM_RIGHT_TOP_LEFT(7); + + companion object { + fun fromIndex(index: Int): GradientDirection { + return entries.firstOrNull { it.index == index } ?: TOP_BOTTOM + } + + fun GradientDirection.toIndex(): Int { + return this.index + } + } + } + + + fun createChipDrawable( + context: Context, + accentFill: Boolean = true, + startColor: Int = 0xFF0000, + endColor: Int = 0x00FF00, + gradientDirection: GradientDirection = GradientDirection.LEFT_RIGHT, + padding: IntArray = intArrayOf(0, 0, 0, 0), + strokeEnabled: Boolean = false, + accentStroke: Boolean = true, + strokeWidth: Int = 2, + strokeColor: Int = 0x000000, + dashedBorderEnabled: Boolean = false, + dashWidth: Int = 4, + dashGap: Int = 4, + cornerRadii: FloatArray = floatArrayOf(0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f) + ): LayerDrawable { + val gradientDrawable = GradientDrawable().apply { + colors = if (accentFill) { + val color = ContextCompat.getColor(context, android.R.color.system_accent1_400) + intArrayOf(color, color) + } else { + intArrayOf(startColor, endColor) + } + orientation = when (gradientDirection) { + GradientDirection.TOP_BOTTOM -> GradientDrawable.Orientation.LEFT_RIGHT + GradientDirection.BOTTOM_TOP -> GradientDrawable.Orientation.RIGHT_LEFT + GradientDirection.LEFT_RIGHT -> GradientDrawable.Orientation.TOP_BOTTOM + GradientDirection.RIGHT_LEFT -> GradientDrawable.Orientation.BOTTOM_TOP + GradientDirection.TOP_LEFT_BOTTOM_RIGHT -> GradientDrawable.Orientation.TL_BR + GradientDirection.TOP_RIGHT_BOTTOM_LEFT -> GradientDrawable.Orientation.TR_BL + GradientDirection.BOTTOM_LEFT_TOP_RIGHT -> GradientDrawable.Orientation.BL_TR + GradientDirection.BOTTOM_RIGHT_TOP_LEFT -> GradientDrawable.Orientation.BR_TL + } + shape = GradientDrawable.RECTANGLE + setPadding( + context.toPx(padding[0]), + context.toPx(padding[1]), + context.toPx(padding[2]), + context.toPx(padding[3]) + ) + setCornerRadii( + cornerRadii.map { context.toPx(it.toInt()).toFloat() }.toFloatArray() + ) + if (strokeEnabled) { + val color = if (accentStroke) { + ContextCompat.getColor(context, android.R.color.system_accent3_400) + } else { + strokeColor + } + if (dashedBorderEnabled) { + setStroke( + context.toPx(strokeWidth), + color, + context.toPx(dashWidth).toFloat(), + context.toPx(dashGap).toFloat() + ) + } else { + setStroke( + context.toPx(strokeWidth), + color + ) + } + } + } + + return LayerDrawable(arrayOf(gradientDrawable)) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/xposed/modules/views/CurrentWeatherView.kt b/app/src/main/java/com/drdisagree/iconify/xposed/modules/views/CurrentWeatherView.kt new file mode 100644 index 000000000..4b19ab067 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/xposed/modules/views/CurrentWeatherView.kt @@ -0,0 +1,528 @@ +package com.drdisagree.iconify.xposed.modules.views + +import android.annotation.SuppressLint +import android.content.Context +import android.content.pm.PackageManager +import android.content.res.Resources +import android.graphics.drawable.Drawable +import android.text.TextUtils +import android.util.Log +import android.util.TypedValue +import android.view.Gravity +import android.widget.ImageView +import android.widget.LinearLayout +import android.widget.TextView +import androidx.core.content.ContextCompat +import androidx.core.content.res.ResourcesCompat +import com.drdisagree.iconify.BuildConfig +import com.drdisagree.iconify.R +import com.drdisagree.iconify.ui.utils.ViewHelper.applyTextSizeRecursively +import com.drdisagree.iconify.ui.utils.ViewHelper.setTextRecursively +import com.drdisagree.iconify.utils.OmniJawsClient +import com.drdisagree.iconify.xposed.HookRes.Companion.modRes +import com.drdisagree.iconify.xposed.modules.utils.ViewHelper.findViewContainsTag +import com.drdisagree.iconify.xposed.modules.utils.ViewHelper.findViewWithTagAndChangeColor +import de.robv.android.xposed.XposedBridge.log +import java.util.Locale +import java.util.function.Consumer + +@SuppressLint("ViewConstructor") +class CurrentWeatherView(context: Context, name: String) : LinearLayout(context), + OmniJawsClient.OmniJawsObserver { + + private var mCurrentImage: ImageView? = null + private var mHumImage: ImageView? = null + private var mWindImage: ImageView? = null + private val mWeatherClient: OmniJawsClient? + private var mWeatherInfo: OmniJawsClient.WeatherInfo? = null + private var mLeftText: TextView? = null + private var mRightText: TextView? = null + private var mWeatherText: TextView? = null // Weather Layout + private var mHumText: TextView? = null + private var mWindText: TextView? = null + private val mWeatherLayout: LinearLayout? = null + private var mHumLayout: LinearLayout? = null + private var mWindLayout: LinearLayout? = null + private var mHumDrawable: Drawable? = null + private var mWindDrawable: Drawable? = null + private var mWeatherBgSelection = 0 + private var mShowWeatherLocation = false + private var mShowWeatherText = false + private var mShowWeatherHumidity = false + private var mShowWeatherWind = false + private var mWeatherHorPadding = 0 + private var mWeatherVerPadding = 0 + private val mContext: Context + private var appContext: Context? = null + + init { + instances.add(arrayOf(this, name)) + mContext = context + try { + appContext = context.createPackageContext( + BuildConfig.APPLICATION_ID, + Context.CONTEXT_IGNORE_SECURITY + ) + } catch (ignored: PackageManager.NameNotFoundException) { + } + mWeatherClient = OmniJawsClient(mContext) + + inflateView() + + enableUpdates() + } + + private fun inflateView() { + inflate(appContext, R.layout.view_current_weather, this) + setupViews() + } + + private fun setupViews() { + mLeftText = findViewContainsTag("leftText") as TextView + mCurrentImage = findViewContainsTag("currentImage") as ImageView + mRightText = findViewContainsTag("rightText") as TextView + mWeatherText = findViewContainsTag("weatherText") as TextView + mHumLayout = findViewContainsTag("humLayout") as LinearLayout + mHumImage = findViewContainsTag("humImage") as ImageView + mHumText = findViewContainsTag("humText") as TextView + mWindLayout = findViewContainsTag("windLayout") as LinearLayout + mWindImage = findViewContainsTag("windImage") as ImageView + mWindText = findViewContainsTag("windText") as TextView + + mWindDrawable = ContextCompat.getDrawable( + appContext!!, + R.drawable.ic_wind_symbol + ) + + mHumDrawable = ContextCompat.getDrawable( + appContext!!, + R.drawable.ic_humidity_symbol + ) + } + + fun updateSizes(weatherTextSize: Int, weatherImageSize: Int, name: String) { + if (instances.isEmpty()) return + updateIconsSize(weatherImageSize, name) + instances + .stream() + .filter { obj: Array -> + obj[1] == name + } + .forEach { obj: Array -> + applyTextSizeRecursively( + obj[0] as CurrentWeatherView, + weatherTextSize + ) + } + } + + fun updateColors(color: Int, name: String) { + if (instances.isEmpty()) return + instances + .stream() + .filter { obj: Array -> + obj[1] == name + } + .forEach { obj: Array -> + val instance = obj[0] as CurrentWeatherView + findViewWithTagAndChangeColor(instance, "text", color) + } + } + + private fun enableUpdates() { + if (mWeatherClient != null) { + mWeatherClient.addObserver(this) + queryAndUpdateWeather() + } + } + + private fun setErrorView(errorReason: Int) { + var reQuery = false + val errorText = when (errorReason) { + OmniJawsClient.EXTRA_ERROR_DISABLED -> modRes.getString(R.string.omnijaws_service_disabled) + OmniJawsClient.EXTRA_ERROR_NO_PERMISSIONS -> modRes.getString(R.string.omnijaws_service_error_permissions) + else -> "" + } + if (!TextUtils.isEmpty(errorText)) { + mLeftText!!.text = errorText + } else { + reQuery = true + } + if (reQuery) { + queryAndUpdateWeather() + } else { + setTextRecursively(this, "") + mCurrentImage!!.setImageDrawable(null) + mHumImage!!.setImageDrawable(null) + mWindImage!!.setImageDrawable(null) + } + } + + override fun weatherError(errorReason: Int) { + // Show only Disabled and Permission errors + log(TAG + "weatherError " + errorReason) + if (errorReason == OmniJawsClient.EXTRA_ERROR_DISABLED) { + mWeatherInfo = null + } + setErrorView(errorReason) + } + + override fun weatherUpdated() { + queryAndUpdateWeather() + } + + override fun updateSettings() { + queryAndUpdateWeather() + } + + @SuppressLint("SetTextI18n") + private fun queryAndUpdateWeather() { + try { + if (mWeatherClient == null || !mWeatherClient.isOmniJawsEnabled) { + setErrorView(2) + return + } + mWeatherClient.queryWeather() + mWeatherInfo = mWeatherClient.weatherInfo + if (mWeatherInfo != null) { + val formattedConditionLowercase = + mWeatherInfo!!.condition.toString().lowercase(Locale.getDefault()) + + val formattedCondition = when { + formattedConditionLowercase.contains("clouds") -> { + modRes.getString(R.string.weather_condition_clouds) + } + + formattedConditionLowercase.contains("rain") -> { + modRes.getString(R.string.weather_condition_rain) + } + + formattedConditionLowercase.contains("clear") -> { + modRes.getString(R.string.weather_condition_clear) + } + + formattedConditionLowercase.contains("storm") -> { + modRes.getString(R.string.weather_condition_storm) + } + + formattedConditionLowercase.contains("snow") -> { + modRes.getString(R.string.weather_condition_snow) + } + + formattedConditionLowercase.contains("wind") -> { + modRes.getString(R.string.weather_condition_wind) + } + + formattedConditionLowercase.contains("mist") -> { + modRes.getString(R.string.weather_condition_mist) + } + + else -> { + mWeatherInfo!!.condition.toString() + } + } + + val d: Drawable = + mWeatherClient.getWeatherConditionImage(mWeatherInfo!!.conditionCode) + mCurrentImage!!.setImageDrawable(d) + mRightText!!.text = mWeatherInfo!!.temp + mWeatherInfo!!.tempUnits + mLeftText!!.text = mWeatherInfo!!.city + mLeftText!!.visibility = if (mShowWeatherLocation) VISIBLE else GONE + mWeatherText!!.text = " · $formattedCondition" + mWeatherText!!.visibility = if (mShowWeatherText) VISIBLE else GONE + + mHumImage!!.setImageDrawable(mHumDrawable) + mHumText!!.text = mWeatherInfo!!.humidity + mHumLayout!!.visibility = if (mShowWeatherHumidity) VISIBLE else GONE + + mWindImage!!.setImageDrawable(mWindDrawable) + mWindText!!.text = + ((mWeatherInfo!!.windDirection + " " + mWeatherInfo!!.pinWheel) + " · " + mWeatherInfo!!.windSpeed) + " " + mWeatherInfo!!.windUnits + mWindLayout!!.visibility = if (mShowWeatherWind) VISIBLE else GONE + } + } catch (e: Exception) { + log(TAG + "Weather query failed" + e.message) + Log.e(TAG, "Weather query failed", e) + } + } + + fun updateWeatherBg(selection: Int, name: String) { + if (instances.isEmpty()) return + instances + .stream() + .filter { obj: Array -> + obj[1] == name + } + .forEach { obj: Array -> + val instance = obj[0] as CurrentWeatherView + instance.mWeatherBgSelection = selection + instance.updateWeatherBg() + } + } + + fun reloadWeatherBg() { + if (instances.isEmpty()) return + instances.forEach(Consumer { obj: Array -> + val instance = obj[0] as CurrentWeatherView + instance.updateWeatherBg() + }) + } + + private fun updateWeatherBg() { + var bg: Drawable? = null + try { + appContext = mContext.createPackageContext( + BuildConfig.APPLICATION_ID, + Context.CONTEXT_IGNORE_SECURITY + ) + } catch (ignored: PackageManager.NameNotFoundException) { + } + when (mWeatherBgSelection) { + 0 -> { + bg = null + mWeatherHorPadding = 0 + mWeatherVerPadding = 0 + } + + 1 -> { + bg = ResourcesCompat.getDrawable( + appContext!!.resources, + R.drawable.date_box_str_border, + appContext!!.theme + ) + mWeatherHorPadding = Math.round( + TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_PX, + modRes.getDimensionPixelSize(R.dimen.widget_date_box_padding_hor).toFloat(), + mContext.resources.displayMetrics + ) + ) + mWeatherVerPadding = Math.round( + TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_PX, + modRes.getDimensionPixelSize(R.dimen.widget_date_box_padding_ver).toFloat(), + mContext.resources.displayMetrics + ) + ) + } + + 2 -> { + bg = ResourcesCompat.getDrawable( + appContext!!.resources, + R.drawable.date_str_border, + appContext!!.theme + ) + mWeatherHorPadding = Math.round( + TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_PX, + modRes.getDimensionPixelSize(R.dimen.widget_date_box_padding_hor).toFloat(), + mContext.resources.displayMetrics + ) + ) + mWeatherVerPadding = Math.round( + TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_PX, + modRes.getDimensionPixelSize(R.dimen.widget_date_box_padding_ver).toFloat(), + mContext.resources.displayMetrics + ) + ) + } + + 3 -> { + bg = ResourcesCompat.getDrawable( + appContext!!.resources, + R.drawable.ambient_indication_pill_background, + appContext!!.theme + ) + mWeatherHorPadding = Math.round( + TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_PX, + modRes.getDimensionPixelSize(R.dimen.q_nowplay_pill_padding_hor).toFloat(), + mContext.resources.displayMetrics + ) + ) + mWeatherVerPadding = Math.round( + TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_PX, + modRes.getDimensionPixelSize(R.dimen.q_nowplay_pill_padding_ver).toFloat(), + mContext.resources.displayMetrics + ) + ) + } + + 4, 5 -> { + bg = ResourcesCompat.getDrawable( + appContext!!.resources, + R.drawable.date_str_accent, + appContext!!.theme + ) + mWeatherHorPadding = Math.round( + TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_PX, + modRes.getDimensionPixelSize(R.dimen.widget_date_accent_box_padding_hor) + .toFloat(), + mContext.resources.displayMetrics + ) + ) + mWeatherVerPadding = Math.round( + TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_PX, + modRes.getDimensionPixelSize(R.dimen.widget_date_accent_box_padding_ver) + .toFloat(), + mContext.resources.displayMetrics + ) + ) + } + + 6 -> { + bg = ResourcesCompat.getDrawable( + appContext!!.resources, + R.drawable.date_str_gradient, + appContext!!.theme + ) + mWeatherHorPadding = Math.round( + TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_PX, + modRes.getDimensionPixelSize(R.dimen.widget_date_accent_box_padding_hor) + .toFloat(), + mContext.resources.displayMetrics + ) + ) + mWeatherVerPadding = Math.round( + TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_PX, + modRes.getDimensionPixelSize(R.dimen.widget_date_accent_box_padding_ver) + .toFloat(), + mContext.resources.displayMetrics + ) + ) + } + + 7 -> { + bg = ResourcesCompat.getDrawable( + appContext!!.resources, + R.drawable.date_str_borderacc, + appContext!!.theme + ) + mWeatherHorPadding = Math.round( + TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_PX, + modRes.getDimensionPixelSize(R.dimen.widget_date_accent_box_padding_hor) + .toFloat(), + mContext.resources.displayMetrics + ) + ) + mWeatherVerPadding = Math.round( + TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_PX, + modRes.getDimensionPixelSize(R.dimen.widget_date_accent_box_padding_ver) + .toFloat(), + mContext.resources.displayMetrics + ) + ) + } + + 8 -> { + bg = ResourcesCompat.getDrawable( + appContext!!.resources, + R.drawable.date_str_bordergrad, + appContext!!.theme + ) + mWeatherHorPadding = Math.round( + TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_PX, + modRes.getDimensionPixelSize(R.dimen.widget_date_accent_box_padding_hor) + .toFloat(), + mContext.resources.displayMetrics + ) + ) + mWeatherVerPadding = Math.round( + TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_PX, + modRes.getDimensionPixelSize(R.dimen.widget_date_accent_box_padding_ver) + .toFloat(), + mContext.resources.displayMetrics + ) + ) + } + + else -> {} + } + setViewBackground(bg, if ((bg != null && mWeatherBgSelection == 5)) 160 else 255) + setPadding(mWeatherHorPadding, mWeatherVerPadding, mWeatherHorPadding, mWeatherVerPadding) + } + + private fun setViewBackground(drawRes: Drawable?, bgAlpha: Int) { + drawRes?.mutate() + background = drawRes + if (drawRes != null) background.alpha = bgAlpha + } + + fun updateWeatherSettings( + showLocation: Boolean, showText: Boolean, + showHumidity: Boolean, showWind: Boolean, name: String + ) { + instances.stream() + .filter { obj: Array -> + obj[1] == name + } + .forEach { obj: Array -> + val instance = obj[0] as CurrentWeatherView + instance.mShowWeatherLocation = showLocation + instance.mShowWeatherText = showText + instance.mShowWeatherHumidity = showHumidity + instance.mShowWeatherWind = showWind + instance.mLeftText!!.visibility = if (showLocation) VISIBLE else GONE + instance.mWeatherText!!.visibility = if (showText) VISIBLE else GONE + instance.mHumLayout!!.visibility = if (showHumidity) VISIBLE else GONE + instance.mWindLayout!!.visibility = if (showWind) VISIBLE else GONE + instance.updateSettings() + } + } + + companion object { + private val TAG: String = CurrentWeatherView::class.java.name + + val Int.dp: Int + get() = (this * Resources.getSystem().displayMetrics.density + 0.5f).toInt() + + @SuppressLint("StaticFieldLeak") + var instances: ArrayList> = ArrayList() + fun updateIconsSize(size: Int, name: String) { + instances + .stream() + .filter { obj: Array -> + obj[1] == name + } + .forEach { obj: Array -> + val instance = obj[0] as CurrentWeatherView + val params = instance.mCurrentImage!!.layoutParams as LayoutParams + params.width = size.dp + params.height = size.dp + params.gravity = Gravity.CENTER_VERTICAL + instance.mCurrentImage!!.layoutParams = params + instance.mHumImage!!.layoutParams = params + instance.mWindImage!!.layoutParams = params + } + } + + fun getInstance(c: Context, name: String): CurrentWeatherView { + for (obj in instances) { + if (obj[1] == name) { + return obj[0] as CurrentWeatherView + } + } + return CurrentWeatherView(c, name) + } + + fun getInstance(name: String): CurrentWeatherView? { + for (obj in instances) { + if (obj[1] == name) { + return obj[0] as CurrentWeatherView + } + } + return null + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/xposed/modules/views/DeviceWidgetView.kt b/app/src/main/java/com/drdisagree/iconify/xposed/modules/views/DeviceWidgetView.kt new file mode 100644 index 000000000..e767a1e3d --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/xposed/modules/views/DeviceWidgetView.kt @@ -0,0 +1,224 @@ +package com.drdisagree.iconify.xposed.modules.views + +import android.app.ActivityManager +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import android.content.IntentFilter +import android.content.pm.PackageManager +import android.content.res.ColorStateList +import android.graphics.Color +import android.media.AudioManager +import android.os.BatteryManager +import android.os.Build +import android.text.TextUtils +import android.widget.FrameLayout +import android.widget.ImageView +import android.widget.ProgressBar +import android.widget.TextView +import androidx.core.content.ContextCompat +import com.drdisagree.iconify.BuildConfig +import com.drdisagree.iconify.R +import com.drdisagree.iconify.xposed.modules.utils.ArcProgressWidget.generateBitmap +import com.drdisagree.iconify.xposed.modules.utils.ViewHelper.findViewContainsTag +import com.drdisagree.iconify.xposed.modules.utils.ViewHelper.findViewWithTagAndChangeColor + +class DeviceWidgetView(private val mContext: Context) : FrameLayout(mContext) { + private var appContext: Context? = null + + private var mBatteryLevelView: TextView? = null + private var mBatteryProgress: ProgressBar? = null + private var mBatteryPercentage = 1 + private var mVolumeLevelArcProgress: ImageView? = null + private var mRamUsageArcProgress: ImageView? = null + + private val mAudioManager: AudioManager + private val mActivityManager: ActivityManager? + + private var mCustomColor = false + private var mProgressColor = 0 + private var mLinearProgressColor = 0 + private var mTextColor = 0 + + init { + try { + appContext = mContext.createPackageContext( + BuildConfig.APPLICATION_ID, + Context.CONTEXT_IGNORE_SECURITY + ) + } catch (ignored: PackageManager.NameNotFoundException) { + } + + mAudioManager = mContext.getSystemService(Context.AUDIO_SERVICE) as AudioManager + mActivityManager = mContext.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager + + try { + val mBatteryReceiver: BroadcastReceiver = object : BroadcastReceiver() { + override fun onReceive(context: Context, intent: Intent) { + if (intent.action != null && intent.action == Intent.ACTION_BATTERY_CHANGED) { + val level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0) + val scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, 100) + mBatteryPercentage = (level * 100) / scale + initBatteryStatus() + } + } + } + mContext.registerReceiver(mBatteryReceiver, IntentFilter(Intent.ACTION_BATTERY_CHANGED)) + } catch (ignored: Exception) { + } + try { + val mVolumeReceiver: BroadcastReceiver = object : BroadcastReceiver() { + override fun onReceive(context: Context, intent: Intent) { + initSoundManager() + } + } + mContext.registerReceiver( + mVolumeReceiver, + IntentFilter("android.media.VOLUME_CHANGED_ACTION") + ) + } catch (ignored: Exception) { + } + + inflateView() + } + + private fun inflateView() { + inflate(appContext, R.layout.view_device_widget, this) + setupViews() + initSoundManager() + } + + private fun setupViews() { + mBatteryLevelView = findViewContainsTag("battery_percentage") as TextView + mBatteryProgress = findViewContainsTag("battery_progressbar") as ProgressBar + mVolumeLevelArcProgress = findViewContainsTag("volume_progress") as ImageView + mRamUsageArcProgress = findViewContainsTag("ram_usage_info") as ImageView + + mBatteryProgress!!.progressTintList = ColorStateList.valueOf( + if (mCustomColor) + if (mLinearProgressColor == 0) mContext.resources.getColor( + mContext.resources.getIdentifier( + "android:color/system_accent1_300", + "color", + mContext.packageName + ), mContext.theme + ) + else mLinearProgressColor + else + mLinearProgressColor + ) + + (findViewContainsTag("device_name") as TextView).text = + Build.MODEL + } + + private fun initBatteryStatus() { + if (mBatteryProgress != null) { + post { + mBatteryProgress!!.progress = mBatteryPercentage + mBatteryProgress!!.progressTintList = ColorStateList.valueOf( + if (mCustomColor) + if (mLinearProgressColor == 0) mContext.resources.getColor( + mContext.resources.getIdentifier( + "android:color/system_accent1_300", + "color", + mContext.packageName + ), mContext.theme + ) + else mLinearProgressColor + else + mLinearProgressColor + ) + } + } + if (mBatteryLevelView != null) { + post { + mBatteryLevelView!!.text = appContext!!.resources + .getString(R.string.percentage_text, mBatteryPercentage) + } + } + + initRamUsage() + } + + private fun initSoundManager() { + val volLevel = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC) + val maxVolLevel = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC) + val volPercent = ((volLevel.toFloat() / maxVolLevel) * 100).toInt() + + if (mVolumeLevelArcProgress != null) { + val widgetBitmap = generateBitmap( + mContext, + volPercent, + appContext!!.resources.getString(R.string.percentage_text, volPercent), + 40, + ContextCompat.getDrawable(appContext!!, R.drawable.ic_volume_up), + 36 + ) + post { mVolumeLevelArcProgress!!.setImageBitmap(widgetBitmap) } + } + } + + private fun initRamUsage() { + if (mActivityManager == null) return + + val memoryInfo = ActivityManager.MemoryInfo() + mActivityManager.getMemoryInfo(memoryInfo) + val usedMemory = memoryInfo.totalMem - memoryInfo.availMem + if (memoryInfo.totalMem == 0L) return + val usedMemoryPercentage = ((usedMemory * 100) / memoryInfo.totalMem).toInt() + + if (mRamUsageArcProgress != null) { + val widgetBitmap = generateBitmap( + context = mContext, + percentage = usedMemoryPercentage, + textInside = appContext!!.resources.getString( + R.string.percentage_text, + usedMemoryPercentage + ), + textInsideSizePx = 40, + textBottom = "RAM", + textBottomSizePx = 28 + ) + post { mRamUsageArcProgress!!.setImageBitmap(widgetBitmap) } + } + } + + fun setCustomColor(customColor: Boolean, linearColor: Int, circularColor: Int) { + mCustomColor = customColor + mProgressColor = linearColor + mLinearProgressColor = circularColor + post { this.initSoundManager() } + post { + findViewWithTagAndChangeColor( + this, + "circularprogress", + if (mCustomColor) mProgressColor else Color.WHITE + ) + } + } + + fun setTextCustomColor(color: Int) { + mTextColor = color + post { + findViewWithTagAndChangeColor( + this, + "text1", + mTextColor + ) + } + } + + fun setDeviceName(devName: String?) { + val deviceName = if (!TextUtils.isEmpty(devName)) { + devName + } else { + Build.MODEL + } + + post { + (findViewContainsTag("device_name") as TextView).text = + deviceName + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/xposed/modules/views/LockscreenWidgetsView.kt b/app/src/main/java/com/drdisagree/iconify/xposed/modules/views/LockscreenWidgetsView.kt new file mode 100644 index 000000000..bbe45ef91 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/xposed/modules/views/LockscreenWidgetsView.kt @@ -0,0 +1,1842 @@ +package com.drdisagree.iconify.xposed.modules.views + +import android.annotation.SuppressLint +import android.bluetooth.BluetoothAdapter +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import android.content.IntentFilter +import android.content.res.ColorStateList +import android.content.res.Configuration +import android.graphics.drawable.Drawable +import android.hardware.camera2.CameraManager +import android.media.AudioManager +import android.media.MediaMetadata +import android.media.session.MediaController +import android.media.session.MediaController.PlaybackInfo +import android.media.session.MediaSessionManager +import android.media.session.PlaybackState +import android.net.ConnectivityManager +import android.net.NetworkCapabilities +import android.net.wifi.WifiConfiguration +import android.net.wifi.WifiManager +import android.os.Build +import android.os.Handler +import android.os.Looper +import android.os.SystemClock +import android.telephony.TelephonyManager +import android.util.Log +import android.view.GestureDetector +import android.view.GestureDetector.SimpleOnGestureListener +import android.view.Gravity +import android.view.HapticFeedbackConstants +import android.view.KeyEvent +import android.view.MotionEvent +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.LinearLayout +import androidx.core.content.ContextCompat +import androidx.core.content.res.ResourcesCompat +import com.drdisagree.iconify.R +import com.drdisagree.iconify.common.Const.FRAMEWORK_PACKAGE +import com.drdisagree.iconify.common.Const.SYSTEMUI_PACKAGE +import com.drdisagree.iconify.utils.OmniJawsClient +import com.drdisagree.iconify.xposed.HookEntry.Companion.enqueueProxyCommand +import com.drdisagree.iconify.xposed.HookRes.Companion.modRes +import com.drdisagree.iconify.xposed.modules.ControllersProvider +import com.drdisagree.iconify.xposed.modules.LockscreenWidgets.Companion.LaunchableImageView +import com.drdisagree.iconify.xposed.modules.LockscreenWidgets.Companion.LaunchableLinearLayout +import com.drdisagree.iconify.xposed.modules.utils.ActivityLauncherUtils +import com.drdisagree.iconify.xposed.modules.utils.ExtendedFAB +import com.drdisagree.iconify.xposed.modules.utils.ViewHelper.toPx +import de.robv.android.xposed.XposedBridge.log +import de.robv.android.xposed.XposedHelpers.callMethod +import de.robv.android.xposed.XposedHelpers.getBooleanField +import java.lang.reflect.Method +import java.util.Locale +import kotlin.math.abs +import kotlin.math.min + +@SuppressLint("ViewConstructor") +class LockscreenWidgetsView(context: Context, activityStarter: Any?) : + LinearLayout(context), OmniJawsClient.OmniJawsObserver { + + private val mContext: Context + + private var mWeatherClient: OmniJawsClient? = null + private var mWeatherInfo: OmniJawsClient.WeatherInfo? = null + + // Two Linear Layouts, one for main widgets and one for secondary widgets + private var mDeviceWidgetContainer: LinearLayout? = null + private var mMainWidgetsContainer: LinearLayout? = null + private var mSecondaryWidgetsContainer: LinearLayout? = null + private var mDeviceWidgetView: DeviceWidgetView? = null + + private var mediaButtonFab: ExtendedFAB? = null + private var torchButtonFab: ExtendedFAB? = null + private var weatherButtonFab: ExtendedFAB? = null + private var wifiButtonFab: ExtendedFAB? = null + private var dataButtonFab: ExtendedFAB? = null + private var ringerButtonFab: ExtendedFAB? = null + private var btButtonFab: ExtendedFAB? = null + private var hotspotButtonFab: ExtendedFAB? = null + private var mediaButton: ImageView? = null + private var torchButton: ImageView? = null + private var weatherButton: ImageView? = null + private var hotspotButton: ImageView? = null + private var wifiButton: ImageView? = null + private var dataButton: ImageView? = null + private var ringerButton: ImageView? = null + private var btButton: ImageView? = null + private val mDarkColor: Int + private val mDarkColorActive: Int + private val mLightColor: Int + private val mLightColorActive: Int + + // Custom Widgets Colors + private var mCustomColors = false + private var mBigInactiveColor = 0 + private var mBigActiveColor = 0 + private var mSmallInactiveColor = 0 + private var mSmallActiveColor = 0 + private var mBigIconInactiveColor = 0 + private var mBigIconActiveColor = 0 + private var mSmallIconInactiveColor = 0 + private var mSmallIconActiveColor = 0 + + // Widgets Dimens + private var mFabWidth = 0 + private var mFabHeight = 0 + private var mFabMarginStart = 0 + private var mFabMarginEnd = 0 + private var mFabPadding = 0 + private var mWidgetCircleSize = 0 + private var mWidgetMarginHorizontal = 0 + private var mWidgetMarginVertical = 0 + private var mWidgetIconPadding = 0 + private var mWidgetsScale = 1f + + private var mMainLockscreenWidgetsList: String? = null + private var mSecondaryLockscreenWidgetsList: String? = null + private var mMainWidgetViews: Array? = null + private var mSecondaryWidgetViews: Array? = null + private var mMainWidgetsList: List? = ArrayList() + private var mSecondaryWidgetsList: List? = ArrayList() + private var mIsLargeClock: Boolean = false + + private val mAudioManager: AudioManager? + private val mWifiManager: WifiManager? + private val mTelephonyManager: TelephonyManager? + private val mConnectivityManager: ConnectivityManager? + private var mController: MediaController? = null + private var mMediaMetadata: MediaMetadata? = null + private var mLastTrackTitle: String? = null + + private var lockscreenWidgetsEnabled = false + private var deviceWidgetsEnabled = false + + private var isBluetoothOn = false + + private var mIsInflated = false + private var mIsLongPress = false + + private val mCameraManager: CameraManager + private var mCameraId: String? = null + private var isFlashOn = false + + private val mAudioMode = 0 + private val mMediaUpdater: Runnable + private val mHandler: Handler + + // Dozing State + private var mDozing: Boolean = false + + private var mActivityLauncherUtils: ActivityLauncherUtils + + private val mScreenOnReceiver: BroadcastReceiver = object : BroadcastReceiver() { + override fun onReceive(context: Context, intent: Intent) { + if (Intent.ACTION_SCREEN_ON == intent.action) { + onVisible() + } + } + } + + private val mMediaCallback: MediaController.Callback = object : MediaController.Callback() { + override fun onPlaybackStateChanged(state: PlaybackState?) { + updateMediaController() + } + + override fun onMetadataChanged(metadata: MediaMetadata?) { + super.onMetadataChanged(metadata) + mMediaMetadata = metadata + updateMediaController() + } + } + + private val mMobileDataCallback: ControllersProvider.OnMobileDataChanged = + object : ControllersProvider.OnMobileDataChanged { + override fun setMobileDataIndicators(mMobileDataIndicators: Any?) { + updateMobileDataState(isMobileDataEnabled) + } + + override fun setNoSims(show: Boolean, simDetected: Boolean) { + updateMobileDataState(simDetected && isMobileDataEnabled) + } + + override fun setIsAirplaneMode(mIconState: Any?) { + updateMobileDataState( + !getBooleanField( + mIconState, + "visible" + ) && isMobileDataEnabled + ) + } + } + + private val mWifiCallback: ControllersProvider.OnWifiChanged = + object : ControllersProvider.OnWifiChanged { + override fun onWifiChanged(mWifiIndicators: Any?) { + updateWiFiButtonState(isWifiEnabled) + } + } + + private val mBluetoothCallback: ControllersProvider.OnBluetoothChanged = + object : ControllersProvider.OnBluetoothChanged { + override fun onBluetoothChanged(enabled: Boolean) { + isBluetoothOn = enabled + updateBtState() + } + } + + private val mTorchCallback: ControllersProvider.OnTorchModeChanged = + object : ControllersProvider.OnTorchModeChanged { + override fun onTorchModeChanged(enabled: Boolean) { + isFlashOn = enabled + updateTorchButtonState() + } + } + + private val mHotspotCallback: ControllersProvider.OnHotspotChanged = + object : ControllersProvider.OnHotspotChanged { + override fun onHotspotChanged(enabled: Boolean, connectedDevices: Int) { + updateHotspotButtonState(connectedDevices) + } + } + + private val mDozeCallback: ControllersProvider.OnDozingChanged = + object : ControllersProvider.OnDozingChanged { + override fun onDozingChanged(dozing: Boolean) { + if (mDozing == dozing) { + return + } + mDozing = dozing + updateContainerVisibility() + } + } + + private fun createDeviceWidgetContainer(context: Context): LinearLayout { + val deviceWidget = LinearLayout(context) + deviceWidget.orientation = HORIZONTAL + deviceWidget.gravity = Gravity.CENTER + deviceWidget.layoutParams = LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT + ) + + if (mDeviceWidgetView == null) mDeviceWidgetView = DeviceWidgetView(context) + + try { + (mDeviceWidgetView!!.parent as ViewGroup).removeView(mDeviceWidgetView) + } catch (ignored: Throwable) { + } + + deviceWidget.addView(mDeviceWidgetView) + deviceWidget.setPadding(0, 0, 0, mContext.toPx(18)) + + return deviceWidget + } + + private fun createMainWidgetsContainer(context: Context): LinearLayout { + val mainWidgetsContainer: LinearLayout = try { + LaunchableLinearLayout!!.getConstructor(Context::class.java) + .newInstance(context) as LinearLayout + } catch (e: Exception) { + // LaunchableLinearLayout not found or other error, ensure the creation of our ImageView + LinearLayout(context) + }.apply { + orientation = HORIZONTAL + gravity = Gravity.CENTER + layoutParams = LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT + ) + } + + // Add FABs to the main widgets container + mMainWidgetViews = arrayOf( + createFAB(context), + createFAB(context) + ) + + for (mMainWidgetView: ExtendedFAB in mMainWidgetViews!!) { + mainWidgetsContainer.addView(mMainWidgetView) + } + + return mainWidgetsContainer + } + + private fun createFAB(context: Context): ExtendedFAB { + val fab = ExtendedFAB(context) + fab.id = generateViewId() + val params = LayoutParams( + (mFabWidth * mWidgetsScale).toInt(), + (mFabHeight * mWidgetsScale).toInt() + ) + params.setMargins( + (mFabMarginStart * mWidgetsScale).toInt(), + 0, + (mFabMarginEnd * mWidgetsScale).toInt(), + 0 + ) + fab.layoutParams = params + fab.setPadding( + (mFabPadding * mWidgetsScale).toInt(), + (mFabPadding * mWidgetsScale).toInt(), + (mFabPadding * mWidgetsScale).toInt(), + (mFabPadding * mWidgetsScale).toInt() + ) + fab.gravity = Gravity.CENTER_VERTICAL + fab.setPadding( + mContext.toPx(24), + mContext.toPx(8), + mContext.toPx(24), + mContext.toPx(8) + ) + return fab + } + + private fun createSecondaryWidgetsContainer(context: Context): LinearLayout { + val secondaryWidgetsContainer: LinearLayout = try { + LaunchableLinearLayout!!.getConstructor(Context::class.java) + .newInstance(context) as LinearLayout + } catch (e: Exception) { + // LaunchableLinearLayout not found or other error, ensure the creation of our ImageView + LinearLayout(context) + }.apply { + orientation = HORIZONTAL + gravity = Gravity.CENTER_HORIZONTAL + layoutParams = LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT + ) + (layoutParams as MarginLayoutParams).apply { + topMargin = modRes.getDimensionPixelSize(R.dimen.kg_widget_margin_vertical) + bottomMargin = modRes.getDimensionPixelSize(R.dimen.kg_widget_margin_bottom) + } + } + + // Add ImageViews to the secondary widgets container + mSecondaryWidgetViews = arrayOf( + createImageView(context), + createImageView(context), + createImageView(context), + createImageView(context) + ) + + for (mSecondaryWidgetView: ImageView? in mSecondaryWidgetViews!!) { + secondaryWidgetsContainer.addView(mSecondaryWidgetView) + } + + return secondaryWidgetsContainer + } + + private fun createImageView(context: Context): ImageView { + val imageView = try { + LaunchableImageView!!.getConstructor(Context::class.java) + .newInstance(context) as ImageView + } catch (e: Exception) { + // LaunchableImageView not found or other error, ensure the creation of our ImageView + ImageView(context) + }.apply { + id = generateViewId() + layoutParams = LayoutParams( + (mWidgetCircleSize * mWidgetsScale).toInt(), + (mWidgetCircleSize * mWidgetsScale).toInt() + ).apply { + setMargins( + (mWidgetMarginHorizontal * mWidgetsScale).toInt(), + 0, + (mWidgetMarginHorizontal * mWidgetsScale).toInt(), + 0 + ) + } + setPadding( + (mWidgetIconPadding * mWidgetsScale).toInt(), + (mWidgetIconPadding * mWidgetsScale).toInt(), + (mWidgetIconPadding * mWidgetsScale).toInt(), + (mWidgetIconPadding * mWidgetsScale).toInt() + ) + isFocusable = true + isClickable = true + } + + return imageView + } + + private val isMediaControllerAvailable: Boolean + get() { + val mediaController = activeLocalMediaController + return mediaController != null && !mediaController.packageName.isNullOrEmpty() + } + + private val activeLocalMediaController: MediaController? + get() { + val mediaSessionManager = + mContext.getSystemService(MediaSessionManager::class.java) + var localController: MediaController? = null + val remoteMediaSessionLists: MutableList = ArrayList() + for (controller: MediaController in mediaSessionManager.getActiveSessions(null)) { + val pi = controller.playbackInfo ?: continue + val playbackState = controller.playbackState ?: continue + if (playbackState.state != PlaybackState.STATE_PLAYING) { + continue + } + if (pi.playbackType == PlaybackInfo.PLAYBACK_TYPE_REMOTE) { + if (localController != null + && localController.packageName!!.contentEquals(controller.packageName) + ) { + localController = null + } + if (!remoteMediaSessionLists.contains(controller.packageName)) { + remoteMediaSessionLists.add(controller.packageName) + } + continue + } + if (pi.playbackType == PlaybackInfo.PLAYBACK_TYPE_LOCAL) { + if (localController == null + && !remoteMediaSessionLists.contains(controller.packageName) + ) { + localController = controller + } + } + } + return localController + } + + private fun isWidgetEnabled(widget: String): Boolean { + if (mMainWidgetViews == null || mSecondaryWidgetViews == null) { + return false + } + return mMainWidgetsList!!.contains(widget) || mSecondaryWidgetsList!!.contains(widget) + } + + private fun updateMediaController() { + if (!isWidgetEnabled("media")) return + val localController = + activeLocalMediaController + if (localController != null && !sameSessions(mController, localController)) { + if (mController != null) { + mController!!.unregisterCallback(mMediaCallback) + mController = null + } + mController = localController + mController!!.registerCallback(mMediaCallback) + } + mMediaMetadata = if (isMediaControllerAvailable) mController!!.metadata else null + updateMediaState() + } + + override fun onVisibilityChanged(changedView: View, visibility: Int) { + super.onVisibilityChanged(changedView, visibility) + if (visibility == VISIBLE && isAttachedToWindow) { + onVisible() + updateMediaController() + } + } + + override fun onWindowVisibilityChanged(visibility: Int) { + super.onWindowVisibilityChanged(visibility) + if (!lockscreenWidgetsEnabled) return + if (visibility == VISIBLE) { + onVisible() + } + } + + private fun enableWeatherUpdates() { + if (mWeatherClient != null) { + mWeatherClient!!.addObserver(this) + queryAndUpdateWeather() + } + } + + private fun disableWeatherUpdates() { + if (mWeatherClient != null) { + weatherButton = null + weatherButtonFab = null + mWeatherClient!!.removeObserver(this) + } + } + + override fun weatherError(errorReason: Int) { + if (errorReason == OmniJawsClient.EXTRA_ERROR_DISABLED) { + mWeatherInfo = null + } + } + + override fun weatherUpdated() { + queryAndUpdateWeather() + } + + override fun updateSettings() { + queryAndUpdateWeather() + } + + @SuppressLint("SetTextI18n") + private fun queryAndUpdateWeather() { + try { + if (mWeatherClient == null || !mWeatherClient!!.isOmniJawsEnabled) { + return + } + mWeatherClient!!.queryWeather() + mWeatherInfo = mWeatherClient!!.weatherInfo + if (mWeatherInfo != null) { + // OpenWeatherMap + var formattedCondition: String = mWeatherInfo!!.condition!! + if (formattedCondition.lowercase(Locale.getDefault()) + .contains("clouds") || formattedCondition.lowercase( + Locale.getDefault() + ).contains("overcast") + ) { + formattedCondition = modRes.getString(R.string.weather_condition_clouds) + } else if (formattedCondition.lowercase(Locale.getDefault()).contains("rain")) { + formattedCondition = modRes.getString(R.string.weather_condition_rain) + } else if (formattedCondition.lowercase(Locale.getDefault()).contains("clear")) { + formattedCondition = modRes.getString(R.string.weather_condition_clear) + } else if (formattedCondition.lowercase(Locale.getDefault()).contains("storm")) { + formattedCondition = modRes.getString(R.string.weather_condition_storm) + } else if (formattedCondition.lowercase(Locale.getDefault()).contains("snow")) { + formattedCondition = modRes.getString(R.string.weather_condition_snow) + } else if (formattedCondition.lowercase(Locale.getDefault()).contains("wind")) { + formattedCondition = modRes.getString(R.string.weather_condition_wind) + } else if (formattedCondition.lowercase(Locale.getDefault()).contains("mist")) { + formattedCondition = modRes.getString(R.string.weather_condition_mist) + } + + // MET Norway + if (formattedCondition.lowercase(Locale.getDefault()).contains("_")) { + val words = + formattedCondition.split("_".toRegex()).dropLastWhile { it.isEmpty() } + .toTypedArray() + val formattedConditionBuilder = StringBuilder() + for (word in words) { + val capitalizedWord = + word.substring(0, 1).uppercase(Locale.getDefault()) + word.substring(1) + formattedConditionBuilder.append(capitalizedWord).append(" ") + } + formattedCondition = formattedConditionBuilder.toString().trim { it <= ' ' } + } + + val d: Drawable = + mWeatherClient!!.getWeatherConditionImage(mWeatherInfo!!.conditionCode) + if (weatherButtonFab != null) { + weatherButtonFab!!.icon = d + weatherButtonFab!!.text = + (mWeatherInfo!!.temp + mWeatherInfo!!.tempUnits) + " • " + formattedCondition + weatherButtonFab!!.iconTint = null + } + if (weatherButton != null) { + weatherButton!!.setImageDrawable(d) + weatherButton!!.imageTintList = null + } + } + } catch (e: java.lang.Exception) { + Log.e("LockscreenWidgets", "Error updating weather: " + e.message) + } + } + + private fun onVisible() { + // Update the widgets when the view is visible + if (isWidgetEnabled("weather")) { + enableWeatherUpdates() + } + updateTorchButtonState() + updateRingerButtonState() + updateBtState() + updateWiFiButtonState(isWifiEnabled) + updateMobileDataState(isMobileDataEnabled) + updateHotspotButtonState(0) + } + + override fun onAttachedToWindow() { + super.onAttachedToWindow() + onVisible() + } + + override fun onDetachedFromWindow() { + super.onDetachedFromWindow() + if (isWidgetEnabled("weather")) { + disableWeatherUpdates() + } + } + + public override fun onConfigurationChanged(newConfig: Configuration) { + super.onConfigurationChanged(newConfig) + updateWidgetViews() + } + + override fun onFinishInflate() { + super.onFinishInflate() + mIsInflated = true + updateWidgetViews() + } + + private fun updateContainerVisibility() { + val isMainWidgetsEmpty = mMainLockscreenWidgetsList.isNullOrEmpty() + val isSecondaryWidgetsEmpty = mSecondaryLockscreenWidgetsList.isNullOrEmpty() + val isEmpty = isMainWidgetsEmpty && isSecondaryWidgetsEmpty + + if (mDeviceWidgetContainer != null) { + mDeviceWidgetContainer?.visibility = if (deviceWidgetsEnabled) { + if (mIsLargeClock) View.GONE else View.VISIBLE + } else { + View.GONE + } + } + if (mMainWidgetsContainer != null) { + mMainWidgetsContainer?.visibility = if (isMainWidgetsEmpty) GONE else VISIBLE + } + if (mSecondaryWidgetsContainer != null) { + mSecondaryWidgetsContainer?.visibility = + if (isSecondaryWidgetsEmpty || mIsLargeClock) GONE else VISIBLE + } + val shouldHideContainer = isEmpty || mDozing || !lockscreenWidgetsEnabled + visibility = if (shouldHideContainer) GONE else VISIBLE + } + + private fun updateWidgetViews() { + if (mMainWidgetViews != null && mMainWidgetsList != null) { + for (i in mMainWidgetViews!!.indices) { + mMainWidgetViews!![i].visibility = + if (i < mMainWidgetsList!!.size) VISIBLE else GONE + } + for (i in 0 until min( + mMainWidgetsList!!.size.toDouble(), + mMainWidgetViews!!.size.toDouble() + ).toInt()) { + val widgetType: String = mMainWidgetsList!![i] + if (i < mMainWidgetViews!!.size) { + setUpWidgetViews(efab = mMainWidgetViews!![i], type = widgetType) + updateMainWidgetResources(mMainWidgetViews!![i], false) + } + } + } + if (mSecondaryWidgetViews != null && mSecondaryWidgetsList != null) { + for (i in mSecondaryWidgetViews!!.indices) { + mSecondaryWidgetViews!![i].visibility = + if (i < mSecondaryWidgetsList!!.size) VISIBLE else GONE + } + for (i in 0 until min( + mSecondaryWidgetsList!!.size.toDouble(), + mSecondaryWidgetViews!!.size.toDouble() + ).toInt()) { + val widgetType: String = mSecondaryWidgetsList!![i] + if (i < mSecondaryWidgetViews!!.size) { + setUpWidgetViews(iv = mSecondaryWidgetViews!![i], type = widgetType) + updateWidgetsResources(mSecondaryWidgetViews!![i]) + } + } + } + updateContainerVisibility() + updateMediaController() + } + + @Suppress("SameParameterValue") + private fun updateMainWidgetResources(efab: ExtendedFAB?, active: Boolean) { + if (efab == null) return + efab.setElevation(0F) + setButtonActiveState(null, efab, false) + val params: ViewGroup.LayoutParams = efab.layoutParams + if (params is LayoutParams) { + if (efab.visibility == VISIBLE && mMainWidgetsList!!.size == 1) { + params.width = modRes.getDimensionPixelSize(R.dimen.kg_widget_main_width) + params.height = modRes.getDimensionPixelSize(R.dimen.kg_widget_main_height) + } else { + params.width = 0 + params.weight = 1f + } + efab.layoutParams = params + } + } + + private fun updateWidgetsResources(iv: ImageView?) { + if (iv == null) return + val d = ResourcesCompat.getDrawable( + modRes, + R.drawable.lockscreen_widget_background_circle, + mContext.theme + ) + iv.background = d + setButtonActiveState(iv, null, false) + } + + private val isNightMode: Boolean + get() { + val config = mContext.resources.configuration + return ((config.uiMode and Configuration.UI_MODE_NIGHT_MASK) + == Configuration.UI_MODE_NIGHT_YES) + } + + private fun setUpWidgetViews(iv: ImageView? = null, efab: ExtendedFAB? = null, type: String) { + when (type) { + "none" -> { + if (iv != null) { + iv.visibility = GONE + } + efab?.visibility = GONE + } + + "wifi" -> { + if (iv != null) { + wifiButton = iv + wifiButton!!.setOnLongClickListener { v: View -> + showInternetDialog(v) + true + } + } + if (efab != null) { + wifiButtonFab = efab + wifiButtonFab!!.setOnLongClickListener { v -> + showInternetDialog(v) + true + } + } + setUpWidgetResources( + iv, efab, + { toggleWiFi() }, getDrawable(WIFI_INACTIVE, FRAMEWORK_PACKAGE), getString( + WIFI_LABEL, SYSTEMUI_PACKAGE + ) + ) + } + + "data" -> { + if (iv != null) { + dataButton = iv + dataButton!!.setOnLongClickListener { v: View -> + showInternetDialog(v) + true + } + } + if (efab != null) { + dataButtonFab = efab + dataButtonFab!!.setOnLongClickListener { v -> + showInternetDialog(v) + true + } + } + setUpWidgetResources( + iv, efab, + { toggleMobileData() }, getDrawable(DATA_ICON, FRAMEWORK_PACKAGE), getString( + DATA_LABEL, SYSTEMUI_PACKAGE + ) + ) + } + + "ringer" -> { + if (iv != null) { + ringerButton = iv + ringerButton!!.setOnLongClickListener { + mActivityLauncherUtils.launchAudioSettings() + true + } + } + if (efab != null) { + ringerButtonFab = efab + ringerButtonFab!!.setOnLongClickListener { + mActivityLauncherUtils.launchAudioSettings() + true + } + } + setUpWidgetResources( + iv, efab, + { toggleRingerMode() }, + ResourcesCompat.getDrawable( + modRes, + R.drawable.ic_ringer_normal, + mContext.theme + ), + ringerText + ) + } + + "bt" -> { + if (iv != null) { + btButton = iv + btButton!!.setOnLongClickListener { v: View -> + showBluetoothDialog(v) + true + } + } + if (efab != null) { + btButtonFab = efab + btButtonFab!!.setOnLongClickListener { v -> + showBluetoothDialog(v) + true + } + } + setUpWidgetResources( + iv, efab, + { toggleBluetoothState() }, getDrawable( + BT_ICON, + SYSTEMUI_PACKAGE + ), getString(BT_LABEL, SYSTEMUI_PACKAGE) + ) + } + + "torch" -> { + if (iv != null) { + torchButton = iv + } + if (efab != null) { + torchButtonFab = efab + } + setUpWidgetResources( + iv, + efab, + { toggleFlashlight() }, + getDrawable(TORCH_INACTIVE, SYSTEMUI_PACKAGE), + getString( + TORCH_LABEL, SYSTEMUI_PACKAGE + ) + ) + } + + "timer" -> setUpWidgetResources(iv, efab, { + mActivityLauncherUtils.launchTimer() + vibrate(1) + }, getDrawable(ALARM_ICON, SYSTEMUI_PACKAGE), modRes.getString(R.string.clock_timer)) + + "camera" -> setUpWidgetResources( + iv, + efab, + { + mActivityLauncherUtils.launchCamera() + vibrate(1) + }, + getDrawable(CAMERA_ICON, SYSTEMUI_PACKAGE), + getString(CAMERA_LABEL, SYSTEMUI_PACKAGE) + ) + + "calculator" -> setUpWidgetResources( + iv, + efab, + { openCalculator() }, + getDrawable(CALCULATOR_ICON, SYSTEMUI_PACKAGE), + getString( + CALCULATOR_LABEL, SYSTEMUI_PACKAGE + ) + ) + + "homecontrols" -> setUpWidgetResources( + iv, + efab, + { view: View -> + this.launchHomeControls( + view + ) + }, + getDrawable(HOME_CONTROLS, SYSTEMUI_PACKAGE), + getString(HOME_CONTROLS_LABEL, SYSTEMUI_PACKAGE) + ) + + "wallet" -> setUpWidgetResources( + iv, + efab, + { view: View -> + this.launchWallet( + view + ) + }, + getDrawable(WALLET_ICON, SYSTEMUI_PACKAGE), + getString(WALLET_LABEL, SYSTEMUI_PACKAGE) + ) + + "media" -> { + if (iv != null) { + mediaButton = iv + mediaButton!!.setOnLongClickListener { true } + } + if (efab != null) { + mediaButtonFab = efab + mediaButtonFab!!.setOnLongClickListener { true } + } + setUpWidgetResources( + iv, efab, + { toggleMediaPlaybackState() }, + ResourcesCompat.getDrawable(modRes, R.drawable.ic_play, mContext.theme), + getString(MEDIA_PLAY_LABEL, SYSTEMUI_PACKAGE) + ) + } + + "weather" -> { + if (iv != null) { + weatherButton = iv + } + if (efab != null) { + weatherButtonFab = efab + } + //setUpWidgetResources(iv, efab, v -> mActivityLauncherUtils.launchWeatherApp(), "ic_alarm", R.string.weather_data_unavailable); + // enableWeatherUpdates() + } + + "hotspot" -> { + if (iv != null) { + hotspotButton = iv + hotspotButton!!.setOnLongClickListener { + mActivityLauncherUtils.launchSettingsComponent("com.android.settings.TetherSettings") + true + } + } + if (efab != null) { + hotspotButtonFab = efab + hotspotButtonFab!!.setOnLongClickListener { + mActivityLauncherUtils.launchSettingsComponent("com.android.settings.TetherSettings") + true + } + } + setUpWidgetResources( + iv, efab, { toggleHotspot() }, + getDrawable(HOTSPOT_INACTIVE, SYSTEMUI_PACKAGE), + getString(HOTSPOT_LABEL, SYSTEMUI_PACKAGE) + ) + } + + else -> {} + } + } + + private fun setUpWidgetResources( + iv: ImageView?, efab: ExtendedFAB?, + cl: OnClickListener, icon: Drawable?, text: String + ) { + if (efab != null) { + efab.setOnClickListener(cl) + efab.icon = icon + efab.text = text + if (mediaButtonFab === efab) { + attachSwipeGesture(efab) + } + } + if (iv != null) { + iv.setOnClickListener(cl) + iv.setImageDrawable(icon) + } + } + + @SuppressLint("ClickableViewAccessibility") + private fun attachSwipeGesture(view: View) { + val gestureDetector = GestureDetector(mContext, object : SimpleOnGestureListener() { + private val SWIPE_THRESHOLD = 100 + private val SWIPE_VELOCITY_THRESHOLD = 100 + override fun onFling( + e1: MotionEvent?, + e2: MotionEvent, + velocityX: Float, + velocityY: Float + ): Boolean { + val diffX = e2.x - e1!!.x + if (abs(diffX.toDouble()) > SWIPE_THRESHOLD && abs(velocityX.toDouble()) > SWIPE_VELOCITY_THRESHOLD) { + if (diffX > 0) { + dispatchMediaKeyWithWakeLockToMediaSession(KeyEvent.KEYCODE_MEDIA_PREVIOUS) + } else { + dispatchMediaKeyWithWakeLockToMediaSession(KeyEvent.KEYCODE_MEDIA_NEXT) + } + vibrate(1) + updateMediaController() + return true + } + return false + } + + override fun onLongPress(e: MotionEvent) { + super.onLongPress(e) + mIsLongPress = true + mHandler.postDelayed({ mIsLongPress = false }, 2500) + } + }) + view.setOnTouchListener { v, event -> + val isClick: Boolean = gestureDetector.onTouchEvent(event) + if ((event.action == MotionEvent.ACTION_UP) && !isClick && !mIsLongPress) { + v.performClick() + } + true + } + } + + private fun setButtonActiveState(iv: ImageView?, efab: ExtendedFAB?, active: Boolean) { + val bgTint: Int + val tintColor: Int + + if (!mCustomColors) { + if (active) { + bgTint = if (isNightMode) mDarkColorActive else mLightColorActive + tintColor = if (isNightMode) mDarkColor else mLightColor + } else { + bgTint = if (isNightMode) mDarkColor else mLightColor + tintColor = if (isNightMode) mLightColor else mDarkColor + } + if (iv != null) { + iv.backgroundTintList = ColorStateList.valueOf(bgTint) + if (iv !== weatherButton) { + iv.imageTintList = ColorStateList.valueOf(tintColor) + } else { + iv.imageTintList = null + } + } + if (efab != null) { + efab.backgroundTintList = ColorStateList.valueOf(bgTint) + if (efab !== weatherButtonFab) { + efab.iconTint = ColorStateList.valueOf(tintColor) + } else { + efab.iconTint = null + } + efab.setTextColor(tintColor) + } + } else { + if (iv != null) { + iv.backgroundTintList = + ColorStateList.valueOf(if (active) mSmallActiveColor else mSmallInactiveColor) + if (iv !== weatherButton) { + iv.imageTintList = + ColorStateList.valueOf(if (active) mSmallIconActiveColor else mSmallIconInactiveColor) + } else { + iv.imageTintList = null + } + } + if (efab != null) { + efab.backgroundTintList = + ColorStateList.valueOf(if (active) mBigActiveColor else mBigInactiveColor) + if (efab !== weatherButtonFab) { + efab.iconTint = + ColorStateList.valueOf(if (active) mBigIconActiveColor else mBigIconInactiveColor) + } else { + efab.iconTint = null + } + efab.setTextColor(if (active) mBigIconActiveColor else mBigIconInactiveColor) + } + } + } + + private fun updateMediaState() { + updateMediaPlaybackState() + mHandler.postDelayed({ this.updateMediaPlaybackState() }, 250) + } + + private fun toggleMediaPlaybackState() { + if (isMediaPlaying) { + mHandler.removeCallbacks(mMediaUpdater) + dispatchMediaKeyWithWakeLockToMediaSession(KeyEvent.KEYCODE_MEDIA_PAUSE) + updateMediaController() + } else { + mMediaUpdater.run() + dispatchMediaKeyWithWakeLockToMediaSession(KeyEvent.KEYCODE_MEDIA_PLAY) + } + } + + private fun dispatchMediaKeyWithWakeLockToMediaSession(keycode: Int) { + val keyIntent = Intent(Intent.ACTION_MEDIA_BUTTON, null) + val keyEvent = KeyEvent( + SystemClock.uptimeMillis(), + SystemClock.uptimeMillis(), + KeyEvent.ACTION_DOWN, + keycode, + 0 + ) + keyIntent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent) + var mediaEvent: KeyEvent? = KeyEvent(KeyEvent.ACTION_DOWN, keycode) + mAudioManager!!.dispatchMediaKeyEvent(mediaEvent) + + mediaEvent = KeyEvent.changeAction(mediaEvent, KeyEvent.ACTION_UP) + keyIntent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent) + mAudioManager.dispatchMediaKeyEvent(mediaEvent) + } + + private fun updateMediaPlaybackState() { + val isPlaying = isMediaPlaying + val icon = ResourcesCompat.getDrawable( + modRes, + if (isPlaying) R.drawable.ic_pause else R.drawable.ic_play, + mContext.theme + ) + if (mediaButton != null) { + mediaButton!!.setImageDrawable(icon) + setButtonActiveState(mediaButton, null, isPlaying) + } + if (mediaButtonFab != null) { + val trackTitle = + if (mMediaMetadata != null) mMediaMetadata!!.getString(MediaMetadata.METADATA_KEY_TITLE) else "" + if (!trackTitle.isNullOrEmpty() && mLastTrackTitle !== trackTitle) { + mLastTrackTitle = trackTitle + } + val canShowTrackTitle = isPlaying || !mLastTrackTitle.isNullOrEmpty() + mediaButtonFab!!.icon = icon + mediaButtonFab!!.text = if (canShowTrackTitle) mLastTrackTitle else "Play" + setButtonActiveState(null, mediaButtonFab, isPlaying) + } + } + + private val isMediaPlaying: Boolean + get() = (isMediaControllerAvailable + && PlaybackState.STATE_PLAYING == getMediaControllerPlaybackState(mController)) + + private fun toggleFlashlight() { + if (torchButton == null && torchButtonFab == null) return + try { + mCameraManager.setTorchMode(mCameraId!!, !isFlashOn) + isFlashOn = !isFlashOn + updateTorchButtonState() + vibrate(1) + } catch (e: Exception) { + log(TAG + "toggleFlashlight error: " + e.message) + } + } + + private fun launchHomeControls(view: View) { + val controlsTile: Any = ControllersProvider.mDeviceControlsTile ?: return + val finalView: View = if (view is ExtendedFAB) { + view.parent as View + } else { + view + } + post { + callMethod( + controlsTile, + "handleClick", + finalView + ) + } + vibrate(1) + } + + private fun launchWallet(view: View) { + val mWalletTile: Any? = ControllersProvider.mWalletTile + if (mWalletTile != null) { + val finalView: View = if (view is ExtendedFAB) { + view.parent as View + } else { + view + } + post { + callMethod( + mWalletTile, + "handleClick", + finalView + ) + } + } else { + mActivityLauncherUtils.launchWallet() + } + vibrate(1) + } + + private fun openCalculator() { + mActivityLauncherUtils.launchCalculator() + vibrate(1) + } + + @Suppress("deprecation") + private fun toggleWiFi() { + val enabled: Boolean = mWifiManager!!.isWifiEnabled + mWifiManager.isWifiEnabled = !enabled + updateWiFiButtonState(!enabled) + mHandler.postDelayed({ updateWiFiButtonState(isWifiEnabled) }, 350L) + vibrate(1) + } + + private fun toggleHotspot() { + val mHotspotTile = ControllersProvider.mHotspotTile + if (mHotspotTile != null) { + val finalView = hotspotButton ?: hotspotButtonFab + callMethod(mHotspotTile, "handleClick", finalView) + } + updateHotspotButtonState(0) + postDelayed({ updateHotspotButtonState(0) }, 350L) + vibrate(1) + } + + private val isMobileDataEnabled: Boolean + get() { + try { + val connectivityManager = + mContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager + val cmClass = Class.forName(ConnectivityManager::class.java.name) + val method = cmClass.getDeclaredMethod("getMobileDataEnabled") + method.isAccessible = true + // Call the method on the ConnectivityManager instance + val result = method.invoke(connectivityManager) + // Safely handle the return value + return if (result is Boolean) result else false + } catch (e: Exception) { + log(TAG + "isMobileDataEnabled error: " + e.message) + return false + } + } + + private val isWifiEnabled: Boolean + get() { + val enabled: Boolean = mWifiManager!!.isWifiEnabled + return enabled + } + + private fun toggleMobileData() { + enqueueProxyCommand { proxy -> + proxy?.runCommand("svc data " + if (isMobileDataEnabled) "disable" else "enable") + } + updateMobileDataState(!isMobileDataEnabled) + mHandler.postDelayed({ updateMobileDataState(isMobileDataEnabled) }, 250L) + vibrate(1) + } + + private fun showInternetDialog(view: View) { + val finalView: View = if (view is ExtendedFAB) { + view.parent as View + } else { + view + } + ControllersProvider.showInternetDialog(finalView) + vibrate(0) + } + + /** + * Toggles the ringer modes + * Normal -> Vibrate -> Silent -> Normal + */ + private fun toggleRingerMode() { + if (mAudioManager != null) { + val mode = mAudioManager.ringerMode + when (mode) { + AudioManager.RINGER_MODE_NORMAL -> callMethod( + mAudioManager, + "setRingerModeInternal", + AudioManager.RINGER_MODE_VIBRATE + ) + + AudioManager.RINGER_MODE_VIBRATE -> callMethod( + mAudioManager, + "setRingerModeInternal", + AudioManager.RINGER_MODE_SILENT + ) + + AudioManager.RINGER_MODE_SILENT -> callMethod( + mAudioManager, + "setRingerModeInternal", + AudioManager.RINGER_MODE_NORMAL + ) + } + updateRingerButtonState() + vibrate(1) + } + } + + private fun updateTileButtonState( + iv: ImageView?, + efab: ExtendedFAB?, + active: Boolean, + icon: Drawable?, + text: String + ) { + post { + if (iv != null) { + iv.setImageDrawable(icon) + setButtonActiveState(iv, null, active) + } + if (efab != null) { + efab.icon = icon + efab.text = text + setButtonActiveState(null, efab, active) + } + } + } + + fun updateTorchButtonState() { + if (!isWidgetEnabled("torch")) return + updateTileButtonState( + torchButton, + torchButtonFab, + isFlashOn, + getDrawable(TORCH_ACTIVE, SYSTEMUI_PACKAGE), + getString(TORCH_LABEL, SYSTEMUI_PACKAGE) + ) + } + + private val mRingerModeReceiver: BroadcastReceiver = object : BroadcastReceiver() { + override fun onReceive(context: Context, intent: Intent) { + updateRingerButtonState() + } + } + + init { + instance = this + + this.layoutParams = LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT + ) + + mContext = context + mAudioManager = mContext.getSystemService(AudioManager::class.java) + mWifiManager = mContext.getSystemService(WifiManager::class.java) + mTelephonyManager = mContext.getSystemService(TelephonyManager::class.java) + mConnectivityManager = mContext.getSystemService(ConnectivityManager::class.java) + mCameraManager = mContext.getSystemService(CameraManager::class.java) + mDarkColor = ResourcesCompat.getColor( + modRes, + R.color.lockscreen_widget_background_color_dark, + mContext.theme + ) + mLightColor = ResourcesCompat.getColor( + modRes, + R.color.lockscreen_widget_background_color_light, + mContext.theme + ) + mDarkColorActive = ResourcesCompat.getColor( + modRes, + R.color.lockscreen_widget_active_color_dark, + mContext.theme + ) + mLightColorActive = ResourcesCompat.getColor( + modRes, + R.color.lockscreen_widget_active_color_light, + mContext.theme + ) + + mActivityLauncherUtils = ActivityLauncherUtils(mContext, activityStarter) + + mHandler = Handler(Looper.getMainLooper()) + if (mWeatherClient == null) { + mWeatherClient = OmniJawsClient(context) + } + + try { + mCameraId = mCameraManager.cameraIdList[0] + } catch (e: Throwable) { + log(TAG + "mCameraId error: " + e.message) + } + + val container = LinearLayout(context) + container.orientation = VERTICAL + container.layoutParams = LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT + ) + + setupDimens() + drawUI() + + addView(container) + + val ringerFilter = IntentFilter("android.media.INTERNAL_RINGER_MODE_CHANGED_ACTION") + mContext.registerReceiver(mRingerModeReceiver, ringerFilter) + mMediaUpdater = object : Runnable { + override fun run() { + updateMediaController() + mHandler.postDelayed(this, 1000) + } + } + updateMediaController() + + ControllersProvider.getInstance().registerMobileDataCallback(mMobileDataCallback) + ControllersProvider.getInstance().registerWifiCallback(mWifiCallback) + ControllersProvider.getInstance().registerBluetoothCallback(mBluetoothCallback) + ControllersProvider.getInstance().registerTorchModeCallback(mTorchCallback) + ControllersProvider.getInstance().registerHotspotCallback(mHotspotCallback) + ControllersProvider.getInstance().registerDozingCallback(mDozeCallback) + + // Add a Screen On Receiver so we can update the widgets state when the screen is turned on + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + mContext.registerReceiver( + mScreenOnReceiver, + IntentFilter(Intent.ACTION_SCREEN_ON), + Context.RECEIVER_EXPORTED + ) + } else { + mContext.registerReceiver( + mScreenOnReceiver, + IntentFilter(Intent.ACTION_SCREEN_ON) + ) + } + } + + private fun setupDimens() { + // Fab Dimens + mFabWidth = modRes.getDimensionPixelSize(R.dimen.kg_widget_main_width) + mFabHeight = modRes.getDimensionPixelSize(R.dimen.kg_widget_main_height) + mFabMarginStart = modRes.getDimensionPixelSize(R.dimen.kg_widgets_main_margin_start) + mFabMarginEnd = modRes.getDimensionPixelSize(R.dimen.kg_widgets_main_margin_end) + mFabPadding = modRes.getDimensionPixelSize(R.dimen.kg_main_widgets_icon_padding) + + // Circle Dimens + mWidgetCircleSize = modRes.getDimensionPixelSize(R.dimen.kg_widget_circle_size) + mWidgetMarginHorizontal = modRes.getDimensionPixelSize(R.dimen.kg_widgets_margin_horizontal) + mWidgetMarginVertical = modRes.getDimensionPixelSize(R.dimen.kg_widget_margin_vertical) + mWidgetIconPadding = modRes.getDimensionPixelSize(R.dimen.kg_widgets_icon_padding) + } + + private fun drawUI() { + val container = LinearLayout(mContext) + container.orientation = VERTICAL + container.layoutParams = LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT + ) + + // Device Widget Container + mDeviceWidgetContainer = createDeviceWidgetContainer(mContext) + container.addView(mDeviceWidgetContainer) + + // Add main widgets container + mMainWidgetsContainer = createMainWidgetsContainer(mContext) + container.addView(mMainWidgetsContainer) + + // Add secondary widgets container + mSecondaryWidgetsContainer = createSecondaryWidgetsContainer(mContext) + container.addView(mSecondaryWidgetsContainer) + + addView(container) + } + + @Suppress("deprecation") + private fun updateWiFiButtonState(enabled: Boolean) { + if (!isWidgetEnabled("wifi")) return + if (wifiButton == null && wifiButtonFab == null) return + val connected: Boolean + var theSsid: String = mWifiManager!!.connectionInfo.ssid + if (theSsid == WifiManager.UNKNOWN_SSID) { + theSsid = getString(WIFI_LABEL, SYSTEMUI_PACKAGE) + connected = false + } else { + if (theSsid.startsWith("\"") && theSsid.endsWith("\"")) { + theSsid = theSsid.substring(1, theSsid.length - 1) + } + connected = true + } + val icon: Drawable? = getDrawable( + if (enabled && connected) WIFI_ACTIVE + else if (enabled) WIFI_ACTIVE + else WIFI_INACTIVE, FRAMEWORK_PACKAGE + ) + updateTileButtonState( + wifiButton, wifiButtonFab, + isWifiEnabled, + icon, theSsid + ) + } + + private fun updateRingerButtonState() { + if (!isWidgetEnabled("ringer")) return + if (ringerButton == null && ringerButtonFab == null) return + if (mAudioManager != null) { + val soundActive = mAudioManager.ringerMode == AudioManager.RINGER_MODE_NORMAL + updateTileButtonState( + ringerButton, ringerButtonFab, + soundActive, + ringerDrawable, + ringerText + ) + } + } + + private fun updateMobileDataState(enabled: Boolean) { + if (!isWidgetEnabled("data")) return + if (dataButton == null && dataButtonFab == null) return + val inactive = getString(DATA_LABEL, SYSTEMUI_PACKAGE) + val networkName = activeMobileDataCarrier.ifEmpty { inactive } + val hasNetwork = enabled && networkName.isNotEmpty() + updateTileButtonState( + dataButton, + dataButtonFab, + enabled, + getDrawable(DATA_ICON, FRAMEWORK_PACKAGE), + if (hasNetwork) networkName else inactive + ) + } + + private val activeMobileDataCarrier: String + get() { + val connectivityManager = + context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager + val telephonyManager = + context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager + + val activeNetwork = connectivityManager.activeNetwork + val networkCapabilities = connectivityManager.getNetworkCapabilities(activeNetwork) + + if (networkCapabilities?.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) == true) { + return telephonyManager.networkOperatorName + } + + return "" // No active mobile data connection + } + + private fun toggleBluetoothState() { + val bluetoothController: Any = ControllersProvider.mBluetoothController ?: return + callMethod(bluetoothController, "setBluetoothEnabled", !isBluetoothEnabled) + updateBtState() + mHandler.postDelayed({ this.updateBtState() }, 350L) + vibrate(1) + } + + private fun showBluetoothDialog(view: View) { + val finalView: View = if (view is ExtendedFAB) { + view.parent as View + } else { + view + } + if (!ControllersProvider.showBluetoothDialog(mContext, finalView)) { + mActivityLauncherUtils.launchBluetoothSettings() + } + vibrate(0) + } + + private fun updateBtState() { + if (!isWidgetEnabled("bt")) return + if (btButton == null && btButtonFab == null) return + val bluetoothController: Any? = ControllersProvider.mBluetoothController + var deviceName: String? = "" + if (isBluetoothEnabled && bluetoothController != null) + deviceName = callMethod(bluetoothController, "getConnectedDeviceName") as String? + val isConnected = !deviceName.isNullOrEmpty() + val icon = getDrawable( + BT_ICON, + SYSTEMUI_PACKAGE + ) + updateTileButtonState( + btButton, btButtonFab, isBluetoothOn, + icon, + if (isConnected) deviceName!! + else getString(BT_LABEL, SYSTEMUI_PACKAGE) + ) + } + + private fun updateHotspotButtonState(numDevices: Int) { + if (!isWidgetEnabled("hotspot")) return + val inactiveString = getString(HOTSPOT_LABEL, SYSTEMUI_PACKAGE) + var activeString = inactiveString + val hotspotEnabled = isHotspotEnabled() + if (hotspotEnabled) { + val hotspotSSID: String = getHotspotSSID() + val devices = "($numDevices)" + if (hotspotSSID.isNotEmpty()) { + activeString = if (numDevices > 0) "$hotspotSSID $devices" + else hotspotSSID + } + } + updateTileButtonState( + hotspotButton, + hotspotButtonFab, + isHotspotEnabled(), + getDrawable(if (hotspotEnabled) HOTSPOT_ACTIVE else HOTSPOT_INACTIVE, SYSTEMUI_PACKAGE), + if (hotspotEnabled) activeString + else inactiveString + ) + } + + @Suppress("deprecation") + private val isBluetoothEnabled: Boolean + get() { + val mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter() + return mBluetoothAdapter != null && mBluetoothAdapter.isEnabled + } + + private fun isHotspotEnabled(): Boolean { + try { + val wifiManager = mContext.getSystemService(WifiManager::class.java) + val method: Method = wifiManager.javaClass.getDeclaredMethod("getWifiApState") + method.isAccessible = true + val actualState = + method.invoke(wifiManager) as Int + return actualState == HOTSPOT_ENABLED + } catch (t: Throwable) { + log(TAG + "isHotspotEnabled error: " + t.message) + } + return false + } + + @Suppress("deprecation") + private fun getHotspotSSID(): String { + try { + val methods: Array = WifiManager::class.java.declaredMethods + for (m in methods) { + if (m.name == "getWifiApConfiguration") { + val config = m.invoke(mWifiManager) as WifiConfiguration + return config.SSID + } + } + } catch (t: Throwable) { + log(TAG + "getHotspotSSID error: " + t.message) + } + return "" + } + + private fun sameSessions(a: MediaController?, b: MediaController): Boolean { + if (a == b) { + return true + } + if (a == null) { + return false + } + return false + } + + private fun getMediaControllerPlaybackState(controller: MediaController?): Int { + if (controller != null) { + val playbackState = controller.playbackState + if (playbackState != null) { + return playbackState.state + } + } + return PlaybackState.STATE_NONE + } + + /** + * Set the options for the lockscreen widgets + * @param lsWidgets true if lockscreen widgets are enabled + * @param deviceWidget true if device widget is enabled + * @param mainWidgets comma separated list of main widgets + * @param secondaryWidgets comma separated list of secondary widgets + */ + fun setOptions( + lsWidgets: Boolean, deviceWidget: Boolean, + mainWidgets: String, secondaryWidgets: String + ) { + instance!!.lockscreenWidgetsEnabled = lsWidgets + instance!!.deviceWidgetsEnabled = deviceWidget + instance!!.mMainLockscreenWidgetsList = mainWidgets + instance!!.mMainWidgetsList = listOf( + *instance!!.mMainLockscreenWidgetsList!!.split(",".toRegex()) + .dropLastWhile { it.isEmpty() } + .toTypedArray()) + instance!!.mSecondaryLockscreenWidgetsList = secondaryWidgets + instance!!.mSecondaryWidgetsList = listOf( + *instance!!.mSecondaryLockscreenWidgetsList!!.split(",".toRegex()) + .dropLastWhile { it.isEmpty() } + .toTypedArray()) + instance!!.updateWidgetViews() + } + + fun setIsLargeClock(isLargeClock: Boolean) { + instance!!.mIsLargeClock = isLargeClock + instance!!.updateContainerVisibility() + } + + /** + * Set the options for the Device Widget + * @param customColor true if custom color is enabled + * @param linearColor color for linear battery progressbar + * @param circularColor color for circular progressbar + * @param textColor color for text + * @param devName device name, keep blank for default Build.MODEL + */ + fun setDeviceWidgetOptions( + customColor: Boolean, + linearColor: Int, + circularColor: Int, + textColor: Int, + devName: String? + ) { + if (instance!!.mDeviceWidgetView == null) return + instance!!.mDeviceWidgetView!!.setCustomColor(customColor, linearColor, circularColor) + instance!!.mDeviceWidgetView!!.setTextCustomColor(textColor) + instance!!.mDeviceWidgetView!!.setDeviceName(devName) + } + + fun setCustomColors( + customColorsEnabled: Boolean, + bigInactive: Int, bigActive: Int, smallInactive: Int, smallActive: Int, + bigIconInactive: Int, bigIconActive: Int, smallIconInactive: Int, smallIconActive: Int + ) { + instance!!.mCustomColors = customColorsEnabled + instance!!.mBigInactiveColor = bigInactive + instance!!.mBigActiveColor = bigActive + instance!!.mSmallInactiveColor = smallInactive + instance!!.mSmallActiveColor = smallActive + instance!!.mBigIconInactiveColor = bigIconInactive + instance!!.mBigIconActiveColor = bigIconActive + instance!!.mSmallIconInactiveColor = smallIconInactive + instance!!.mSmallIconActiveColor = smallIconActive + instance!!.updateWidgetViews() + } + + fun setScale(scale: Float) { + instance!!.mWidgetsScale = scale + instance!!.removeAllViews() + instance!!.drawUI() + instance!!.updateWidgetViews() + } + + fun setActivityStarter(activityStarter: Any?) { + mActivityLauncherUtils = ActivityLauncherUtils(mContext, activityStarter) + } + + fun setDozingState(isDozing: Boolean) { + instance!!.mDozing = isDozing + instance!!.updateContainerVisibility() + } + + @Suppress("DiscouragedApi") + private fun getDrawable(drawableRes: String, pkg: String): Drawable? { + try { + return ContextCompat.getDrawable( + mContext, + mContext.resources.getIdentifier(drawableRes, "drawable", pkg) + ) + } catch (t: Throwable) { + // We have a calculator icon, so if SystemUI doesn't just return ours + return when (drawableRes) { + CALCULATOR_ICON -> ResourcesCompat.getDrawable( + modRes, + R.drawable.ic_calculator, + mContext.theme + ) + + HOTSPOT_ACTIVE -> getDrawable(HOTSPOT_A12, SYSTEMUI_PACKAGE) + HOTSPOT_INACTIVE -> getDrawable(HOTSPOT_A12, SYSTEMUI_PACKAGE) + BT_ICON -> getDrawable(BT_A12, FRAMEWORK_PACKAGE) + TORCH_ACTIVE -> getDrawable(TORCH_A12, FRAMEWORK_PACKAGE) + TORCH_INACTIVE -> getDrawable(TORCH_A12, FRAMEWORK_PACKAGE) + + else -> { + log(TAG + "getDrawable $drawableRes from $pkg error $t") + return null + } + } + } + } + + @Suppress("DiscouragedApi", "SameParameterValue") + private fun getString(stringRes: String, pkg: String): String { + try { + return mContext.resources.getString( + mContext.resources.getIdentifier(stringRes, "string", pkg) + ) + } catch (t: Throwable) { + // We have our own strings too, so return them if SystemUI doesn't + when (stringRes) { + HOME_CONTROLS_LABEL -> { + return modRes.getString(R.string.home_controls) + } + + CALCULATOR_LABEL -> { + return modRes.getString(R.string.calculator) + } + + CAMERA_LABEL -> { + return modRes.getString(R.string.camera) + } + + WALLET_LABEL -> { + return modRes.getString(R.string.wallet) + } + + MEDIA_PLAY_LABEL -> { + return "Play" + } + } + + log(TAG + "getString $stringRes from $pkg error $t") + return "" + } + } + + private val ringerDrawable: Drawable? + get() { + val resName = when (mAudioManager!!.ringerMode) { + AudioManager.RINGER_MODE_NORMAL -> R.drawable.ic_ringer_normal + AudioManager.RINGER_MODE_VIBRATE -> R.drawable.ic_ringer_vibrate + AudioManager.RINGER_MODE_SILENT -> R.drawable.ic_ringer_mute + else -> throw IllegalStateException("Unexpected value: " + mAudioManager.ringerMode) + } + + return ResourcesCompat.getDrawable( + modRes, + resName, + mContext.theme + ) + } + + private val ringerText: String + get() { + val resName = when (mAudioManager!!.ringerMode) { + AudioManager.RINGER_MODE_NORMAL -> R.string.ringer_normal + AudioManager.RINGER_MODE_VIBRATE -> R.string.ringer_vibrate + AudioManager.RINGER_MODE_SILENT -> R.string.ringer_silent + else -> throw IllegalStateException("Unexpected value: " + mAudioManager.ringerMode) + } + + return modRes.getString(resName) + } + + /** + * Vibrate the device + * @param type 0 = click, 1 = tick + */ + private fun vibrate(type: Int) { + if (type == 0) { + this.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS) + } else if (type == 1) { + this.performHapticFeedback(HapticFeedbackConstants.CONTEXT_CLICK) + } + } + + companion object { + private val TAG = "Iconify - ${LockscreenWidgetsView::class.java.simpleName}: " + + const val HOTSPOT_ENABLED = 13 + + const val BT_ICON: String = "qs_bluetooth_icon_on" + const val DATA_ICON: String = "perm_group_network" + const val TORCH_ACTIVE: String = "qs_flashlight_icon_on" + const val TORCH_INACTIVE: String = "qs_flashlight_icon_off" + const val WIFI_ACTIVE: String = "ic_wifi_signal_4" + const val WIFI_INACTIVE: String = "ic_wifi_signal_0" + const val HOME_CONTROLS: String = "controls_icon" + const val CALCULATOR_ICON: String = "status_bar_qs_calculator_inactive" + const val CAMERA_ICON: String = "ic_camera" // Use qs camera access icon for camera + const val ALARM_ICON: String = "ic_alarm" + const val WALLET_ICON: String = "ic_wallet_lockscreen" + const val HOTSPOT_ACTIVE: String = "qs_hotspot_icon_on" + const val HOTSPOT_INACTIVE: String = "qs_hotspot_icon_off" + + // A12 icons + const val HOTSPOT_A12: String = "ic_hotspot" + const val BT_A12: String = "ic_qs_bluetooth" + const val TORCH_A12: String = "ic_qs_flashlight" + + const val GENERAL_INACTIVE: String = "switch_bar_off" + const val GENERAL_ACTIVE: String = "switch_bar_on" + + const val BT_LABEL: String = "quick_settings_bluetooth_label" + const val DATA_LABEL: String = "quick_settings_internet_label" + const val WIFI_LABEL: String = "quick_settings_wifi_label" + const val TORCH_LABEL: String = "quick_settings_flashlight_label" + const val HOME_CONTROLS_LABEL: String = "quick_controls_title" + const val MEDIA_PLAY_LABEL: String = "controls_media_button_play" + const val CALCULATOR_LABEL: String = "keyboard_shortcut_group_applications_calculator" + const val CAMERA_LABEL: String = "accessibility_camera_button" + const val WALLET_LABEL: String = "wallet_title" + const val HOTSPOT_LABEL: String = "quick_settings_hotspot_label" + + @Volatile + private var instance: LockscreenWidgetsView? = null + + fun getInstance(context: Context, activityStarter: Any?): LockscreenWidgetsView { + return instance ?: synchronized(this) { + instance ?: LockscreenWidgetsView(context, activityStarter).also { instance = it } + } + } + + fun getInstance(): LockscreenWidgetsView? { + return instance + } + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/xposed/modules/views/MediaPlayerPagerAdapter.kt b/app/src/main/java/com/drdisagree/iconify/xposed/modules/views/MediaPlayerPagerAdapter.kt new file mode 100644 index 000000000..36ff4a61d --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/xposed/modules/views/MediaPlayerPagerAdapter.kt @@ -0,0 +1,30 @@ +package com.drdisagree.iconify.xposed.modules.views + +import android.view.View +import android.view.ViewGroup +import androidx.viewpager.widget.PagerAdapter + +class MediaPlayerPagerAdapter( + private val mediaPlayerViews: MutableList> +) : PagerAdapter() { + + override fun getCount(): Int { + return mediaPlayerViews.size + } + + override fun isViewFromObject(view: View, `object`: Any): Boolean { + return view == `object` + } + + override fun instantiateItem(container: ViewGroup, position: Int): Any { + val view = mediaPlayerViews[position].second + val index = (view.parent as? ViewGroup)?.indexOfChild(view)?.coerceAtLeast(0) ?: 0 + (view.parent as? ViewGroup)?.removeView(view) + container.addView(view, index) + return view + } + + override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) { + container.removeView(`object` as OpQsMediaPlayerView) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/xposed/modules/views/OpQsHeaderView.kt b/app/src/main/java/com/drdisagree/iconify/xposed/modules/views/OpQsHeaderView.kt new file mode 100644 index 000000000..96c1b137d --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/xposed/modules/views/OpQsHeaderView.kt @@ -0,0 +1,561 @@ +package com.drdisagree.iconify.xposed.modules.views + +import android.content.Context +import android.content.pm.PackageManager +import android.content.res.ColorStateList +import android.content.res.Configuration +import android.graphics.Color +import android.graphics.Typeface +import android.graphics.drawable.Drawable +import android.graphics.drawable.GradientDrawable +import android.util.TypedValue +import android.view.Gravity +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.LinearLayout +import android.widget.TextView +import androidx.cardview.widget.CardView +import androidx.core.content.ContextCompat +import androidx.viewpager.widget.ViewPager +import com.drdisagree.iconify.BuildConfig +import com.drdisagree.iconify.common.Const.FRAMEWORK_PACKAGE +import com.drdisagree.iconify.common.Const.SYSTEMUI_PACKAGE +import com.drdisagree.iconify.xposed.modules.OpQsHeader.Companion.launchableLinearLayout +import com.drdisagree.iconify.xposed.modules.utils.ViewHelper.toPx +import kotlin.properties.Delegates + +@Suppress("DiscouragedApi") +class OpQsHeaderView(private val mContext: Context) : LinearLayout(mContext) { + + private lateinit var appContext: Context + + private lateinit var mInternetTile: ViewGroup + private lateinit var mInternetIcon: ImageView + private lateinit var mInternetText: TextView + private lateinit var mInternetChevron: ImageView + + private lateinit var mBluetoothTile: ViewGroup + private lateinit var mBluetoothIcon: ImageView + private lateinit var mBluetoothText: TextView + private lateinit var mBluetoothChevron: ImageView + + private lateinit var mMediaPlayerContainer: ViewPager + + private var qsIconSize by Delegates.notNull() + private var qsTextSize by Delegates.notNull() + private var qsTextFontFamily by Delegates.notNull() + private var qsTileCornerRadius by Delegates.notNull() + private var qsTilePadding by Delegates.notNull() + private var qsTileStartPadding by Delegates.notNull() + private var qsLabelContainerMargin by Delegates.notNull() + private var qsTileMarginHorizontal by Delegates.notNull() + private var qsTileMarginVertical by Delegates.notNull() + private var qqsTileHeight by Delegates.notNull() + private lateinit var qsTileBackgroundDrawable: Drawable + private lateinit var appIconBackgroundDrawable: GradientDrawable + private lateinit var opMediaForegroundClipDrawable: GradientDrawable + private lateinit var opMediaAppIconDrawable: Drawable + private lateinit var mediaOutputSwitcherIconDrawable: Drawable + private lateinit var opMediaPrevIconDrawable: Drawable + private lateinit var opMediaNextIconDrawable: Drawable + private lateinit var opMediaPlayIconDrawable: Drawable + private lateinit var opMediaPauseIconDrawable: Drawable + + private var mOnConfigurationChanged: ((Configuration?) -> Unit)? = null + private var mOnAttach: (() -> Unit)? = null + private var mOnDetach: (() -> Unit)? = null + + init { + initResources() + createOpQsHeaderView() + } + + val internetTile: ViewGroup + get() = mInternetTile + + val bluetoothTile: ViewGroup + get() = mBluetoothTile + + val mediaPlayerContainer: ViewPager + get() = mMediaPlayerContainer + + private fun initResources() { + try { + appContext = mContext.createPackageContext( + BuildConfig.APPLICATION_ID, + Context.CONTEXT_IGNORE_SECURITY + ) + } catch (ignored: PackageManager.NameNotFoundException) { + } + + qsTileCornerRadius = mContext.resources.getDimensionPixelSize( + mContext.resources.getIdentifier( + "qs_corner_radius", + "dimen", + SYSTEMUI_PACKAGE + ) + ).toFloat() + qsTileBackgroundDrawable = ContextCompat.getDrawable( + mContext, + mContext.resources.getIdentifier( + "qs_tile_background_shape", + "drawable", + SYSTEMUI_PACKAGE + ) + )!! + qsTilePadding = mContext.resources.getDimensionPixelSize( + mContext.resources.getIdentifier( + "qs_tile_padding", + "dimen", + SYSTEMUI_PACKAGE + ) + ) + qsTileStartPadding = mContext.resources.getDimensionPixelSize( + mContext.resources.getIdentifier( + "qs_tile_start_padding", + "dimen", + SYSTEMUI_PACKAGE + ) + ) + qsLabelContainerMargin = mContext.resources.getDimensionPixelSize( + mContext.resources.getIdentifier( + "qs_label_container_margin", + "dimen", + SYSTEMUI_PACKAGE + ) + ) + qsTileMarginHorizontal = mContext.resources.getDimensionPixelSize( + mContext.resources.getIdentifier( + "qs_tile_margin_horizontal", + "dimen", + SYSTEMUI_PACKAGE + ) + ) + qsTileMarginVertical = mContext.resources.getDimensionPixelSize( + mContext.resources.getIdentifier( + "qs_tile_margin_vertical", + "dimen", + SYSTEMUI_PACKAGE + ) + ) + qqsTileHeight = mContext.resources.getDimensionPixelSize( + mContext.resources.getIdentifier( + "qs_quick_tile_size", + "dimen", + SYSTEMUI_PACKAGE + ) + ) + qsIconSize = mContext.resources.getDimensionPixelSize( + mContext.resources.getIdentifier( + "qs_icon_size", + "dimen", + SYSTEMUI_PACKAGE + ) + ) + qsTextSize = mContext.resources.getDimensionPixelSize( + mContext.resources.getIdentifier( + "qs_icon_size", + "dimen", + SYSTEMUI_PACKAGE + ) + ) + qsTextFontFamily = mContext.resources.getString( + mContext.resources.getIdentifier( + "config_bodyFontFamilyMedium", + "string", + FRAMEWORK_PACKAGE + ) + ) + appIconBackgroundDrawable = GradientDrawable().apply { + shape = GradientDrawable.OVAL + } + opMediaForegroundClipDrawable = GradientDrawable().apply { + shape = GradientDrawable.RECTANGLE + cornerRadius = qsTileCornerRadius + } + opMediaAppIconDrawable = ContextCompat.getDrawable( + appContext, + appContext.resources.getIdentifier( + "ic_op_media_player_icon", + "drawable", + appContext.packageName + ) + )!! + mediaOutputSwitcherIconDrawable = ContextCompat.getDrawable( + appContext, + appContext.resources.getIdentifier( + "ic_op_media_player_output_switcher", + "drawable", + appContext.packageName + ) + )!! + opMediaPrevIconDrawable = ContextCompat.getDrawable( + appContext, + appContext.resources.getIdentifier( + "ic_op_media_player_action_prev", + "drawable", + appContext.packageName + ) + )!! + opMediaNextIconDrawable = ContextCompat.getDrawable( + appContext, + appContext.resources.getIdentifier( + "ic_op_media_player_action_next", + "drawable", + appContext.packageName + ) + )!! + opMediaPlayIconDrawable = ContextCompat.getDrawable( + appContext, + appContext.resources.getIdentifier( + "ic_op_media_player_action_play", + "drawable", + appContext.packageName + ) + )!! + opMediaPauseIconDrawable = ContextCompat.getDrawable( + appContext, + appContext.resources.getIdentifier( + "ic_op_media_player_action_pause", + "drawable", + appContext.packageName + ) + )!! + } + + private fun createOpQsHeaderView() { + layoutParams = LayoutParams( + LayoutParams.MATCH_PARENT, + (qqsTileHeight * 2) + qsTileMarginVertical + ).apply { + bottomMargin = qsTileMarginVertical + } + id = generateViewId() + orientation = HORIZONTAL + gravity = Gravity.CENTER_VERTICAL + + val leftSection = LinearLayout(mContext).apply { + layoutParams = LayoutParams( + 0, + LayoutParams.MATCH_PARENT, + 1F + ) + orientation = VERTICAL + (layoutParams as MarginLayoutParams).marginEnd = qsTileMarginHorizontal / 2 + } + + leftSection.apply { + createTiles() + addView(mInternetTile) + addView(mBluetoothTile) + } + + val rightSection = CardView(mContext).apply { + layoutParams = LayoutParams( + 0, + LayoutParams.MATCH_PARENT, + 1F + ) + setBackgroundColor(Color.TRANSPARENT) + radius = qsTileCornerRadius + cardElevation = 0F + (layoutParams as MarginLayoutParams).marginStart = qsTileMarginHorizontal / 2 + } + + rightSection.apply { + createOpMediaLayoutContainer() + addView(mMediaPlayerContainer) + } + + addView(leftSection) + addView(rightSection) + } + + private fun createTiles() { + mInternetTile = createTile().apply { + mInternetIcon = getChildAt(0) as ImageView + mInternetText = getChildAt(1) as TextView + mInternetChevron = getChildAt(2) as ImageView + (layoutParams as MarginLayoutParams).bottomMargin = qsTileMarginVertical / 2 + + val iconResId = mContext.resources.getIdentifier( + "ic_qs_wifi_disconnected", + "drawable", + SYSTEMUI_PACKAGE + ) + if (iconResId != 0) { + mInternetIcon.setImageDrawable(ContextCompat.getDrawable(mContext, iconResId)) + } else { + mInternetIcon.setImageDrawable( + ContextCompat.getDrawable( + appContext, + appContext.resources.getIdentifier( + "ic_qs_wifi_disconnected", + "drawable", + appContext.packageName + ) + ) + ) + } + + val textResId = mContext.resources.getIdentifier( + "quick_settings_internet_label", + "string", + SYSTEMUI_PACKAGE + ) + if (textResId != 0) { + mInternetText.setText(textResId) + } else { + mInternetText.setText( + appContext.resources.getIdentifier( + "quick_settings_internet_label", + "string", + appContext.packageName + ) + ) + } + } + + mBluetoothTile = createTile().apply { + mBluetoothIcon = getChildAt(0) as ImageView + mBluetoothText = getChildAt(1) as TextView + mBluetoothChevron = getChildAt(2) as ImageView + (layoutParams as MarginLayoutParams).topMargin = qsTileMarginVertical / 2 + + val iconResId = mContext.resources.getIdentifier( + "ic_qs_bluetooth", + "drawable", + FRAMEWORK_PACKAGE + ) + if (iconResId != 0) { + mBluetoothIcon.setImageDrawable(ContextCompat.getDrawable(mContext, iconResId)) + } else { + mBluetoothIcon.setImageDrawable( + ContextCompat.getDrawable( + appContext, + appContext.resources.getIdentifier( + "ic_bluetooth_disconnected", + "drawable", + appContext.packageName + ) + ) + ) + } + + val textResId = mContext.resources.getIdentifier( + "quick_settings_bluetooth_label", + "string", + SYSTEMUI_PACKAGE + ) + if (textResId != 0) { + mBluetoothText.setText(textResId) + } else { + mBluetoothText.setText( + appContext.resources.getIdentifier( + "quick_settings_bluetooth_label", + "string", + appContext.packageName + ) + ) + } + } + } + + private fun createTile(): LinearLayout { + val tileLayout = try { + launchableLinearLayout!!.getConstructor(Context::class.java) + .newInstance(mContext) as LinearLayout + } catch (ignored: Throwable) { + LinearLayout(mContext) + }.apply { + layoutParams = LayoutParams( + LayoutParams.MATCH_PARENT, + 0, + 1F + ) + background = qsTileBackgroundDrawable.constantState?.newDrawable()?.mutate() + gravity = Gravity.START or Gravity.CENTER + orientation = HORIZONTAL + setPaddingRelative(qsTileStartPadding, qsTilePadding, qsTilePadding, qsTilePadding) + } + + val iconView = ImageView(mContext).apply { + layoutParams = LayoutParams( + qsIconSize, + qsIconSize + ).apply { + gravity = Gravity.START or Gravity.CENTER + } + } + + val textView = TextView(mContext).apply { + layoutParams = LayoutParams( + 0, + LayoutParams.WRAP_CONTENT, + 1F + ).apply { + marginStart = qsLabelContainerMargin + marginEnd = mContext.toPx(10) + } + freezesText = true + isSingleLine = true + textDirection = View.TEXT_DIRECTION_LOCALE + textSize = 14f + typeface = Typeface.create(qsTextFontFamily, Typeface.NORMAL) + letterSpacing = 0.01f + lineHeight = TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_SP, + 20f, + mContext.resources.displayMetrics + ).toInt() + isVerticalFadingEdgeEnabled = false + isHorizontalFadingEdgeEnabled = true + setFadingEdgeLength(mContext.toPx(8)) + } + + val chevronIcon = ImageView(mContext).apply { + layoutParams = LayoutParams( + qsIconSize, + qsIconSize + ).apply { + gravity = Gravity.END or Gravity.CENTER + } + val iconResId = mContext.resources.getIdentifier( + "ic_chevron_end", + "drawable", + FRAMEWORK_PACKAGE + ) + if (iconResId != 0) { + setImageDrawable(ContextCompat.getDrawable(mContext, iconResId)) + } else { + setImageDrawable( + ContextCompat.getDrawable( + appContext, + appContext.resources.getIdentifier( + "ic_chevron_end", + "drawable", + appContext.packageName + ) + ) + ) + } + } + + tileLayout.apply { + addView(iconView) + addView(textView) + addView(chevronIcon) + } + + return tileLayout + } + + private fun createOpMediaLayoutContainer() { + mMediaPlayerContainer = ViewPager(mContext).apply { + layoutParams = LayoutParams( + LayoutParams.MATCH_PARENT, + LayoutParams.MATCH_PARENT, + ) + } + } + + fun setInternetIcon(resId: Int) { + mInternetIcon.setImageResource(resId) + } + + fun setInternetIcon(icon: Drawable) { + mInternetIcon.setImageDrawable(icon) + } + + fun setInternetText(resId: Int) { + mInternetText.setText(resId) + } + + fun setInternetText(title: String) { + mInternetText.text = title + } + + fun setInternetText(charSequence: CharSequence) { + mInternetText.text = charSequence + } + + fun setBlueToothIcon(resId: Int) { + mBluetoothIcon.setImageResource(resId) + } + + fun setBlueToothIcon(icon: Drawable) { + mBluetoothIcon.setImageDrawable(icon) + } + + fun setBlueToothText(resId: Int) { + mBluetoothText.setText(resId) + } + + fun setBlueToothText(title: String) { + mBluetoothText.text = title + } + + fun setBlueToothText(charSequence: CharSequence) { + mBluetoothText.text = charSequence + } + + fun setInternetTileColor(tileColor: Int?, labelColor: Int?) { + if (tileColor == null || labelColor == null) return + + mInternetTile.background.mutate().setTint(tileColor) + mInternetIcon.imageTintList = ColorStateList.valueOf(labelColor) + mInternetIcon.drawable.mutate().setTint(labelColor) + mInternetChevron.imageTintList = ColorStateList.valueOf(labelColor) + mInternetChevron.drawable.mutate().setTint(labelColor) + mInternetText.setTextColor(labelColor) + } + + fun setBluetoothTileColor(tileColor: Int?, labelColor: Int?) { + if (tileColor == null || labelColor == null) return + + mBluetoothTile.background.mutate().setTint(tileColor) + mBluetoothIcon.imageTintList = ColorStateList.valueOf(labelColor) + mBluetoothIcon.drawable.mutate().setTint(labelColor) + mBluetoothChevron.imageTintList = ColorStateList.valueOf(labelColor) + mBluetoothChevron.drawable.mutate().setTint(labelColor) + mBluetoothText.setTextColor(labelColor) + } + + fun setOnClickListeners( + onClickListener: OnClickListener, + onLongClickListener: OnLongClickListener + ) { + mInternetTile.setOnClickListener(onClickListener) + mBluetoothTile.setOnClickListener(onClickListener) + mInternetTile.setOnLongClickListener(onLongClickListener) + mBluetoothTile.setOnLongClickListener(onLongClickListener) + } + + fun setOnAttachListener(onAttach: () -> Unit) { + this.mOnAttach = onAttach + } + + fun setOnDetachListener(onDetach: () -> Unit) { + this.mOnDetach = onDetach + } + + fun setOnConfigurationChangedListener(onConfigurationChanged: (newConfig: Configuration?) -> Unit) { + this.mOnConfigurationChanged = onConfigurationChanged + } + + override fun onAttachedToWindow() { + super.onAttachedToWindow() + mOnAttach?.invoke() + } + + override fun onDetachedFromWindow() { + super.onDetachedFromWindow() + mOnDetach?.invoke() + } + + override fun onConfigurationChanged(newConfig: Configuration?) { + super.onConfigurationChanged(newConfig) + mOnConfigurationChanged?.invoke(newConfig) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/xposed/modules/views/OpQsMediaPlayerView.kt b/app/src/main/java/com/drdisagree/iconify/xposed/modules/views/OpQsMediaPlayerView.kt new file mode 100644 index 000000000..2461a882d --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/xposed/modules/views/OpQsMediaPlayerView.kt @@ -0,0 +1,518 @@ +package com.drdisagree.iconify.xposed.modules.views + +import android.content.Context +import android.content.pm.PackageManager +import android.content.res.ColorStateList +import android.content.res.Configuration +import android.graphics.Bitmap +import android.graphics.Color +import android.graphics.Typeface +import android.graphics.drawable.Drawable +import android.graphics.drawable.GradientDrawable +import android.graphics.drawable.Icon +import android.util.TypedValue +import android.view.Gravity +import android.view.View +import android.widget.ImageButton +import android.widget.ImageView +import android.widget.LinearLayout +import android.widget.TextView +import androidx.cardview.widget.CardView +import androidx.constraintlayout.widget.ConstraintLayout +import androidx.constraintlayout.widget.ConstraintSet +import androidx.core.content.ContextCompat +import androidx.core.view.setPadding +import com.drdisagree.iconify.BuildConfig +import com.drdisagree.iconify.common.Const.SYSTEMUI_PACKAGE +import com.drdisagree.iconify.xposed.modules.OpQsHeader.Companion.launchableImageView +import com.drdisagree.iconify.xposed.modules.utils.ViewHelper.toPx +import kotlin.properties.Delegates + +@Suppress("DiscouragedApi") +class OpQsMediaPlayerView(private val mContext: Context) : CardView(mContext) { + + private lateinit var appContext: Context + + private lateinit var mMediaPlayerBackground: ImageView + private lateinit var mAppIcon: ImageButton + private lateinit var mMediaOutputSwitcher: ImageView + private lateinit var mMediaPlayerTitle: TextView + private lateinit var mMediaPlayerSubtitle: TextView + private lateinit var mMediaBtnPrev: ImageButton + private lateinit var mMediaBtnNext: ImageButton + private lateinit var mMediaBtnPlayPause: ImageButton + + private var qsTileCornerRadius by Delegates.notNull() + private var qsTileMarginHorizontal by Delegates.notNull() + private lateinit var qsTileBackgroundDrawable: Drawable + private lateinit var appIconBackgroundDrawable: GradientDrawable + private lateinit var opMediaForegroundClipDrawable: GradientDrawable + private lateinit var opMediaAppIconDrawable: Drawable + private lateinit var mediaOutputSwitcherIconDrawable: Drawable + private lateinit var opMediaPrevIconDrawable: Drawable + private lateinit var opMediaNextIconDrawable: Drawable + private lateinit var opMediaPlayIconDrawable: Drawable + private lateinit var opMediaPauseIconDrawable: Drawable + + private var mOnConfigurationChanged: ((Configuration?) -> Unit)? = null + private var mOnAttach: (() -> Unit)? = null + private var mOnDetach: (() -> Unit)? = null + + init { + initResources() + createOpQsMediaPlayerView() + } + + val mediaPlayerBackground: ImageView + get() = mMediaPlayerBackground + + val mediaAppIcon: ImageButton + get() = mAppIcon + + val mediaOutputSwitcher: ImageView + get() = mMediaOutputSwitcher + + val mediaPlayerPrevBtn: ImageButton + get() = mMediaBtnPrev + + val mediaPlayerNextBtn: ImageButton + get() = mMediaBtnNext + + val mediaPlayerPlayPauseBtn: ImageButton + get() = mMediaBtnPlayPause + + val mediaPlayerTitle: TextView + get() = mMediaPlayerTitle + + val mediaPlayerSubtitle: TextView + get() = mMediaPlayerSubtitle + + val mediaAppIconDrawable: Drawable + get() = opMediaAppIconDrawable + + val mediaPlayIconDrawable: Drawable + get() = opMediaPlayIconDrawable + + val mediaPauseIconDrawable: Drawable + get() = opMediaPauseIconDrawable + + private fun initResources() { + try { + appContext = mContext.createPackageContext( + BuildConfig.APPLICATION_ID, + Context.CONTEXT_IGNORE_SECURITY + ) + } catch (ignored: PackageManager.NameNotFoundException) { + } + + qsTileCornerRadius = mContext.resources.getDimensionPixelSize( + mContext.resources.getIdentifier( + "qs_corner_radius", + "dimen", + SYSTEMUI_PACKAGE + ) + ).toFloat() + qsTileBackgroundDrawable = ContextCompat.getDrawable( + mContext, + mContext.resources.getIdentifier( + "qs_tile_background_shape", + "drawable", + SYSTEMUI_PACKAGE + ) + )!! + qsTileMarginHorizontal = mContext.resources.getDimensionPixelSize( + mContext.resources.getIdentifier( + "qs_tile_margin_horizontal", + "dimen", + SYSTEMUI_PACKAGE + ) + ) + appIconBackgroundDrawable = GradientDrawable().apply { + shape = GradientDrawable.OVAL + } + opMediaForegroundClipDrawable = GradientDrawable().apply { + shape = GradientDrawable.RECTANGLE + cornerRadius = qsTileCornerRadius + } + opMediaDefaultBackground = GradientDrawable().apply { + shape = GradientDrawable.RECTANGLE + cornerRadius = qsTileCornerRadius + } + opMediaAppIconDrawable = ContextCompat.getDrawable( + appContext, + appContext.resources.getIdentifier( + "ic_op_media_player_icon", + "drawable", + appContext.packageName + ) + )!! + mediaOutputSwitcherIconDrawable = ContextCompat.getDrawable( + appContext, + appContext.resources.getIdentifier( + "ic_op_media_player_output_switcher", + "drawable", + appContext.packageName + ) + )!! + opMediaPrevIconDrawable = ContextCompat.getDrawable( + appContext, + appContext.resources.getIdentifier( + "ic_op_media_player_action_prev", + "drawable", + appContext.packageName + ) + )!! + opMediaNextIconDrawable = ContextCompat.getDrawable( + appContext, + appContext.resources.getIdentifier( + "ic_op_media_player_action_next", + "drawable", + appContext.packageName + ) + )!! + opMediaPlayIconDrawable = ContextCompat.getDrawable( + appContext, + appContext.resources.getIdentifier( + "ic_op_media_player_action_play", + "drawable", + appContext.packageName + ) + )!! + opMediaPauseIconDrawable = ContextCompat.getDrawable( + appContext, + appContext.resources.getIdentifier( + "ic_op_media_player_action_pause", + "drawable", + appContext.packageName + ) + )!! + } + + private fun createOpQsMediaPlayerView() { + layoutParams = LayoutParams( + LayoutParams.MATCH_PARENT, + LayoutParams.MATCH_PARENT + ) + id = generateViewId() + radius = qsTileCornerRadius + cardElevation = 0F + setBackgroundColor(Color.TRANSPARENT) + + createOpMediaArtworkLayout() + addView(mMediaPlayerBackground) + addView(createOpMediaLayout()) + } + + private fun createOpMediaArtworkLayout() { + mMediaPlayerBackground = try { + launchableImageView!!.getConstructor(Context::class.java) + .newInstance(mContext) as ImageView + } catch (ignored: Throwable) { + ImageView(mContext) + }.apply { + layoutParams = LayoutParams( + LayoutParams.MATCH_PARENT, + LayoutParams.MATCH_PARENT + ) + foreground = opMediaForegroundClipDrawable + scaleType = ImageView.ScaleType.CENTER_CROP + background = opMediaDefaultBackground + } + } + + private fun createOpMediaLayout(): ConstraintLayout { + val mediaLayout = ConstraintLayout(mContext).apply { + layoutParams = ConstraintLayout.LayoutParams( + ConstraintLayout.LayoutParams.MATCH_PARENT, + ConstraintLayout.LayoutParams.MATCH_PARENT + ) + } + + mAppIcon = ImageButton(mContext).apply { + layoutParams = ConstraintLayout.LayoutParams( + mContext.toPx(24), + mContext.toPx(24) + ).apply { + setMargins(mContext.toPx(16), mContext.toPx(16), mContext.toPx(16), 0) + startToStart = ConstraintSet.PARENT_ID + topToTop = ConstraintSet.PARENT_ID + } + id = generateViewId() + background = appIconBackgroundDrawable + scaleType = ImageView.ScaleType.CENTER_INSIDE + setPadding(mContext.toPx(4)) + setImageDrawable(opMediaAppIconDrawable) + } + + mMediaOutputSwitcher = try { + launchableImageView!!.getConstructor(Context::class.java) + .newInstance(mContext) as ImageView + } catch (ignored: Throwable) { + ImageView(mContext) + }.apply { + layoutParams = ConstraintLayout.LayoutParams( + mContext.toPx(24), + mContext.toPx(24) + ).apply { + setMargins(mContext.toPx(16), mContext.toPx(16), mContext.toPx(16), 0) + endToEnd = ConstraintSet.PARENT_ID + topToTop = ConstraintSet.PARENT_ID + } + id = generateViewId() + background = null + scaleType = ImageView.ScaleType.CENTER_INSIDE + setImageDrawable(mediaOutputSwitcherIconDrawable) + } + + mMediaBtnPrev = ImageButton(mContext).apply { + layoutParams = ConstraintLayout.LayoutParams( + mContext.toPx(32), + mContext.toPx(32) + ).apply { + setMargins(mContext.toPx(12), 0, 0, mContext.toPx(12)) + startToStart = ConstraintSet.PARENT_ID + bottomToBottom = ConstraintSet.PARENT_ID + } + id = generateViewId() + background = null + scaleType = ImageView.ScaleType.CENTER_INSIDE + layoutDirection = View.LAYOUT_DIRECTION_LTR + setPadding(mContext.toPx(4)) + setImageDrawable(opMediaPrevIconDrawable) + } + + mMediaBtnNext = ImageButton(mContext).apply { + layoutParams = ConstraintLayout.LayoutParams( + mContext.toPx(32), + mContext.toPx(32) + ).apply { + setMargins(0, 0, mContext.toPx(12), mContext.toPx(12)) + endToEnd = ConstraintSet.PARENT_ID + bottomToBottom = ConstraintSet.PARENT_ID + } + id = generateViewId() + background = null + scaleType = ImageView.ScaleType.CENTER_INSIDE + layoutDirection = View.LAYOUT_DIRECTION_LTR + setPadding(mContext.toPx(4)) + setImageDrawable(opMediaNextIconDrawable) + } + + mMediaBtnPlayPause = ImageButton(mContext).apply { + layoutParams = ConstraintLayout.LayoutParams( + mContext.toPx(32), + mContext.toPx(32) + ).apply { + setMargins(0, 0, 0, mContext.toPx(12)) + startToStart = ConstraintSet.PARENT_ID + endToEnd = ConstraintSet.PARENT_ID + bottomToBottom = ConstraintSet.PARENT_ID + } + id = generateViewId() + background = null + scaleType = ImageView.ScaleType.CENTER_INSIDE + layoutDirection = View.LAYOUT_DIRECTION_LTR + setPadding(mContext.toPx(4)) + setImageDrawable(opMediaPlayIconDrawable) + } + + val textContainer = LinearLayout(mContext).apply { + layoutParams = ConstraintLayout.LayoutParams( + 0, + ConstraintLayout.LayoutParams.WRAP_CONTENT + ).apply { + gravity = Gravity.CENTER + startToStart = ConstraintSet.PARENT_ID + endToEnd = ConstraintSet.PARENT_ID + topToTop = ConstraintSet.PARENT_ID + bottomToBottom = ConstraintSet.PARENT_ID + marginStart = mContext.toPx(20) + marginEnd = mContext.toPx(20) + } + id = generateViewId() + gravity = Gravity.CENTER + orientation = LinearLayout.VERTICAL + } + + mMediaPlayerTitle = TextView(mContext).apply { + layoutParams = ConstraintLayout.LayoutParams( + ConstraintLayout.LayoutParams.WRAP_CONTENT, + ConstraintLayout.LayoutParams.WRAP_CONTENT + ) + id = generateViewId() + typeface = Typeface.create("sans-serif-medium", Typeface.NORMAL) + textSize = 14F + freezesText = true + isSingleLine = true + letterSpacing = 0.01f + lineHeight = TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_SP, + 20F, + mContext.resources.displayMetrics + ).toInt() + textDirection = View.TEXT_DIRECTION_LOCALE + textAlignment = View.TEXT_ALIGNMENT_CENTER + text = appContext.getString( + appContext.resources.getIdentifier( + "media_player_not_playing", + "string", + appContext.packageName + ) + ) + isVerticalFadingEdgeEnabled = false + isHorizontalFadingEdgeEnabled = true + setFadingEdgeLength(mContext.toPx(16)) + } + + mMediaPlayerSubtitle = TextView(mContext).apply { + layoutParams = ConstraintLayout.LayoutParams( + ConstraintLayout.LayoutParams.WRAP_CONTENT, + ConstraintLayout.LayoutParams.WRAP_CONTENT + ) + id = generateViewId() + typeface = Typeface.create("sans-serif-medium", Typeface.NORMAL) + textSize = 12F + freezesText = true + isSingleLine = true + letterSpacing = 0.01f + lineHeight = TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_SP, + 20F, + mContext.resources.displayMetrics + ).toInt() + textDirection = View.TEXT_DIRECTION_LOCALE + textAlignment = View.TEXT_ALIGNMENT_CENTER + alpha = 0.8F + visibility = View.GONE + isVerticalFadingEdgeEnabled = false + isHorizontalFadingEdgeEnabled = true + setFadingEdgeLength(mContext.toPx(16)) + } + + textContainer.apply { + addView(mMediaPlayerTitle) + addView(mMediaPlayerSubtitle) + } + + return mediaLayout.apply { + addView(mAppIcon) + addView(mMediaOutputSwitcher) + addView(mMediaBtnPrev) + addView(mMediaBtnNext) + addView(mMediaBtnPlayPause) + addView(textContainer) + } + } + + fun setMediaPlayerBackground(drawable: Drawable?) { + if (drawable == null) return + + if (mMediaPlayerBackground.drawable != drawable) { + mMediaPlayerBackground.setImageDrawable(drawable) + mMediaPlayerBackground.scaleType = ImageView.ScaleType.CENTER_CROP + mMediaPlayerBackground.clipToOutline = true + } + } + + fun resetMediaAppIcon() { + if (mAppIcon.drawable != opMediaAppIconDrawable) { + mAppIcon.setImageDrawable(opMediaAppIconDrawable) + } + } + + fun setMediaAppIcon(icon: Icon) { + mAppIcon.setImageIcon(icon) + } + + fun setMediaAppIconDrawable(drawable: Drawable) { + mAppIcon.setImageDrawable(drawable) + } + + fun setMediaAppIconBitmap(bitmap: Bitmap) { + mAppIcon.setImageBitmap(bitmap) + } + + fun setMediaAppIconColor(backgroundColor: Int, iconColor: Int) { + mAppIcon.backgroundTintList = ColorStateList.valueOf(backgroundColor) + mAppIcon.imageTintList = ColorStateList.valueOf(iconColor) + } + + fun resetMediaAppIconColor(backgroundColor: Int) { + mAppIcon.backgroundTintList = ColorStateList.valueOf(backgroundColor) + mAppIcon.imageTintList = null + } + + fun setMediaTitle(title: String) { + mMediaPlayerTitle.text = title + } + + fun setMediaArtist(artist: String?) { + mMediaPlayerSubtitle.text = artist + + if (artist.isNullOrEmpty()) { + mMediaPlayerSubtitle.visibility = View.GONE + } else { + mMediaPlayerSubtitle.visibility = View.VISIBLE + } + } + + fun setMediaPlayingIcon(isPlaying: Boolean) { + mMediaBtnPlayPause.setImageDrawable( + if (isPlaying) { + opMediaPauseIconDrawable + } else { + opMediaPlayIconDrawable + } + ) + } + + fun setMediaPlayerItemsColor(itemColor: Int?) { + if (itemColor == null) return + + mMediaOutputSwitcher.setColorFilter(itemColor) + mMediaBtnPrev.setColorFilter(itemColor) + mMediaBtnNext.setColorFilter(itemColor) + mMediaBtnPlayPause.setColorFilter(itemColor) + mMediaPlayerTitle.setTextColor(itemColor) + mMediaPlayerSubtitle.setTextColor(itemColor) + } + + fun setOnClickListeners(onClickListener: OnClickListener) { + mMediaPlayerBackground.setOnClickListener(onClickListener) + mMediaOutputSwitcher.setOnClickListener(onClickListener) + mMediaBtnPrev.setOnClickListener(onClickListener) + mMediaBtnNext.setOnClickListener(onClickListener) + mMediaBtnPlayPause.setOnClickListener(onClickListener) + } + + fun setOnAttachListener(onAttach: () -> Unit) { + this.mOnAttach = onAttach + } + + fun setOnDetachListener(onDetach: () -> Unit) { + this.mOnDetach = onDetach + } + + fun setOnConfigurationChangedListener(onConfigurationChanged: (newConfig: Configuration?) -> Unit) { + this.mOnConfigurationChanged = onConfigurationChanged + } + + override fun onAttachedToWindow() { + super.onAttachedToWindow() + mOnAttach?.invoke() + } + + override fun onDetachedFromWindow() { + super.onDetachedFromWindow() + mOnDetach?.invoke() + } + + override fun onConfigurationChanged(newConfig: Configuration?) { + super.onConfigurationChanged(newConfig) + mOnConfigurationChanged?.invoke(newConfig) + } + + companion object { + lateinit var opMediaDefaultBackground: Drawable + } +} \ No newline at end of file diff --git a/app/src/main/java/com/drdisagree/iconify/xposed/utils/BootLoopProtector.kt b/app/src/main/java/com/drdisagree/iconify/xposed/utils/BootLoopProtector.kt index d305a7471..4cf5b414e 100644 --- a/app/src/main/java/com/drdisagree/iconify/xposed/utils/BootLoopProtector.kt +++ b/app/src/main/java/com/drdisagree/iconify/xposed/utils/BootLoopProtector.kt @@ -1,7 +1,8 @@ package com.drdisagree.iconify.xposed.utils import android.annotation.SuppressLint -import com.drdisagree.iconify.config.XPrefs.Xprefs +import com.drdisagree.iconify.xposed.utils.XPrefs.Xprefs +import com.drdisagree.iconify.xposed.utils.XPrefs.XprefsIsInitialized import java.util.Calendar object BootLoopProtector { @@ -11,23 +12,23 @@ object BootLoopProtector { @SuppressLint("ApplySharedPref") fun isBootLooped(packageName: String): Boolean { - if (Xprefs == null) return false + if (!XprefsIsInitialized) return false val loadTimeKey = "$LOAD_TIME_KEY_KEY$packageName" val strikeKey = "$PACKAGE_STRIKE_KEY_KEY$packageName" val currentTime = Calendar.getInstance().time.time - val lastLoadTime = Xprefs!!.getLong(loadTimeKey, 0) - var strikeCount = Xprefs!!.getInt(strikeKey, 0) + val lastLoadTime = Xprefs.getLong(loadTimeKey, 0) + var strikeCount = Xprefs.getInt(strikeKey, 0) if (currentTime - lastLoadTime > 40000) { - Xprefs!!.edit() + Xprefs.edit() .putLong(loadTimeKey, currentTime) .putInt(strikeKey, 0) .commit() } else if (strikeCount >= 3) { return true } else { - Xprefs!!.edit() + Xprefs.edit() .putInt(strikeKey, ++strikeCount) .commit() } @@ -37,14 +38,14 @@ object BootLoopProtector { @SuppressLint("ApplySharedPref") fun resetCounter(packageName: String) { - if (Xprefs == null) return + if (!XprefsIsInitialized) return try { val loadTimeKey = "$LOAD_TIME_KEY_KEY$packageName" val strikeKey = "$PACKAGE_STRIKE_KEY_KEY$packageName" val currentTime = Calendar.getInstance().time.time - Xprefs!!.edit() + Xprefs.edit() .putLong(loadTimeKey, currentTime) .putInt(strikeKey, 0) .commit() diff --git a/app/src/main/java/com/drdisagree/iconify/xposed/utils/ExtendedRemotePreferences.kt b/app/src/main/java/com/drdisagree/iconify/xposed/utils/ExtendedRemotePreferences.kt new file mode 100644 index 000000000..82e26a80f --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/xposed/utils/ExtendedRemotePreferences.kt @@ -0,0 +1,38 @@ +package com.drdisagree.iconify.xposed.utils + +import android.content.Context +import com.crossbowffs.remotepreferences.RemotePreferences +import com.drdisagree.iconify.ui.preferences.SliderPreference + +@Suppress("unused") +class ExtendedRemotePreferences : RemotePreferences { + + constructor(context: Context, authority: String, prefFileName: String) : super( + context, + authority, + prefFileName + ) + + constructor( + context: Context, + authority: String, + prefFileName: String, + strictMode: Boolean + ) : super(context, authority, prefFileName, strictMode) + + fun getBoolean(key: String?): Boolean { + return getBoolean(key, false) + } + + fun getSliderInt(key: String?, defaultVal: Int): Int { + return SliderPreference.getSingleIntValue(this, key, defaultVal) + } + + fun getSliderFloat(key: String?, defaultVal: Float): Float { + return SliderPreference.getSingleFloatValue(this, key, defaultVal) + } + + fun getSliderValues(key: String?, defaultValue: Float): List { + return SliderPreference.getValues(this, key, defaultValue) + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/xposed/utils/SystemUtil.kt b/app/src/main/java/com/drdisagree/iconify/xposed/utils/SystemUtil.kt deleted file mode 100644 index 8f1d605c1..000000000 --- a/app/src/main/java/com/drdisagree/iconify/xposed/utils/SystemUtil.kt +++ /dev/null @@ -1,63 +0,0 @@ -package com.drdisagree.iconify.xposed.utils - -import android.annotation.SuppressLint -import android.app.Application -import android.content.Context -import android.content.res.Configuration -import android.os.Build -import android.os.Process -import com.drdisagree.iconify.xposed.utils.BootLoopProtector.resetCounter -import com.topjohnwu.superuser.Shell -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.delay -import kotlinx.coroutines.launch - -class SystemUtil(var mContext: Context) { - - init { - instance = this - } - - private val isDark: Boolean - get() = mContext.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_YES == Configuration.UI_MODE_NIGHT_YES - - companion object { - @SuppressLint("StaticFieldLeak") - var instance: SystemUtil? = null - private var darkSwitching = false - val isDarkMode: Boolean - get() = if (instance == null) false else instance!!.isDark - - fun doubleToggleDarkMode() { - val isDark = isDarkMode - - CoroutineScope(Dispatchers.Default).launch { - try { - while (darkSwitching) { - delay(100) - } - - darkSwitching = true - - Shell.cmd("cmd uimode night ${if (isDark) "no" else "yes"}").exec() - delay(1000) - Shell.cmd("cmd uimode night ${if (isDark) "yes" else "no"}").exec() - delay(500) - - darkSwitching = false - } catch (ignored: Exception) { - } - } - } - - fun killSelf() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - resetCounter(Process.myProcessName()) - } else { - resetCounter(Application.getProcessName()) - } - Process.killProcess(Process.myPid()) - } - } -} diff --git a/app/src/main/java/com/drdisagree/iconify/xposed/utils/SystemUtils.kt b/app/src/main/java/com/drdisagree/iconify/xposed/utils/SystemUtils.kt new file mode 100644 index 000000000..58308f2f2 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/xposed/utils/SystemUtils.kt @@ -0,0 +1,75 @@ +package com.drdisagree.iconify.xposed.utils + +import android.annotation.SuppressLint +import android.app.Application +import android.content.Context +import android.content.res.Configuration +import android.os.Build +import android.os.Process +import com.drdisagree.iconify.xposed.utils.BootLoopProtector.resetCounter +import com.topjohnwu.superuser.Shell +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch + + +class SystemUtils(var mContext: Context) { + + init { + instance = this + } + + private val isDark: Boolean + get() = mContext.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_YES == + Configuration.UI_MODE_NIGHT_YES + + companion object { + @SuppressLint("StaticFieldLeak") + var instance: SystemUtils? = null + + private var darkSwitching = false + + val isDarkMode: Boolean get() = instance?.isDark ?: false + + fun sleep(millis: Int) { + try { + Thread.sleep(millis.toLong()) + } catch (ignored: Throwable) { + } + } + + fun doubleToggleDarkMode() { + val isDark = isDarkMode + + CoroutineScope(Dispatchers.Default).launch { + try { + while (darkSwitching) { + delay(100) + } + + darkSwitching = true + + Shell.cmd("cmd uimode night ${if (isDark) "no" else "yes"}").exec() + delay(1000) + Shell.cmd("cmd uimode night ${if (isDark) "yes" else "no"}").exec() + delay(500) + + darkSwitching = false + } catch (ignored: Exception) { + } + } + } + + fun killSelf() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + resetCounter(Process.myProcessName()) + } else { + resetCounter(Application.getProcessName()) + } + Process.killProcess(Process.myPid()) + } + + private val TAG = "Iconify - ${this::class.java.simpleName}: " + } +} diff --git a/app/src/main/java/com/drdisagree/iconify/xposed/utils/XPrefs.kt b/app/src/main/java/com/drdisagree/iconify/xposed/utils/XPrefs.kt new file mode 100644 index 000000000..50b9e3774 --- /dev/null +++ b/app/src/main/java/com/drdisagree/iconify/xposed/utils/XPrefs.kt @@ -0,0 +1,53 @@ +package com.drdisagree.iconify.xposed.utils + +import android.annotation.SuppressLint +import android.content.Context +import android.content.SharedPreferences +import android.content.SharedPreferences.OnSharedPreferenceChangeListener +import com.crossbowffs.remotepreferences.RemotePreferences +import com.drdisagree.iconify.BuildConfig +import com.drdisagree.iconify.common.Const.PREF_UPDATE_EXCLUSIONS +import com.drdisagree.iconify.common.Resources.SHARED_XPREFERENCES +import com.drdisagree.iconify.xposed.HookEntry +import de.robv.android.xposed.XposedBridge.log + +object XPrefs { + + @SuppressLint("StaticFieldLeak") + lateinit var Xprefs: ExtendedRemotePreferences + private val TAG = "Iconify - ${XPrefs::class.java.simpleName}: " + private val listener = OnSharedPreferenceChangeListener { _: SharedPreferences?, key: String? -> + loadEverything( + key + ) + } + + val XprefsIsInitialized: Boolean + get() = ::Xprefs.isInitialized + + fun init(context: Context) { + Xprefs = ExtendedRemotePreferences( + context, + BuildConfig.APPLICATION_ID, + SHARED_XPREFERENCES, + true + ) + (Xprefs as RemotePreferences).registerOnSharedPreferenceChangeListener(listener) + } + + private fun loadEverything(vararg key: String?) { + if (key.isEmpty() || key[0].isNullOrEmpty() || PREF_UPDATE_EXCLUSIONS.any { exclusion -> + key[0]?.equals(exclusion) == true + }) { + return + } + + HookEntry.runningMods.forEach { thisMod -> + try { + thisMod.updatePrefs(*key.filterNotNull().toTypedArray()) + } catch (throwable: Throwable) { + log(TAG + "${thisMod.javaClass.simpleName} -> " + throwable) + } + } + } +} diff --git a/app/src/main/res/color/color_material_ripple_error.xml b/app/src/main/res/color/color_material_ripple_error.xml new file mode 100644 index 000000000..b055f630c --- /dev/null +++ b/app/src/main/res/color/color_material_ripple_error.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/color/color_surface_semitransparent.xml b/app/src/main/res/color/color_surface_semitransparent.xml new file mode 100644 index 000000000..3ae7ffeb6 --- /dev/null +++ b/app/src/main/res/color/color_surface_semitransparent.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-night-v24/toast_frame_style_12.xml b/app/src/main/res/drawable-night-v24/toast_frame_style_12.xml new file mode 100644 index 000000000..7e0ed0367 --- /dev/null +++ b/app/src/main/res/drawable-night-v24/toast_frame_style_12.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable-nodpi/google_0.png b/app/src/main/res/drawable-nodpi/google_0.png new file mode 100644 index 000000000..fc9e40efd Binary files /dev/null and b/app/src/main/res/drawable-nodpi/google_0.png differ diff --git a/app/src/main/res/drawable-nodpi/google_1.png b/app/src/main/res/drawable-nodpi/google_1.png new file mode 100644 index 000000000..be0b0130f Binary files /dev/null and b/app/src/main/res/drawable-nodpi/google_1.png differ diff --git a/app/src/main/res/drawable-nodpi/google_10.png b/app/src/main/res/drawable-nodpi/google_10.png new file mode 100644 index 000000000..fbb99c76e Binary files /dev/null and b/app/src/main/res/drawable-nodpi/google_10.png differ diff --git a/app/src/main/res/drawable-nodpi/google_11.png b/app/src/main/res/drawable-nodpi/google_11.png new file mode 100644 index 000000000..c582b6a45 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/google_11.png differ diff --git a/app/src/main/res/drawable-nodpi/google_12.png b/app/src/main/res/drawable-nodpi/google_12.png new file mode 100644 index 000000000..c582b6a45 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/google_12.png differ diff --git a/app/src/main/res/drawable-nodpi/google_13.png b/app/src/main/res/drawable-nodpi/google_13.png new file mode 100644 index 000000000..283e387f2 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/google_13.png differ diff --git a/app/src/main/res/drawable-nodpi/google_14.png b/app/src/main/res/drawable-nodpi/google_14.png new file mode 100644 index 000000000..283e387f2 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/google_14.png differ diff --git a/app/src/main/res/drawable-nodpi/google_15.png b/app/src/main/res/drawable-nodpi/google_15.png new file mode 100644 index 000000000..283e387f2 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/google_15.png differ diff --git a/app/src/main/res/drawable-nodpi/google_16.png b/app/src/main/res/drawable-nodpi/google_16.png new file mode 100644 index 000000000..283e387f2 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/google_16.png differ diff --git a/app/src/main/res/drawable-nodpi/google_17.png b/app/src/main/res/drawable-nodpi/google_17.png new file mode 100644 index 000000000..283e387f2 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/google_17.png differ diff --git a/app/src/main/res/drawable-nodpi/google_18.png b/app/src/main/res/drawable-nodpi/google_18.png new file mode 100644 index 000000000..283e387f2 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/google_18.png differ diff --git a/app/src/main/res/drawable-nodpi/google_19.png b/app/src/main/res/drawable-nodpi/google_19.png new file mode 100644 index 000000000..79202ffbd Binary files /dev/null and b/app/src/main/res/drawable-nodpi/google_19.png differ diff --git a/app/src/main/res/drawable-nodpi/google_2.png b/app/src/main/res/drawable-nodpi/google_2.png new file mode 100644 index 000000000..fc9e40efd Binary files /dev/null and b/app/src/main/res/drawable-nodpi/google_2.png differ diff --git a/app/src/main/res/drawable-nodpi/google_20.png b/app/src/main/res/drawable-nodpi/google_20.png new file mode 100644 index 000000000..79202ffbd Binary files /dev/null and b/app/src/main/res/drawable-nodpi/google_20.png differ diff --git a/app/src/main/res/drawable-nodpi/google_21.png b/app/src/main/res/drawable-nodpi/google_21.png new file mode 100644 index 000000000..79202ffbd Binary files /dev/null and b/app/src/main/res/drawable-nodpi/google_21.png differ diff --git a/app/src/main/res/drawable-nodpi/google_22.png b/app/src/main/res/drawable-nodpi/google_22.png new file mode 100644 index 000000000..79202ffbd Binary files /dev/null and b/app/src/main/res/drawable-nodpi/google_22.png differ diff --git a/app/src/main/res/drawable-nodpi/google_23.png b/app/src/main/res/drawable-nodpi/google_23.png new file mode 100644 index 000000000..4a4eb7e17 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/google_23.png differ diff --git a/app/src/main/res/drawable-nodpi/google_24.png b/app/src/main/res/drawable-nodpi/google_24.png new file mode 100644 index 000000000..4a4eb7e17 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/google_24.png differ diff --git a/app/src/main/res/drawable-nodpi/google_25.png b/app/src/main/res/drawable-nodpi/google_25.png new file mode 100644 index 000000000..352049fcf Binary files /dev/null and b/app/src/main/res/drawable-nodpi/google_25.png differ diff --git a/app/src/main/res/drawable-nodpi/google_26.png b/app/src/main/res/drawable-nodpi/google_26.png new file mode 100644 index 000000000..d1ad43f1b Binary files /dev/null and b/app/src/main/res/drawable-nodpi/google_26.png differ diff --git a/app/src/main/res/drawable-nodpi/google_27.png b/app/src/main/res/drawable-nodpi/google_27.png new file mode 100644 index 000000000..2bcffcf3b Binary files /dev/null and b/app/src/main/res/drawable-nodpi/google_27.png differ diff --git a/app/src/main/res/drawable-nodpi/google_28.png b/app/src/main/res/drawable-nodpi/google_28.png new file mode 100644 index 000000000..8952def4d Binary files /dev/null and b/app/src/main/res/drawable-nodpi/google_28.png differ diff --git a/app/src/main/res/drawable-nodpi/google_29.png b/app/src/main/res/drawable-nodpi/google_29.png new file mode 100644 index 000000000..5e6d872d1 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/google_29.png differ diff --git a/app/src/main/res/drawable-nodpi/google_3.png b/app/src/main/res/drawable-nodpi/google_3.png new file mode 100644 index 000000000..be0b0130f Binary files /dev/null and b/app/src/main/res/drawable-nodpi/google_3.png differ diff --git a/app/src/main/res/drawable-nodpi/google_30.png b/app/src/main/res/drawable-nodpi/google_30.png new file mode 100644 index 000000000..22340fb42 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/google_30.png differ diff --git a/app/src/main/res/drawable-nodpi/google_31.png b/app/src/main/res/drawable-nodpi/google_31.png new file mode 100644 index 000000000..4d379cc04 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/google_31.png differ diff --git a/app/src/main/res/drawable-nodpi/google_32.png b/app/src/main/res/drawable-nodpi/google_32.png new file mode 100644 index 000000000..18fcc8570 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/google_32.png differ diff --git a/app/src/main/res/drawable-nodpi/google_33.png b/app/src/main/res/drawable-nodpi/google_33.png new file mode 100644 index 000000000..4d379cc04 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/google_33.png differ diff --git a/app/src/main/res/drawable-nodpi/google_34.png b/app/src/main/res/drawable-nodpi/google_34.png new file mode 100644 index 000000000..18fcc8570 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/google_34.png differ diff --git a/app/src/main/res/drawable-nodpi/google_35.png b/app/src/main/res/drawable-nodpi/google_35.png new file mode 100644 index 000000000..fbb99c76e Binary files /dev/null and b/app/src/main/res/drawable-nodpi/google_35.png differ diff --git a/app/src/main/res/drawable-nodpi/google_36.png b/app/src/main/res/drawable-nodpi/google_36.png new file mode 100644 index 000000000..40a462a09 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/google_36.png differ diff --git a/app/src/main/res/drawable-nodpi/google_37.png b/app/src/main/res/drawable-nodpi/google_37.png new file mode 100644 index 000000000..6c3cef69f Binary files /dev/null and b/app/src/main/res/drawable-nodpi/google_37.png differ diff --git a/app/src/main/res/drawable-nodpi/google_38.png b/app/src/main/res/drawable-nodpi/google_38.png new file mode 100644 index 000000000..6c3cef69f Binary files /dev/null and b/app/src/main/res/drawable-nodpi/google_38.png differ diff --git a/app/src/main/res/drawable-nodpi/google_39.png b/app/src/main/res/drawable-nodpi/google_39.png new file mode 100644 index 000000000..6c3cef69f Binary files /dev/null and b/app/src/main/res/drawable-nodpi/google_39.png differ diff --git a/app/src/main/res/drawable-nodpi/google_4.png b/app/src/main/res/drawable-nodpi/google_4.png new file mode 100644 index 000000000..be0b0130f Binary files /dev/null and b/app/src/main/res/drawable-nodpi/google_4.png differ diff --git a/app/src/main/res/drawable-nodpi/google_40.png b/app/src/main/res/drawable-nodpi/google_40.png new file mode 100644 index 000000000..fdb88bb72 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/google_40.png differ diff --git a/app/src/main/res/drawable-nodpi/google_41.png b/app/src/main/res/drawable-nodpi/google_41.png new file mode 100644 index 000000000..283e387f2 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/google_41.png differ diff --git a/app/src/main/res/drawable-nodpi/google_42.png b/app/src/main/res/drawable-nodpi/google_42.png new file mode 100644 index 000000000..25a9756cc Binary files /dev/null and b/app/src/main/res/drawable-nodpi/google_42.png differ diff --git a/app/src/main/res/drawable-nodpi/google_43.png b/app/src/main/res/drawable-nodpi/google_43.png new file mode 100644 index 000000000..283e387f2 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/google_43.png differ diff --git a/app/src/main/res/drawable-nodpi/google_44.png b/app/src/main/res/drawable-nodpi/google_44.png new file mode 100644 index 000000000..5e6d872d1 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/google_44.png differ diff --git a/app/src/main/res/drawable-nodpi/google_45.png b/app/src/main/res/drawable-nodpi/google_45.png new file mode 100644 index 000000000..a13050595 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/google_45.png differ diff --git a/app/src/main/res/drawable-nodpi/google_46.png b/app/src/main/res/drawable-nodpi/google_46.png new file mode 100644 index 000000000..25a9756cc Binary files /dev/null and b/app/src/main/res/drawable-nodpi/google_46.png differ diff --git a/app/src/main/res/drawable-nodpi/google_47.png b/app/src/main/res/drawable-nodpi/google_47.png new file mode 100644 index 000000000..a13050595 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/google_47.png differ diff --git a/app/src/main/res/drawable-nodpi/google_5.png b/app/src/main/res/drawable-nodpi/google_5.png new file mode 100644 index 000000000..fbb99c76e Binary files /dev/null and b/app/src/main/res/drawable-nodpi/google_5.png differ diff --git a/app/src/main/res/drawable-nodpi/google_6.png b/app/src/main/res/drawable-nodpi/google_6.png new file mode 100644 index 000000000..fbb99c76e Binary files /dev/null and b/app/src/main/res/drawable-nodpi/google_6.png differ diff --git a/app/src/main/res/drawable-nodpi/google_7.png b/app/src/main/res/drawable-nodpi/google_7.png new file mode 100644 index 000000000..fbb99c76e Binary files /dev/null and b/app/src/main/res/drawable-nodpi/google_7.png differ diff --git a/app/src/main/res/drawable-nodpi/google_8.png b/app/src/main/res/drawable-nodpi/google_8.png new file mode 100644 index 000000000..fbb99c76e Binary files /dev/null and b/app/src/main/res/drawable-nodpi/google_8.png differ diff --git a/app/src/main/res/drawable-nodpi/google_9.png b/app/src/main/res/drawable-nodpi/google_9.png new file mode 100644 index 000000000..c582b6a45 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/google_9.png differ diff --git a/app/src/main/res/drawable-nodpi/google_na.png b/app/src/main/res/drawable-nodpi/google_na.png new file mode 100644 index 000000000..21e3dfb27 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/google_na.png differ diff --git a/app/src/main/res/drawable-nodpi/icons8_color_hand_0.png b/app/src/main/res/drawable-nodpi/icons8_color_hand_0.png new file mode 100644 index 000000000..67f702701 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/icons8_color_hand_0.png differ diff --git a/app/src/main/res/drawable-nodpi/icons8_color_hand_1.png b/app/src/main/res/drawable-nodpi/icons8_color_hand_1.png new file mode 100644 index 000000000..38e4fec62 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/icons8_color_hand_1.png differ diff --git a/app/src/main/res/drawable-nodpi/icons8_color_hand_10.png b/app/src/main/res/drawable-nodpi/icons8_color_hand_10.png new file mode 100644 index 000000000..fb65d0bd7 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/icons8_color_hand_10.png differ diff --git a/app/src/main/res/drawable-nodpi/icons8_color_hand_11.png b/app/src/main/res/drawable-nodpi/icons8_color_hand_11.png new file mode 100644 index 000000000..8c2c1e21d Binary files /dev/null and b/app/src/main/res/drawable-nodpi/icons8_color_hand_11.png differ diff --git a/app/src/main/res/drawable-nodpi/icons8_color_hand_12.png b/app/src/main/res/drawable-nodpi/icons8_color_hand_12.png new file mode 100644 index 000000000..8c2c1e21d Binary files /dev/null and b/app/src/main/res/drawable-nodpi/icons8_color_hand_12.png differ diff --git a/app/src/main/res/drawable-nodpi/icons8_color_hand_13.png b/app/src/main/res/drawable-nodpi/icons8_color_hand_13.png new file mode 100644 index 000000000..afd219db9 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/icons8_color_hand_13.png differ diff --git a/app/src/main/res/drawable-nodpi/icons8_color_hand_14.png b/app/src/main/res/drawable-nodpi/icons8_color_hand_14.png new file mode 100644 index 000000000..afd219db9 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/icons8_color_hand_14.png differ diff --git a/app/src/main/res/drawable-nodpi/icons8_color_hand_15.png b/app/src/main/res/drawable-nodpi/icons8_color_hand_15.png new file mode 100644 index 000000000..afd219db9 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/icons8_color_hand_15.png differ diff --git a/app/src/main/res/drawable-nodpi/icons8_color_hand_16.png b/app/src/main/res/drawable-nodpi/icons8_color_hand_16.png new file mode 100644 index 000000000..afd219db9 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/icons8_color_hand_16.png differ diff --git a/app/src/main/res/drawable-nodpi/icons8_color_hand_17.png b/app/src/main/res/drawable-nodpi/icons8_color_hand_17.png new file mode 100644 index 000000000..afd219db9 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/icons8_color_hand_17.png differ diff --git a/app/src/main/res/drawable-nodpi/icons8_color_hand_18.png b/app/src/main/res/drawable-nodpi/icons8_color_hand_18.png new file mode 100644 index 000000000..afd219db9 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/icons8_color_hand_18.png differ diff --git a/app/src/main/res/drawable-nodpi/icons8_color_hand_19.png b/app/src/main/res/drawable-nodpi/icons8_color_hand_19.png new file mode 100644 index 000000000..f8c7055fd Binary files /dev/null and b/app/src/main/res/drawable-nodpi/icons8_color_hand_19.png differ diff --git a/app/src/main/res/drawable-nodpi/icons8_color_hand_2.png b/app/src/main/res/drawable-nodpi/icons8_color_hand_2.png new file mode 100644 index 000000000..67f702701 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/icons8_color_hand_2.png differ diff --git a/app/src/main/res/drawable-nodpi/icons8_color_hand_20.png b/app/src/main/res/drawable-nodpi/icons8_color_hand_20.png new file mode 100644 index 000000000..f8c7055fd Binary files /dev/null and b/app/src/main/res/drawable-nodpi/icons8_color_hand_20.png differ diff --git a/app/src/main/res/drawable-nodpi/icons8_color_hand_21.png b/app/src/main/res/drawable-nodpi/icons8_color_hand_21.png new file mode 100644 index 000000000..f8c7055fd Binary files /dev/null and b/app/src/main/res/drawable-nodpi/icons8_color_hand_21.png differ diff --git a/app/src/main/res/drawable-nodpi/icons8_color_hand_22.png b/app/src/main/res/drawable-nodpi/icons8_color_hand_22.png new file mode 100644 index 000000000..f8c7055fd Binary files /dev/null and b/app/src/main/res/drawable-nodpi/icons8_color_hand_22.png differ diff --git a/app/src/main/res/drawable-nodpi/icons8_color_hand_23.png b/app/src/main/res/drawable-nodpi/icons8_color_hand_23.png new file mode 100644 index 000000000..61c07a8b7 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/icons8_color_hand_23.png differ diff --git a/app/src/main/res/drawable-nodpi/icons8_color_hand_24.png b/app/src/main/res/drawable-nodpi/icons8_color_hand_24.png new file mode 100644 index 000000000..61c07a8b7 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/icons8_color_hand_24.png differ diff --git a/app/src/main/res/drawable-nodpi/icons8_color_hand_25.png b/app/src/main/res/drawable-nodpi/icons8_color_hand_25.png new file mode 100644 index 000000000..6435bee12 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/icons8_color_hand_25.png differ diff --git a/app/src/main/res/drawable-nodpi/icons8_color_hand_26.png b/app/src/main/res/drawable-nodpi/icons8_color_hand_26.png new file mode 100644 index 000000000..1ef60681f Binary files /dev/null and b/app/src/main/res/drawable-nodpi/icons8_color_hand_26.png differ diff --git a/app/src/main/res/drawable-nodpi/icons8_color_hand_27.png b/app/src/main/res/drawable-nodpi/icons8_color_hand_27.png new file mode 100644 index 000000000..26f43604a Binary files /dev/null and b/app/src/main/res/drawable-nodpi/icons8_color_hand_27.png differ diff --git a/app/src/main/res/drawable-nodpi/icons8_color_hand_28.png b/app/src/main/res/drawable-nodpi/icons8_color_hand_28.png new file mode 100644 index 000000000..432775585 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/icons8_color_hand_28.png differ diff --git a/app/src/main/res/drawable-nodpi/icons8_color_hand_29.png b/app/src/main/res/drawable-nodpi/icons8_color_hand_29.png new file mode 100644 index 000000000..26f43604a Binary files /dev/null and b/app/src/main/res/drawable-nodpi/icons8_color_hand_29.png differ diff --git a/app/src/main/res/drawable-nodpi/icons8_color_hand_3.png b/app/src/main/res/drawable-nodpi/icons8_color_hand_3.png new file mode 100644 index 000000000..38e4fec62 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/icons8_color_hand_3.png differ diff --git a/app/src/main/res/drawable-nodpi/icons8_color_hand_30.png b/app/src/main/res/drawable-nodpi/icons8_color_hand_30.png new file mode 100644 index 000000000..432775585 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/icons8_color_hand_30.png differ diff --git a/app/src/main/res/drawable-nodpi/icons8_color_hand_31.png b/app/src/main/res/drawable-nodpi/icons8_color_hand_31.png new file mode 100644 index 000000000..7a19b27ad Binary files /dev/null and b/app/src/main/res/drawable-nodpi/icons8_color_hand_31.png differ diff --git a/app/src/main/res/drawable-nodpi/icons8_color_hand_32.png b/app/src/main/res/drawable-nodpi/icons8_color_hand_32.png new file mode 100644 index 000000000..954fb7db4 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/icons8_color_hand_32.png differ diff --git a/app/src/main/res/drawable-nodpi/icons8_color_hand_33.png b/app/src/main/res/drawable-nodpi/icons8_color_hand_33.png new file mode 100644 index 000000000..7a19b27ad Binary files /dev/null and b/app/src/main/res/drawable-nodpi/icons8_color_hand_33.png differ diff --git a/app/src/main/res/drawable-nodpi/icons8_color_hand_34.png b/app/src/main/res/drawable-nodpi/icons8_color_hand_34.png new file mode 100644 index 000000000..954fb7db4 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/icons8_color_hand_34.png differ diff --git a/app/src/main/res/drawable-nodpi/icons8_color_hand_35.png b/app/src/main/res/drawable-nodpi/icons8_color_hand_35.png new file mode 100644 index 000000000..fb65d0bd7 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/icons8_color_hand_35.png differ diff --git a/app/src/main/res/drawable-nodpi/icons8_color_hand_36.png b/app/src/main/res/drawable-nodpi/icons8_color_hand_36.png new file mode 100644 index 000000000..b845de252 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/icons8_color_hand_36.png differ diff --git a/app/src/main/res/drawable-nodpi/icons8_color_hand_37.png b/app/src/main/res/drawable-nodpi/icons8_color_hand_37.png new file mode 100644 index 000000000..38e4fec62 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/icons8_color_hand_37.png differ diff --git a/app/src/main/res/drawable-nodpi/icons8_color_hand_38.png b/app/src/main/res/drawable-nodpi/icons8_color_hand_38.png new file mode 100644 index 000000000..38e4fec62 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/icons8_color_hand_38.png differ diff --git a/app/src/main/res/drawable-nodpi/icons8_color_hand_39.png b/app/src/main/res/drawable-nodpi/icons8_color_hand_39.png new file mode 100644 index 000000000..38e4fec62 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/icons8_color_hand_39.png differ diff --git a/app/src/main/res/drawable-nodpi/icons8_color_hand_4.png b/app/src/main/res/drawable-nodpi/icons8_color_hand_4.png new file mode 100644 index 000000000..fb65d0bd7 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/icons8_color_hand_4.png differ diff --git a/app/src/main/res/drawable-nodpi/icons8_color_hand_40.png b/app/src/main/res/drawable-nodpi/icons8_color_hand_40.png new file mode 100644 index 000000000..8c2c1e21d Binary files /dev/null and b/app/src/main/res/drawable-nodpi/icons8_color_hand_40.png differ diff --git a/app/src/main/res/drawable-nodpi/icons8_color_hand_41.png b/app/src/main/res/drawable-nodpi/icons8_color_hand_41.png new file mode 100644 index 000000000..afd219db9 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/icons8_color_hand_41.png differ diff --git a/app/src/main/res/drawable-nodpi/icons8_color_hand_42.png b/app/src/main/res/drawable-nodpi/icons8_color_hand_42.png new file mode 100644 index 000000000..eeb2814d8 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/icons8_color_hand_42.png differ diff --git a/app/src/main/res/drawable-nodpi/icons8_color_hand_43.png b/app/src/main/res/drawable-nodpi/icons8_color_hand_43.png new file mode 100644 index 000000000..afd219db9 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/icons8_color_hand_43.png differ diff --git a/app/src/main/res/drawable-nodpi/icons8_color_hand_44.png b/app/src/main/res/drawable-nodpi/icons8_color_hand_44.png new file mode 100644 index 000000000..26f43604a Binary files /dev/null and b/app/src/main/res/drawable-nodpi/icons8_color_hand_44.png differ diff --git a/app/src/main/res/drawable-nodpi/icons8_color_hand_45.png b/app/src/main/res/drawable-nodpi/icons8_color_hand_45.png new file mode 100644 index 000000000..8c2c1e21d Binary files /dev/null and b/app/src/main/res/drawable-nodpi/icons8_color_hand_45.png differ diff --git a/app/src/main/res/drawable-nodpi/icons8_color_hand_46.png b/app/src/main/res/drawable-nodpi/icons8_color_hand_46.png new file mode 100644 index 000000000..eeb2814d8 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/icons8_color_hand_46.png differ diff --git a/app/src/main/res/drawable-nodpi/icons8_color_hand_47.png b/app/src/main/res/drawable-nodpi/icons8_color_hand_47.png new file mode 100644 index 000000000..2d04cff7b Binary files /dev/null and b/app/src/main/res/drawable-nodpi/icons8_color_hand_47.png differ diff --git a/app/src/main/res/drawable-nodpi/icons8_color_hand_5.png b/app/src/main/res/drawable-nodpi/icons8_color_hand_5.png new file mode 100644 index 000000000..fb65d0bd7 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/icons8_color_hand_5.png differ diff --git a/app/src/main/res/drawable-nodpi/icons8_color_hand_6.png b/app/src/main/res/drawable-nodpi/icons8_color_hand_6.png new file mode 100644 index 000000000..fb65d0bd7 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/icons8_color_hand_6.png differ diff --git a/app/src/main/res/drawable-nodpi/icons8_color_hand_7.png b/app/src/main/res/drawable-nodpi/icons8_color_hand_7.png new file mode 100644 index 000000000..fb65d0bd7 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/icons8_color_hand_7.png differ diff --git a/app/src/main/res/drawable-nodpi/icons8_color_hand_8.png b/app/src/main/res/drawable-nodpi/icons8_color_hand_8.png new file mode 100644 index 000000000..fb65d0bd7 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/icons8_color_hand_8.png differ diff --git a/app/src/main/res/drawable-nodpi/icons8_color_hand_9.png b/app/src/main/res/drawable-nodpi/icons8_color_hand_9.png new file mode 100644 index 000000000..8c2c1e21d Binary files /dev/null and b/app/src/main/res/drawable-nodpi/icons8_color_hand_9.png differ diff --git a/app/src/main/res/drawable-nodpi/icons8_color_hand_na.png b/app/src/main/res/drawable-nodpi/icons8_color_hand_na.png new file mode 100644 index 000000000..954fb7db4 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/icons8_color_hand_na.png differ diff --git a/app/src/main/res/drawable-nodpi/marshmallow_0.png b/app/src/main/res/drawable-nodpi/marshmallow_0.png new file mode 100644 index 000000000..d25b81149 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/marshmallow_0.png differ diff --git a/app/src/main/res/drawable-nodpi/marshmallow_1.png b/app/src/main/res/drawable-nodpi/marshmallow_1.png new file mode 100644 index 000000000..d25b81149 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/marshmallow_1.png differ diff --git a/app/src/main/res/drawable-nodpi/marshmallow_10.png b/app/src/main/res/drawable-nodpi/marshmallow_10.png new file mode 100644 index 000000000..6b9789ca8 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/marshmallow_10.png differ diff --git a/app/src/main/res/drawable-nodpi/marshmallow_11.png b/app/src/main/res/drawable-nodpi/marshmallow_11.png new file mode 100644 index 000000000..eb7a4fb9f Binary files /dev/null and b/app/src/main/res/drawable-nodpi/marshmallow_11.png differ diff --git a/app/src/main/res/drawable-nodpi/marshmallow_12.png b/app/src/main/res/drawable-nodpi/marshmallow_12.png new file mode 100644 index 000000000..eb7a4fb9f Binary files /dev/null and b/app/src/main/res/drawable-nodpi/marshmallow_12.png differ diff --git a/app/src/main/res/drawable-nodpi/marshmallow_13.png b/app/src/main/res/drawable-nodpi/marshmallow_13.png new file mode 100644 index 000000000..09bd249ed Binary files /dev/null and b/app/src/main/res/drawable-nodpi/marshmallow_13.png differ diff --git a/app/src/main/res/drawable-nodpi/marshmallow_14.png b/app/src/main/res/drawable-nodpi/marshmallow_14.png new file mode 100644 index 000000000..259b46685 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/marshmallow_14.png differ diff --git a/app/src/main/res/drawable-nodpi/marshmallow_15.png b/app/src/main/res/drawable-nodpi/marshmallow_15.png new file mode 100644 index 000000000..2c6fcf792 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/marshmallow_15.png differ diff --git a/app/src/main/res/drawable-nodpi/marshmallow_16.png b/app/src/main/res/drawable-nodpi/marshmallow_16.png new file mode 100644 index 000000000..f203a55b9 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/marshmallow_16.png differ diff --git a/app/src/main/res/drawable-nodpi/marshmallow_17.png b/app/src/main/res/drawable-nodpi/marshmallow_17.png new file mode 100644 index 000000000..2e76eaa84 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/marshmallow_17.png differ diff --git a/app/src/main/res/drawable-nodpi/marshmallow_18.png b/app/src/main/res/drawable-nodpi/marshmallow_18.png new file mode 100644 index 000000000..61b541064 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/marshmallow_18.png differ diff --git a/app/src/main/res/drawable-nodpi/marshmallow_19.png b/app/src/main/res/drawable-nodpi/marshmallow_19.png new file mode 100644 index 000000000..fba3b21d4 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/marshmallow_19.png differ diff --git a/app/src/main/res/drawable-nodpi/marshmallow_2.png b/app/src/main/res/drawable-nodpi/marshmallow_2.png new file mode 100644 index 000000000..d25b81149 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/marshmallow_2.png differ diff --git a/app/src/main/res/drawable-nodpi/marshmallow_20.png b/app/src/main/res/drawable-nodpi/marshmallow_20.png new file mode 100644 index 000000000..50562acec Binary files /dev/null and b/app/src/main/res/drawable-nodpi/marshmallow_20.png differ diff --git a/app/src/main/res/drawable-nodpi/marshmallow_21.png b/app/src/main/res/drawable-nodpi/marshmallow_21.png new file mode 100644 index 000000000..fba3b21d4 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/marshmallow_21.png differ diff --git a/app/src/main/res/drawable-nodpi/marshmallow_22.png b/app/src/main/res/drawable-nodpi/marshmallow_22.png new file mode 100644 index 000000000..fba3b21d4 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/marshmallow_22.png differ diff --git a/app/src/main/res/drawable-nodpi/marshmallow_23.png b/app/src/main/res/drawable-nodpi/marshmallow_23.png new file mode 100644 index 000000000..511d2a77b Binary files /dev/null and b/app/src/main/res/drawable-nodpi/marshmallow_23.png differ diff --git a/app/src/main/res/drawable-nodpi/marshmallow_24.png b/app/src/main/res/drawable-nodpi/marshmallow_24.png new file mode 100644 index 000000000..511d2a77b Binary files /dev/null and b/app/src/main/res/drawable-nodpi/marshmallow_24.png differ diff --git a/app/src/main/res/drawable-nodpi/marshmallow_25.png b/app/src/main/res/drawable-nodpi/marshmallow_25.png new file mode 100644 index 000000000..f267c84f3 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/marshmallow_25.png differ diff --git a/app/src/main/res/drawable-nodpi/marshmallow_26.png b/app/src/main/res/drawable-nodpi/marshmallow_26.png new file mode 100644 index 000000000..689aa1f75 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/marshmallow_26.png differ diff --git a/app/src/main/res/drawable-nodpi/marshmallow_27.png b/app/src/main/res/drawable-nodpi/marshmallow_27.png new file mode 100644 index 000000000..75a34aac4 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/marshmallow_27.png differ diff --git a/app/src/main/res/drawable-nodpi/marshmallow_28.png b/app/src/main/res/drawable-nodpi/marshmallow_28.png new file mode 100644 index 000000000..9cab75a1a Binary files /dev/null and b/app/src/main/res/drawable-nodpi/marshmallow_28.png differ diff --git a/app/src/main/res/drawable-nodpi/marshmallow_29.png b/app/src/main/res/drawable-nodpi/marshmallow_29.png new file mode 100644 index 000000000..75a34aac4 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/marshmallow_29.png differ diff --git a/app/src/main/res/drawable-nodpi/marshmallow_3.png b/app/src/main/res/drawable-nodpi/marshmallow_3.png new file mode 100644 index 000000000..26c7a43e9 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/marshmallow_3.png differ diff --git a/app/src/main/res/drawable-nodpi/marshmallow_30.png b/app/src/main/res/drawable-nodpi/marshmallow_30.png new file mode 100644 index 000000000..9cab75a1a Binary files /dev/null and b/app/src/main/res/drawable-nodpi/marshmallow_30.png differ diff --git a/app/src/main/res/drawable-nodpi/marshmallow_31.png b/app/src/main/res/drawable-nodpi/marshmallow_31.png new file mode 100644 index 000000000..3b059e5f0 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/marshmallow_31.png differ diff --git a/app/src/main/res/drawable-nodpi/marshmallow_32.png b/app/src/main/res/drawable-nodpi/marshmallow_32.png new file mode 100644 index 000000000..f8dbce831 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/marshmallow_32.png differ diff --git a/app/src/main/res/drawable-nodpi/marshmallow_33.png b/app/src/main/res/drawable-nodpi/marshmallow_33.png new file mode 100644 index 000000000..3b059e5f0 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/marshmallow_33.png differ diff --git a/app/src/main/res/drawable-nodpi/marshmallow_34.png b/app/src/main/res/drawable-nodpi/marshmallow_34.png new file mode 100644 index 000000000..f8dbce831 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/marshmallow_34.png differ diff --git a/app/src/main/res/drawable-nodpi/marshmallow_35.png b/app/src/main/res/drawable-nodpi/marshmallow_35.png new file mode 100644 index 000000000..6b9789ca8 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/marshmallow_35.png differ diff --git a/app/src/main/res/drawable-nodpi/marshmallow_36.png b/app/src/main/res/drawable-nodpi/marshmallow_36.png new file mode 100644 index 000000000..86a980caa Binary files /dev/null and b/app/src/main/res/drawable-nodpi/marshmallow_36.png differ diff --git a/app/src/main/res/drawable-nodpi/marshmallow_37.png b/app/src/main/res/drawable-nodpi/marshmallow_37.png new file mode 100644 index 000000000..9083cd762 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/marshmallow_37.png differ diff --git a/app/src/main/res/drawable-nodpi/marshmallow_38.png b/app/src/main/res/drawable-nodpi/marshmallow_38.png new file mode 100644 index 000000000..9083cd762 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/marshmallow_38.png differ diff --git a/app/src/main/res/drawable-nodpi/marshmallow_39.png b/app/src/main/res/drawable-nodpi/marshmallow_39.png new file mode 100644 index 000000000..9083cd762 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/marshmallow_39.png differ diff --git a/app/src/main/res/drawable-nodpi/marshmallow_4.png b/app/src/main/res/drawable-nodpi/marshmallow_4.png new file mode 100644 index 000000000..26c7a43e9 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/marshmallow_4.png differ diff --git a/app/src/main/res/drawable-nodpi/marshmallow_40.png b/app/src/main/res/drawable-nodpi/marshmallow_40.png new file mode 100644 index 000000000..88e88794e Binary files /dev/null and b/app/src/main/res/drawable-nodpi/marshmallow_40.png differ diff --git a/app/src/main/res/drawable-nodpi/marshmallow_41.png b/app/src/main/res/drawable-nodpi/marshmallow_41.png new file mode 100644 index 000000000..1d215345c Binary files /dev/null and b/app/src/main/res/drawable-nodpi/marshmallow_41.png differ diff --git a/app/src/main/res/drawable-nodpi/marshmallow_42.png b/app/src/main/res/drawable-nodpi/marshmallow_42.png new file mode 100644 index 000000000..2208ac455 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/marshmallow_42.png differ diff --git a/app/src/main/res/drawable-nodpi/marshmallow_43.png b/app/src/main/res/drawable-nodpi/marshmallow_43.png new file mode 100644 index 000000000..1d215345c Binary files /dev/null and b/app/src/main/res/drawable-nodpi/marshmallow_43.png differ diff --git a/app/src/main/res/drawable-nodpi/marshmallow_44.png b/app/src/main/res/drawable-nodpi/marshmallow_44.png new file mode 100644 index 000000000..9cab75a1a Binary files /dev/null and b/app/src/main/res/drawable-nodpi/marshmallow_44.png differ diff --git a/app/src/main/res/drawable-nodpi/marshmallow_45.png b/app/src/main/res/drawable-nodpi/marshmallow_45.png new file mode 100644 index 000000000..26c7a43e9 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/marshmallow_45.png differ diff --git a/app/src/main/res/drawable-nodpi/marshmallow_46.png b/app/src/main/res/drawable-nodpi/marshmallow_46.png new file mode 100644 index 000000000..2208ac455 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/marshmallow_46.png differ diff --git a/app/src/main/res/drawable-nodpi/marshmallow_47.png b/app/src/main/res/drawable-nodpi/marshmallow_47.png new file mode 100644 index 000000000..26c7a43e9 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/marshmallow_47.png differ diff --git a/app/src/main/res/drawable-nodpi/marshmallow_5.png b/app/src/main/res/drawable-nodpi/marshmallow_5.png new file mode 100644 index 000000000..61b541064 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/marshmallow_5.png differ diff --git a/app/src/main/res/drawable-nodpi/marshmallow_6.png b/app/src/main/res/drawable-nodpi/marshmallow_6.png new file mode 100644 index 000000000..df2357894 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/marshmallow_6.png differ diff --git a/app/src/main/res/drawable-nodpi/marshmallow_7.png b/app/src/main/res/drawable-nodpi/marshmallow_7.png new file mode 100644 index 000000000..61b541064 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/marshmallow_7.png differ diff --git a/app/src/main/res/drawable-nodpi/marshmallow_8.png b/app/src/main/res/drawable-nodpi/marshmallow_8.png new file mode 100644 index 000000000..6b9789ca8 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/marshmallow_8.png differ diff --git a/app/src/main/res/drawable-nodpi/marshmallow_9.png b/app/src/main/res/drawable-nodpi/marshmallow_9.png new file mode 100644 index 000000000..041867829 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/marshmallow_9.png differ diff --git a/app/src/main/res/drawable-nodpi/marshmallow_na.png b/app/src/main/res/drawable-nodpi/marshmallow_na.png new file mode 100644 index 000000000..9c7abaadf Binary files /dev/null and b/app/src/main/res/drawable-nodpi/marshmallow_na.png differ diff --git a/app/src/main/res/drawable-nodpi/stickers_0.png b/app/src/main/res/drawable-nodpi/stickers_0.png new file mode 100644 index 000000000..49bb8af8f Binary files /dev/null and b/app/src/main/res/drawable-nodpi/stickers_0.png differ diff --git a/app/src/main/res/drawable-nodpi/stickers_1.png b/app/src/main/res/drawable-nodpi/stickers_1.png new file mode 100644 index 000000000..2f1a5bbd3 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/stickers_1.png differ diff --git a/app/src/main/res/drawable-nodpi/stickers_10.png b/app/src/main/res/drawable-nodpi/stickers_10.png new file mode 100644 index 000000000..99cdb36aa Binary files /dev/null and b/app/src/main/res/drawable-nodpi/stickers_10.png differ diff --git a/app/src/main/res/drawable-nodpi/stickers_11.png b/app/src/main/res/drawable-nodpi/stickers_11.png new file mode 100644 index 000000000..afdb9d523 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/stickers_11.png differ diff --git a/app/src/main/res/drawable-nodpi/stickers_12.png b/app/src/main/res/drawable-nodpi/stickers_12.png new file mode 100644 index 000000000..afdb9d523 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/stickers_12.png differ diff --git a/app/src/main/res/drawable-nodpi/stickers_13.png b/app/src/main/res/drawable-nodpi/stickers_13.png new file mode 100644 index 000000000..3cd97d6c1 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/stickers_13.png differ diff --git a/app/src/main/res/drawable-nodpi/stickers_14.png b/app/src/main/res/drawable-nodpi/stickers_14.png new file mode 100644 index 000000000..3cd97d6c1 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/stickers_14.png differ diff --git a/app/src/main/res/drawable-nodpi/stickers_15.png b/app/src/main/res/drawable-nodpi/stickers_15.png new file mode 100644 index 000000000..3cd97d6c1 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/stickers_15.png differ diff --git a/app/src/main/res/drawable-nodpi/stickers_16.png b/app/src/main/res/drawable-nodpi/stickers_16.png new file mode 100644 index 000000000..3cd97d6c1 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/stickers_16.png differ diff --git a/app/src/main/res/drawable-nodpi/stickers_17.png b/app/src/main/res/drawable-nodpi/stickers_17.png new file mode 100644 index 000000000..3cd97d6c1 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/stickers_17.png differ diff --git a/app/src/main/res/drawable-nodpi/stickers_18.png b/app/src/main/res/drawable-nodpi/stickers_18.png new file mode 100644 index 000000000..3cd97d6c1 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/stickers_18.png differ diff --git a/app/src/main/res/drawable-nodpi/stickers_19.png b/app/src/main/res/drawable-nodpi/stickers_19.png new file mode 100644 index 000000000..35b0777bd Binary files /dev/null and b/app/src/main/res/drawable-nodpi/stickers_19.png differ diff --git a/app/src/main/res/drawable-nodpi/stickers_2.png b/app/src/main/res/drawable-nodpi/stickers_2.png new file mode 100644 index 000000000..49bb8af8f Binary files /dev/null and b/app/src/main/res/drawable-nodpi/stickers_2.png differ diff --git a/app/src/main/res/drawable-nodpi/stickers_20.png b/app/src/main/res/drawable-nodpi/stickers_20.png new file mode 100644 index 000000000..35b0777bd Binary files /dev/null and b/app/src/main/res/drawable-nodpi/stickers_20.png differ diff --git a/app/src/main/res/drawable-nodpi/stickers_21.png b/app/src/main/res/drawable-nodpi/stickers_21.png new file mode 100644 index 000000000..35b0777bd Binary files /dev/null and b/app/src/main/res/drawable-nodpi/stickers_21.png differ diff --git a/app/src/main/res/drawable-nodpi/stickers_22.png b/app/src/main/res/drawable-nodpi/stickers_22.png new file mode 100644 index 000000000..35b0777bd Binary files /dev/null and b/app/src/main/res/drawable-nodpi/stickers_22.png differ diff --git a/app/src/main/res/drawable-nodpi/stickers_23.png b/app/src/main/res/drawable-nodpi/stickers_23.png new file mode 100644 index 000000000..4866291d8 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/stickers_23.png differ diff --git a/app/src/main/res/drawable-nodpi/stickers_24.png b/app/src/main/res/drawable-nodpi/stickers_24.png new file mode 100644 index 000000000..4866291d8 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/stickers_24.png differ diff --git a/app/src/main/res/drawable-nodpi/stickers_25.png b/app/src/main/res/drawable-nodpi/stickers_25.png new file mode 100644 index 000000000..490b1bc18 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/stickers_25.png differ diff --git a/app/src/main/res/drawable-nodpi/stickers_26.png b/app/src/main/res/drawable-nodpi/stickers_26.png new file mode 100644 index 000000000..30a6279f4 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/stickers_26.png differ diff --git a/app/src/main/res/drawable-nodpi/stickers_27.png b/app/src/main/res/drawable-nodpi/stickers_27.png new file mode 100644 index 000000000..0891ead99 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/stickers_27.png differ diff --git a/app/src/main/res/drawable-nodpi/stickers_28.png b/app/src/main/res/drawable-nodpi/stickers_28.png new file mode 100644 index 000000000..e789fcea7 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/stickers_28.png differ diff --git a/app/src/main/res/drawable-nodpi/stickers_29.png b/app/src/main/res/drawable-nodpi/stickers_29.png new file mode 100644 index 000000000..8476a2ce7 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/stickers_29.png differ diff --git a/app/src/main/res/drawable-nodpi/stickers_3.png b/app/src/main/res/drawable-nodpi/stickers_3.png new file mode 100644 index 000000000..2f1a5bbd3 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/stickers_3.png differ diff --git a/app/src/main/res/drawable-nodpi/stickers_30.png b/app/src/main/res/drawable-nodpi/stickers_30.png new file mode 100644 index 000000000..d347d4f44 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/stickers_30.png differ diff --git a/app/src/main/res/drawable-nodpi/stickers_31.png b/app/src/main/res/drawable-nodpi/stickers_31.png new file mode 100644 index 000000000..afb85c087 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/stickers_31.png differ diff --git a/app/src/main/res/drawable-nodpi/stickers_32.png b/app/src/main/res/drawable-nodpi/stickers_32.png new file mode 100644 index 000000000..6881ccb25 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/stickers_32.png differ diff --git a/app/src/main/res/drawable-nodpi/stickers_33.png b/app/src/main/res/drawable-nodpi/stickers_33.png new file mode 100644 index 000000000..afb85c087 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/stickers_33.png differ diff --git a/app/src/main/res/drawable-nodpi/stickers_34.png b/app/src/main/res/drawable-nodpi/stickers_34.png new file mode 100644 index 000000000..6881ccb25 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/stickers_34.png differ diff --git a/app/src/main/res/drawable-nodpi/stickers_35.png b/app/src/main/res/drawable-nodpi/stickers_35.png new file mode 100644 index 000000000..99cdb36aa Binary files /dev/null and b/app/src/main/res/drawable-nodpi/stickers_35.png differ diff --git a/app/src/main/res/drawable-nodpi/stickers_36.png b/app/src/main/res/drawable-nodpi/stickers_36.png new file mode 100644 index 000000000..f040604ef Binary files /dev/null and b/app/src/main/res/drawable-nodpi/stickers_36.png differ diff --git a/app/src/main/res/drawable-nodpi/stickers_37.png b/app/src/main/res/drawable-nodpi/stickers_37.png new file mode 100644 index 000000000..2f1a5bbd3 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/stickers_37.png differ diff --git a/app/src/main/res/drawable-nodpi/stickers_38.png b/app/src/main/res/drawable-nodpi/stickers_38.png new file mode 100644 index 000000000..2f1a5bbd3 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/stickers_38.png differ diff --git a/app/src/main/res/drawable-nodpi/stickers_39.png b/app/src/main/res/drawable-nodpi/stickers_39.png new file mode 100644 index 000000000..2f1a5bbd3 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/stickers_39.png differ diff --git a/app/src/main/res/drawable-nodpi/stickers_4.png b/app/src/main/res/drawable-nodpi/stickers_4.png new file mode 100644 index 000000000..2f1a5bbd3 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/stickers_4.png differ diff --git a/app/src/main/res/drawable-nodpi/stickers_40.png b/app/src/main/res/drawable-nodpi/stickers_40.png new file mode 100644 index 000000000..afdb9d523 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/stickers_40.png differ diff --git a/app/src/main/res/drawable-nodpi/stickers_41.png b/app/src/main/res/drawable-nodpi/stickers_41.png new file mode 100644 index 000000000..3cd97d6c1 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/stickers_41.png differ diff --git a/app/src/main/res/drawable-nodpi/stickers_42.png b/app/src/main/res/drawable-nodpi/stickers_42.png new file mode 100644 index 000000000..3cd97d6c1 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/stickers_42.png differ diff --git a/app/src/main/res/drawable-nodpi/stickers_43.png b/app/src/main/res/drawable-nodpi/stickers_43.png new file mode 100644 index 000000000..3cd97d6c1 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/stickers_43.png differ diff --git a/app/src/main/res/drawable-nodpi/stickers_44.png b/app/src/main/res/drawable-nodpi/stickers_44.png new file mode 100644 index 000000000..0891ead99 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/stickers_44.png differ diff --git a/app/src/main/res/drawable-nodpi/stickers_45.png b/app/src/main/res/drawable-nodpi/stickers_45.png new file mode 100644 index 000000000..2f1a5bbd3 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/stickers_45.png differ diff --git a/app/src/main/res/drawable-nodpi/stickers_46.png b/app/src/main/res/drawable-nodpi/stickers_46.png new file mode 100644 index 000000000..3cd97d6c1 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/stickers_46.png differ diff --git a/app/src/main/res/drawable-nodpi/stickers_47.png b/app/src/main/res/drawable-nodpi/stickers_47.png new file mode 100644 index 000000000..2f1a5bbd3 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/stickers_47.png differ diff --git a/app/src/main/res/drawable-nodpi/stickers_5.png b/app/src/main/res/drawable-nodpi/stickers_5.png new file mode 100644 index 000000000..99cdb36aa Binary files /dev/null and b/app/src/main/res/drawable-nodpi/stickers_5.png differ diff --git a/app/src/main/res/drawable-nodpi/stickers_6.png b/app/src/main/res/drawable-nodpi/stickers_6.png new file mode 100644 index 000000000..99cdb36aa Binary files /dev/null and b/app/src/main/res/drawable-nodpi/stickers_6.png differ diff --git a/app/src/main/res/drawable-nodpi/stickers_7.png b/app/src/main/res/drawable-nodpi/stickers_7.png new file mode 100644 index 000000000..99cdb36aa Binary files /dev/null and b/app/src/main/res/drawable-nodpi/stickers_7.png differ diff --git a/app/src/main/res/drawable-nodpi/stickers_8.png b/app/src/main/res/drawable-nodpi/stickers_8.png new file mode 100644 index 000000000..99cdb36aa Binary files /dev/null and b/app/src/main/res/drawable-nodpi/stickers_8.png differ diff --git a/app/src/main/res/drawable-nodpi/stickers_9.png b/app/src/main/res/drawable-nodpi/stickers_9.png new file mode 100644 index 000000000..afdb9d523 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/stickers_9.png differ diff --git a/app/src/main/res/drawable-nodpi/stickers_na.png b/app/src/main/res/drawable-nodpi/stickers_na.png new file mode 100644 index 000000000..8f8c5818e Binary files /dev/null and b/app/src/main/res/drawable-nodpi/stickers_na.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_color_0.png b/app/src/main/res/drawable-nodpi/weather_color_0.png new file mode 100644 index 000000000..5bc8f8549 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_color_0.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_color_1.png b/app/src/main/res/drawable-nodpi/weather_color_1.png new file mode 100644 index 000000000..1664c72ca Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_color_1.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_color_10.png b/app/src/main/res/drawable-nodpi/weather_color_10.png new file mode 100644 index 000000000..e261b2b49 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_color_10.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_color_11.png b/app/src/main/res/drawable-nodpi/weather_color_11.png new file mode 100644 index 000000000..5f1b6b6c0 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_color_11.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_color_12.png b/app/src/main/res/drawable-nodpi/weather_color_12.png new file mode 100644 index 000000000..5f1b6b6c0 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_color_12.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_color_13.png b/app/src/main/res/drawable-nodpi/weather_color_13.png new file mode 100644 index 000000000..58936279d Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_color_13.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_color_14.png b/app/src/main/res/drawable-nodpi/weather_color_14.png new file mode 100644 index 000000000..58936279d Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_color_14.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_color_15.png b/app/src/main/res/drawable-nodpi/weather_color_15.png new file mode 100644 index 000000000..58936279d Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_color_15.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_color_16.png b/app/src/main/res/drawable-nodpi/weather_color_16.png new file mode 100644 index 000000000..58936279d Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_color_16.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_color_17.png b/app/src/main/res/drawable-nodpi/weather_color_17.png new file mode 100644 index 000000000..c9a81c11a Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_color_17.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_color_18.png b/app/src/main/res/drawable-nodpi/weather_color_18.png new file mode 100644 index 000000000..e1d2691bb Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_color_18.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_color_19.png b/app/src/main/res/drawable-nodpi/weather_color_19.png new file mode 100644 index 000000000..052cfc68d Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_color_19.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_color_2.png b/app/src/main/res/drawable-nodpi/weather_color_2.png new file mode 100644 index 000000000..1664c72ca Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_color_2.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_color_20.png b/app/src/main/res/drawable-nodpi/weather_color_20.png new file mode 100644 index 000000000..d5c2da1c7 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_color_20.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_color_21.png b/app/src/main/res/drawable-nodpi/weather_color_21.png new file mode 100644 index 000000000..5830cb4d6 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_color_21.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_color_22.png b/app/src/main/res/drawable-nodpi/weather_color_22.png new file mode 100644 index 000000000..191a1b045 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_color_22.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_color_23.png b/app/src/main/res/drawable-nodpi/weather_color_23.png new file mode 100644 index 000000000..d7a10eed9 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_color_23.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_color_24.png b/app/src/main/res/drawable-nodpi/weather_color_24.png new file mode 100644 index 000000000..d7a10eed9 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_color_24.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_color_25.png b/app/src/main/res/drawable-nodpi/weather_color_25.png new file mode 100644 index 000000000..6d42b04ec Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_color_25.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_color_26.png b/app/src/main/res/drawable-nodpi/weather_color_26.png new file mode 100644 index 000000000..5c6057de8 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_color_26.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_color_27.png b/app/src/main/res/drawable-nodpi/weather_color_27.png new file mode 100644 index 000000000..06b10f2c6 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_color_27.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_color_28.png b/app/src/main/res/drawable-nodpi/weather_color_28.png new file mode 100644 index 000000000..82b98ab8f Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_color_28.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_color_29.png b/app/src/main/res/drawable-nodpi/weather_color_29.png new file mode 100644 index 000000000..288a1eb00 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_color_29.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_color_3.png b/app/src/main/res/drawable-nodpi/weather_color_3.png new file mode 100644 index 000000000..5bc8f8549 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_color_3.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_color_30.png b/app/src/main/res/drawable-nodpi/weather_color_30.png new file mode 100644 index 000000000..52ae67dd9 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_color_30.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_color_31.png b/app/src/main/res/drawable-nodpi/weather_color_31.png new file mode 100644 index 000000000..3214e2d5f Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_color_31.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_color_32.png b/app/src/main/res/drawable-nodpi/weather_color_32.png new file mode 100644 index 000000000..da6d3d53b Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_color_32.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_color_33.png b/app/src/main/res/drawable-nodpi/weather_color_33.png new file mode 100644 index 000000000..a6ad077ff Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_color_33.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_color_34.png b/app/src/main/res/drawable-nodpi/weather_color_34.png new file mode 100644 index 000000000..36974c906 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_color_34.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_color_35.png b/app/src/main/res/drawable-nodpi/weather_color_35.png new file mode 100644 index 000000000..eaa92970c Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_color_35.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_color_36.png b/app/src/main/res/drawable-nodpi/weather_color_36.png new file mode 100644 index 000000000..dccd3c997 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_color_36.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_color_37.png b/app/src/main/res/drawable-nodpi/weather_color_37.png new file mode 100644 index 000000000..ee51d9305 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_color_37.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_color_38.png b/app/src/main/res/drawable-nodpi/weather_color_38.png new file mode 100644 index 000000000..ee51d9305 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_color_38.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_color_39.png b/app/src/main/res/drawable-nodpi/weather_color_39.png new file mode 100644 index 000000000..ee51d9305 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_color_39.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_color_4.png b/app/src/main/res/drawable-nodpi/weather_color_4.png new file mode 100644 index 000000000..5bc8f8549 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_color_4.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_color_40.png b/app/src/main/res/drawable-nodpi/weather_color_40.png new file mode 100644 index 000000000..d4b64e598 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_color_40.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_color_41.png b/app/src/main/res/drawable-nodpi/weather_color_41.png new file mode 100644 index 000000000..393df8b38 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_color_41.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_color_42.png b/app/src/main/res/drawable-nodpi/weather_color_42.png new file mode 100644 index 000000000..58936279d Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_color_42.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_color_43.png b/app/src/main/res/drawable-nodpi/weather_color_43.png new file mode 100644 index 000000000..393df8b38 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_color_43.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_color_44.png b/app/src/main/res/drawable-nodpi/weather_color_44.png new file mode 100644 index 000000000..a6ad077ff Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_color_44.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_color_45.png b/app/src/main/res/drawable-nodpi/weather_color_45.png new file mode 100644 index 000000000..5a6297f3d Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_color_45.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_color_46.png b/app/src/main/res/drawable-nodpi/weather_color_46.png new file mode 100644 index 000000000..d9c5bf515 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_color_46.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_color_47.png b/app/src/main/res/drawable-nodpi/weather_color_47.png new file mode 100644 index 000000000..e8768872c Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_color_47.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_color_5.png b/app/src/main/res/drawable-nodpi/weather_color_5.png new file mode 100644 index 000000000..e1d2691bb Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_color_5.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_color_6.png b/app/src/main/res/drawable-nodpi/weather_color_6.png new file mode 100644 index 000000000..e1d2691bb Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_color_6.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_color_7.png b/app/src/main/res/drawable-nodpi/weather_color_7.png new file mode 100644 index 000000000..58936279d Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_color_7.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_color_8.png b/app/src/main/res/drawable-nodpi/weather_color_8.png new file mode 100644 index 000000000..05836a51d Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_color_8.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_color_9.png b/app/src/main/res/drawable-nodpi/weather_color_9.png new file mode 100644 index 000000000..0ab22e9d4 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_color_9.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_color_na.png b/app/src/main/res/drawable-nodpi/weather_color_na.png new file mode 100644 index 000000000..5b8c4ce37 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_color_na.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_faded_0.png b/app/src/main/res/drawable-nodpi/weather_faded_0.png new file mode 100644 index 000000000..c82c10efa Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_faded_0.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_faded_1.png b/app/src/main/res/drawable-nodpi/weather_faded_1.png new file mode 100644 index 000000000..164118e50 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_faded_1.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_faded_10.png b/app/src/main/res/drawable-nodpi/weather_faded_10.png new file mode 100644 index 000000000..4b2d447fe Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_faded_10.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_faded_11.png b/app/src/main/res/drawable-nodpi/weather_faded_11.png new file mode 100644 index 000000000..f5a1bdb39 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_faded_11.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_faded_12.png b/app/src/main/res/drawable-nodpi/weather_faded_12.png new file mode 100644 index 000000000..812606f7f Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_faded_12.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_faded_13.png b/app/src/main/res/drawable-nodpi/weather_faded_13.png new file mode 100644 index 000000000..4c2ef119b Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_faded_13.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_faded_14.png b/app/src/main/res/drawable-nodpi/weather_faded_14.png new file mode 100644 index 000000000..d1ba90975 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_faded_14.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_faded_15.png b/app/src/main/res/drawable-nodpi/weather_faded_15.png new file mode 100644 index 000000000..eef24d04c Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_faded_15.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_faded_16.png b/app/src/main/res/drawable-nodpi/weather_faded_16.png new file mode 100644 index 000000000..135523f63 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_faded_16.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_faded_17.png b/app/src/main/res/drawable-nodpi/weather_faded_17.png new file mode 100644 index 000000000..85d8fe511 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_faded_17.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_faded_18.png b/app/src/main/res/drawable-nodpi/weather_faded_18.png new file mode 100644 index 000000000..8eff44bbf Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_faded_18.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_faded_19.png b/app/src/main/res/drawable-nodpi/weather_faded_19.png new file mode 100644 index 000000000..7d7f1bf74 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_faded_19.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_faded_2.png b/app/src/main/res/drawable-nodpi/weather_faded_2.png new file mode 100644 index 000000000..c82c10efa Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_faded_2.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_faded_20.png b/app/src/main/res/drawable-nodpi/weather_faded_20.png new file mode 100644 index 000000000..15861b018 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_faded_20.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_faded_21.png b/app/src/main/res/drawable-nodpi/weather_faded_21.png new file mode 100644 index 000000000..7d7f1bf74 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_faded_21.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_faded_22.png b/app/src/main/res/drawable-nodpi/weather_faded_22.png new file mode 100644 index 000000000..15861b018 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_faded_22.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_faded_23.png b/app/src/main/res/drawable-nodpi/weather_faded_23.png new file mode 100644 index 000000000..20300a59a Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_faded_23.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_faded_24.png b/app/src/main/res/drawable-nodpi/weather_faded_24.png new file mode 100644 index 000000000..805986374 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_faded_24.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_faded_25.png b/app/src/main/res/drawable-nodpi/weather_faded_25.png new file mode 100644 index 000000000..4c2ef119b Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_faded_25.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_faded_26.png b/app/src/main/res/drawable-nodpi/weather_faded_26.png new file mode 100644 index 000000000..6759bccca Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_faded_26.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_faded_27.png b/app/src/main/res/drawable-nodpi/weather_faded_27.png new file mode 100644 index 000000000..1a789a388 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_faded_27.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_faded_28.png b/app/src/main/res/drawable-nodpi/weather_faded_28.png new file mode 100644 index 000000000..8627e12d3 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_faded_28.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_faded_29.png b/app/src/main/res/drawable-nodpi/weather_faded_29.png new file mode 100644 index 000000000..7e549a5ad Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_faded_29.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_faded_3.png b/app/src/main/res/drawable-nodpi/weather_faded_3.png new file mode 100644 index 000000000..812606f7f Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_faded_3.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_faded_30.png b/app/src/main/res/drawable-nodpi/weather_faded_30.png new file mode 100644 index 000000000..6759bccca Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_faded_30.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_faded_31.png b/app/src/main/res/drawable-nodpi/weather_faded_31.png new file mode 100644 index 000000000..9494dcda4 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_faded_31.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_faded_32.png b/app/src/main/res/drawable-nodpi/weather_faded_32.png new file mode 100644 index 000000000..773b5f0f3 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_faded_32.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_faded_33.png b/app/src/main/res/drawable-nodpi/weather_faded_33.png new file mode 100644 index 000000000..9494dcda4 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_faded_33.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_faded_34.png b/app/src/main/res/drawable-nodpi/weather_faded_34.png new file mode 100644 index 000000000..773b5f0f3 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_faded_34.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_faded_35.png b/app/src/main/res/drawable-nodpi/weather_faded_35.png new file mode 100644 index 000000000..eef24d04c Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_faded_35.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_faded_36.png b/app/src/main/res/drawable-nodpi/weather_faded_36.png new file mode 100644 index 000000000..773b5f0f3 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_faded_36.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_faded_37.png b/app/src/main/res/drawable-nodpi/weather_faded_37.png new file mode 100644 index 000000000..812606f7f Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_faded_37.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_faded_38.png b/app/src/main/res/drawable-nodpi/weather_faded_38.png new file mode 100644 index 000000000..812606f7f Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_faded_38.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_faded_39.png b/app/src/main/res/drawable-nodpi/weather_faded_39.png new file mode 100644 index 000000000..f5a1bdb39 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_faded_39.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_faded_4.png b/app/src/main/res/drawable-nodpi/weather_faded_4.png new file mode 100644 index 000000000..812606f7f Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_faded_4.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_faded_40.png b/app/src/main/res/drawable-nodpi/weather_faded_40.png new file mode 100644 index 000000000..45ddcdfde Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_faded_40.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_faded_41.png b/app/src/main/res/drawable-nodpi/weather_faded_41.png new file mode 100644 index 000000000..d1ba90975 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_faded_41.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_faded_42.png b/app/src/main/res/drawable-nodpi/weather_faded_42.png new file mode 100644 index 000000000..eef24d04c Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_faded_42.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_faded_43.png b/app/src/main/res/drawable-nodpi/weather_faded_43.png new file mode 100644 index 000000000..eef24d04c Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_faded_43.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_faded_44.png b/app/src/main/res/drawable-nodpi/weather_faded_44.png new file mode 100644 index 000000000..6759bccca Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_faded_44.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_faded_45.png b/app/src/main/res/drawable-nodpi/weather_faded_45.png new file mode 100644 index 000000000..f5a1bdb39 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_faded_45.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_faded_46.png b/app/src/main/res/drawable-nodpi/weather_faded_46.png new file mode 100644 index 000000000..eef24d04c Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_faded_46.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_faded_47.png b/app/src/main/res/drawable-nodpi/weather_faded_47.png new file mode 100644 index 000000000..f5a1bdb39 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_faded_47.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_faded_5.png b/app/src/main/res/drawable-nodpi/weather_faded_5.png new file mode 100644 index 000000000..4b2d447fe Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_faded_5.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_faded_6.png b/app/src/main/res/drawable-nodpi/weather_faded_6.png new file mode 100644 index 000000000..d1ba90975 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_faded_6.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_faded_7.png b/app/src/main/res/drawable-nodpi/weather_faded_7.png new file mode 100644 index 000000000..d1ba90975 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_faded_7.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_faded_8.png b/app/src/main/res/drawable-nodpi/weather_faded_8.png new file mode 100644 index 000000000..4b2d447fe Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_faded_8.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_faded_9.png b/app/src/main/res/drawable-nodpi/weather_faded_9.png new file mode 100644 index 000000000..c35b2ef1b Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_faded_9.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_faded_na.png b/app/src/main/res/drawable-nodpi/weather_faded_na.png new file mode 100644 index 000000000..42fc5ec60 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_faded_na.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_faded_refresh.png b/app/src/main/res/drawable-nodpi/weather_faded_refresh.png new file mode 100644 index 000000000..42fc5ec60 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_faded_refresh.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_gs6_0.png b/app/src/main/res/drawable-nodpi/weather_gs6_0.png new file mode 100644 index 000000000..3f9aaed90 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_gs6_0.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_gs6_1.png b/app/src/main/res/drawable-nodpi/weather_gs6_1.png new file mode 100644 index 000000000..3f9aaed90 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_gs6_1.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_gs6_10.png b/app/src/main/res/drawable-nodpi/weather_gs6_10.png new file mode 100644 index 000000000..16da4cf00 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_gs6_10.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_gs6_11.png b/app/src/main/res/drawable-nodpi/weather_gs6_11.png new file mode 100644 index 000000000..16da4cf00 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_gs6_11.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_gs6_12.png b/app/src/main/res/drawable-nodpi/weather_gs6_12.png new file mode 100644 index 000000000..16da4cf00 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_gs6_12.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_gs6_13.png b/app/src/main/res/drawable-nodpi/weather_gs6_13.png new file mode 100644 index 000000000..81b844702 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_gs6_13.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_gs6_14.png b/app/src/main/res/drawable-nodpi/weather_gs6_14.png new file mode 100644 index 000000000..81b844702 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_gs6_14.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_gs6_15.png b/app/src/main/res/drawable-nodpi/weather_gs6_15.png new file mode 100644 index 000000000..81b844702 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_gs6_15.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_gs6_16.png b/app/src/main/res/drawable-nodpi/weather_gs6_16.png new file mode 100644 index 000000000..81b844702 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_gs6_16.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_gs6_17.png b/app/src/main/res/drawable-nodpi/weather_gs6_17.png new file mode 100644 index 000000000..d60b46c23 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_gs6_17.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_gs6_18.png b/app/src/main/res/drawable-nodpi/weather_gs6_18.png new file mode 100644 index 000000000..d60b46c23 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_gs6_18.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_gs6_19.png b/app/src/main/res/drawable-nodpi/weather_gs6_19.png new file mode 100644 index 000000000..3f9aaed90 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_gs6_19.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_gs6_2.png b/app/src/main/res/drawable-nodpi/weather_gs6_2.png new file mode 100644 index 000000000..3f9aaed90 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_gs6_2.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_gs6_20.png b/app/src/main/res/drawable-nodpi/weather_gs6_20.png new file mode 100644 index 000000000..0516f020b Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_gs6_20.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_gs6_21.png b/app/src/main/res/drawable-nodpi/weather_gs6_21.png new file mode 100644 index 000000000..f72ed9f1b Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_gs6_21.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_gs6_22.png b/app/src/main/res/drawable-nodpi/weather_gs6_22.png new file mode 100644 index 000000000..89d1624a7 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_gs6_22.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_gs6_23.png b/app/src/main/res/drawable-nodpi/weather_gs6_23.png new file mode 100644 index 000000000..3f9aaed90 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_gs6_23.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_gs6_24.png b/app/src/main/res/drawable-nodpi/weather_gs6_24.png new file mode 100644 index 000000000..3f9aaed90 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_gs6_24.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_gs6_25.png b/app/src/main/res/drawable-nodpi/weather_gs6_25.png new file mode 100644 index 000000000..cfa73747d Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_gs6_25.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_gs6_26.png b/app/src/main/res/drawable-nodpi/weather_gs6_26.png new file mode 100644 index 000000000..0516f020b Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_gs6_26.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_gs6_27.png b/app/src/main/res/drawable-nodpi/weather_gs6_27.png new file mode 100644 index 000000000..15a7222ee Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_gs6_27.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_gs6_28.png b/app/src/main/res/drawable-nodpi/weather_gs6_28.png new file mode 100644 index 000000000..f72ed9f1b Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_gs6_28.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_gs6_29.png b/app/src/main/res/drawable-nodpi/weather_gs6_29.png new file mode 100644 index 000000000..15a7222ee Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_gs6_29.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_gs6_3.png b/app/src/main/res/drawable-nodpi/weather_gs6_3.png new file mode 100644 index 000000000..cadc03f84 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_gs6_3.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_gs6_30.png b/app/src/main/res/drawable-nodpi/weather_gs6_30.png new file mode 100644 index 000000000..f72ed9f1b Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_gs6_30.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_gs6_31.png b/app/src/main/res/drawable-nodpi/weather_gs6_31.png new file mode 100644 index 000000000..9268f5c05 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_gs6_31.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_gs6_32.png b/app/src/main/res/drawable-nodpi/weather_gs6_32.png new file mode 100644 index 000000000..542a58694 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_gs6_32.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_gs6_33.png b/app/src/main/res/drawable-nodpi/weather_gs6_33.png new file mode 100644 index 000000000..9268f5c05 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_gs6_33.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_gs6_34.png b/app/src/main/res/drawable-nodpi/weather_gs6_34.png new file mode 100644 index 000000000..542a58694 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_gs6_34.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_gs6_35.png b/app/src/main/res/drawable-nodpi/weather_gs6_35.png new file mode 100644 index 000000000..8e887a02c Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_gs6_35.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_gs6_36.png b/app/src/main/res/drawable-nodpi/weather_gs6_36.png new file mode 100644 index 000000000..6299e7f50 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_gs6_36.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_gs6_37.png b/app/src/main/res/drawable-nodpi/weather_gs6_37.png new file mode 100644 index 000000000..d8ad4b462 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_gs6_37.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_gs6_38.png b/app/src/main/res/drawable-nodpi/weather_gs6_38.png new file mode 100644 index 000000000..d8ad4b462 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_gs6_38.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_gs6_39.png b/app/src/main/res/drawable-nodpi/weather_gs6_39.png new file mode 100644 index 000000000..d8ad4b462 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_gs6_39.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_gs6_4.png b/app/src/main/res/drawable-nodpi/weather_gs6_4.png new file mode 100644 index 000000000..cadc03f84 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_gs6_4.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_gs6_40.png b/app/src/main/res/drawable-nodpi/weather_gs6_40.png new file mode 100644 index 000000000..1140c2465 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_gs6_40.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_gs6_41.png b/app/src/main/res/drawable-nodpi/weather_gs6_41.png new file mode 100644 index 000000000..81b844702 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_gs6_41.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_gs6_42.png b/app/src/main/res/drawable-nodpi/weather_gs6_42.png new file mode 100644 index 000000000..81b844702 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_gs6_42.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_gs6_43.png b/app/src/main/res/drawable-nodpi/weather_gs6_43.png new file mode 100644 index 000000000..81b844702 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_gs6_43.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_gs6_44.png b/app/src/main/res/drawable-nodpi/weather_gs6_44.png new file mode 100644 index 000000000..15a7222ee Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_gs6_44.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_gs6_45.png b/app/src/main/res/drawable-nodpi/weather_gs6_45.png new file mode 100644 index 000000000..cadc03f84 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_gs6_45.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_gs6_46.png b/app/src/main/res/drawable-nodpi/weather_gs6_46.png new file mode 100644 index 000000000..81b844702 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_gs6_46.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_gs6_47.png b/app/src/main/res/drawable-nodpi/weather_gs6_47.png new file mode 100644 index 000000000..cadc03f84 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_gs6_47.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_gs6_5.png b/app/src/main/res/drawable-nodpi/weather_gs6_5.png new file mode 100644 index 000000000..cbcc679d1 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_gs6_5.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_gs6_6.png b/app/src/main/res/drawable-nodpi/weather_gs6_6.png new file mode 100644 index 000000000..cbcc679d1 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_gs6_6.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_gs6_7.png b/app/src/main/res/drawable-nodpi/weather_gs6_7.png new file mode 100644 index 000000000..cbcc679d1 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_gs6_7.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_gs6_8.png b/app/src/main/res/drawable-nodpi/weather_gs6_8.png new file mode 100644 index 000000000..8e887a02c Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_gs6_8.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_gs6_9.png b/app/src/main/res/drawable-nodpi/weather_gs6_9.png new file mode 100644 index 000000000..8e887a02c Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_gs6_9.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_gs6_na.png b/app/src/main/res/drawable-nodpi/weather_gs6_na.png new file mode 100644 index 000000000..349f373b8 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_gs6_na.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_gs6_refresh.png b/app/src/main/res/drawable-nodpi/weather_gs6_refresh.png new file mode 100644 index 000000000..a308e7dd2 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_gs6_refresh.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_magical_0.png b/app/src/main/res/drawable-nodpi/weather_magical_0.png new file mode 100644 index 000000000..9353f9b85 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_magical_0.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_magical_1.png b/app/src/main/res/drawable-nodpi/weather_magical_1.png new file mode 100644 index 000000000..47e5345c9 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_magical_1.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_magical_10.png b/app/src/main/res/drawable-nodpi/weather_magical_10.png new file mode 100644 index 000000000..595d2863d Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_magical_10.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_magical_11.png b/app/src/main/res/drawable-nodpi/weather_magical_11.png new file mode 100644 index 000000000..042a6bd6d Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_magical_11.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_magical_12.png b/app/src/main/res/drawable-nodpi/weather_magical_12.png new file mode 100644 index 000000000..042a6bd6d Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_magical_12.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_magical_13.png b/app/src/main/res/drawable-nodpi/weather_magical_13.png new file mode 100644 index 000000000..6101bd1dd Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_magical_13.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_magical_14.png b/app/src/main/res/drawable-nodpi/weather_magical_14.png new file mode 100644 index 000000000..595d2863d Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_magical_14.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_magical_15.png b/app/src/main/res/drawable-nodpi/weather_magical_15.png new file mode 100644 index 000000000..6101bd1dd Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_magical_15.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_magical_16.png b/app/src/main/res/drawable-nodpi/weather_magical_16.png new file mode 100644 index 000000000..6101bd1dd Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_magical_16.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_magical_17.png b/app/src/main/res/drawable-nodpi/weather_magical_17.png new file mode 100644 index 000000000..467927eef Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_magical_17.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_magical_18.png b/app/src/main/res/drawable-nodpi/weather_magical_18.png new file mode 100644 index 000000000..595d2863d Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_magical_18.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_magical_19.png b/app/src/main/res/drawable-nodpi/weather_magical_19.png new file mode 100644 index 000000000..3c46af9e5 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_magical_19.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_magical_2.png b/app/src/main/res/drawable-nodpi/weather_magical_2.png new file mode 100644 index 000000000..47e5345c9 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_magical_2.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_magical_20.png b/app/src/main/res/drawable-nodpi/weather_magical_20.png new file mode 100644 index 000000000..3c46af9e5 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_magical_20.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_magical_21.png b/app/src/main/res/drawable-nodpi/weather_magical_21.png new file mode 100644 index 000000000..3c46af9e5 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_magical_21.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_magical_22.png b/app/src/main/res/drawable-nodpi/weather_magical_22.png new file mode 100644 index 000000000..742a48581 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_magical_22.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_magical_23.png b/app/src/main/res/drawable-nodpi/weather_magical_23.png new file mode 100644 index 000000000..79d1b993a Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_magical_23.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_magical_24.png b/app/src/main/res/drawable-nodpi/weather_magical_24.png new file mode 100644 index 000000000..79d1b993a Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_magical_24.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_magical_25.png b/app/src/main/res/drawable-nodpi/weather_magical_25.png new file mode 100644 index 000000000..7c8d100ba Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_magical_25.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_magical_26.png b/app/src/main/res/drawable-nodpi/weather_magical_26.png new file mode 100644 index 000000000..dfcf73615 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_magical_26.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_magical_27.png b/app/src/main/res/drawable-nodpi/weather_magical_27.png new file mode 100644 index 000000000..62830cebb Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_magical_27.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_magical_28.png b/app/src/main/res/drawable-nodpi/weather_magical_28.png new file mode 100644 index 000000000..0fb3fe38e Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_magical_28.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_magical_29.png b/app/src/main/res/drawable-nodpi/weather_magical_29.png new file mode 100644 index 000000000..f20fb8744 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_magical_29.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_magical_3.png b/app/src/main/res/drawable-nodpi/weather_magical_3.png new file mode 100644 index 000000000..47e5345c9 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_magical_3.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_magical_30.png b/app/src/main/res/drawable-nodpi/weather_magical_30.png new file mode 100644 index 000000000..3b9e9df78 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_magical_30.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_magical_31.png b/app/src/main/res/drawable-nodpi/weather_magical_31.png new file mode 100644 index 000000000..5bca0a014 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_magical_31.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_magical_32.png b/app/src/main/res/drawable-nodpi/weather_magical_32.png new file mode 100644 index 000000000..39f2007f6 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_magical_32.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_magical_33.png b/app/src/main/res/drawable-nodpi/weather_magical_33.png new file mode 100644 index 000000000..a8a06d759 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_magical_33.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_magical_34.png b/app/src/main/res/drawable-nodpi/weather_magical_34.png new file mode 100644 index 000000000..97151f0d5 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_magical_34.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_magical_35.png b/app/src/main/res/drawable-nodpi/weather_magical_35.png new file mode 100644 index 000000000..33763f8c8 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_magical_35.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_magical_36.png b/app/src/main/res/drawable-nodpi/weather_magical_36.png new file mode 100644 index 000000000..5af988cde Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_magical_36.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_magical_37.png b/app/src/main/res/drawable-nodpi/weather_magical_37.png new file mode 100644 index 000000000..ae277929c Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_magical_37.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_magical_38.png b/app/src/main/res/drawable-nodpi/weather_magical_38.png new file mode 100644 index 000000000..44344e4cb Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_magical_38.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_magical_39.png b/app/src/main/res/drawable-nodpi/weather_magical_39.png new file mode 100644 index 000000000..44344e4cb Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_magical_39.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_magical_4.png b/app/src/main/res/drawable-nodpi/weather_magical_4.png new file mode 100644 index 000000000..47e5345c9 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_magical_4.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_magical_40.png b/app/src/main/res/drawable-nodpi/weather_magical_40.png new file mode 100644 index 000000000..10a3729c6 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_magical_40.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_magical_41.png b/app/src/main/res/drawable-nodpi/weather_magical_41.png new file mode 100644 index 000000000..6101bd1dd Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_magical_41.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_magical_42.png b/app/src/main/res/drawable-nodpi/weather_magical_42.png new file mode 100644 index 000000000..6101bd1dd Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_magical_42.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_magical_43.png b/app/src/main/res/drawable-nodpi/weather_magical_43.png new file mode 100644 index 000000000..0574cf30c Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_magical_43.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_magical_44.png b/app/src/main/res/drawable-nodpi/weather_magical_44.png new file mode 100644 index 000000000..62830cebb Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_magical_44.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_magical_45.png b/app/src/main/res/drawable-nodpi/weather_magical_45.png new file mode 100644 index 000000000..2b6fe7f6e Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_magical_45.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_magical_46.png b/app/src/main/res/drawable-nodpi/weather_magical_46.png new file mode 100644 index 000000000..903edaf35 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_magical_46.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_magical_47.png b/app/src/main/res/drawable-nodpi/weather_magical_47.png new file mode 100644 index 000000000..ae114573e Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_magical_47.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_magical_5.png b/app/src/main/res/drawable-nodpi/weather_magical_5.png new file mode 100644 index 000000000..595d2863d Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_magical_5.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_magical_6.png b/app/src/main/res/drawable-nodpi/weather_magical_6.png new file mode 100644 index 000000000..595d2863d Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_magical_6.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_magical_7.png b/app/src/main/res/drawable-nodpi/weather_magical_7.png new file mode 100644 index 000000000..6101bd1dd Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_magical_7.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_magical_8.png b/app/src/main/res/drawable-nodpi/weather_magical_8.png new file mode 100644 index 000000000..10a3729c6 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_magical_8.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_magical_9.png b/app/src/main/res/drawable-nodpi/weather_magical_9.png new file mode 100644 index 000000000..5339ab977 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_magical_9.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_magical_na.png b/app/src/main/res/drawable-nodpi/weather_magical_na.png new file mode 100644 index 000000000..b5e542d41 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_magical_na.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_miui_0.png b/app/src/main/res/drawable-nodpi/weather_miui_0.png new file mode 100644 index 000000000..a4a3b8dc1 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_miui_0.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_miui_1.png b/app/src/main/res/drawable-nodpi/weather_miui_1.png new file mode 100644 index 000000000..a4a3b8dc1 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_miui_1.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_miui_10.png b/app/src/main/res/drawable-nodpi/weather_miui_10.png new file mode 100644 index 000000000..e3f443ceb Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_miui_10.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_miui_11.png b/app/src/main/res/drawable-nodpi/weather_miui_11.png new file mode 100644 index 000000000..e23f49273 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_miui_11.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_miui_12.png b/app/src/main/res/drawable-nodpi/weather_miui_12.png new file mode 100644 index 000000000..e23f49273 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_miui_12.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_miui_13.png b/app/src/main/res/drawable-nodpi/weather_miui_13.png new file mode 100644 index 000000000..c2216a62a Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_miui_13.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_miui_14.png b/app/src/main/res/drawable-nodpi/weather_miui_14.png new file mode 100644 index 000000000..e3f443ceb Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_miui_14.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_miui_15.png b/app/src/main/res/drawable-nodpi/weather_miui_15.png new file mode 100644 index 000000000..c2216a62a Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_miui_15.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_miui_16.png b/app/src/main/res/drawable-nodpi/weather_miui_16.png new file mode 100644 index 000000000..c2216a62a Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_miui_16.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_miui_17.png b/app/src/main/res/drawable-nodpi/weather_miui_17.png new file mode 100644 index 000000000..e23f49273 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_miui_17.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_miui_18.png b/app/src/main/res/drawable-nodpi/weather_miui_18.png new file mode 100644 index 000000000..e3f443ceb Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_miui_18.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_miui_19.png b/app/src/main/res/drawable-nodpi/weather_miui_19.png new file mode 100644 index 000000000..0c6f985b8 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_miui_19.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_miui_2.png b/app/src/main/res/drawable-nodpi/weather_miui_2.png new file mode 100644 index 000000000..a4a3b8dc1 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_miui_2.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_miui_20.png b/app/src/main/res/drawable-nodpi/weather_miui_20.png new file mode 100644 index 000000000..b02eb24b9 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_miui_20.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_miui_21.png b/app/src/main/res/drawable-nodpi/weather_miui_21.png new file mode 100644 index 000000000..b02eb24b9 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_miui_21.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_miui_22.png b/app/src/main/res/drawable-nodpi/weather_miui_22.png new file mode 100644 index 000000000..0c6f985b8 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_miui_22.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_miui_23.png b/app/src/main/res/drawable-nodpi/weather_miui_23.png new file mode 100644 index 000000000..0c6f985b8 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_miui_23.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_miui_24.png b/app/src/main/res/drawable-nodpi/weather_miui_24.png new file mode 100644 index 000000000..90e7f063b Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_miui_24.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_miui_25.png b/app/src/main/res/drawable-nodpi/weather_miui_25.png new file mode 100644 index 000000000..0c6f985b8 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_miui_25.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_miui_26.png b/app/src/main/res/drawable-nodpi/weather_miui_26.png new file mode 100644 index 000000000..90e7f063b Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_miui_26.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_miui_27.png b/app/src/main/res/drawable-nodpi/weather_miui_27.png new file mode 100644 index 000000000..2e4ec962b Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_miui_27.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_miui_28.png b/app/src/main/res/drawable-nodpi/weather_miui_28.png new file mode 100644 index 000000000..a20e6b730 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_miui_28.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_miui_29.png b/app/src/main/res/drawable-nodpi/weather_miui_29.png new file mode 100644 index 000000000..114d37cb5 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_miui_29.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_miui_3.png b/app/src/main/res/drawable-nodpi/weather_miui_3.png new file mode 100644 index 000000000..a4a3b8dc1 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_miui_3.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_miui_30.png b/app/src/main/res/drawable-nodpi/weather_miui_30.png new file mode 100644 index 000000000..5adc15bf5 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_miui_30.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_miui_31.png b/app/src/main/res/drawable-nodpi/weather_miui_31.png new file mode 100644 index 000000000..fa5d8ab2c Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_miui_31.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_miui_32.png b/app/src/main/res/drawable-nodpi/weather_miui_32.png new file mode 100644 index 000000000..d483024cc Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_miui_32.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_miui_33.png b/app/src/main/res/drawable-nodpi/weather_miui_33.png new file mode 100644 index 000000000..fa5d8ab2c Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_miui_33.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_miui_34.png b/app/src/main/res/drawable-nodpi/weather_miui_34.png new file mode 100644 index 000000000..d483024cc Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_miui_34.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_miui_35.png b/app/src/main/res/drawable-nodpi/weather_miui_35.png new file mode 100644 index 000000000..e3f443ceb Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_miui_35.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_miui_36.png b/app/src/main/res/drawable-nodpi/weather_miui_36.png new file mode 100644 index 000000000..d483024cc Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_miui_36.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_miui_37.png b/app/src/main/res/drawable-nodpi/weather_miui_37.png new file mode 100644 index 000000000..79a60a761 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_miui_37.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_miui_38.png b/app/src/main/res/drawable-nodpi/weather_miui_38.png new file mode 100644 index 000000000..79a60a761 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_miui_38.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_miui_39.png b/app/src/main/res/drawable-nodpi/weather_miui_39.png new file mode 100644 index 000000000..79a60a761 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_miui_39.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_miui_4.png b/app/src/main/res/drawable-nodpi/weather_miui_4.png new file mode 100644 index 000000000..a4a3b8dc1 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_miui_4.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_miui_40.png b/app/src/main/res/drawable-nodpi/weather_miui_40.png new file mode 100644 index 000000000..fb2a6b0bb Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_miui_40.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_miui_41.png b/app/src/main/res/drawable-nodpi/weather_miui_41.png new file mode 100644 index 000000000..c2216a62a Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_miui_41.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_miui_42.png b/app/src/main/res/drawable-nodpi/weather_miui_42.png new file mode 100644 index 000000000..c2216a62a Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_miui_42.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_miui_43.png b/app/src/main/res/drawable-nodpi/weather_miui_43.png new file mode 100644 index 000000000..c2216a62a Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_miui_43.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_miui_44.png b/app/src/main/res/drawable-nodpi/weather_miui_44.png new file mode 100644 index 000000000..90e7f063b Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_miui_44.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_miui_45.png b/app/src/main/res/drawable-nodpi/weather_miui_45.png new file mode 100644 index 000000000..7705b64cf Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_miui_45.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_miui_46.png b/app/src/main/res/drawable-nodpi/weather_miui_46.png new file mode 100644 index 000000000..c2216a62a Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_miui_46.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_miui_47.png b/app/src/main/res/drawable-nodpi/weather_miui_47.png new file mode 100644 index 000000000..33b8d723e Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_miui_47.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_miui_5.png b/app/src/main/res/drawable-nodpi/weather_miui_5.png new file mode 100644 index 000000000..e3f443ceb Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_miui_5.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_miui_6.png b/app/src/main/res/drawable-nodpi/weather_miui_6.png new file mode 100644 index 000000000..e3f443ceb Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_miui_6.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_miui_7.png b/app/src/main/res/drawable-nodpi/weather_miui_7.png new file mode 100644 index 000000000..c2216a62a Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_miui_7.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_miui_8.png b/app/src/main/res/drawable-nodpi/weather_miui_8.png new file mode 100644 index 000000000..e3f443ceb Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_miui_8.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_miui_9.png b/app/src/main/res/drawable-nodpi/weather_miui_9.png new file mode 100644 index 000000000..083b91b0f Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_miui_9.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_miui_na.png b/app/src/main/res/drawable-nodpi/weather_miui_na.png new file mode 100644 index 000000000..d4aea19c3 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_miui_na.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_sthul_0.png b/app/src/main/res/drawable-nodpi/weather_sthul_0.png new file mode 100644 index 000000000..95038f34b Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_sthul_0.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_sthul_1.png b/app/src/main/res/drawable-nodpi/weather_sthul_1.png new file mode 100644 index 000000000..3cae4ce5f Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_sthul_1.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_sthul_10.png b/app/src/main/res/drawable-nodpi/weather_sthul_10.png new file mode 100644 index 000000000..45b819359 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_sthul_10.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_sthul_11.png b/app/src/main/res/drawable-nodpi/weather_sthul_11.png new file mode 100644 index 000000000..f7a6f0fe3 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_sthul_11.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_sthul_12.png b/app/src/main/res/drawable-nodpi/weather_sthul_12.png new file mode 100644 index 000000000..8615555bb Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_sthul_12.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_sthul_13.png b/app/src/main/res/drawable-nodpi/weather_sthul_13.png new file mode 100644 index 000000000..9dfad0dd1 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_sthul_13.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_sthul_14.png b/app/src/main/res/drawable-nodpi/weather_sthul_14.png new file mode 100644 index 000000000..21572fbbd Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_sthul_14.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_sthul_15.png b/app/src/main/res/drawable-nodpi/weather_sthul_15.png new file mode 100644 index 000000000..672239ba4 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_sthul_15.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_sthul_16.png b/app/src/main/res/drawable-nodpi/weather_sthul_16.png new file mode 100644 index 000000000..b9212816e Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_sthul_16.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_sthul_17.png b/app/src/main/res/drawable-nodpi/weather_sthul_17.png new file mode 100644 index 000000000..872cddb20 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_sthul_17.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_sthul_18.png b/app/src/main/res/drawable-nodpi/weather_sthul_18.png new file mode 100644 index 000000000..36f52825e Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_sthul_18.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_sthul_19.png b/app/src/main/res/drawable-nodpi/weather_sthul_19.png new file mode 100644 index 000000000..002c9ace5 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_sthul_19.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_sthul_2.png b/app/src/main/res/drawable-nodpi/weather_sthul_2.png new file mode 100644 index 000000000..800ade9b4 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_sthul_2.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_sthul_20.png b/app/src/main/res/drawable-nodpi/weather_sthul_20.png new file mode 100644 index 000000000..e30db16d7 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_sthul_20.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_sthul_21.png b/app/src/main/res/drawable-nodpi/weather_sthul_21.png new file mode 100644 index 000000000..0f2e3dcd6 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_sthul_21.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_sthul_22.png b/app/src/main/res/drawable-nodpi/weather_sthul_22.png new file mode 100644 index 000000000..352dfedc5 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_sthul_22.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_sthul_23.png b/app/src/main/res/drawable-nodpi/weather_sthul_23.png new file mode 100644 index 000000000..87f063f59 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_sthul_23.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_sthul_24.png b/app/src/main/res/drawable-nodpi/weather_sthul_24.png new file mode 100644 index 000000000..0268c2bf2 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_sthul_24.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_sthul_25.png b/app/src/main/res/drawable-nodpi/weather_sthul_25.png new file mode 100644 index 000000000..1b8b153a3 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_sthul_25.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_sthul_26.png b/app/src/main/res/drawable-nodpi/weather_sthul_26.png new file mode 100644 index 000000000..742bd0a62 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_sthul_26.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_sthul_27.png b/app/src/main/res/drawable-nodpi/weather_sthul_27.png new file mode 100644 index 000000000..d63e230c9 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_sthul_27.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_sthul_28.png b/app/src/main/res/drawable-nodpi/weather_sthul_28.png new file mode 100644 index 000000000..ee9dde697 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_sthul_28.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_sthul_29.png b/app/src/main/res/drawable-nodpi/weather_sthul_29.png new file mode 100644 index 000000000..bf2690897 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_sthul_29.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_sthul_3.png b/app/src/main/res/drawable-nodpi/weather_sthul_3.png new file mode 100644 index 000000000..54fb8d6fb Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_sthul_3.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_sthul_30.png b/app/src/main/res/drawable-nodpi/weather_sthul_30.png new file mode 100644 index 000000000..730d99ce9 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_sthul_30.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_sthul_31.png b/app/src/main/res/drawable-nodpi/weather_sthul_31.png new file mode 100644 index 000000000..942bb0f46 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_sthul_31.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_sthul_32.png b/app/src/main/res/drawable-nodpi/weather_sthul_32.png new file mode 100644 index 000000000..bc7ffa91a Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_sthul_32.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_sthul_33.png b/app/src/main/res/drawable-nodpi/weather_sthul_33.png new file mode 100644 index 000000000..2bcdb8861 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_sthul_33.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_sthul_34.png b/app/src/main/res/drawable-nodpi/weather_sthul_34.png new file mode 100644 index 000000000..9515fe6cd Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_sthul_34.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_sthul_35.png b/app/src/main/res/drawable-nodpi/weather_sthul_35.png new file mode 100644 index 000000000..45230ff81 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_sthul_35.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_sthul_36.png b/app/src/main/res/drawable-nodpi/weather_sthul_36.png new file mode 100644 index 000000000..a551e8eb3 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_sthul_36.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_sthul_37.png b/app/src/main/res/drawable-nodpi/weather_sthul_37.png new file mode 100644 index 000000000..16dff2136 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_sthul_37.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_sthul_38.png b/app/src/main/res/drawable-nodpi/weather_sthul_38.png new file mode 100644 index 000000000..f617b46a6 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_sthul_38.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_sthul_39.png b/app/src/main/res/drawable-nodpi/weather_sthul_39.png new file mode 100644 index 000000000..e3ff84e4f Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_sthul_39.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_sthul_4.png b/app/src/main/res/drawable-nodpi/weather_sthul_4.png new file mode 100644 index 000000000..45d41d3c4 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_sthul_4.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_sthul_40.png b/app/src/main/res/drawable-nodpi/weather_sthul_40.png new file mode 100644 index 000000000..e5b8a9c92 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_sthul_40.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_sthul_41.png b/app/src/main/res/drawable-nodpi/weather_sthul_41.png new file mode 100644 index 000000000..f50aee9fd Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_sthul_41.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_sthul_42.png b/app/src/main/res/drawable-nodpi/weather_sthul_42.png new file mode 100644 index 000000000..e9665a255 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_sthul_42.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_sthul_43.png b/app/src/main/res/drawable-nodpi/weather_sthul_43.png new file mode 100644 index 000000000..8f7b400ab Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_sthul_43.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_sthul_44.png b/app/src/main/res/drawable-nodpi/weather_sthul_44.png new file mode 100644 index 000000000..43f86dc0e Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_sthul_44.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_sthul_45.png b/app/src/main/res/drawable-nodpi/weather_sthul_45.png new file mode 100644 index 000000000..35dac640e Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_sthul_45.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_sthul_46.png b/app/src/main/res/drawable-nodpi/weather_sthul_46.png new file mode 100644 index 000000000..ec11ba511 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_sthul_46.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_sthul_47.png b/app/src/main/res/drawable-nodpi/weather_sthul_47.png new file mode 100644 index 000000000..e662fecb1 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_sthul_47.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_sthul_5.png b/app/src/main/res/drawable-nodpi/weather_sthul_5.png new file mode 100644 index 000000000..7dbec8c62 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_sthul_5.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_sthul_6.png b/app/src/main/res/drawable-nodpi/weather_sthul_6.png new file mode 100644 index 000000000..ee0961d59 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_sthul_6.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_sthul_7.png b/app/src/main/res/drawable-nodpi/weather_sthul_7.png new file mode 100644 index 000000000..e313b7ef2 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_sthul_7.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_sthul_8.png b/app/src/main/res/drawable-nodpi/weather_sthul_8.png new file mode 100644 index 000000000..56b2e45e4 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_sthul_8.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_sthul_9.png b/app/src/main/res/drawable-nodpi/weather_sthul_9.png new file mode 100644 index 000000000..2853ac1bc Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_sthul_9.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_sthul_na.png b/app/src/main/res/drawable-nodpi/weather_sthul_na.png new file mode 100644 index 000000000..0724949e6 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_sthul_na.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_tapas_0.png b/app/src/main/res/drawable-nodpi/weather_tapas_0.png new file mode 100644 index 000000000..29785012a Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_tapas_0.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_tapas_1.png b/app/src/main/res/drawable-nodpi/weather_tapas_1.png new file mode 100644 index 000000000..af4dd7026 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_tapas_1.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_tapas_10.png b/app/src/main/res/drawable-nodpi/weather_tapas_10.png new file mode 100644 index 000000000..707d6435e Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_tapas_10.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_tapas_11.png b/app/src/main/res/drawable-nodpi/weather_tapas_11.png new file mode 100644 index 000000000..5e461f2c3 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_tapas_11.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_tapas_12.png b/app/src/main/res/drawable-nodpi/weather_tapas_12.png new file mode 100644 index 000000000..5e461f2c3 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_tapas_12.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_tapas_13.png b/app/src/main/res/drawable-nodpi/weather_tapas_13.png new file mode 100644 index 000000000..6690be984 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_tapas_13.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_tapas_14.png b/app/src/main/res/drawable-nodpi/weather_tapas_14.png new file mode 100644 index 000000000..6690be984 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_tapas_14.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_tapas_15.png b/app/src/main/res/drawable-nodpi/weather_tapas_15.png new file mode 100644 index 000000000..f545f6ff6 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_tapas_15.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_tapas_16.png b/app/src/main/res/drawable-nodpi/weather_tapas_16.png new file mode 100644 index 000000000..0923262b4 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_tapas_16.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_tapas_17.png b/app/src/main/res/drawable-nodpi/weather_tapas_17.png new file mode 100644 index 000000000..ec73390bb Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_tapas_17.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_tapas_18.png b/app/src/main/res/drawable-nodpi/weather_tapas_18.png new file mode 100644 index 000000000..975737fc8 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_tapas_18.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_tapas_19.png b/app/src/main/res/drawable-nodpi/weather_tapas_19.png new file mode 100644 index 000000000..83b9392b2 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_tapas_19.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_tapas_2.png b/app/src/main/res/drawable-nodpi/weather_tapas_2.png new file mode 100644 index 000000000..af4dd7026 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_tapas_2.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_tapas_20.png b/app/src/main/res/drawable-nodpi/weather_tapas_20.png new file mode 100644 index 000000000..3d1b2cd28 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_tapas_20.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_tapas_21.png b/app/src/main/res/drawable-nodpi/weather_tapas_21.png new file mode 100644 index 000000000..fb9231e8b Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_tapas_21.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_tapas_22.png b/app/src/main/res/drawable-nodpi/weather_tapas_22.png new file mode 100644 index 000000000..6caad39d3 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_tapas_22.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_tapas_23.png b/app/src/main/res/drawable-nodpi/weather_tapas_23.png new file mode 100644 index 000000000..8c0d933db Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_tapas_23.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_tapas_24.png b/app/src/main/res/drawable-nodpi/weather_tapas_24.png new file mode 100644 index 000000000..d5eed6102 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_tapas_24.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_tapas_25.png b/app/src/main/res/drawable-nodpi/weather_tapas_25.png new file mode 100644 index 000000000..bae092f49 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_tapas_25.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_tapas_26.png b/app/src/main/res/drawable-nodpi/weather_tapas_26.png new file mode 100644 index 000000000..de86f4c20 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_tapas_26.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_tapas_27.png b/app/src/main/res/drawable-nodpi/weather_tapas_27.png new file mode 100644 index 000000000..b41e0ade0 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_tapas_27.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_tapas_28.png b/app/src/main/res/drawable-nodpi/weather_tapas_28.png new file mode 100644 index 000000000..2214b5e0d Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_tapas_28.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_tapas_29.png b/app/src/main/res/drawable-nodpi/weather_tapas_29.png new file mode 100644 index 000000000..7e4c26755 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_tapas_29.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_tapas_3.png b/app/src/main/res/drawable-nodpi/weather_tapas_3.png new file mode 100644 index 000000000..8274abc30 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_tapas_3.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_tapas_30.png b/app/src/main/res/drawable-nodpi/weather_tapas_30.png new file mode 100644 index 000000000..5bb554c87 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_tapas_30.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_tapas_31.png b/app/src/main/res/drawable-nodpi/weather_tapas_31.png new file mode 100644 index 000000000..ae95f2d38 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_tapas_31.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_tapas_32.png b/app/src/main/res/drawable-nodpi/weather_tapas_32.png new file mode 100644 index 000000000..4382ec6e3 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_tapas_32.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_tapas_33.png b/app/src/main/res/drawable-nodpi/weather_tapas_33.png new file mode 100644 index 000000000..ae95f2d38 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_tapas_33.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_tapas_34.png b/app/src/main/res/drawable-nodpi/weather_tapas_34.png new file mode 100644 index 000000000..4382ec6e3 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_tapas_34.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_tapas_35.png b/app/src/main/res/drawable-nodpi/weather_tapas_35.png new file mode 100644 index 000000000..eef9340c9 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_tapas_35.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_tapas_36.png b/app/src/main/res/drawable-nodpi/weather_tapas_36.png new file mode 100644 index 000000000..a9978850d Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_tapas_36.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_tapas_37.png b/app/src/main/res/drawable-nodpi/weather_tapas_37.png new file mode 100644 index 000000000..4d5ee0a3d Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_tapas_37.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_tapas_38.png b/app/src/main/res/drawable-nodpi/weather_tapas_38.png new file mode 100644 index 000000000..4d5ee0a3d Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_tapas_38.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_tapas_39.png b/app/src/main/res/drawable-nodpi/weather_tapas_39.png new file mode 100644 index 000000000..4d5ee0a3d Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_tapas_39.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_tapas_4.png b/app/src/main/res/drawable-nodpi/weather_tapas_4.png new file mode 100644 index 000000000..8274abc30 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_tapas_4.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_tapas_40.png b/app/src/main/res/drawable-nodpi/weather_tapas_40.png new file mode 100644 index 000000000..c6acf94b2 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_tapas_40.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_tapas_41.png b/app/src/main/res/drawable-nodpi/weather_tapas_41.png new file mode 100644 index 000000000..552649d0e Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_tapas_41.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_tapas_42.png b/app/src/main/res/drawable-nodpi/weather_tapas_42.png new file mode 100644 index 000000000..10e13783c Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_tapas_42.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_tapas_43.png b/app/src/main/res/drawable-nodpi/weather_tapas_43.png new file mode 100644 index 000000000..7b9eb4cb0 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_tapas_43.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_tapas_44.png b/app/src/main/res/drawable-nodpi/weather_tapas_44.png new file mode 100644 index 000000000..35052c122 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_tapas_44.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_tapas_45.png b/app/src/main/res/drawable-nodpi/weather_tapas_45.png new file mode 100644 index 000000000..b47abc71b Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_tapas_45.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_tapas_46.png b/app/src/main/res/drawable-nodpi/weather_tapas_46.png new file mode 100644 index 000000000..617978631 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_tapas_46.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_tapas_47.png b/app/src/main/res/drawable-nodpi/weather_tapas_47.png new file mode 100644 index 000000000..6b8b85567 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_tapas_47.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_vclouds_0.png b/app/src/main/res/drawable-nodpi/weather_vclouds_0.png new file mode 100644 index 000000000..bdd8df6b0 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_vclouds_0.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_vclouds_1.png b/app/src/main/res/drawable-nodpi/weather_vclouds_1.png new file mode 100644 index 000000000..bdd8df6b0 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_vclouds_1.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_vclouds_10.png b/app/src/main/res/drawable-nodpi/weather_vclouds_10.png new file mode 100644 index 000000000..3bafd9be8 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_vclouds_10.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_vclouds_11.png b/app/src/main/res/drawable-nodpi/weather_vclouds_11.png new file mode 100644 index 000000000..e397372f8 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_vclouds_11.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_vclouds_12.png b/app/src/main/res/drawable-nodpi/weather_vclouds_12.png new file mode 100644 index 000000000..99c362b9b Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_vclouds_12.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_vclouds_13.png b/app/src/main/res/drawable-nodpi/weather_vclouds_13.png new file mode 100644 index 000000000..53390671f Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_vclouds_13.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_vclouds_14.png b/app/src/main/res/drawable-nodpi/weather_vclouds_14.png new file mode 100644 index 000000000..e9ce659f1 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_vclouds_14.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_vclouds_15.png b/app/src/main/res/drawable-nodpi/weather_vclouds_15.png new file mode 100644 index 000000000..7a02bca3a Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_vclouds_15.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_vclouds_16.png b/app/src/main/res/drawable-nodpi/weather_vclouds_16.png new file mode 100644 index 000000000..85171e713 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_vclouds_16.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_vclouds_17.png b/app/src/main/res/drawable-nodpi/weather_vclouds_17.png new file mode 100644 index 000000000..bdd8df6b0 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_vclouds_17.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_vclouds_18.png b/app/src/main/res/drawable-nodpi/weather_vclouds_18.png new file mode 100644 index 000000000..1e140bbd0 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_vclouds_18.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_vclouds_19.png b/app/src/main/res/drawable-nodpi/weather_vclouds_19.png new file mode 100644 index 000000000..3b010d534 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_vclouds_19.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_vclouds_2.png b/app/src/main/res/drawable-nodpi/weather_vclouds_2.png new file mode 100644 index 000000000..bdd8df6b0 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_vclouds_2.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_vclouds_20.png b/app/src/main/res/drawable-nodpi/weather_vclouds_20.png new file mode 100644 index 000000000..419fdf057 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_vclouds_20.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_vclouds_21.png b/app/src/main/res/drawable-nodpi/weather_vclouds_21.png new file mode 100644 index 000000000..677c7d472 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_vclouds_21.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_vclouds_22.png b/app/src/main/res/drawable-nodpi/weather_vclouds_22.png new file mode 100644 index 000000000..f132bd314 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_vclouds_22.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_vclouds_23.png b/app/src/main/res/drawable-nodpi/weather_vclouds_23.png new file mode 100644 index 000000000..c3f8771d7 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_vclouds_23.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_vclouds_24.png b/app/src/main/res/drawable-nodpi/weather_vclouds_24.png new file mode 100644 index 000000000..c3f8771d7 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_vclouds_24.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_vclouds_25.png b/app/src/main/res/drawable-nodpi/weather_vclouds_25.png new file mode 100644 index 000000000..8e55ccd4c Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_vclouds_25.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_vclouds_26.png b/app/src/main/res/drawable-nodpi/weather_vclouds_26.png new file mode 100644 index 000000000..6c7b14fea Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_vclouds_26.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_vclouds_27.png b/app/src/main/res/drawable-nodpi/weather_vclouds_27.png new file mode 100644 index 000000000..0e7ef6ce9 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_vclouds_27.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_vclouds_28.png b/app/src/main/res/drawable-nodpi/weather_vclouds_28.png new file mode 100644 index 000000000..7e5419c06 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_vclouds_28.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_vclouds_29.png b/app/src/main/res/drawable-nodpi/weather_vclouds_29.png new file mode 100644 index 000000000..9d6d56b95 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_vclouds_29.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_vclouds_3.png b/app/src/main/res/drawable-nodpi/weather_vclouds_3.png new file mode 100644 index 000000000..bdd8df6b0 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_vclouds_3.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_vclouds_30.png b/app/src/main/res/drawable-nodpi/weather_vclouds_30.png new file mode 100644 index 000000000..90d642d4c Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_vclouds_30.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_vclouds_31.png b/app/src/main/res/drawable-nodpi/weather_vclouds_31.png new file mode 100644 index 000000000..b73db1bf4 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_vclouds_31.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_vclouds_32.png b/app/src/main/res/drawable-nodpi/weather_vclouds_32.png new file mode 100644 index 000000000..ed5f305a9 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_vclouds_32.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_vclouds_33.png b/app/src/main/res/drawable-nodpi/weather_vclouds_33.png new file mode 100644 index 000000000..3f3eed56e Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_vclouds_33.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_vclouds_34.png b/app/src/main/res/drawable-nodpi/weather_vclouds_34.png new file mode 100644 index 000000000..ca3e7a920 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_vclouds_34.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_vclouds_35.png b/app/src/main/res/drawable-nodpi/weather_vclouds_35.png new file mode 100644 index 000000000..bdd8df6b0 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_vclouds_35.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_vclouds_36.png b/app/src/main/res/drawable-nodpi/weather_vclouds_36.png new file mode 100644 index 000000000..59bd2208c Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_vclouds_36.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_vclouds_37.png b/app/src/main/res/drawable-nodpi/weather_vclouds_37.png new file mode 100644 index 000000000..7265d4e08 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_vclouds_37.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_vclouds_38.png b/app/src/main/res/drawable-nodpi/weather_vclouds_38.png new file mode 100644 index 000000000..7265d4e08 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_vclouds_38.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_vclouds_39.png b/app/src/main/res/drawable-nodpi/weather_vclouds_39.png new file mode 100644 index 000000000..de5fe9a14 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_vclouds_39.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_vclouds_4.png b/app/src/main/res/drawable-nodpi/weather_vclouds_4.png new file mode 100644 index 000000000..bdd8df6b0 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_vclouds_4.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_vclouds_40.png b/app/src/main/res/drawable-nodpi/weather_vclouds_40.png new file mode 100644 index 000000000..99c362b9b Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_vclouds_40.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_vclouds_41.png b/app/src/main/res/drawable-nodpi/weather_vclouds_41.png new file mode 100644 index 000000000..507464795 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_vclouds_41.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_vclouds_42.png b/app/src/main/res/drawable-nodpi/weather_vclouds_42.png new file mode 100644 index 000000000..85171e713 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_vclouds_42.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_vclouds_43.png b/app/src/main/res/drawable-nodpi/weather_vclouds_43.png new file mode 100644 index 000000000..7a02bca3a Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_vclouds_43.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_vclouds_44.png b/app/src/main/res/drawable-nodpi/weather_vclouds_44.png new file mode 100644 index 000000000..679a79be8 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_vclouds_44.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_vclouds_45.png b/app/src/main/res/drawable-nodpi/weather_vclouds_45.png new file mode 100644 index 000000000..345518fb6 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_vclouds_45.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_vclouds_46.png b/app/src/main/res/drawable-nodpi/weather_vclouds_46.png new file mode 100644 index 000000000..9be4bade2 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_vclouds_46.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_vclouds_47.png b/app/src/main/res/drawable-nodpi/weather_vclouds_47.png new file mode 100644 index 000000000..bc896c4fc Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_vclouds_47.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_vclouds_5.png b/app/src/main/res/drawable-nodpi/weather_vclouds_5.png new file mode 100644 index 000000000..f6608f0d3 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_vclouds_5.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_vclouds_6.png b/app/src/main/res/drawable-nodpi/weather_vclouds_6.png new file mode 100644 index 000000000..6c96e68fb Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_vclouds_6.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_vclouds_7.png b/app/src/main/res/drawable-nodpi/weather_vclouds_7.png new file mode 100644 index 000000000..5c51709d4 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_vclouds_7.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_vclouds_8.png b/app/src/main/res/drawable-nodpi/weather_vclouds_8.png new file mode 100644 index 000000000..3af9bab22 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_vclouds_8.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_vclouds_9.png b/app/src/main/res/drawable-nodpi/weather_vclouds_9.png new file mode 100644 index 000000000..beab92f02 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_vclouds_9.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_vclouds_na.png b/app/src/main/res/drawable-nodpi/weather_vclouds_na.png new file mode 100644 index 000000000..679a79be8 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_vclouds_na.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_weezle_0.png b/app/src/main/res/drawable-nodpi/weather_weezle_0.png new file mode 100644 index 000000000..6acb871e6 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_weezle_0.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_weezle_1.png b/app/src/main/res/drawable-nodpi/weather_weezle_1.png new file mode 100644 index 000000000..f52e18e5e Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_weezle_1.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_weezle_10.png b/app/src/main/res/drawable-nodpi/weather_weezle_10.png new file mode 100644 index 000000000..940be3fc3 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_weezle_10.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_weezle_11.png b/app/src/main/res/drawable-nodpi/weather_weezle_11.png new file mode 100644 index 000000000..cc1a9d0f8 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_weezle_11.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_weezle_12.png b/app/src/main/res/drawable-nodpi/weather_weezle_12.png new file mode 100644 index 000000000..cc1a9d0f8 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_weezle_12.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_weezle_13.png b/app/src/main/res/drawable-nodpi/weather_weezle_13.png new file mode 100644 index 000000000..7bd818046 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_weezle_13.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_weezle_14.png b/app/src/main/res/drawable-nodpi/weather_weezle_14.png new file mode 100644 index 000000000..49f259f3a Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_weezle_14.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_weezle_15.png b/app/src/main/res/drawable-nodpi/weather_weezle_15.png new file mode 100644 index 000000000..49f259f3a Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_weezle_15.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_weezle_16.png b/app/src/main/res/drawable-nodpi/weather_weezle_16.png new file mode 100644 index 000000000..7bd818046 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_weezle_16.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_weezle_17.png b/app/src/main/res/drawable-nodpi/weather_weezle_17.png new file mode 100644 index 000000000..940be3fc3 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_weezle_17.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_weezle_18.png b/app/src/main/res/drawable-nodpi/weather_weezle_18.png new file mode 100644 index 000000000..940be3fc3 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_weezle_18.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_weezle_19.png b/app/src/main/res/drawable-nodpi/weather_weezle_19.png new file mode 100644 index 000000000..f52e18e5e Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_weezle_19.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_weezle_2.png b/app/src/main/res/drawable-nodpi/weather_weezle_2.png new file mode 100644 index 000000000..f52e18e5e Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_weezle_2.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_weezle_20.png b/app/src/main/res/drawable-nodpi/weather_weezle_20.png new file mode 100644 index 000000000..f52e18e5e Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_weezle_20.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_weezle_21.png b/app/src/main/res/drawable-nodpi/weather_weezle_21.png new file mode 100644 index 000000000..f52e18e5e Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_weezle_21.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_weezle_22.png b/app/src/main/res/drawable-nodpi/weather_weezle_22.png new file mode 100644 index 000000000..f52e18e5e Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_weezle_22.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_weezle_23.png b/app/src/main/res/drawable-nodpi/weather_weezle_23.png new file mode 100644 index 000000000..2dc291908 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_weezle_23.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_weezle_24.png b/app/src/main/res/drawable-nodpi/weather_weezle_24.png new file mode 100644 index 000000000..830341c03 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_weezle_24.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_weezle_25.png b/app/src/main/res/drawable-nodpi/weather_weezle_25.png new file mode 100644 index 000000000..be622dcbc Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_weezle_25.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_weezle_26.png b/app/src/main/res/drawable-nodpi/weather_weezle_26.png new file mode 100644 index 000000000..2dc291908 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_weezle_26.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_weezle_27.png b/app/src/main/res/drawable-nodpi/weather_weezle_27.png new file mode 100644 index 000000000..ff9b86b43 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_weezle_27.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_weezle_28.png b/app/src/main/res/drawable-nodpi/weather_weezle_28.png new file mode 100644 index 000000000..b28a7cced Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_weezle_28.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_weezle_29.png b/app/src/main/res/drawable-nodpi/weather_weezle_29.png new file mode 100644 index 000000000..ff9b86b43 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_weezle_29.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_weezle_3.png b/app/src/main/res/drawable-nodpi/weather_weezle_3.png new file mode 100644 index 000000000..6acb871e6 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_weezle_3.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_weezle_30.png b/app/src/main/res/drawable-nodpi/weather_weezle_30.png new file mode 100644 index 000000000..a44793060 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_weezle_30.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_weezle_31.png b/app/src/main/res/drawable-nodpi/weather_weezle_31.png new file mode 100644 index 000000000..d628547b4 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_weezle_31.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_weezle_32.png b/app/src/main/res/drawable-nodpi/weather_weezle_32.png new file mode 100644 index 000000000..68ec56a7f Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_weezle_32.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_weezle_33.png b/app/src/main/res/drawable-nodpi/weather_weezle_33.png new file mode 100644 index 000000000..a98d8c8bc Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_weezle_33.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_weezle_34.png b/app/src/main/res/drawable-nodpi/weather_weezle_34.png new file mode 100644 index 000000000..4dc679e25 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_weezle_34.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_weezle_35.png b/app/src/main/res/drawable-nodpi/weather_weezle_35.png new file mode 100644 index 000000000..54651599a Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_weezle_35.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_weezle_36.png b/app/src/main/res/drawable-nodpi/weather_weezle_36.png new file mode 100644 index 000000000..b9931df0c Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_weezle_36.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_weezle_37.png b/app/src/main/res/drawable-nodpi/weather_weezle_37.png new file mode 100644 index 000000000..d9f45d19b Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_weezle_37.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_weezle_38.png b/app/src/main/res/drawable-nodpi/weather_weezle_38.png new file mode 100644 index 000000000..d9f45d19b Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_weezle_38.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_weezle_39.png b/app/src/main/res/drawable-nodpi/weather_weezle_39.png new file mode 100644 index 000000000..d9f45d19b Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_weezle_39.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_weezle_4.png b/app/src/main/res/drawable-nodpi/weather_weezle_4.png new file mode 100644 index 000000000..6acb871e6 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_weezle_4.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_weezle_40.png b/app/src/main/res/drawable-nodpi/weather_weezle_40.png new file mode 100644 index 000000000..0f0dbc07d Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_weezle_40.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_weezle_41.png b/app/src/main/res/drawable-nodpi/weather_weezle_41.png new file mode 100644 index 000000000..7bd818046 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_weezle_41.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_weezle_42.png b/app/src/main/res/drawable-nodpi/weather_weezle_42.png new file mode 100644 index 000000000..49f259f3a Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_weezle_42.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_weezle_43.png b/app/src/main/res/drawable-nodpi/weather_weezle_43.png new file mode 100644 index 000000000..7bd818046 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_weezle_43.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_weezle_44.png b/app/src/main/res/drawable-nodpi/weather_weezle_44.png new file mode 100644 index 000000000..ff9b86b43 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_weezle_44.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_weezle_45.png b/app/src/main/res/drawable-nodpi/weather_weezle_45.png new file mode 100644 index 000000000..f6c2efcec Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_weezle_45.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_weezle_46.png b/app/src/main/res/drawable-nodpi/weather_weezle_46.png new file mode 100644 index 000000000..c1794c0c4 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_weezle_46.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_weezle_47.png b/app/src/main/res/drawable-nodpi/weather_weezle_47.png new file mode 100644 index 000000000..f6c2efcec Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_weezle_47.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_weezle_5.png b/app/src/main/res/drawable-nodpi/weather_weezle_5.png new file mode 100644 index 000000000..54651599a Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_weezle_5.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_weezle_6.png b/app/src/main/res/drawable-nodpi/weather_weezle_6.png new file mode 100644 index 000000000..54651599a Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_weezle_6.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_weezle_7.png b/app/src/main/res/drawable-nodpi/weather_weezle_7.png new file mode 100644 index 000000000..54651599a Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_weezle_7.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_weezle_8.png b/app/src/main/res/drawable-nodpi/weather_weezle_8.png new file mode 100644 index 000000000..940be3fc3 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_weezle_8.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_weezle_9.png b/app/src/main/res/drawable-nodpi/weather_weezle_9.png new file mode 100644 index 000000000..3bd8fb43c Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_weezle_9.png differ diff --git a/app/src/main/res/drawable-nodpi/weather_weezle_na.png b/app/src/main/res/drawable-nodpi/weather_weezle_na.png new file mode 100644 index 000000000..694791a5f Binary files /dev/null and b/app/src/main/res/drawable-nodpi/weather_weezle_na.png differ diff --git a/app/src/main/res/drawable-v24/chip_status_bar_1.xml b/app/src/main/res/drawable-v24/chip_status_bar_1.xml deleted file mode 100644 index a73df5cf6..000000000 --- a/app/src/main/res/drawable-v24/chip_status_bar_1.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/chip_status_bar_2.xml b/app/src/main/res/drawable-v24/chip_status_bar_2.xml deleted file mode 100644 index 5828926d2..000000000 --- a/app/src/main/res/drawable-v24/chip_status_bar_2.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/chip_status_bar_3.xml b/app/src/main/res/drawable-v24/chip_status_bar_3.xml deleted file mode 100644 index 916c112fc..000000000 --- a/app/src/main/res/drawable-v24/chip_status_bar_3.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/app/src/main/res/drawable-v24/chip_status_bar_4.xml b/app/src/main/res/drawable-v24/chip_status_bar_4.xml deleted file mode 100644 index 2339dcacc..000000000 --- a/app/src/main/res/drawable-v24/chip_status_bar_4.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/drawable-v24/chip_status_bar_5.xml b/app/src/main/res/drawable-v24/chip_status_bar_5.xml deleted file mode 100644 index c4a0e6ce1..000000000 --- a/app/src/main/res/drawable-v24/chip_status_bar_5.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/chip_status_bar_6.xml b/app/src/main/res/drawable-v24/chip_status_bar_6.xml deleted file mode 100644 index 99b72ac9a..000000000 --- a/app/src/main/res/drawable-v24/chip_status_bar_6.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/chip_status_bar_7.xml b/app/src/main/res/drawable-v24/chip_status_bar_7.xml deleted file mode 100644 index fd853dc30..000000000 --- a/app/src/main/res/drawable-v24/chip_status_bar_7.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/chip_status_icons_1.xml b/app/src/main/res/drawable-v24/chip_status_icons_1.xml deleted file mode 100644 index 04f3a3643..000000000 --- a/app/src/main/res/drawable-v24/chip_status_icons_1.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/chip_status_icons_2.xml b/app/src/main/res/drawable-v24/chip_status_icons_2.xml deleted file mode 100644 index c0f203479..000000000 --- a/app/src/main/res/drawable-v24/chip_status_icons_2.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/drawable-v24/chip_status_icons_3.xml b/app/src/main/res/drawable-v24/chip_status_icons_3.xml deleted file mode 100644 index e1b6b8970..000000000 --- a/app/src/main/res/drawable-v24/chip_status_icons_3.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/app/src/main/res/drawable-v24/chip_status_icons_4.xml b/app/src/main/res/drawable-v24/chip_status_icons_4.xml deleted file mode 100644 index 398d3744b..000000000 --- a/app/src/main/res/drawable-v24/chip_status_icons_4.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/drawable-v24/chip_status_icons_5.xml b/app/src/main/res/drawable-v24/chip_status_icons_5.xml deleted file mode 100644 index 674235ef0..000000000 --- a/app/src/main/res/drawable-v24/chip_status_icons_5.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/chip_status_icons_6.xml b/app/src/main/res/drawable-v24/chip_status_icons_6.xml deleted file mode 100644 index 4401f3bed..000000000 --- a/app/src/main/res/drawable-v24/chip_status_icons_6.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/container_main_no_ripple.xml b/app/src/main/res/drawable-v24/container_main_no_ripple.xml new file mode 100644 index 000000000..dcbd158b7 --- /dev/null +++ b/app/src/main/res/drawable-v24/container_main_no_ripple.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/ic_humidity_symbol.xml b/app/src/main/res/drawable-v24/ic_humidity_symbol.xml new file mode 100644 index 000000000..c52b21cbf --- /dev/null +++ b/app/src/main/res/drawable-v24/ic_humidity_symbol.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/ic_navbar_tweaks_checked.xml b/app/src/main/res/drawable-v24/ic_navbar_tweaks_checked.xml index bd00a8e3a..ad4306f16 100644 --- a/app/src/main/res/drawable-v24/ic_navbar_tweaks_checked.xml +++ b/app/src/main/res/drawable-v24/ic_navbar_tweaks_checked.xml @@ -1,22 +1,9 @@ - - - - + android:pathData="M16.19,2H7.81C4.17,2 2,4.17 2,7.81V16.18C2,19.83 4.17,22 7.81,22H16.18C19.82,22 21.99,19.83 21.99,16.19V7.81C22,4.17 19.83,2 16.19,2ZM7.67,5.5C7.67,5.09 8.01,4.75 8.42,4.75C8.83,4.75 9.17,5.09 9.17,5.5V9.4C9.17,9.81 8.83,10.15 8.42,10.15C8.01,10.15 7.67,9.81 7.67,9.4V5.5ZM9.523,16.431C9.319,16.522 9.17,16.713 9.17,16.936V18.5C9.17,18.91 8.83,19.25 8.42,19.25C8.01,19.25 7.67,18.91 7.67,18.5V16.936C7.67,16.713 7.521,16.522 7.317,16.431C6.363,16.006 5.7,15.058 5.7,13.95C5.7,12.45 6.92,11.22 8.42,11.22C9.92,11.22 11.15,12.44 11.15,13.95C11.15,15.058 10.479,16.007 9.523,16.431ZM16.33,18.5C16.33,18.91 15.99,19.25 15.58,19.25C15.17,19.25 14.83,18.91 14.83,18.5V14.6C14.83,14.19 15.17,13.85 15.58,13.85C15.99,13.85 16.33,14.19 16.33,14.6V18.5ZM15.58,12.77C14.08,12.77 12.85,11.55 12.85,10.04C12.85,8.932 13.521,7.983 14.477,7.559C14.681,7.468 14.83,7.277 14.83,7.054V5.5C14.83,5.09 15.17,4.75 15.58,4.75C15.99,4.75 16.33,5.09 16.33,5.5V7.064C16.33,7.287 16.479,7.478 16.683,7.569C17.637,7.994 18.3,8.942 18.3,10.05C18.3,11.55 17.08,12.77 15.58,12.77Z" /> diff --git a/app/src/main/res/drawable-v24/ic_navbar_tweaks_unchecked.xml b/app/src/main/res/drawable-v24/ic_navbar_tweaks_unchecked.xml index f65ff0eea..bf95a6b3a 100644 --- a/app/src/main/res/drawable-v24/ic_navbar_tweaks_unchecked.xml +++ b/app/src/main/res/drawable-v24/ic_navbar_tweaks_unchecked.xml @@ -1,22 +1,27 @@ + android:pathData="M15,22.75H9C3.57,22.75 1.25,20.43 1.25,15V9C1.25,3.57 3.57,1.25 9,1.25H15C20.43,1.25 22.75,3.57 22.75,9V15C22.75,20.43 20.43,22.75 15,22.75ZM9,2.75C4.39,2.75 2.75,4.39 2.75,9V15C2.75,19.61 4.39,21.25 9,21.25H15C19.61,21.25 21.25,19.61 21.25,15V9C21.25,4.39 19.61,2.75 15,2.75H9Z" /> + android:pathData="M15.58,19.25C15.17,19.25 14.83,18.91 14.83,18.5V14.6C14.83,14.19 15.17,13.85 15.58,13.85C15.99,13.85 16.33,14.19 16.33,14.6V18.5C16.33,18.91 15.99,19.25 15.58,19.25Z" /> + android:pathData="M15.58,8.2C15.17,8.2 14.83,7.86 14.83,7.45V5.5C14.83,5.09 15.17,4.75 15.58,4.75C15.99,4.75 16.33,5.09 16.33,5.5V7.45C16.33,7.86 15.99,8.2 15.58,8.2Z" /> + android:pathData="M15.58,13.4C13.731,13.4 12.231,11.9 12.231,10.05C12.231,8.2 13.731,6.7 15.58,6.7C17.431,6.7 18.931,8.2 18.931,10.05C18.931,11.9 17.42,13.4 15.58,13.4ZM15.58,8.2C14.561,8.2 13.731,9.03 13.731,10.05C13.731,11.07 14.561,11.9 15.58,11.9C16.601,11.9 17.431,11.07 17.431,10.05C17.431,9.03 16.59,8.2 15.58,8.2Z" /> + android:pathData="M8.42,19.25C8.01,19.25 7.67,18.91 7.67,18.5V16.55C7.67,16.14 8.01,15.8 8.42,15.8C8.83,15.8 9.17,16.14 9.17,16.55V18.5C9.17,18.91 8.84,19.25 8.42,19.25Z" /> + + diff --git a/app/src/main/res/drawable-v24/ic_navbar_xposed.xml b/app/src/main/res/drawable-v24/ic_navbar_xposed.xml new file mode 100644 index 000000000..d3056699d --- /dev/null +++ b/app/src/main/res/drawable-v24/ic_navbar_xposed.xml @@ -0,0 +1,4 @@ + + + + diff --git a/app/src/main/res/drawable-v24/ic_navbar_xposed_checked.xml b/app/src/main/res/drawable-v24/ic_navbar_xposed_checked.xml new file mode 100644 index 000000000..bd00a8e3a --- /dev/null +++ b/app/src/main/res/drawable-v24/ic_navbar_xposed_checked.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/app/src/main/res/drawable-v24/ic_navbar_xposed_unchecked.xml b/app/src/main/res/drawable-v24/ic_navbar_xposed_unchecked.xml new file mode 100644 index 000000000..f65ff0eea --- /dev/null +++ b/app/src/main/res/drawable-v24/ic_navbar_xposed_unchecked.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/app/src/main/res/drawable-v24/ic_ringer_mute.xml b/app/src/main/res/drawable-v24/ic_ringer_mute.xml new file mode 100644 index 000000000..1665b0a9a --- /dev/null +++ b/app/src/main/res/drawable-v24/ic_ringer_mute.xml @@ -0,0 +1,17 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/ic_ringer_normal.xml b/app/src/main/res/drawable-v24/ic_ringer_normal.xml new file mode 100644 index 000000000..7626cf637 --- /dev/null +++ b/app/src/main/res/drawable-v24/ic_ringer_normal.xml @@ -0,0 +1,17 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/ic_ringer_vibrate.xml b/app/src/main/res/drawable-v24/ic_ringer_vibrate.xml new file mode 100644 index 000000000..e858e54c1 --- /dev/null +++ b/app/src/main/res/drawable-v24/ic_ringer_vibrate.xml @@ -0,0 +1,17 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/ic_styles_signal_icons.xml b/app/src/main/res/drawable-v24/ic_styles_signal_icons.xml new file mode 100644 index 000000000..1fce16655 --- /dev/null +++ b/app/src/main/res/drawable-v24/ic_styles_signal_icons.xml @@ -0,0 +1,27 @@ + + + + + diff --git a/app/src/main/res/drawable-v24/ic_styles_wifi_icons.xml b/app/src/main/res/drawable-v24/ic_styles_wifi_icons.xml new file mode 100644 index 000000000..5bf7c3541 --- /dev/null +++ b/app/src/main/res/drawable-v24/ic_styles_wifi_icons.xml @@ -0,0 +1,34 @@ + + + + + + diff --git a/app/src/main/res/drawable-v24/ic_wind_symbol.xml b/app/src/main/res/drawable-v24/ic_wind_symbol.xml new file mode 100644 index 000000000..236f1c338 --- /dev/null +++ b/app/src/main/res/drawable-v24/ic_wind_symbol.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/ic_xposed_lockscreen_widgets.xml b/app/src/main/res/drawable-v24/ic_xposed_lockscreen_widgets.xml new file mode 100644 index 000000000..9e338ee47 --- /dev/null +++ b/app/src/main/res/drawable-v24/ic_xposed_lockscreen_widgets.xml @@ -0,0 +1,15 @@ + + + + + diff --git a/app/src/main/res/drawable-v24/preview_aquarium_ic_signal_cellular_1_4_bar.xml b/app/src/main/res/drawable-v24/preview_aquarium_ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..effcde5d9 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_aquarium_ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,10 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_aquarium_ic_signal_cellular_2_4_bar.xml b/app/src/main/res/drawable-v24/preview_aquarium_ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..504cc95a7 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_aquarium_ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_aquarium_ic_signal_cellular_3_4_bar.xml b/app/src/main/res/drawable-v24/preview_aquarium_ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..e6aad62df --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_aquarium_ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_aquarium_ic_signal_cellular_4_4_bar.xml b/app/src/main/res/drawable-v24/preview_aquarium_ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..62f871e78 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_aquarium_ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_aurora_ic_signal_cellular_1_4_bar.xml b/app/src/main/res/drawable-v24/preview_aurora_ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..add7e5812 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_aurora_ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,22 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_aurora_ic_signal_cellular_2_4_bar.xml b/app/src/main/res/drawable-v24/preview_aurora_ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..c4a9923ea --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_aurora_ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,30 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_aurora_ic_signal_cellular_3_4_bar.xml b/app/src/main/res/drawable-v24/preview_aurora_ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..88825e53a --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_aurora_ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,38 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_aurora_ic_signal_cellular_4_4_bar.xml b/app/src/main/res/drawable-v24/preview_aurora_ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..e65bc2f95 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_aurora_ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,38 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_aurora_ic_wifi_signal_1.xml b/app/src/main/res/drawable-v24/preview_aurora_ic_wifi_signal_1.xml new file mode 100644 index 000000000..fec096e70 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_aurora_ic_wifi_signal_1.xml @@ -0,0 +1,22 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_aurora_ic_wifi_signal_2.xml b/app/src/main/res/drawable-v24/preview_aurora_ic_wifi_signal_2.xml new file mode 100644 index 000000000..5dd08b195 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_aurora_ic_wifi_signal_2.xml @@ -0,0 +1,30 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_aurora_ic_wifi_signal_3.xml b/app/src/main/res/drawable-v24/preview_aurora_ic_wifi_signal_3.xml new file mode 100644 index 000000000..1974b4d26 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_aurora_ic_wifi_signal_3.xml @@ -0,0 +1,38 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_aurora_ic_wifi_signal_4.xml b/app/src/main/res/drawable-v24/preview_aurora_ic_wifi_signal_4.xml new file mode 100644 index 000000000..18eec4e44 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_aurora_ic_wifi_signal_4.xml @@ -0,0 +1,38 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_bars_ic_signal_cellular_1_4_bar.xml b/app/src/main/res/drawable-v24/preview_bars_ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..1ecbce706 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_bars_ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,9 @@ + + + + + + + + diff --git a/app/src/main/res/drawable-v24/preview_bars_ic_signal_cellular_2_4_bar.xml b/app/src/main/res/drawable-v24/preview_bars_ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..7b7b7ec05 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_bars_ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,9 @@ + + + + + + + + diff --git a/app/src/main/res/drawable-v24/preview_bars_ic_signal_cellular_3_4_bar.xml b/app/src/main/res/drawable-v24/preview_bars_ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..28bcab505 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_bars_ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,9 @@ + + + + + + + + diff --git a/app/src/main/res/drawable-v24/preview_bars_ic_signal_cellular_4_4_bar.xml b/app/src/main/res/drawable-v24/preview_bars_ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..06c36c0fd --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_bars_ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,9 @@ + + + + + + + + diff --git a/app/src/main/res/drawable-v24/preview_bars_ic_wifi_signal_1.xml b/app/src/main/res/drawable-v24/preview_bars_ic_wifi_signal_1.xml new file mode 100644 index 000000000..f05deda6a --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_bars_ic_wifi_signal_1.xml @@ -0,0 +1,11 @@ + + + + + + + + + + diff --git a/app/src/main/res/drawable-v24/preview_bars_ic_wifi_signal_2.xml b/app/src/main/res/drawable-v24/preview_bars_ic_wifi_signal_2.xml new file mode 100644 index 000000000..a6d1cf1be --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_bars_ic_wifi_signal_2.xml @@ -0,0 +1,11 @@ + + + + + + + + + + diff --git a/app/src/main/res/drawable-v24/preview_bars_ic_wifi_signal_3.xml b/app/src/main/res/drawable-v24/preview_bars_ic_wifi_signal_3.xml new file mode 100644 index 000000000..b668f00d7 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_bars_ic_wifi_signal_3.xml @@ -0,0 +1,11 @@ + + + + + + + + + + diff --git a/app/src/main/res/drawable-v24/preview_bars_ic_wifi_signal_4.xml b/app/src/main/res/drawable-v24/preview_bars_ic_wifi_signal_4.xml new file mode 100644 index 000000000..82cf3b616 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_bars_ic_wifi_signal_4.xml @@ -0,0 +1,10 @@ + + + + + + + + + diff --git a/app/src/main/res/drawable-v24/preview_butterfly_ic_signal_cellular_1_4_bar.xml b/app/src/main/res/drawable-v24/preview_butterfly_ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..39fa79c91 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_butterfly_ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,17 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_butterfly_ic_signal_cellular_2_4_bar.xml b/app/src/main/res/drawable-v24/preview_butterfly_ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..185ee1072 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_butterfly_ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,17 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_butterfly_ic_signal_cellular_3_4_bar.xml b/app/src/main/res/drawable-v24/preview_butterfly_ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..b8f1b43b5 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_butterfly_ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,17 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_butterfly_ic_signal_cellular_4_4_bar.xml b/app/src/main/res/drawable-v24/preview_butterfly_ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..bf29c73d1 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_butterfly_ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,17 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_circle_ic_signal_cellular_1_4_bar.xml b/app/src/main/res/drawable-v24/preview_circle_ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..d1312a6f0 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_circle_ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_circle_ic_signal_cellular_2_4_bar.xml b/app/src/main/res/drawable-v24/preview_circle_ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..36143d3c8 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_circle_ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_circle_ic_signal_cellular_3_4_bar.xml b/app/src/main/res/drawable-v24/preview_circle_ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..554850966 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_circle_ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_circle_ic_signal_cellular_4_4_bar.xml b/app/src/main/res/drawable-v24/preview_circle_ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..725a41460 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_circle_ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_color_picker_border.xml b/app/src/main/res/drawable-v24/preview_color_picker_border.xml new file mode 100644 index 000000000..c23a934ca --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_color_picker_border.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_daun_ic_signal_cellular_1_4_bar.xml b/app/src/main/res/drawable-v24/preview_daun_ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..b10190819 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_daun_ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,17 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_daun_ic_signal_cellular_2_4_bar.xml b/app/src/main/res/drawable-v24/preview_daun_ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..ae4b4ad54 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_daun_ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,17 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_daun_ic_signal_cellular_3_4_bar.xml b/app/src/main/res/drawable-v24/preview_daun_ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..a9ec0f75e --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_daun_ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,17 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_daun_ic_signal_cellular_4_4_bar.xml b/app/src/main/res/drawable-v24/preview_daun_ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..3f6137d42 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_daun_ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,17 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_dec_ic_signal_cellular_1_4_bar.xml b/app/src/main/res/drawable-v24/preview_dec_ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..91105c9f4 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_dec_ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_dec_ic_signal_cellular_2_4_bar.xml b/app/src/main/res/drawable-v24/preview_dec_ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..df462a481 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_dec_ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_dec_ic_signal_cellular_3_4_bar.xml b/app/src/main/res/drawable-v24/preview_dec_ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..72af92adb --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_dec_ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_dec_ic_signal_cellular_4_4_bar.xml b/app/src/main/res/drawable-v24/preview_dec_ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..9df8b17db --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_dec_ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_deep_ic_signal_cellular_1_4_bar.xml b/app/src/main/res/drawable-v24/preview_deep_ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..c096b8452 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_deep_ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,17 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_deep_ic_signal_cellular_2_4_bar.xml b/app/src/main/res/drawable-v24/preview_deep_ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..f1133a5eb --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_deep_ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,17 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_deep_ic_signal_cellular_3_4_bar.xml b/app/src/main/res/drawable-v24/preview_deep_ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..ac4d88565 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_deep_ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,17 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_deep_ic_signal_cellular_4_4_bar.xml b/app/src/main/res/drawable-v24/preview_deep_ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..b7e93666c --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_deep_ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,17 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_dora_ic_signal_cellular_1_4_bar.xml b/app/src/main/res/drawable-v24/preview_dora_ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..445681baa --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_dora_ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_dora_ic_signal_cellular_2_4_bar.xml b/app/src/main/res/drawable-v24/preview_dora_ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..b2d37469d --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_dora_ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_dora_ic_signal_cellular_3_4_bar.xml b/app/src/main/res/drawable-v24/preview_dora_ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..49d9ecd88 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_dora_ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_dora_ic_signal_cellular_4_4_bar.xml b/app/src/main/res/drawable-v24/preview_dora_ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..11b7d92a9 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_dora_ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_dora_ic_wifi_signal_1.xml b/app/src/main/res/drawable-v24/preview_dora_ic_wifi_signal_1.xml new file mode 100644 index 000000000..361725009 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_dora_ic_wifi_signal_1.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_dora_ic_wifi_signal_2.xml b/app/src/main/res/drawable-v24/preview_dora_ic_wifi_signal_2.xml new file mode 100644 index 000000000..a9c6992e5 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_dora_ic_wifi_signal_2.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_dora_ic_wifi_signal_3.xml b/app/src/main/res/drawable-v24/preview_dora_ic_wifi_signal_3.xml new file mode 100644 index 000000000..d902c2970 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_dora_ic_wifi_signal_3.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_dora_ic_wifi_signal_4.xml b/app/src/main/res/drawable-v24/preview_dora_ic_wifi_signal_4.xml new file mode 100644 index 000000000..f96ae041a --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_dora_ic_wifi_signal_4.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_equal_ic_signal_cellular_1_4_bar.xml b/app/src/main/res/drawable-v24/preview_equal_ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..f625c4edb --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_equal_ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_equal_ic_signal_cellular_2_4_bar.xml b/app/src/main/res/drawable-v24/preview_equal_ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..316b0d3a5 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_equal_ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_equal_ic_signal_cellular_3_4_bar.xml b/app/src/main/res/drawable-v24/preview_equal_ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..4106a2347 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_equal_ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_equal_ic_signal_cellular_4_4_bar.xml b/app/src/main/res/drawable-v24/preview_equal_ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..cf10b0123 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_equal_ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_faint_ui_ic_signal_cellular_1_4_bar.xml b/app/src/main/res/drawable-v24/preview_faint_ui_ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..b4bed1feb --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_faint_ui_ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,60 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_faint_ui_ic_signal_cellular_2_4_bar.xml b/app/src/main/res/drawable-v24/preview_faint_ui_ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..59adc2ab9 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_faint_ui_ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,60 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_faint_ui_ic_signal_cellular_3_4_bar.xml b/app/src/main/res/drawable-v24/preview_faint_ui_ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..b1c402dfc --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_faint_ui_ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,60 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_faint_ui_ic_signal_cellular_4_4_bar.xml b/app/src/main/res/drawable-v24/preview_faint_ui_ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..5836f94f2 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_faint_ui_ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,60 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_faint_ui_ic_wifi_signal_1.xml b/app/src/main/res/drawable-v24/preview_faint_ui_ic_wifi_signal_1.xml new file mode 100644 index 000000000..1ea85488b --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_faint_ui_ic_wifi_signal_1.xml @@ -0,0 +1,30 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_faint_ui_ic_wifi_signal_2.xml b/app/src/main/res/drawable-v24/preview_faint_ui_ic_wifi_signal_2.xml new file mode 100644 index 000000000..b366d77d9 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_faint_ui_ic_wifi_signal_2.xml @@ -0,0 +1,38 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_faint_ui_ic_wifi_signal_3.xml b/app/src/main/res/drawable-v24/preview_faint_ui_ic_wifi_signal_3.xml new file mode 100644 index 000000000..d827bca42 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_faint_ui_ic_wifi_signal_3.xml @@ -0,0 +1,46 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_faint_ui_ic_wifi_signal_4.xml b/app/src/main/res/drawable-v24/preview_faint_ui_ic_wifi_signal_4.xml new file mode 100644 index 000000000..7c0a964be --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_faint_ui_ic_wifi_signal_4.xml @@ -0,0 +1,46 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_fan_ic_signal_cellular_1_4_bar.xml b/app/src/main/res/drawable-v24/preview_fan_ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..70c43f196 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_fan_ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_fan_ic_signal_cellular_2_4_bar.xml b/app/src/main/res/drawable-v24/preview_fan_ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..3ba81ab0c --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_fan_ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_fan_ic_signal_cellular_3_4_bar.xml b/app/src/main/res/drawable-v24/preview_fan_ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..7326f8eeb --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_fan_ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_fan_ic_signal_cellular_4_4_bar.xml b/app/src/main/res/drawable-v24/preview_fan_ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..882677438 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_fan_ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_gradicon_ic_signal_cellular_1_4_bar.xml b/app/src/main/res/drawable-v24/preview_gradicon_ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..531a080a4 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_gradicon_ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,183 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_gradicon_ic_signal_cellular_2_4_bar.xml b/app/src/main/res/drawable-v24/preview_gradicon_ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..c9e74bc8d --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_gradicon_ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,183 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_gradicon_ic_signal_cellular_3_4_bar.xml b/app/src/main/res/drawable-v24/preview_gradicon_ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..9da5e2d31 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_gradicon_ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,183 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_gradicon_ic_signal_cellular_4_4_bar.xml b/app/src/main/res/drawable-v24/preview_gradicon_ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..6c8b26399 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_gradicon_ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,183 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_gradicon_ic_wifi_signal_1.xml b/app/src/main/res/drawable-v24/preview_gradicon_ic_wifi_signal_1.xml new file mode 100644 index 000000000..867de6807 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_gradicon_ic_wifi_signal_1.xml @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_gradicon_ic_wifi_signal_2.xml b/app/src/main/res/drawable-v24/preview_gradicon_ic_wifi_signal_2.xml new file mode 100644 index 000000000..e2207408d --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_gradicon_ic_wifi_signal_2.xml @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_gradicon_ic_wifi_signal_3.xml b/app/src/main/res/drawable-v24/preview_gradicon_ic_wifi_signal_3.xml new file mode 100644 index 000000000..eef571d59 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_gradicon_ic_wifi_signal_3.xml @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_gradicon_ic_wifi_signal_4.xml b/app/src/main/res/drawable-v24/preview_gradicon_ic_wifi_signal_4.xml new file mode 100644 index 000000000..eef571d59 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_gradicon_ic_wifi_signal_4.xml @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_huawei_ic_signal_cellular_1_4_bar.xml b/app/src/main/res/drawable-v24/preview_huawei_ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..aceafa1c8 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_huawei_ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,21 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_huawei_ic_signal_cellular_2_4_bar.xml b/app/src/main/res/drawable-v24/preview_huawei_ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..dcfadbe81 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_huawei_ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,21 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_huawei_ic_signal_cellular_3_4_bar.xml b/app/src/main/res/drawable-v24/preview_huawei_ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..8407c90b2 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_huawei_ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,21 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_huawei_ic_signal_cellular_4_4_bar.xml b/app/src/main/res/drawable-v24/preview_huawei_ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..3c485ea27 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_huawei_ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,21 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_inside_ic_signal_cellular_1_4_bar.xml b/app/src/main/res/drawable-v24/preview_inside_ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..785eacb11 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_inside_ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/res/drawable-v24/preview_inside_ic_signal_cellular_2_4_bar.xml b/app/src/main/res/drawable-v24/preview_inside_ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..07de2487d --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_inside_ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/res/drawable-v24/preview_inside_ic_signal_cellular_3_4_bar.xml b/app/src/main/res/drawable-v24/preview_inside_ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..0a24a937d --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_inside_ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/res/drawable-v24/preview_inside_ic_signal_cellular_4_4_bar.xml b/app/src/main/res/drawable-v24/preview_inside_ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..1333943e8 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_inside_ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/res/drawable-v24/preview_inside_ic_wifi_signal_1.xml b/app/src/main/res/drawable-v24/preview_inside_ic_wifi_signal_1.xml new file mode 100644 index 000000000..ece630995 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_inside_ic_wifi_signal_1.xml @@ -0,0 +1,9 @@ + + + + + + + + diff --git a/app/src/main/res/drawable-v24/preview_inside_ic_wifi_signal_2.xml b/app/src/main/res/drawable-v24/preview_inside_ic_wifi_signal_2.xml new file mode 100644 index 000000000..41e4caea8 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_inside_ic_wifi_signal_2.xml @@ -0,0 +1,9 @@ + + + + + + + + diff --git a/app/src/main/res/drawable-v24/preview_inside_ic_wifi_signal_3.xml b/app/src/main/res/drawable-v24/preview_inside_ic_wifi_signal_3.xml new file mode 100644 index 000000000..6e7a27fb8 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_inside_ic_wifi_signal_3.xml @@ -0,0 +1,9 @@ + + + + + + + + diff --git a/app/src/main/res/drawable-v24/preview_inside_ic_wifi_signal_4.xml b/app/src/main/res/drawable-v24/preview_inside_ic_wifi_signal_4.xml new file mode 100644 index 000000000..70e9d7a9e --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_inside_ic_wifi_signal_4.xml @@ -0,0 +1,9 @@ + + + + + + + + diff --git a/app/src/main/res/drawable-v24/preview_ios_ic_signal_cellular_1_4_bar.xml b/app/src/main/res/drawable-v24/preview_ios_ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..579843a31 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_ios_ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_ios_ic_signal_cellular_2_4_bar.xml b/app/src/main/res/drawable-v24/preview_ios_ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..0284f9ea2 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_ios_ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_ios_ic_signal_cellular_3_4_bar.xml b/app/src/main/res/drawable-v24/preview_ios_ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..49dce55ce --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_ios_ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_ios_ic_signal_cellular_4_4_bar.xml b/app/src/main/res/drawable-v24/preview_ios_ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..c6cc45a68 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_ios_ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_lorn_ic_signal_cellular_1_4_bar.xml b/app/src/main/res/drawable-v24/preview_lorn_ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..695c5263e --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_lorn_ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,22 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_lorn_ic_signal_cellular_2_4_bar.xml b/app/src/main/res/drawable-v24/preview_lorn_ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..695c5263e --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_lorn_ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,22 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_lorn_ic_signal_cellular_3_4_bar.xml b/app/src/main/res/drawable-v24/preview_lorn_ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..83254ff81 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_lorn_ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,22 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_lorn_ic_signal_cellular_4_4_bar.xml b/app/src/main/res/drawable-v24/preview_lorn_ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..4f271f0a1 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_lorn_ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,22 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_lorn_ic_wifi_signal_1.xml b/app/src/main/res/drawable-v24/preview_lorn_ic_wifi_signal_1.xml new file mode 100644 index 000000000..500617c4b --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_lorn_ic_wifi_signal_1.xml @@ -0,0 +1,22 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_lorn_ic_wifi_signal_2.xml b/app/src/main/res/drawable-v24/preview_lorn_ic_wifi_signal_2.xml new file mode 100644 index 000000000..f0aa6e016 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_lorn_ic_wifi_signal_2.xml @@ -0,0 +1,22 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_lorn_ic_wifi_signal_3.xml b/app/src/main/res/drawable-v24/preview_lorn_ic_wifi_signal_3.xml new file mode 100644 index 000000000..23c0e7f0f --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_lorn_ic_wifi_signal_3.xml @@ -0,0 +1,22 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_lorn_ic_wifi_signal_4.xml b/app/src/main/res/drawable-v24/preview_lorn_ic_wifi_signal_4.xml new file mode 100644 index 000000000..23c0e7f0f --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_lorn_ic_wifi_signal_4.xml @@ -0,0 +1,22 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_mini_ic_signal_cellular_1_4_bar.xml b/app/src/main/res/drawable-v24/preview_mini_ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..57cf89631 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_mini_ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_mini_ic_signal_cellular_2_4_bar.xml b/app/src/main/res/drawable-v24/preview_mini_ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..d609fdc79 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_mini_ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_mini_ic_signal_cellular_3_4_bar.xml b/app/src/main/res/drawable-v24/preview_mini_ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..f291f636e --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_mini_ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_mini_ic_signal_cellular_4_4_bar.xml b/app/src/main/res/drawable-v24/preview_mini_ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..fbe8dbc5c --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_mini_ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_nothing_dot_ic_signal_cellular_1_4_bar.xml b/app/src/main/res/drawable-v24/preview_nothing_dot_ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..4cefd75ae --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_nothing_dot_ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/app/src/main/res/drawable-v24/preview_nothing_dot_ic_signal_cellular_2_4_bar.xml b/app/src/main/res/drawable-v24/preview_nothing_dot_ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..c03935468 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_nothing_dot_ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/app/src/main/res/drawable-v24/preview_nothing_dot_ic_signal_cellular_3_4_bar.xml b/app/src/main/res/drawable-v24/preview_nothing_dot_ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..3bfb02198 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_nothing_dot_ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/app/src/main/res/drawable-v24/preview_nothing_dot_ic_signal_cellular_4_4_bar.xml b/app/src/main/res/drawable-v24/preview_nothing_dot_ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..2f0a9bf75 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_nothing_dot_ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/app/src/main/res/drawable-v24/preview_nothing_dot_ic_wifi_signal_1.xml b/app/src/main/res/drawable-v24/preview_nothing_dot_ic_wifi_signal_1.xml new file mode 100644 index 000000000..a3865f829 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_nothing_dot_ic_wifi_signal_1.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/src/main/res/drawable-v24/preview_nothing_dot_ic_wifi_signal_2.xml b/app/src/main/res/drawable-v24/preview_nothing_dot_ic_wifi_signal_2.xml new file mode 100644 index 000000000..eb32dd9a8 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_nothing_dot_ic_wifi_signal_2.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/src/main/res/drawable-v24/preview_nothing_dot_ic_wifi_signal_3.xml b/app/src/main/res/drawable-v24/preview_nothing_dot_ic_wifi_signal_3.xml new file mode 100644 index 000000000..aaae51a35 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_nothing_dot_ic_wifi_signal_3.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/src/main/res/drawable-v24/preview_nothing_dot_ic_wifi_signal_4.xml b/app/src/main/res/drawable-v24/preview_nothing_dot_ic_wifi_signal_4.xml new file mode 100644 index 000000000..4f2da1a5d --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_nothing_dot_ic_wifi_signal_4.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/src/main/res/drawable-v24/preview_odin_ic_signal_cellular_1_4_bar.xml b/app/src/main/res/drawable-v24/preview_odin_ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..1fa47ca92 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_odin_ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_odin_ic_signal_cellular_2_4_bar.xml b/app/src/main/res/drawable-v24/preview_odin_ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..60c215086 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_odin_ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_odin_ic_signal_cellular_3_4_bar.xml b/app/src/main/res/drawable-v24/preview_odin_ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..a11914a63 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_odin_ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_odin_ic_signal_cellular_4_4_bar.xml b/app/src/main/res/drawable-v24/preview_odin_ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..ba2da49b0 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_odin_ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_pills_ic_signal_cellular_1_4_bar.xml b/app/src/main/res/drawable-v24/preview_pills_ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..b9178b2f4 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_pills_ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_pills_ic_signal_cellular_2_4_bar.xml b/app/src/main/res/drawable-v24/preview_pills_ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..3d12a6fd1 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_pills_ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_pills_ic_signal_cellular_3_4_bar.xml b/app/src/main/res/drawable-v24/preview_pills_ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..590dd2c2e --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_pills_ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_pills_ic_signal_cellular_4_4_bar.xml b/app/src/main/res/drawable-v24/preview_pills_ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..74f9d4730 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_pills_ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_plumpy_ic_signal_cellular_1_4_bar.xml b/app/src/main/res/drawable-v24/preview_plumpy_ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..f08da03ca --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_plumpy_ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,22 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_plumpy_ic_signal_cellular_2_4_bar.xml b/app/src/main/res/drawable-v24/preview_plumpy_ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..900bbd66d --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_plumpy_ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,22 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_plumpy_ic_signal_cellular_3_4_bar.xml b/app/src/main/res/drawable-v24/preview_plumpy_ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..97dc06545 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_plumpy_ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,22 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_plumpy_ic_signal_cellular_4_4_bar.xml b/app/src/main/res/drawable-v24/preview_plumpy_ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..5e4c24270 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_plumpy_ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,22 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_plumpy_ic_wifi_signal_1.xml b/app/src/main/res/drawable-v24/preview_plumpy_ic_wifi_signal_1.xml new file mode 100644 index 000000000..175ec6658 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_plumpy_ic_wifi_signal_1.xml @@ -0,0 +1,22 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_plumpy_ic_wifi_signal_2.xml b/app/src/main/res/drawable-v24/preview_plumpy_ic_wifi_signal_2.xml new file mode 100644 index 000000000..702a4471f --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_plumpy_ic_wifi_signal_2.xml @@ -0,0 +1,22 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_plumpy_ic_wifi_signal_3.xml b/app/src/main/res/drawable-v24/preview_plumpy_ic_wifi_signal_3.xml new file mode 100644 index 000000000..2b58058e3 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_plumpy_ic_wifi_signal_3.xml @@ -0,0 +1,22 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_plumpy_ic_wifi_signal_4.xml b/app/src/main/res/drawable-v24/preview_plumpy_ic_wifi_signal_4.xml new file mode 100644 index 000000000..f84d7689d --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_plumpy_ic_wifi_signal_4.xml @@ -0,0 +1,22 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_rel_ic_signal_cellular_1_4_bar.xml b/app/src/main/res/drawable-v24/preview_rel_ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..e683bbefd --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_rel_ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,19 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_rel_ic_signal_cellular_2_4_bar.xml b/app/src/main/res/drawable-v24/preview_rel_ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..e75b2a6d5 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_rel_ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,19 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_rel_ic_signal_cellular_3_4_bar.xml b/app/src/main/res/drawable-v24/preview_rel_ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..50f76bd71 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_rel_ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,19 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_rel_ic_signal_cellular_4_4_bar.xml b/app/src/main/res/drawable-v24/preview_rel_ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..4f18862b0 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_rel_ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,19 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_roman_ic_signal_cellular_1_4_bar.xml b/app/src/main/res/drawable-v24/preview_roman_ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..e4eb791c5 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_roman_ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_roman_ic_signal_cellular_2_4_bar.xml b/app/src/main/res/drawable-v24/preview_roman_ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..2ce739f0c --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_roman_ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_roman_ic_signal_cellular_3_4_bar.xml b/app/src/main/res/drawable-v24/preview_roman_ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..6e33da8da --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_roman_ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_roman_ic_signal_cellular_4_4_bar.xml b/app/src/main/res/drawable-v24/preview_roman_ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..a36c4b048 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_roman_ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_round_ic_signal_cellular_1_4_bar.xml b/app/src/main/res/drawable-v24/preview_round_ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..6ea3f7147 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_round_ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable-v24/preview_round_ic_signal_cellular_2_4_bar.xml b/app/src/main/res/drawable-v24/preview_round_ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..7d8ba2f21 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_round_ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable-v24/preview_round_ic_signal_cellular_3_4_bar.xml b/app/src/main/res/drawable-v24/preview_round_ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..db5411db2 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_round_ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable-v24/preview_round_ic_signal_cellular_4_4_bar.xml b/app/src/main/res/drawable-v24/preview_round_ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..29c3ea284 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_round_ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/res/drawable-v24/preview_round_ic_wifi_signal_1.xml b/app/src/main/res/drawable-v24/preview_round_ic_wifi_signal_1.xml new file mode 100644 index 000000000..f8fbf1e32 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_round_ic_wifi_signal_1.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable-v24/preview_round_ic_wifi_signal_2.xml b/app/src/main/res/drawable-v24/preview_round_ic_wifi_signal_2.xml new file mode 100644 index 000000000..226d28263 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_round_ic_wifi_signal_2.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable-v24/preview_round_ic_wifi_signal_3.xml b/app/src/main/res/drawable-v24/preview_round_ic_wifi_signal_3.xml new file mode 100644 index 000000000..de80ec9e8 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_round_ic_wifi_signal_3.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/res/drawable-v24/preview_round_ic_wifi_signal_4.xml b/app/src/main/res/drawable-v24/preview_round_ic_wifi_signal_4.xml new file mode 100644 index 000000000..de80ec9e8 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_round_ic_wifi_signal_4.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/res/drawable-v24/preview_scroll_ic_signal_cellular_1_4_bar.xml b/app/src/main/res/drawable-v24/preview_scroll_ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..6164e201b --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_scroll_ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_scroll_ic_signal_cellular_2_4_bar.xml b/app/src/main/res/drawable-v24/preview_scroll_ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..e771017df --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_scroll_ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_scroll_ic_signal_cellular_3_4_bar.xml b/app/src/main/res/drawable-v24/preview_scroll_ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..8934ed54f --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_scroll_ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_scroll_ic_signal_cellular_4_4_bar.xml b/app/src/main/res/drawable-v24/preview_scroll_ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..52285595a --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_scroll_ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_sea_ic_signal_cellular_1_4_bar.xml b/app/src/main/res/drawable-v24/preview_sea_ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..4c767ccba --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_sea_ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + diff --git a/app/src/main/res/drawable-v24/preview_sea_ic_signal_cellular_2_4_bar.xml b/app/src/main/res/drawable-v24/preview_sea_ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..561b1fd55 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_sea_ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + diff --git a/app/src/main/res/drawable-v24/preview_sea_ic_signal_cellular_3_4_bar.xml b/app/src/main/res/drawable-v24/preview_sea_ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..53c8458db --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_sea_ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + diff --git a/app/src/main/res/drawable-v24/preview_sea_ic_signal_cellular_4_4_bar.xml b/app/src/main/res/drawable-v24/preview_sea_ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..9f93ea0b8 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_sea_ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + diff --git a/app/src/main/res/drawable-v24/preview_sneaky_ic_signal_cellular_1_4_bar.xml b/app/src/main/res/drawable-v24/preview_sneaky_ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..2d71803c7 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_sneaky_ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/res/drawable-v24/preview_sneaky_ic_signal_cellular_2_4_bar.xml b/app/src/main/res/drawable-v24/preview_sneaky_ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..72f83cf96 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_sneaky_ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/res/drawable-v24/preview_sneaky_ic_signal_cellular_3_4_bar.xml b/app/src/main/res/drawable-v24/preview_sneaky_ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..c2af388b9 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_sneaky_ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/res/drawable-v24/preview_sneaky_ic_signal_cellular_4_4_bar.xml b/app/src/main/res/drawable-v24/preview_sneaky_ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..04d4d2702 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_sneaky_ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/res/drawable-v24/preview_sneaky_ic_wifi_signal_1.xml b/app/src/main/res/drawable-v24/preview_sneaky_ic_wifi_signal_1.xml new file mode 100644 index 000000000..465a729ab --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_sneaky_ic_wifi_signal_1.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/res/drawable-v24/preview_sneaky_ic_wifi_signal_2.xml b/app/src/main/res/drawable-v24/preview_sneaky_ic_wifi_signal_2.xml new file mode 100644 index 000000000..a4553d7ec --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_sneaky_ic_wifi_signal_2.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/res/drawable-v24/preview_sneaky_ic_wifi_signal_3.xml b/app/src/main/res/drawable-v24/preview_sneaky_ic_wifi_signal_3.xml new file mode 100644 index 000000000..df7b1d63a --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_sneaky_ic_wifi_signal_3.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/res/drawable-v24/preview_sneaky_ic_wifi_signal_4.xml b/app/src/main/res/drawable-v24/preview_sneaky_ic_wifi_signal_4.xml new file mode 100644 index 000000000..abc3a1a1b --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_sneaky_ic_wifi_signal_4.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/res/drawable-v24/preview_stack_ic_signal_cellular_1_4_bar.xml b/app/src/main/res/drawable-v24/preview_stack_ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..016a3a8fc --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_stack_ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_stack_ic_signal_cellular_2_4_bar.xml b/app/src/main/res/drawable-v24/preview_stack_ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..71f52d4bd --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_stack_ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_stack_ic_signal_cellular_3_4_bar.xml b/app/src/main/res/drawable-v24/preview_stack_ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..852c1dac1 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_stack_ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_stack_ic_signal_cellular_4_4_bar.xml b/app/src/main/res/drawable-v24/preview_stack_ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..8f7b90a15 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_stack_ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_stroke_ic_signal_cellular_1_4_bar.xml b/app/src/main/res/drawable-v24/preview_stroke_ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..b149a1d54 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_stroke_ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_stroke_ic_signal_cellular_2_4_bar.xml b/app/src/main/res/drawable-v24/preview_stroke_ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..ceb7d5095 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_stroke_ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_stroke_ic_signal_cellular_3_4_bar.xml b/app/src/main/res/drawable-v24/preview_stroke_ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..d355efa26 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_stroke_ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_stroke_ic_signal_cellular_4_4_bar.xml b/app/src/main/res/drawable-v24/preview_stroke_ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..ffb465530 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_stroke_ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_stroke_ic_wifi_signal_1.xml b/app/src/main/res/drawable-v24/preview_stroke_ic_wifi_signal_1.xml new file mode 100644 index 000000000..d33292b6b --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_stroke_ic_wifi_signal_1.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable-v24/preview_stroke_ic_wifi_signal_2.xml b/app/src/main/res/drawable-v24/preview_stroke_ic_wifi_signal_2.xml new file mode 100644 index 000000000..16a2e9902 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_stroke_ic_wifi_signal_2.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable-v24/preview_stroke_ic_wifi_signal_3.xml b/app/src/main/res/drawable-v24/preview_stroke_ic_wifi_signal_3.xml new file mode 100644 index 000000000..aa17764ba --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_stroke_ic_wifi_signal_3.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable-v24/preview_stroke_ic_wifi_signal_4.xml b/app/src/main/res/drawable-v24/preview_stroke_ic_wifi_signal_4.xml new file mode 100644 index 000000000..894c47966 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_stroke_ic_wifi_signal_4.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable-v24/preview_wannui_ic_signal_cellular_1_4_bar.xml b/app/src/main/res/drawable-v24/preview_wannui_ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..052a63233 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_wannui_ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_wannui_ic_signal_cellular_2_4_bar.xml b/app/src/main/res/drawable-v24/preview_wannui_ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..64c1aff54 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_wannui_ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_wannui_ic_signal_cellular_3_4_bar.xml b/app/src/main/res/drawable-v24/preview_wannui_ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..8b6edabe9 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_wannui_ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_wannui_ic_signal_cellular_4_4_bar.xml b/app/src/main/res/drawable-v24/preview_wannui_ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..1aa6aa09a --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_wannui_ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_wavy_ic_signal_cellular_1_4_bar.xml b/app/src/main/res/drawable-v24/preview_wavy_ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..0c9074b83 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_wavy_ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/res/drawable-v24/preview_wavy_ic_signal_cellular_2_4_bar.xml b/app/src/main/res/drawable-v24/preview_wavy_ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..ac81a3de8 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_wavy_ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/res/drawable-v24/preview_wavy_ic_signal_cellular_3_4_bar.xml b/app/src/main/res/drawable-v24/preview_wavy_ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..c2259b10b --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_wavy_ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/res/drawable-v24/preview_wavy_ic_signal_cellular_4_4_bar.xml b/app/src/main/res/drawable-v24/preview_wavy_ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..b71c4c6c7 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_wavy_ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/res/drawable-v24/preview_wavy_ic_wifi_signal_1.xml b/app/src/main/res/drawable-v24/preview_wavy_ic_wifi_signal_1.xml new file mode 100644 index 000000000..6b42ba14a --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_wavy_ic_wifi_signal_1.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable-v24/preview_wavy_ic_wifi_signal_2.xml b/app/src/main/res/drawable-v24/preview_wavy_ic_wifi_signal_2.xml new file mode 100644 index 000000000..7617c3fbd --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_wavy_ic_wifi_signal_2.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/res/drawable-v24/preview_wavy_ic_wifi_signal_3.xml b/app/src/main/res/drawable-v24/preview_wavy_ic_wifi_signal_3.xml new file mode 100644 index 000000000..746887bc3 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_wavy_ic_wifi_signal_3.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/res/drawable-v24/preview_wavy_ic_wifi_signal_4.xml b/app/src/main/res/drawable-v24/preview_wavy_ic_wifi_signal_4.xml new file mode 100644 index 000000000..88ae44047 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_wavy_ic_wifi_signal_4.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/res/drawable-v24/preview_weed_ic_wifi_signal_1.xml b/app/src/main/res/drawable-v24/preview_weed_ic_wifi_signal_1.xml new file mode 100644 index 000000000..204e906b2 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_weed_ic_wifi_signal_1.xml @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_weed_ic_wifi_signal_2.xml b/app/src/main/res/drawable-v24/preview_weed_ic_wifi_signal_2.xml new file mode 100644 index 000000000..f5a538cdb --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_weed_ic_wifi_signal_2.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_weed_ic_wifi_signal_3.xml b/app/src/main/res/drawable-v24/preview_weed_ic_wifi_signal_3.xml new file mode 100644 index 000000000..b57747aa4 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_weed_ic_wifi_signal_3.xml @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_weed_ic_wifi_signal_4.xml b/app/src/main/res/drawable-v24/preview_weed_ic_wifi_signal_4.xml new file mode 100644 index 000000000..66fb6e362 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_weed_ic_wifi_signal_4.xml @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_windows_ic_signal_cellular_1_4_bar.xml b/app/src/main/res/drawable-v24/preview_windows_ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..c5b3d1692 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_windows_ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_windows_ic_signal_cellular_2_4_bar.xml b/app/src/main/res/drawable-v24/preview_windows_ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..ecb0f760b --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_windows_ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_windows_ic_signal_cellular_3_4_bar.xml b/app/src/main/res/drawable-v24/preview_windows_ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..407fbdee0 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_windows_ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_windows_ic_signal_cellular_4_4_bar.xml b/app/src/main/res/drawable-v24/preview_windows_ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..0cc865c10 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_windows_ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_wing_ic_signal_cellular_1_4_bar.xml b/app/src/main/res/drawable-v24/preview_wing_ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..3ed9275ee --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_wing_ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_wing_ic_signal_cellular_2_4_bar.xml b/app/src/main/res/drawable-v24/preview_wing_ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..2ef8f395c --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_wing_ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_wing_ic_signal_cellular_3_4_bar.xml b/app/src/main/res/drawable-v24/preview_wing_ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..288ebe57c --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_wing_ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_wing_ic_signal_cellular_4_4_bar.xml b/app/src/main/res/drawable-v24/preview_wing_ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..d341b92d4 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_wing_ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/preview_xperia_ic_signal_cellular_1_4_bar.xml b/app/src/main/res/drawable-v24/preview_xperia_ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..bc74851e3 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_xperia_ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/res/drawable-v24/preview_xperia_ic_signal_cellular_2_4_bar.xml b/app/src/main/res/drawable-v24/preview_xperia_ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..09a9de7dc --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_xperia_ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/res/drawable-v24/preview_xperia_ic_signal_cellular_3_4_bar.xml b/app/src/main/res/drawable-v24/preview_xperia_ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..aebc5b341 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_xperia_ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/res/drawable-v24/preview_xperia_ic_signal_cellular_4_4_bar.xml b/app/src/main/res/drawable-v24/preview_xperia_ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..e6f8c660c --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_xperia_ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/res/drawable-v24/preview_xperia_ic_wifi_signal_1.xml b/app/src/main/res/drawable-v24/preview_xperia_ic_wifi_signal_1.xml new file mode 100644 index 000000000..d1a978fa8 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_xperia_ic_wifi_signal_1.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/res/drawable-v24/preview_xperia_ic_wifi_signal_2.xml b/app/src/main/res/drawable-v24/preview_xperia_ic_wifi_signal_2.xml new file mode 100644 index 000000000..f9e7b669c --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_xperia_ic_wifi_signal_2.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/res/drawable-v24/preview_xperia_ic_wifi_signal_3.xml b/app/src/main/res/drawable-v24/preview_xperia_ic_wifi_signal_3.xml new file mode 100644 index 000000000..056f813de --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_xperia_ic_wifi_signal_3.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/res/drawable-v24/preview_xperia_ic_wifi_signal_4.xml b/app/src/main/res/drawable-v24/preview_xperia_ic_wifi_signal_4.xml new file mode 100644 index 000000000..056f813de --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_xperia_ic_wifi_signal_4.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/res/drawable-v24/preview_zigzag_ic_signal_cellular_1_4_bar.xml b/app/src/main/res/drawable-v24/preview_zigzag_ic_signal_cellular_1_4_bar.xml new file mode 100644 index 000000000..581331608 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_zigzag_ic_signal_cellular_1_4_bar.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable-v24/preview_zigzag_ic_signal_cellular_2_4_bar.xml b/app/src/main/res/drawable-v24/preview_zigzag_ic_signal_cellular_2_4_bar.xml new file mode 100644 index 000000000..7765c318e --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_zigzag_ic_signal_cellular_2_4_bar.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable-v24/preview_zigzag_ic_signal_cellular_3_4_bar.xml b/app/src/main/res/drawable-v24/preview_zigzag_ic_signal_cellular_3_4_bar.xml new file mode 100644 index 000000000..679d52e93 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_zigzag_ic_signal_cellular_3_4_bar.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable-v24/preview_zigzag_ic_signal_cellular_4_4_bar.xml b/app/src/main/res/drawable-v24/preview_zigzag_ic_signal_cellular_4_4_bar.xml new file mode 100644 index 000000000..6876c0799 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_zigzag_ic_signal_cellular_4_4_bar.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/res/drawable-v24/preview_zigzag_ic_wifi_signal_1.xml b/app/src/main/res/drawable-v24/preview_zigzag_ic_wifi_signal_1.xml new file mode 100644 index 000000000..e33ba2644 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_zigzag_ic_wifi_signal_1.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/res/drawable-v24/preview_zigzag_ic_wifi_signal_2.xml b/app/src/main/res/drawable-v24/preview_zigzag_ic_wifi_signal_2.xml new file mode 100644 index 000000000..83908487d --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_zigzag_ic_wifi_signal_2.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/res/drawable-v24/preview_zigzag_ic_wifi_signal_3.xml b/app/src/main/res/drawable-v24/preview_zigzag_ic_wifi_signal_3.xml new file mode 100644 index 000000000..6195b24b0 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_zigzag_ic_wifi_signal_3.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/res/drawable-v24/preview_zigzag_ic_wifi_signal_4.xml b/app/src/main/res/drawable-v24/preview_zigzag_ic_wifi_signal_4.xml new file mode 100644 index 000000000..76c0868a4 --- /dev/null +++ b/app/src/main/res/drawable-v24/preview_zigzag_ic_wifi_signal_4.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/res/drawable-v24/toast_frame_style_12.xml b/app/src/main/res/drawable-v24/toast_frame_style_12.xml new file mode 100644 index 000000000..a76a7f88b --- /dev/null +++ b/app/src/main/res/drawable-v24/toast_frame_style_12.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/action_bar_item_background_material.xml b/app/src/main/res/drawable/action_bar_item_background_material.xml new file mode 100644 index 000000000..dfb7b4a21 --- /dev/null +++ b/app/src/main/res/drawable/action_bar_item_background_material.xml @@ -0,0 +1,14 @@ + + \ No newline at end of file diff --git a/app/src/main/res/drawable/action_bar_item_background_material_error.xml b/app/src/main/res/drawable/action_bar_item_background_material_error.xml new file mode 100644 index 000000000..6356f2960 --- /dev/null +++ b/app/src/main/res/drawable/action_bar_item_background_material_error.xml @@ -0,0 +1,14 @@ + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ambient_indication_pill_background.xml b/app/src/main/res/drawable/ambient_indication_pill_background.xml new file mode 100644 index 000000000..0ba67ea56 --- /dev/null +++ b/app/src/main/res/drawable/ambient_indication_pill_background.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/container_background_accent.xml b/app/src/main/res/drawable/container_background_accent.xml new file mode 100644 index 000000000..6935db8d2 --- /dev/null +++ b/app/src/main/res/drawable/container_background_accent.xml @@ -0,0 +1,9 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/container_small.xml b/app/src/main/res/drawable/container_small.xml new file mode 100644 index 000000000..0924231c3 --- /dev/null +++ b/app/src/main/res/drawable/container_small.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/date_box_str_border.xml b/app/src/main/res/drawable/date_box_str_border.xml new file mode 100644 index 000000000..ad2096e0e --- /dev/null +++ b/app/src/main/res/drawable/date_box_str_border.xml @@ -0,0 +1,9 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/date_str_accent.xml b/app/src/main/res/drawable/date_str_accent.xml new file mode 100644 index 000000000..91fe01cd2 --- /dev/null +++ b/app/src/main/res/drawable/date_str_accent.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/date_str_border.xml b/app/src/main/res/drawable/date_str_border.xml new file mode 100644 index 000000000..7143de116 --- /dev/null +++ b/app/src/main/res/drawable/date_str_border.xml @@ -0,0 +1,9 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/date_str_borderacc.xml b/app/src/main/res/drawable/date_str_borderacc.xml new file mode 100644 index 000000000..97f5afa68 --- /dev/null +++ b/app/src/main/res/drawable/date_str_borderacc.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/date_str_bordergrad.xml b/app/src/main/res/drawable/date_str_bordergrad.xml new file mode 100644 index 000000000..9e5ae1a33 --- /dev/null +++ b/app/src/main/res/drawable/date_str_bordergrad.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/date_str_gradient.xml b/app/src/main/res/drawable/date_str_gradient.xml new file mode 100644 index 000000000..20d5245d1 --- /dev/null +++ b/app/src/main/res/drawable/date_str_gradient.xml @@ -0,0 +1,10 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/google_new_dark_0.xml b/app/src/main/res/drawable/google_new_dark_0.xml new file mode 100644 index 000000000..5c228785e --- /dev/null +++ b/app/src/main/res/drawable/google_new_dark_0.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_dark_1.xml b/app/src/main/res/drawable/google_new_dark_1.xml new file mode 100644 index 000000000..ae9cbfd7a --- /dev/null +++ b/app/src/main/res/drawable/google_new_dark_1.xml @@ -0,0 +1,20 @@ + + + + + diff --git a/app/src/main/res/drawable/google_new_dark_10.xml b/app/src/main/res/drawable/google_new_dark_10.xml new file mode 100644 index 000000000..cc20489ac --- /dev/null +++ b/app/src/main/res/drawable/google_new_dark_10.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_dark_11.xml b/app/src/main/res/drawable/google_new_dark_11.xml new file mode 100644 index 000000000..cb2eb96a7 --- /dev/null +++ b/app/src/main/res/drawable/google_new_dark_11.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_dark_12.xml b/app/src/main/res/drawable/google_new_dark_12.xml new file mode 100644 index 000000000..1e9770239 --- /dev/null +++ b/app/src/main/res/drawable/google_new_dark_12.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_dark_13.xml b/app/src/main/res/drawable/google_new_dark_13.xml new file mode 100644 index 000000000..aeaf1e9a8 --- /dev/null +++ b/app/src/main/res/drawable/google_new_dark_13.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_dark_14.xml b/app/src/main/res/drawable/google_new_dark_14.xml new file mode 100644 index 000000000..aeaf1e9a8 --- /dev/null +++ b/app/src/main/res/drawable/google_new_dark_14.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_dark_15.xml b/app/src/main/res/drawable/google_new_dark_15.xml new file mode 100644 index 000000000..aeaf1e9a8 --- /dev/null +++ b/app/src/main/res/drawable/google_new_dark_15.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_dark_16.xml b/app/src/main/res/drawable/google_new_dark_16.xml new file mode 100644 index 000000000..aeaf1e9a8 --- /dev/null +++ b/app/src/main/res/drawable/google_new_dark_16.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_dark_17.xml b/app/src/main/res/drawable/google_new_dark_17.xml new file mode 100644 index 000000000..eb9c19097 --- /dev/null +++ b/app/src/main/res/drawable/google_new_dark_17.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_dark_18.xml b/app/src/main/res/drawable/google_new_dark_18.xml new file mode 100644 index 000000000..e4aae1dbe --- /dev/null +++ b/app/src/main/res/drawable/google_new_dark_18.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_dark_19.xml b/app/src/main/res/drawable/google_new_dark_19.xml new file mode 100644 index 000000000..267a93e0c --- /dev/null +++ b/app/src/main/res/drawable/google_new_dark_19.xml @@ -0,0 +1,15 @@ + + + + + + diff --git a/app/src/main/res/drawable/google_new_dark_2.xml b/app/src/main/res/drawable/google_new_dark_2.xml new file mode 100644 index 000000000..ae9cbfd7a --- /dev/null +++ b/app/src/main/res/drawable/google_new_dark_2.xml @@ -0,0 +1,20 @@ + + + + + diff --git a/app/src/main/res/drawable/google_new_dark_20.xml b/app/src/main/res/drawable/google_new_dark_20.xml new file mode 100644 index 000000000..267a93e0c --- /dev/null +++ b/app/src/main/res/drawable/google_new_dark_20.xml @@ -0,0 +1,15 @@ + + + + + + diff --git a/app/src/main/res/drawable/google_new_dark_21.xml b/app/src/main/res/drawable/google_new_dark_21.xml new file mode 100644 index 000000000..267a93e0c --- /dev/null +++ b/app/src/main/res/drawable/google_new_dark_21.xml @@ -0,0 +1,15 @@ + + + + + + diff --git a/app/src/main/res/drawable/google_new_dark_22.xml b/app/src/main/res/drawable/google_new_dark_22.xml new file mode 100644 index 000000000..267a93e0c --- /dev/null +++ b/app/src/main/res/drawable/google_new_dark_22.xml @@ -0,0 +1,15 @@ + + + + + + diff --git a/app/src/main/res/drawable/google_new_dark_23.xml b/app/src/main/res/drawable/google_new_dark_23.xml new file mode 100644 index 000000000..80c800ae1 --- /dev/null +++ b/app/src/main/res/drawable/google_new_dark_23.xml @@ -0,0 +1,15 @@ + + + + + + diff --git a/app/src/main/res/drawable/google_new_dark_24.xml b/app/src/main/res/drawable/google_new_dark_24.xml new file mode 100644 index 000000000..80c800ae1 --- /dev/null +++ b/app/src/main/res/drawable/google_new_dark_24.xml @@ -0,0 +1,15 @@ + + + + + + diff --git a/app/src/main/res/drawable/google_new_dark_25.xml b/app/src/main/res/drawable/google_new_dark_25.xml new file mode 100644 index 000000000..534450949 --- /dev/null +++ b/app/src/main/res/drawable/google_new_dark_25.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_dark_26.xml b/app/src/main/res/drawable/google_new_dark_26.xml new file mode 100644 index 000000000..801027c06 --- /dev/null +++ b/app/src/main/res/drawable/google_new_dark_26.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_dark_27.xml b/app/src/main/res/drawable/google_new_dark_27.xml new file mode 100644 index 000000000..fe7413aa9 --- /dev/null +++ b/app/src/main/res/drawable/google_new_dark_27.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_dark_28.xml b/app/src/main/res/drawable/google_new_dark_28.xml new file mode 100644 index 000000000..d01eac06b --- /dev/null +++ b/app/src/main/res/drawable/google_new_dark_28.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_dark_29.xml b/app/src/main/res/drawable/google_new_dark_29.xml new file mode 100644 index 000000000..df6eb5b0c --- /dev/null +++ b/app/src/main/res/drawable/google_new_dark_29.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_dark_3.xml b/app/src/main/res/drawable/google_new_dark_3.xml new file mode 100644 index 000000000..49f65ee0c --- /dev/null +++ b/app/src/main/res/drawable/google_new_dark_3.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_dark_30.xml b/app/src/main/res/drawable/google_new_dark_30.xml new file mode 100644 index 000000000..04184b6d5 --- /dev/null +++ b/app/src/main/res/drawable/google_new_dark_30.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_dark_31.xml b/app/src/main/res/drawable/google_new_dark_31.xml new file mode 100644 index 000000000..ab39a06d9 --- /dev/null +++ b/app/src/main/res/drawable/google_new_dark_31.xml @@ -0,0 +1,22 @@ + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_dark_32.xml b/app/src/main/res/drawable/google_new_dark_32.xml new file mode 100644 index 000000000..cf0b67928 --- /dev/null +++ b/app/src/main/res/drawable/google_new_dark_32.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_dark_33.xml b/app/src/main/res/drawable/google_new_dark_33.xml new file mode 100644 index 000000000..b257340c2 --- /dev/null +++ b/app/src/main/res/drawable/google_new_dark_33.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_dark_34.xml b/app/src/main/res/drawable/google_new_dark_34.xml new file mode 100644 index 000000000..902f7fb6e --- /dev/null +++ b/app/src/main/res/drawable/google_new_dark_34.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_dark_35.xml b/app/src/main/res/drawable/google_new_dark_35.xml new file mode 100644 index 000000000..49f65ee0c --- /dev/null +++ b/app/src/main/res/drawable/google_new_dark_35.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_dark_36.xml b/app/src/main/res/drawable/google_new_dark_36.xml new file mode 100644 index 000000000..a070b25cf --- /dev/null +++ b/app/src/main/res/drawable/google_new_dark_36.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_dark_37.xml b/app/src/main/res/drawable/google_new_dark_37.xml new file mode 100644 index 000000000..4e78472be --- /dev/null +++ b/app/src/main/res/drawable/google_new_dark_37.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_dark_38.xml b/app/src/main/res/drawable/google_new_dark_38.xml new file mode 100644 index 000000000..4e78472be --- /dev/null +++ b/app/src/main/res/drawable/google_new_dark_38.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_dark_39.xml b/app/src/main/res/drawable/google_new_dark_39.xml new file mode 100644 index 000000000..4e78472be --- /dev/null +++ b/app/src/main/res/drawable/google_new_dark_39.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_dark_4.xml b/app/src/main/res/drawable/google_new_dark_4.xml new file mode 100644 index 000000000..49f65ee0c --- /dev/null +++ b/app/src/main/res/drawable/google_new_dark_4.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_dark_40.xml b/app/src/main/res/drawable/google_new_dark_40.xml new file mode 100644 index 000000000..ec0d980ff --- /dev/null +++ b/app/src/main/res/drawable/google_new_dark_40.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_dark_41.xml b/app/src/main/res/drawable/google_new_dark_41.xml new file mode 100644 index 000000000..c2ef137f6 --- /dev/null +++ b/app/src/main/res/drawable/google_new_dark_41.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_dark_42.xml b/app/src/main/res/drawable/google_new_dark_42.xml new file mode 100644 index 000000000..c2ef137f6 --- /dev/null +++ b/app/src/main/res/drawable/google_new_dark_42.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_dark_43.xml b/app/src/main/res/drawable/google_new_dark_43.xml new file mode 100644 index 000000000..902f7fb6e --- /dev/null +++ b/app/src/main/res/drawable/google_new_dark_43.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_dark_44.xml b/app/src/main/res/drawable/google_new_dark_44.xml new file mode 100644 index 000000000..b257340c2 --- /dev/null +++ b/app/src/main/res/drawable/google_new_dark_44.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_dark_45.xml b/app/src/main/res/drawable/google_new_dark_45.xml new file mode 100644 index 000000000..49f65ee0c --- /dev/null +++ b/app/src/main/res/drawable/google_new_dark_45.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_dark_46.xml b/app/src/main/res/drawable/google_new_dark_46.xml new file mode 100644 index 000000000..4f3c7bd68 --- /dev/null +++ b/app/src/main/res/drawable/google_new_dark_46.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_dark_47.xml b/app/src/main/res/drawable/google_new_dark_47.xml new file mode 100644 index 000000000..de5d4dc74 --- /dev/null +++ b/app/src/main/res/drawable/google_new_dark_47.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_dark_5.xml b/app/src/main/res/drawable/google_new_dark_5.xml new file mode 100644 index 000000000..5e7cdf71c --- /dev/null +++ b/app/src/main/res/drawable/google_new_dark_5.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_dark_6.xml b/app/src/main/res/drawable/google_new_dark_6.xml new file mode 100644 index 000000000..5e7cdf71c --- /dev/null +++ b/app/src/main/res/drawable/google_new_dark_6.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_dark_7.xml b/app/src/main/res/drawable/google_new_dark_7.xml new file mode 100644 index 000000000..aeaf1e9a8 --- /dev/null +++ b/app/src/main/res/drawable/google_new_dark_7.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_dark_8.xml b/app/src/main/res/drawable/google_new_dark_8.xml new file mode 100644 index 000000000..cc20489ac --- /dev/null +++ b/app/src/main/res/drawable/google_new_dark_8.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_dark_9.xml b/app/src/main/res/drawable/google_new_dark_9.xml new file mode 100644 index 000000000..3c920bd27 --- /dev/null +++ b/app/src/main/res/drawable/google_new_dark_9.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_dark_na.xml b/app/src/main/res/drawable/google_new_dark_na.xml new file mode 100644 index 000000000..e51d0ff18 --- /dev/null +++ b/app/src/main/res/drawable/google_new_dark_na.xml @@ -0,0 +1,7 @@ + + + diff --git a/app/src/main/res/drawable/google_new_light_0.xml b/app/src/main/res/drawable/google_new_light_0.xml new file mode 100644 index 000000000..e4d74e2cf --- /dev/null +++ b/app/src/main/res/drawable/google_new_light_0.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_light_1.xml b/app/src/main/res/drawable/google_new_light_1.xml new file mode 100644 index 000000000..496148864 --- /dev/null +++ b/app/src/main/res/drawable/google_new_light_1.xml @@ -0,0 +1,23 @@ + + + + + + diff --git a/app/src/main/res/drawable/google_new_light_10.xml b/app/src/main/res/drawable/google_new_light_10.xml new file mode 100644 index 000000000..af5cd5a27 --- /dev/null +++ b/app/src/main/res/drawable/google_new_light_10.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_light_11.xml b/app/src/main/res/drawable/google_new_light_11.xml new file mode 100644 index 000000000..4c46d95a6 --- /dev/null +++ b/app/src/main/res/drawable/google_new_light_11.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_light_12.xml b/app/src/main/res/drawable/google_new_light_12.xml new file mode 100644 index 000000000..422a7f449 --- /dev/null +++ b/app/src/main/res/drawable/google_new_light_12.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_light_13.xml b/app/src/main/res/drawable/google_new_light_13.xml new file mode 100644 index 000000000..2efbe0721 --- /dev/null +++ b/app/src/main/res/drawable/google_new_light_13.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_light_14.xml b/app/src/main/res/drawable/google_new_light_14.xml new file mode 100644 index 000000000..2efbe0721 --- /dev/null +++ b/app/src/main/res/drawable/google_new_light_14.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_light_15.xml b/app/src/main/res/drawable/google_new_light_15.xml new file mode 100644 index 000000000..2efbe0721 --- /dev/null +++ b/app/src/main/res/drawable/google_new_light_15.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_light_16.xml b/app/src/main/res/drawable/google_new_light_16.xml new file mode 100644 index 000000000..2efbe0721 --- /dev/null +++ b/app/src/main/res/drawable/google_new_light_16.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_light_17.xml b/app/src/main/res/drawable/google_new_light_17.xml new file mode 100644 index 000000000..3cb2b1717 --- /dev/null +++ b/app/src/main/res/drawable/google_new_light_17.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_light_18.xml b/app/src/main/res/drawable/google_new_light_18.xml new file mode 100644 index 000000000..4e3d5423b --- /dev/null +++ b/app/src/main/res/drawable/google_new_light_18.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_light_19.xml b/app/src/main/res/drawable/google_new_light_19.xml new file mode 100644 index 000000000..6b19f1607 --- /dev/null +++ b/app/src/main/res/drawable/google_new_light_19.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/google_new_light_2.xml b/app/src/main/res/drawable/google_new_light_2.xml new file mode 100644 index 000000000..496148864 --- /dev/null +++ b/app/src/main/res/drawable/google_new_light_2.xml @@ -0,0 +1,23 @@ + + + + + + diff --git a/app/src/main/res/drawable/google_new_light_20.xml b/app/src/main/res/drawable/google_new_light_20.xml new file mode 100644 index 000000000..6b19f1607 --- /dev/null +++ b/app/src/main/res/drawable/google_new_light_20.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/google_new_light_21.xml b/app/src/main/res/drawable/google_new_light_21.xml new file mode 100644 index 000000000..6b19f1607 --- /dev/null +++ b/app/src/main/res/drawable/google_new_light_21.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/google_new_light_22.xml b/app/src/main/res/drawable/google_new_light_22.xml new file mode 100644 index 000000000..6b19f1607 --- /dev/null +++ b/app/src/main/res/drawable/google_new_light_22.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/google_new_light_23.xml b/app/src/main/res/drawable/google_new_light_23.xml new file mode 100644 index 000000000..29f8fdad7 --- /dev/null +++ b/app/src/main/res/drawable/google_new_light_23.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/google_new_light_24.xml b/app/src/main/res/drawable/google_new_light_24.xml new file mode 100644 index 000000000..29f8fdad7 --- /dev/null +++ b/app/src/main/res/drawable/google_new_light_24.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/google_new_light_25.xml b/app/src/main/res/drawable/google_new_light_25.xml new file mode 100644 index 000000000..fbbb9fbc5 --- /dev/null +++ b/app/src/main/res/drawable/google_new_light_25.xml @@ -0,0 +1,27 @@ + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_light_26.xml b/app/src/main/res/drawable/google_new_light_26.xml new file mode 100644 index 000000000..e14f8bfc7 --- /dev/null +++ b/app/src/main/res/drawable/google_new_light_26.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_light_27.xml b/app/src/main/res/drawable/google_new_light_27.xml new file mode 100644 index 000000000..ed8cde424 --- /dev/null +++ b/app/src/main/res/drawable/google_new_light_27.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_light_28.xml b/app/src/main/res/drawable/google_new_light_28.xml new file mode 100644 index 000000000..4efc08996 --- /dev/null +++ b/app/src/main/res/drawable/google_new_light_28.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_light_29.xml b/app/src/main/res/drawable/google_new_light_29.xml new file mode 100644 index 000000000..8068be87c --- /dev/null +++ b/app/src/main/res/drawable/google_new_light_29.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_light_3.xml b/app/src/main/res/drawable/google_new_light_3.xml new file mode 100644 index 000000000..8c802f89a --- /dev/null +++ b/app/src/main/res/drawable/google_new_light_3.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_light_30.xml b/app/src/main/res/drawable/google_new_light_30.xml new file mode 100644 index 000000000..86a17cbb1 --- /dev/null +++ b/app/src/main/res/drawable/google_new_light_30.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_light_31.xml b/app/src/main/res/drawable/google_new_light_31.xml new file mode 100644 index 000000000..79cc0e15a --- /dev/null +++ b/app/src/main/res/drawable/google_new_light_31.xml @@ -0,0 +1,22 @@ + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_light_32.xml b/app/src/main/res/drawable/google_new_light_32.xml new file mode 100644 index 000000000..1f43ea4d5 --- /dev/null +++ b/app/src/main/res/drawable/google_new_light_32.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_light_33.xml b/app/src/main/res/drawable/google_new_light_33.xml new file mode 100644 index 000000000..be9da9b10 --- /dev/null +++ b/app/src/main/res/drawable/google_new_light_33.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_light_34.xml b/app/src/main/res/drawable/google_new_light_34.xml new file mode 100644 index 000000000..5bc97810f --- /dev/null +++ b/app/src/main/res/drawable/google_new_light_34.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_light_35.xml b/app/src/main/res/drawable/google_new_light_35.xml new file mode 100644 index 000000000..8c802f89a --- /dev/null +++ b/app/src/main/res/drawable/google_new_light_35.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_light_36.xml b/app/src/main/res/drawable/google_new_light_36.xml new file mode 100644 index 000000000..863eefde5 --- /dev/null +++ b/app/src/main/res/drawable/google_new_light_36.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_light_37.xml b/app/src/main/res/drawable/google_new_light_37.xml new file mode 100644 index 000000000..27649d778 --- /dev/null +++ b/app/src/main/res/drawable/google_new_light_37.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_light_38.xml b/app/src/main/res/drawable/google_new_light_38.xml new file mode 100644 index 000000000..27649d778 --- /dev/null +++ b/app/src/main/res/drawable/google_new_light_38.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_light_39.xml b/app/src/main/res/drawable/google_new_light_39.xml new file mode 100644 index 000000000..27649d778 --- /dev/null +++ b/app/src/main/res/drawable/google_new_light_39.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_light_4.xml b/app/src/main/res/drawable/google_new_light_4.xml new file mode 100644 index 000000000..8c802f89a --- /dev/null +++ b/app/src/main/res/drawable/google_new_light_4.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_light_40.xml b/app/src/main/res/drawable/google_new_light_40.xml new file mode 100644 index 000000000..1a7aa8d11 --- /dev/null +++ b/app/src/main/res/drawable/google_new_light_40.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_light_41.xml b/app/src/main/res/drawable/google_new_light_41.xml new file mode 100644 index 000000000..ec7f66141 --- /dev/null +++ b/app/src/main/res/drawable/google_new_light_41.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_light_42.xml b/app/src/main/res/drawable/google_new_light_42.xml new file mode 100644 index 000000000..ec7f66141 --- /dev/null +++ b/app/src/main/res/drawable/google_new_light_42.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_light_43.xml b/app/src/main/res/drawable/google_new_light_43.xml new file mode 100644 index 000000000..5bc97810f --- /dev/null +++ b/app/src/main/res/drawable/google_new_light_43.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_light_44.xml b/app/src/main/res/drawable/google_new_light_44.xml new file mode 100644 index 000000000..be9da9b10 --- /dev/null +++ b/app/src/main/res/drawable/google_new_light_44.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_light_45.xml b/app/src/main/res/drawable/google_new_light_45.xml new file mode 100644 index 000000000..8c802f89a --- /dev/null +++ b/app/src/main/res/drawable/google_new_light_45.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_light_46.xml b/app/src/main/res/drawable/google_new_light_46.xml new file mode 100644 index 000000000..01228732f --- /dev/null +++ b/app/src/main/res/drawable/google_new_light_46.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_light_47.xml b/app/src/main/res/drawable/google_new_light_47.xml new file mode 100644 index 000000000..3baee5de7 --- /dev/null +++ b/app/src/main/res/drawable/google_new_light_47.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_light_5.xml b/app/src/main/res/drawable/google_new_light_5.xml new file mode 100644 index 000000000..8609df59b --- /dev/null +++ b/app/src/main/res/drawable/google_new_light_5.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_light_6.xml b/app/src/main/res/drawable/google_new_light_6.xml new file mode 100644 index 000000000..8609df59b --- /dev/null +++ b/app/src/main/res/drawable/google_new_light_6.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_light_7.xml b/app/src/main/res/drawable/google_new_light_7.xml new file mode 100644 index 000000000..2efbe0721 --- /dev/null +++ b/app/src/main/res/drawable/google_new_light_7.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_light_8.xml b/app/src/main/res/drawable/google_new_light_8.xml new file mode 100644 index 000000000..af5cd5a27 --- /dev/null +++ b/app/src/main/res/drawable/google_new_light_8.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_light_9.xml b/app/src/main/res/drawable/google_new_light_9.xml new file mode 100644 index 000000000..f37aa5813 --- /dev/null +++ b/app/src/main/res/drawable/google_new_light_9.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/google_new_light_na.xml b/app/src/main/res/drawable/google_new_light_na.xml new file mode 100644 index 000000000..e51d0ff18 --- /dev/null +++ b/app/src/main/res/drawable/google_new_light_na.xml @@ -0,0 +1,7 @@ + + + diff --git a/app/src/main/res/drawable/ic_bluetooth_connected.xml b/app/src/main/res/drawable/ic_bluetooth_connected.xml new file mode 100644 index 000000000..49a2084df --- /dev/null +++ b/app/src/main/res/drawable/ic_bluetooth_connected.xml @@ -0,0 +1,30 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_bluetooth_disconnected.xml b/app/src/main/res/drawable/ic_bluetooth_disconnected.xml new file mode 100644 index 000000000..37c0c2032 --- /dev/null +++ b/app/src/main/res/drawable/ic_bluetooth_disconnected.xml @@ -0,0 +1,25 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_calculator.xml b/app/src/main/res/drawable/ic_calculator.xml new file mode 100644 index 000000000..7b957f0c1 --- /dev/null +++ b/app/src/main/res/drawable/ic_calculator.xml @@ -0,0 +1,62 @@ + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_chevron_end.xml b/app/src/main/res/drawable/ic_chevron_end.xml new file mode 100644 index 000000000..e0ab14f04 --- /dev/null +++ b/app/src/main/res/drawable/ic_chevron_end.xml @@ -0,0 +1,26 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_clear.xml b/app/src/main/res/drawable/ic_clear.xml new file mode 100644 index 000000000..46bbe1c1d --- /dev/null +++ b/app/src/main/res/drawable/ic_clear.xml @@ -0,0 +1,15 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_history.xml b/app/src/main/res/drawable/ic_history.xml new file mode 100644 index 000000000..09c1757b2 --- /dev/null +++ b/app/src/main/res/drawable/ic_history.xml @@ -0,0 +1,11 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_info_duotone.xml b/app/src/main/res/drawable/ic_info_duotone.xml new file mode 100644 index 000000000..bca772290 --- /dev/null +++ b/app/src/main/res/drawable/ic_info_duotone.xml @@ -0,0 +1,16 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_op_media_player_action_next.xml b/app/src/main/res/drawable/ic_op_media_player_action_next.xml new file mode 100644 index 000000000..ed693c90e --- /dev/null +++ b/app/src/main/res/drawable/ic_op_media_player_action_next.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_op_media_player_action_pause.xml b/app/src/main/res/drawable/ic_op_media_player_action_pause.xml new file mode 100644 index 000000000..a062141c4 --- /dev/null +++ b/app/src/main/res/drawable/ic_op_media_player_action_pause.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_op_media_player_action_play.xml b/app/src/main/res/drawable/ic_op_media_player_action_play.xml new file mode 100644 index 000000000..159c04650 --- /dev/null +++ b/app/src/main/res/drawable/ic_op_media_player_action_play.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_op_media_player_action_prev.xml b/app/src/main/res/drawable/ic_op_media_player_action_prev.xml new file mode 100644 index 000000000..3ecb64634 --- /dev/null +++ b/app/src/main/res/drawable/ic_op_media_player_action_prev.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_op_media_player_icon.xml b/app/src/main/res/drawable/ic_op_media_player_icon.xml new file mode 100644 index 000000000..c1c1429e3 --- /dev/null +++ b/app/src/main/res/drawable/ic_op_media_player_icon.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_op_media_player_output_switcher.xml b/app/src/main/res/drawable/ic_op_media_player_output_switcher.xml new file mode 100644 index 000000000..e845fdbdc --- /dev/null +++ b/app/src/main/res/drawable/ic_op_media_player_output_switcher.xml @@ -0,0 +1,14 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_qs_wifi_disconnected.xml b/app/src/main/res/drawable/ic_qs_wifi_disconnected.xml new file mode 100644 index 000000000..90cc9c396 --- /dev/null +++ b/app/src/main/res/drawable/ic_qs_wifi_disconnected.xml @@ -0,0 +1,33 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_search.xml b/app/src/main/res/drawable/ic_search.xml new file mode 100644 index 000000000..51f9113b3 --- /dev/null +++ b/app/src/main/res/drawable/ic_search.xml @@ -0,0 +1,21 @@ + + + + diff --git a/app/src/main/res/drawable/ic_translate.xml b/app/src/main/res/drawable/ic_translate.xml new file mode 100644 index 000000000..98ab722a2 --- /dev/null +++ b/app/src/main/res/drawable/ic_translate.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_vibrate.xml b/app/src/main/res/drawable/ic_vibrate.xml new file mode 100644 index 000000000..b26fc7913 --- /dev/null +++ b/app/src/main/res/drawable/ic_vibrate.xml @@ -0,0 +1,7 @@ + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_wind.xml b/app/src/main/res/drawable/ic_wind.xml new file mode 100644 index 000000000..363840af6 --- /dev/null +++ b/app/src/main/res/drawable/ic_wind.xml @@ -0,0 +1,24 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_xposed_lockscreen_weather.xml b/app/src/main/res/drawable/ic_xposed_lockscreen_weather.xml new file mode 100644 index 000000000..fa68fe1f3 --- /dev/null +++ b/app/src/main/res/drawable/ic_xposed_lockscreen_weather.xml @@ -0,0 +1,20 @@ + + + + diff --git a/app/src/main/res/drawable/ic_xposed_op_qs_header.xml b/app/src/main/res/drawable/ic_xposed_op_qs_header.xml new file mode 100644 index 000000000..f02463a07 --- /dev/null +++ b/app/src/main/res/drawable/ic_xposed_op_qs_header.xml @@ -0,0 +1,41 @@ + + + + + + + diff --git a/app/src/main/res/drawable/ios_widget_line_progress_track.xml b/app/src/main/res/drawable/ios_widget_line_progress_track.xml index fbdcc88d5..af6605a92 100644 --- a/app/src/main/res/drawable/ios_widget_line_progress_track.xml +++ b/app/src/main/res/drawable/ios_widget_line_progress_track.xml @@ -4,8 +4,8 @@ - - + + diff --git a/app/src/main/res/drawable/lockscreen_widget_background_circle.xml b/app/src/main/res/drawable/lockscreen_widget_background_circle.xml new file mode 100644 index 000000000..1504ef9d7 --- /dev/null +++ b/app/src/main/res/drawable/lockscreen_widget_background_circle.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/outline_0.xml b/app/src/main/res/drawable/outline_0.xml new file mode 100644 index 000000000..13912e97b --- /dev/null +++ b/app/src/main/res/drawable/outline_0.xml @@ -0,0 +1,44 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/outline_1.xml b/app/src/main/res/drawable/outline_1.xml new file mode 100644 index 000000000..df37551b0 --- /dev/null +++ b/app/src/main/res/drawable/outline_1.xml @@ -0,0 +1,50 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/outline_10.xml b/app/src/main/res/drawable/outline_10.xml new file mode 100644 index 000000000..3519f4725 --- /dev/null +++ b/app/src/main/res/drawable/outline_10.xml @@ -0,0 +1,76 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/outline_11.xml b/app/src/main/res/drawable/outline_11.xml new file mode 100644 index 000000000..f55a2773c --- /dev/null +++ b/app/src/main/res/drawable/outline_11.xml @@ -0,0 +1,102 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/outline_12.xml b/app/src/main/res/drawable/outline_12.xml new file mode 100644 index 000000000..89fb6f492 --- /dev/null +++ b/app/src/main/res/drawable/outline_12.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/outline_13.xml b/app/src/main/res/drawable/outline_13.xml new file mode 100644 index 000000000..28e7cedc8 --- /dev/null +++ b/app/src/main/res/drawable/outline_13.xml @@ -0,0 +1,82 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/outline_14.xml b/app/src/main/res/drawable/outline_14.xml new file mode 100644 index 000000000..fb2d5df47 --- /dev/null +++ b/app/src/main/res/drawable/outline_14.xml @@ -0,0 +1,92 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/outline_15.xml b/app/src/main/res/drawable/outline_15.xml new file mode 100644 index 000000000..a47dd6e5c --- /dev/null +++ b/app/src/main/res/drawable/outline_15.xml @@ -0,0 +1,133 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/outline_16.xml b/app/src/main/res/drawable/outline_16.xml new file mode 100644 index 000000000..fb2d5df47 --- /dev/null +++ b/app/src/main/res/drawable/outline_16.xml @@ -0,0 +1,92 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/outline_17.xml b/app/src/main/res/drawable/outline_17.xml new file mode 100644 index 000000000..5eb035803 --- /dev/null +++ b/app/src/main/res/drawable/outline_17.xml @@ -0,0 +1,99 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/outline_18.xml b/app/src/main/res/drawable/outline_18.xml new file mode 100644 index 000000000..3519f4725 --- /dev/null +++ b/app/src/main/res/drawable/outline_18.xml @@ -0,0 +1,76 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/outline_19.xml b/app/src/main/res/drawable/outline_19.xml new file mode 100644 index 000000000..f75464b1b --- /dev/null +++ b/app/src/main/res/drawable/outline_19.xml @@ -0,0 +1,25 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/outline_2.xml b/app/src/main/res/drawable/outline_2.xml new file mode 100644 index 000000000..13912e97b --- /dev/null +++ b/app/src/main/res/drawable/outline_2.xml @@ -0,0 +1,44 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/outline_20.xml b/app/src/main/res/drawable/outline_20.xml new file mode 100644 index 000000000..f75464b1b --- /dev/null +++ b/app/src/main/res/drawable/outline_20.xml @@ -0,0 +1,25 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/outline_21.xml b/app/src/main/res/drawable/outline_21.xml new file mode 100644 index 000000000..f75464b1b --- /dev/null +++ b/app/src/main/res/drawable/outline_21.xml @@ -0,0 +1,25 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/outline_22.xml b/app/src/main/res/drawable/outline_22.xml new file mode 100644 index 000000000..f75464b1b --- /dev/null +++ b/app/src/main/res/drawable/outline_22.xml @@ -0,0 +1,25 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/outline_23.xml b/app/src/main/res/drawable/outline_23.xml new file mode 100644 index 000000000..f75464b1b --- /dev/null +++ b/app/src/main/res/drawable/outline_23.xml @@ -0,0 +1,25 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/outline_24.xml b/app/src/main/res/drawable/outline_24.xml new file mode 100644 index 000000000..13912e97b --- /dev/null +++ b/app/src/main/res/drawable/outline_24.xml @@ -0,0 +1,44 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/outline_25.xml b/app/src/main/res/drawable/outline_25.xml new file mode 100644 index 000000000..296b513fa --- /dev/null +++ b/app/src/main/res/drawable/outline_25.xml @@ -0,0 +1,44 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/outline_26.xml b/app/src/main/res/drawable/outline_26.xml new file mode 100644 index 000000000..97bf72758 --- /dev/null +++ b/app/src/main/res/drawable/outline_26.xml @@ -0,0 +1,54 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/outline_27.xml b/app/src/main/res/drawable/outline_27.xml new file mode 100644 index 000000000..8ef23dd1d --- /dev/null +++ b/app/src/main/res/drawable/outline_27.xml @@ -0,0 +1,53 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/outline_28.xml b/app/src/main/res/drawable/outline_28.xml new file mode 100644 index 000000000..8ef23dd1d --- /dev/null +++ b/app/src/main/res/drawable/outline_28.xml @@ -0,0 +1,53 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/outline_29.xml b/app/src/main/res/drawable/outline_29.xml new file mode 100644 index 000000000..bfbb66d42 --- /dev/null +++ b/app/src/main/res/drawable/outline_29.xml @@ -0,0 +1,45 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/outline_3.xml b/app/src/main/res/drawable/outline_3.xml new file mode 100644 index 000000000..df37551b0 --- /dev/null +++ b/app/src/main/res/drawable/outline_3.xml @@ -0,0 +1,50 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/outline_30.xml b/app/src/main/res/drawable/outline_30.xml new file mode 100644 index 000000000..d77cf1f01 --- /dev/null +++ b/app/src/main/res/drawable/outline_30.xml @@ -0,0 +1,113 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/outline_31.xml b/app/src/main/res/drawable/outline_31.xml new file mode 100644 index 000000000..c17731fb3 --- /dev/null +++ b/app/src/main/res/drawable/outline_31.xml @@ -0,0 +1,19 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/outline_32.xml b/app/src/main/res/drawable/outline_32.xml new file mode 100644 index 000000000..36ea58e56 --- /dev/null +++ b/app/src/main/res/drawable/outline_32.xml @@ -0,0 +1,113 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/outline_33.xml b/app/src/main/res/drawable/outline_33.xml new file mode 100644 index 000000000..c17731fb3 --- /dev/null +++ b/app/src/main/res/drawable/outline_33.xml @@ -0,0 +1,19 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/outline_34.xml b/app/src/main/res/drawable/outline_34.xml new file mode 100644 index 000000000..36ea58e56 --- /dev/null +++ b/app/src/main/res/drawable/outline_34.xml @@ -0,0 +1,113 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/outline_35.xml b/app/src/main/res/drawable/outline_35.xml new file mode 100644 index 000000000..3519f4725 --- /dev/null +++ b/app/src/main/res/drawable/outline_35.xml @@ -0,0 +1,76 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/outline_36.xml b/app/src/main/res/drawable/outline_36.xml new file mode 100644 index 000000000..296b513fa --- /dev/null +++ b/app/src/main/res/drawable/outline_36.xml @@ -0,0 +1,44 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/outline_37.xml b/app/src/main/res/drawable/outline_37.xml new file mode 100644 index 000000000..302b87c7c --- /dev/null +++ b/app/src/main/res/drawable/outline_37.xml @@ -0,0 +1,140 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/outline_38.xml b/app/src/main/res/drawable/outline_38.xml new file mode 100644 index 000000000..302b87c7c --- /dev/null +++ b/app/src/main/res/drawable/outline_38.xml @@ -0,0 +1,140 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/outline_39.xml b/app/src/main/res/drawable/outline_39.xml new file mode 100644 index 000000000..302b87c7c --- /dev/null +++ b/app/src/main/res/drawable/outline_39.xml @@ -0,0 +1,140 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/outline_4.xml b/app/src/main/res/drawable/outline_4.xml new file mode 100644 index 000000000..df37551b0 --- /dev/null +++ b/app/src/main/res/drawable/outline_4.xml @@ -0,0 +1,50 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/outline_40.xml b/app/src/main/res/drawable/outline_40.xml new file mode 100644 index 000000000..bf890a130 --- /dev/null +++ b/app/src/main/res/drawable/outline_40.xml @@ -0,0 +1,70 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/outline_41.xml b/app/src/main/res/drawable/outline_41.xml new file mode 100644 index 000000000..a47dd6e5c --- /dev/null +++ b/app/src/main/res/drawable/outline_41.xml @@ -0,0 +1,133 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/outline_42.xml b/app/src/main/res/drawable/outline_42.xml new file mode 100644 index 000000000..fb2d5df47 --- /dev/null +++ b/app/src/main/res/drawable/outline_42.xml @@ -0,0 +1,92 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/outline_43.xml b/app/src/main/res/drawable/outline_43.xml new file mode 100644 index 000000000..a47dd6e5c --- /dev/null +++ b/app/src/main/res/drawable/outline_43.xml @@ -0,0 +1,133 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/outline_44.xml b/app/src/main/res/drawable/outline_44.xml new file mode 100644 index 000000000..8e44b2491 --- /dev/null +++ b/app/src/main/res/drawable/outline_44.xml @@ -0,0 +1,113 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/outline_45.xml b/app/src/main/res/drawable/outline_45.xml new file mode 100644 index 000000000..302b87c7c --- /dev/null +++ b/app/src/main/res/drawable/outline_45.xml @@ -0,0 +1,140 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/outline_46.xml b/app/src/main/res/drawable/outline_46.xml new file mode 100644 index 000000000..fcb6804b7 --- /dev/null +++ b/app/src/main/res/drawable/outline_46.xml @@ -0,0 +1,106 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/outline_47.xml b/app/src/main/res/drawable/outline_47.xml new file mode 100644 index 000000000..302b87c7c --- /dev/null +++ b/app/src/main/res/drawable/outline_47.xml @@ -0,0 +1,140 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/outline_5.xml b/app/src/main/res/drawable/outline_5.xml new file mode 100644 index 000000000..fcb6804b7 --- /dev/null +++ b/app/src/main/res/drawable/outline_5.xml @@ -0,0 +1,106 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/outline_6.xml b/app/src/main/res/drawable/outline_6.xml new file mode 100644 index 000000000..fcb6804b7 --- /dev/null +++ b/app/src/main/res/drawable/outline_6.xml @@ -0,0 +1,106 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/outline_7.xml b/app/src/main/res/drawable/outline_7.xml new file mode 100644 index 000000000..fcb6804b7 --- /dev/null +++ b/app/src/main/res/drawable/outline_7.xml @@ -0,0 +1,106 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/outline_8.xml b/app/src/main/res/drawable/outline_8.xml new file mode 100644 index 000000000..522c724f2 --- /dev/null +++ b/app/src/main/res/drawable/outline_8.xml @@ -0,0 +1,82 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/outline_9.xml b/app/src/main/res/drawable/outline_9.xml new file mode 100644 index 000000000..5eb035803 --- /dev/null +++ b/app/src/main/res/drawable/outline_9.xml @@ -0,0 +1,99 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/outline_na.xml b/app/src/main/res/drawable/outline_na.xml new file mode 100644 index 000000000..31f593206 --- /dev/null +++ b/app/src/main/res/drawable/outline_na.xml @@ -0,0 +1,30 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/preview_lockscreen_clock_10_background.xml b/app/src/main/res/drawable/preview_lockscreen_clock_10_background.xml new file mode 100644 index 000000000..4bb6329a1 --- /dev/null +++ b/app/src/main/res/drawable/preview_lockscreen_clock_10_background.xml @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/search_hint_color.xml b/app/src/main/res/drawable/search_hint_color.xml new file mode 100644 index 000000000..ba37c27a8 --- /dev/null +++ b/app/src/main/res/drawable/search_hint_color.xml @@ -0,0 +1,20 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/text_field_corners.xml b/app/src/main/res/drawable/text_field_corners.xml new file mode 100644 index 000000000..3034c1bce --- /dev/null +++ b/app/src/main/res/drawable/text_field_corners.xml @@ -0,0 +1,9 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/time_container_background.xml b/app/src/main/res/drawable/time_container_background.xml new file mode 100644 index 000000000..6fad4b371 --- /dev/null +++ b/app/src/main/res/drawable/time_container_background.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/weatherclient_0.xml b/app/src/main/res/drawable/weatherclient_0.xml new file mode 100644 index 000000000..344a6f4ba --- /dev/null +++ b/app/src/main/res/drawable/weatherclient_0.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/weatherclient_1.xml b/app/src/main/res/drawable/weatherclient_1.xml new file mode 100644 index 000000000..344a6f4ba --- /dev/null +++ b/app/src/main/res/drawable/weatherclient_1.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/weatherclient_10.xml b/app/src/main/res/drawable/weatherclient_10.xml new file mode 100644 index 000000000..35415f66f --- /dev/null +++ b/app/src/main/res/drawable/weatherclient_10.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/weatherclient_11.xml b/app/src/main/res/drawable/weatherclient_11.xml new file mode 100644 index 000000000..13fe25cf7 --- /dev/null +++ b/app/src/main/res/drawable/weatherclient_11.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/weatherclient_12.xml b/app/src/main/res/drawable/weatherclient_12.xml new file mode 100644 index 000000000..13fe25cf7 --- /dev/null +++ b/app/src/main/res/drawable/weatherclient_12.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/weatherclient_13.xml b/app/src/main/res/drawable/weatherclient_13.xml new file mode 100644 index 000000000..35415f66f --- /dev/null +++ b/app/src/main/res/drawable/weatherclient_13.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/weatherclient_14.xml b/app/src/main/res/drawable/weatherclient_14.xml new file mode 100644 index 000000000..35415f66f --- /dev/null +++ b/app/src/main/res/drawable/weatherclient_14.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/weatherclient_15.xml b/app/src/main/res/drawable/weatherclient_15.xml new file mode 100644 index 000000000..35415f66f --- /dev/null +++ b/app/src/main/res/drawable/weatherclient_15.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/weatherclient_16.xml b/app/src/main/res/drawable/weatherclient_16.xml new file mode 100644 index 000000000..35415f66f --- /dev/null +++ b/app/src/main/res/drawable/weatherclient_16.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/weatherclient_17.xml b/app/src/main/res/drawable/weatherclient_17.xml new file mode 100644 index 000000000..35415f66f --- /dev/null +++ b/app/src/main/res/drawable/weatherclient_17.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/weatherclient_18.xml b/app/src/main/res/drawable/weatherclient_18.xml new file mode 100644 index 000000000..35415f66f --- /dev/null +++ b/app/src/main/res/drawable/weatherclient_18.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/weatherclient_19.xml b/app/src/main/res/drawable/weatherclient_19.xml new file mode 100644 index 000000000..c9d56b9f5 --- /dev/null +++ b/app/src/main/res/drawable/weatherclient_19.xml @@ -0,0 +1,26 @@ + + + + + + diff --git a/app/src/main/res/drawable/weatherclient_20.xml b/app/src/main/res/drawable/weatherclient_20.xml new file mode 100644 index 000000000..c9d56b9f5 --- /dev/null +++ b/app/src/main/res/drawable/weatherclient_20.xml @@ -0,0 +1,26 @@ + + + + + + diff --git a/app/src/main/res/drawable/weatherclient_21.xml b/app/src/main/res/drawable/weatherclient_21.xml new file mode 100644 index 000000000..c9d56b9f5 --- /dev/null +++ b/app/src/main/res/drawable/weatherclient_21.xml @@ -0,0 +1,26 @@ + + + + + + diff --git a/app/src/main/res/drawable/weatherclient_22.xml b/app/src/main/res/drawable/weatherclient_22.xml new file mode 100644 index 000000000..c9d56b9f5 --- /dev/null +++ b/app/src/main/res/drawable/weatherclient_22.xml @@ -0,0 +1,26 @@ + + + + + + diff --git a/app/src/main/res/drawable/weatherclient_23.xml b/app/src/main/res/drawable/weatherclient_23.xml new file mode 100644 index 000000000..f6c07c144 --- /dev/null +++ b/app/src/main/res/drawable/weatherclient_23.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/weatherclient_24.xml b/app/src/main/res/drawable/weatherclient_24.xml new file mode 100644 index 000000000..f6c07c144 --- /dev/null +++ b/app/src/main/res/drawable/weatherclient_24.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/weatherclient_25.xml b/app/src/main/res/drawable/weatherclient_25.xml new file mode 100644 index 000000000..c2346c238 --- /dev/null +++ b/app/src/main/res/drawable/weatherclient_25.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/weatherclient_26.xml b/app/src/main/res/drawable/weatherclient_26.xml new file mode 100644 index 000000000..7442cf883 --- /dev/null +++ b/app/src/main/res/drawable/weatherclient_26.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/weatherclient_27.xml b/app/src/main/res/drawable/weatherclient_27.xml new file mode 100644 index 000000000..f63eb2cfd --- /dev/null +++ b/app/src/main/res/drawable/weatherclient_27.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/weatherclient_28.xml b/app/src/main/res/drawable/weatherclient_28.xml new file mode 100644 index 000000000..b495aeaaf --- /dev/null +++ b/app/src/main/res/drawable/weatherclient_28.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/weatherclient_29.xml b/app/src/main/res/drawable/weatherclient_29.xml new file mode 100644 index 000000000..a47ef9cba --- /dev/null +++ b/app/src/main/res/drawable/weatherclient_29.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/weatherclient_3.xml b/app/src/main/res/drawable/weatherclient_3.xml new file mode 100644 index 000000000..344a6f4ba --- /dev/null +++ b/app/src/main/res/drawable/weatherclient_3.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/weatherclient_30.xml b/app/src/main/res/drawable/weatherclient_30.xml new file mode 100644 index 000000000..370f4115a --- /dev/null +++ b/app/src/main/res/drawable/weatherclient_30.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/weatherclient_31.xml b/app/src/main/res/drawable/weatherclient_31.xml new file mode 100644 index 000000000..681e433b9 --- /dev/null +++ b/app/src/main/res/drawable/weatherclient_31.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/weatherclient_32.xml b/app/src/main/res/drawable/weatherclient_32.xml new file mode 100644 index 000000000..4dc8be873 --- /dev/null +++ b/app/src/main/res/drawable/weatherclient_32.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + diff --git a/app/src/main/res/drawable/weatherclient_33.xml b/app/src/main/res/drawable/weatherclient_33.xml new file mode 100644 index 000000000..c4f341559 --- /dev/null +++ b/app/src/main/res/drawable/weatherclient_33.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/weatherclient_34.xml b/app/src/main/res/drawable/weatherclient_34.xml new file mode 100644 index 000000000..4dc8be873 --- /dev/null +++ b/app/src/main/res/drawable/weatherclient_34.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + diff --git a/app/src/main/res/drawable/weatherclient_35.xml b/app/src/main/res/drawable/weatherclient_35.xml new file mode 100644 index 000000000..344a6f4ba --- /dev/null +++ b/app/src/main/res/drawable/weatherclient_35.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/weatherclient_36.xml b/app/src/main/res/drawable/weatherclient_36.xml new file mode 100644 index 000000000..f5f13b181 --- /dev/null +++ b/app/src/main/res/drawable/weatherclient_36.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + diff --git a/app/src/main/res/drawable/weatherclient_37.xml b/app/src/main/res/drawable/weatherclient_37.xml new file mode 100644 index 000000000..338579d51 --- /dev/null +++ b/app/src/main/res/drawable/weatherclient_37.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/weatherclient_38.xml b/app/src/main/res/drawable/weatherclient_38.xml new file mode 100644 index 000000000..338579d51 --- /dev/null +++ b/app/src/main/res/drawable/weatherclient_38.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/weatherclient_39.xml b/app/src/main/res/drawable/weatherclient_39.xml new file mode 100644 index 000000000..338579d51 --- /dev/null +++ b/app/src/main/res/drawable/weatherclient_39.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/weatherclient_4.xml b/app/src/main/res/drawable/weatherclient_4.xml new file mode 100644 index 000000000..344a6f4ba --- /dev/null +++ b/app/src/main/res/drawable/weatherclient_4.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/weatherclient_40.xml b/app/src/main/res/drawable/weatherclient_40.xml new file mode 100644 index 000000000..762eea97e --- /dev/null +++ b/app/src/main/res/drawable/weatherclient_40.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/weatherclient_41.xml b/app/src/main/res/drawable/weatherclient_41.xml new file mode 100644 index 000000000..35415f66f --- /dev/null +++ b/app/src/main/res/drawable/weatherclient_41.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/weatherclient_42.xml b/app/src/main/res/drawable/weatherclient_42.xml new file mode 100644 index 000000000..35415f66f --- /dev/null +++ b/app/src/main/res/drawable/weatherclient_42.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/weatherclient_43.xml b/app/src/main/res/drawable/weatherclient_43.xml new file mode 100644 index 000000000..370f4115a --- /dev/null +++ b/app/src/main/res/drawable/weatherclient_43.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/weatherclient_44.xml b/app/src/main/res/drawable/weatherclient_44.xml new file mode 100644 index 000000000..370f4115a --- /dev/null +++ b/app/src/main/res/drawable/weatherclient_44.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/weatherclient_45.xml b/app/src/main/res/drawable/weatherclient_45.xml new file mode 100644 index 000000000..344a6f4ba --- /dev/null +++ b/app/src/main/res/drawable/weatherclient_45.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/weatherclient_46.xml b/app/src/main/res/drawable/weatherclient_46.xml new file mode 100644 index 000000000..35415f66f --- /dev/null +++ b/app/src/main/res/drawable/weatherclient_46.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/weatherclient_47.xml b/app/src/main/res/drawable/weatherclient_47.xml new file mode 100644 index 000000000..a020b6b16 --- /dev/null +++ b/app/src/main/res/drawable/weatherclient_47.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/weatherclient_5.xml b/app/src/main/res/drawable/weatherclient_5.xml new file mode 100644 index 000000000..344a6f4ba --- /dev/null +++ b/app/src/main/res/drawable/weatherclient_5.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/weatherclient_6.xml b/app/src/main/res/drawable/weatherclient_6.xml new file mode 100644 index 000000000..35415f66f --- /dev/null +++ b/app/src/main/res/drawable/weatherclient_6.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/weatherclient_7.xml b/app/src/main/res/drawable/weatherclient_7.xml new file mode 100644 index 000000000..35415f66f --- /dev/null +++ b/app/src/main/res/drawable/weatherclient_7.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/weatherclient_8.xml b/app/src/main/res/drawable/weatherclient_8.xml new file mode 100644 index 000000000..35415f66f --- /dev/null +++ b/app/src/main/res/drawable/weatherclient_8.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/weatherclient_9.xml b/app/src/main/res/drawable/weatherclient_9.xml new file mode 100644 index 000000000..13fe25cf7 --- /dev/null +++ b/app/src/main/res/drawable/weatherclient_9.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/weatherclient_na.xml b/app/src/main/res/drawable/weatherclient_na.xml new file mode 100644 index 000000000..9ba51aba5 --- /dev/null +++ b/app/src/main/res/drawable/weatherclient_na.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/font/consolas.otf b/app/src/main/res/font/consolas.otf new file mode 100644 index 000000000..af3db6789 Binary files /dev/null and b/app/src/main/res/font/consolas.otf differ diff --git a/app/src/main/res/layout/activity_home_page.xml b/app/src/main/res/layout/activity_home_page.xml deleted file mode 100644 index 0cc470b13..000000000 --- a/app/src/main/res/layout/activity_home_page.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 000000000..96d9e7c50 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,143 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/cpv_preference_circle.xml b/app/src/main/res/layout/cpv_preference_circle.xml new file mode 100644 index 000000000..875109bfe --- /dev/null +++ b/app/src/main/res/layout/cpv_preference_circle.xml @@ -0,0 +1,7 @@ + \ No newline at end of file diff --git a/app/src/main/res/layout/cpv_preference_circle_large.xml b/app/src/main/res/layout/cpv_preference_circle_large.xml new file mode 100644 index 000000000..4c3579592 --- /dev/null +++ b/app/src/main/res/layout/cpv_preference_circle_large.xml @@ -0,0 +1,7 @@ + \ No newline at end of file diff --git a/app/src/main/res/layout/cpv_preference_square.xml b/app/src/main/res/layout/cpv_preference_square.xml new file mode 100644 index 000000000..06f8f76d0 --- /dev/null +++ b/app/src/main/res/layout/cpv_preference_square.xml @@ -0,0 +1,7 @@ + \ No newline at end of file diff --git a/app/src/main/res/layout/cpv_preference_square_large.xml b/app/src/main/res/layout/cpv_preference_square_large.xml new file mode 100644 index 000000000..e8fa81aa6 --- /dev/null +++ b/app/src/main/res/layout/cpv_preference_square_large.xml @@ -0,0 +1,7 @@ + \ No newline at end of file diff --git a/app/src/main/res/layout/custom_preference_category.xml b/app/src/main/res/layout/custom_preference_category.xml new file mode 100644 index 000000000..413de72e5 --- /dev/null +++ b/app/src/main/res/layout/custom_preference_category.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/custom_preference_color.xml b/app/src/main/res/layout/custom_preference_color.xml new file mode 100644 index 000000000..062a58f93 --- /dev/null +++ b/app/src/main/res/layout/custom_preference_color.xml @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/custom_preference_edit_text.xml b/app/src/main/res/layout/custom_preference_edit_text.xml new file mode 100644 index 000000000..8b9357379 --- /dev/null +++ b/app/src/main/res/layout/custom_preference_edit_text.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/custom_preference_filepicker.xml b/app/src/main/res/layout/custom_preference_filepicker.xml new file mode 100644 index 000000000..be1ef8c7d --- /dev/null +++ b/app/src/main/res/layout/custom_preference_filepicker.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/custom_preference_list.xml b/app/src/main/res/layout/custom_preference_list.xml new file mode 100644 index 000000000..4019f5194 --- /dev/null +++ b/app/src/main/res/layout/custom_preference_list.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/custom_preference_menu.xml b/app/src/main/res/layout/custom_preference_menu.xml new file mode 100644 index 000000000..7707a5ab9 --- /dev/null +++ b/app/src/main/res/layout/custom_preference_menu.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/custom_preference_recyclerview.xml b/app/src/main/res/layout/custom_preference_recyclerview.xml new file mode 100644 index 000000000..ecdf031ff --- /dev/null +++ b/app/src/main/res/layout/custom_preference_recyclerview.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/custom_preference_slider.xml b/app/src/main/res/layout/custom_preference_slider.xml new file mode 100644 index 000000000..a96d75d13 --- /dev/null +++ b/app/src/main/res/layout/custom_preference_slider.xml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/custom_preference_switch.xml b/app/src/main/res/layout/custom_preference_switch.xml new file mode 100644 index 000000000..a37eae15f --- /dev/null +++ b/app/src/main/res/layout/custom_preference_switch.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/custom_preference_time_picker.xml b/app/src/main/res/layout/custom_preference_time_picker.xml new file mode 100644 index 000000000..9addadb37 --- /dev/null +++ b/app/src/main/res/layout/custom_preference_time_picker.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_app_updates.xml b/app/src/main/res/layout/fragment_app_updates.xml index 0c71550cc..b6f03ad1d 100644 --- a/app/src/main/res/layout/fragment_app_updates.xml +++ b/app/src/main/res/layout/fragment_app_updates.xml @@ -5,7 +5,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:clipChildren="false" - tools:context=".ui.fragments.AppUpdates"> + tools:context=".ui.fragments.settings.AppUpdates"> + tools:context=".ui.fragments.tweaks.BasicColors"> + tools:context=".ui.fragments.home.BrightnessBar"> + tools:context=".ui.fragments.home.BrightnessBarPixel"> + tools:context=".ui.fragments.settings.Changelog"> + tools:context=".ui.fragments.tweaks.ColorEngine"> + app:isChecked="true" + app:summaryText="@string/system_monet_desc" + app:titleText="@string/system_monet_title" /> diff --git a/app/src/main/res/layout/fragment_colored_battery.xml b/app/src/main/res/layout/fragment_colored_battery.xml index 1f39a6ef5..717002c20 100644 --- a/app/src/main/res/layout/fragment_colored_battery.xml +++ b/app/src/main/res/layout/fragment_colored_battery.xml @@ -5,7 +5,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:clipChildren="false" - tools:context=".ui.fragments.ColoredBattery"> + tools:context=".ui.fragments.tweaks.ColoredBattery"> + tools:context=".ui.fragments.settings.Credits"> - - - - - + app:layout_behavior="@string/appbar_scrolling_view_behavior" /> + tools:context=".ui.fragments.settings.Experimental"> - - + + + + diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml deleted file mode 100644 index 352d23907..000000000 --- a/app/src/main/res/layout/fragment_home.xml +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_icon_pack.xml b/app/src/main/res/layout/fragment_icon_pack.xml index 7c646a4f3..92295c878 100644 --- a/app/src/main/res/layout/fragment_icon_pack.xml +++ b/app/src/main/res/layout/fragment_icon_pack.xml @@ -5,7 +5,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:clipChildren="false" - tools:context=".ui.fragments.IconPack"> + tools:context=".ui.fragments.home.IconPack"> + tools:context=".ui.fragments.home.IconShape"> - - - - - - - - + android:paddingVertical="8dp" + app:layout_behavior="@string/appbar_scrolling_view_behavior" /> + tools:context=".ui.fragments.home.MediaIcons"> + tools:context=".ui.fragments.tweaks.MediaPlayer"> + tools:context=".ui.fragments.tweaks.Miscellaneous"> + tools:context=".ui.fragments.tweaks.MonetEngine"> + tools:context=".ui.fragments.tweaks.NavigationBar"> + tools:context=".ui.fragments.home.Notification"> + tools:context=".ui.fragments.home.NotificationPixel"> + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_preference_container_home.xml b/app/src/main/res/layout/fragment_preference_container_home.xml new file mode 100644 index 000000000..ff942d322 --- /dev/null +++ b/app/src/main/res/layout/fragment_preference_container_home.xml @@ -0,0 +1,18 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_progress_bar.xml b/app/src/main/res/layout/fragment_progress_bar.xml index 1d8ae4df8..00bb3ff30 100644 --- a/app/src/main/res/layout/fragment_progress_bar.xml +++ b/app/src/main/res/layout/fragment_progress_bar.xml @@ -5,7 +5,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:clipChildren="false" - tools:context=".ui.fragments.ProgressBar"> + tools:context=".ui.fragments.home.ProgressBar"> + tools:context=".ui.fragments.tweaks.QsIconLabel"> + tools:context=".ui.fragments.tweaks.QsPanelMargin"> + tools:context=".ui.fragments.home.QsPanelTile"> + tools:context=".ui.fragments.home.QsPanelTilePixel"> + tools:context=".ui.fragments.tweaks.QsRowColumn"> + tools:context=".ui.fragments.tweaks.QsTileSize"> - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_settings_icons.xml b/app/src/main/res/layout/fragment_settings_icons.xml index 861c29633..b559a8de3 100644 --- a/app/src/main/res/layout/fragment_settings_icons.xml +++ b/app/src/main/res/layout/fragment_settings_icons.xml @@ -5,7 +5,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:clipChildren="false" - tools:context=".ui.fragments.SettingsIcons"> + tools:context=".ui.fragments.home.SettingsIcons"> + tools:context=".ui.fragments.tweaks.Statusbar"> + android:paddingVertical="16dp"> + tools:context=".ui.fragments.home.Switch"> + tools:context=".ui.fragments.home.ToastFrame"> - - - - - - - - + android:paddingVertical="8dp" + app:layout_behavior="@string/appbar_scrolling_view_behavior" /> - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_ui_roundness.xml b/app/src/main/res/layout/fragment_ui_roundness.xml index 5552dc83f..ca5ea6980 100644 --- a/app/src/main/res/layout/fragment_ui_roundness.xml +++ b/app/src/main/res/layout/fragment_ui_roundness.xml @@ -5,7 +5,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:clipChildren="false" - tools:context=".ui.fragments.UiRoundness"> + tools:context=".ui.fragments.tweaks.UiRoundness"> + tools:context=".ui.fragments.tweaks.VolumePanel"> + android:paddingVertical="16dp"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_xposed_battery_style.xml b/app/src/main/res/layout/fragment_xposed_battery_style.xml deleted file mode 100644 index fe3add1f9..000000000 --- a/app/src/main/res/layout/fragment_xposed_battery_style.xml +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_xposed_clock_chip.xml b/app/src/main/res/layout/fragment_xposed_clock_chip.xml new file mode 100644 index 000000000..c80cabe42 --- /dev/null +++ b/app/src/main/res/layout/fragment_xposed_clock_chip.xml @@ -0,0 +1,284 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_xposed_depth_wallpaper.xml b/app/src/main/res/layout/fragment_xposed_depth_wallpaper.xml deleted file mode 100644 index e778ccdd9..000000000 --- a/app/src/main/res/layout/fragment_xposed_depth_wallpaper.xml +++ /dev/null @@ -1,105 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_xposed_header_clock.xml b/app/src/main/res/layout/fragment_xposed_header_clock.xml deleted file mode 100644 index b4991239c..000000000 --- a/app/src/main/res/layout/fragment_xposed_header_clock.xml +++ /dev/null @@ -1,200 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_xposed_header_image.xml b/app/src/main/res/layout/fragment_xposed_header_image.xml deleted file mode 100644 index 3fe3d6cdf..000000000 --- a/app/src/main/res/layout/fragment_xposed_header_image.xml +++ /dev/null @@ -1,88 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_xposed_location_browse.xml b/app/src/main/res/layout/fragment_xposed_location_browse.xml new file mode 100644 index 000000000..8d742b88e --- /dev/null +++ b/app/src/main/res/layout/fragment_xposed_location_browse.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_xposed_lockscreen_clock.xml b/app/src/main/res/layout/fragment_xposed_lockscreen_clock.xml deleted file mode 100644 index 5c78d308b..000000000 --- a/app/src/main/res/layout/fragment_xposed_lockscreen_clock.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_xposed_menu.xml b/app/src/main/res/layout/fragment_xposed_menu.xml deleted file mode 100644 index 11aa30a3b..000000000 --- a/app/src/main/res/layout/fragment_xposed_menu.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/fragment_xposed_others.xml b/app/src/main/res/layout/fragment_xposed_others.xml deleted file mode 100644 index 5192a8c2c..000000000 --- a/app/src/main/res/layout/fragment_xposed_others.xml +++ /dev/null @@ -1,117 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_xposed_quick_settings.xml b/app/src/main/res/layout/fragment_xposed_quick_settings.xml deleted file mode 100644 index fbcc05ad8..000000000 --- a/app/src/main/res/layout/fragment_xposed_quick_settings.xml +++ /dev/null @@ -1,119 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_xposed_status_icons_chip.xml b/app/src/main/res/layout/fragment_xposed_status_icons_chip.xml new file mode 100644 index 000000000..bbbc13185 --- /dev/null +++ b/app/src/main/res/layout/fragment_xposed_status_icons_chip.xml @@ -0,0 +1,296 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_xposed_themes.xml b/app/src/main/res/layout/fragment_xposed_themes.xml deleted file mode 100644 index 14edd6634..000000000 --- a/app/src/main/res/layout/fragment_xposed_themes.xml +++ /dev/null @@ -1,110 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_xposed_transparency_blur.xml b/app/src/main/res/layout/fragment_xposed_transparency_blur.xml deleted file mode 100644 index b8f01bd81..000000000 --- a/app/src/main/res/layout/fragment_xposed_transparency_blur.xml +++ /dev/null @@ -1,100 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_xposed_volume_panel.xml b/app/src/main/res/layout/fragment_xposed_volume_panel.xml deleted file mode 100644 index 51637bfab..000000000 --- a/app/src/main/res/layout/fragment_xposed_volume_panel.xml +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/preference_category.xml b/app/src/main/res/layout/preference_category.xml new file mode 100644 index 000000000..e64d38783 --- /dev/null +++ b/app/src/main/res/layout/preference_category.xml @@ -0,0 +1,8 @@ + + \ No newline at end of file diff --git a/app/src/main/res/layout/preference_footer.xml b/app/src/main/res/layout/preference_footer.xml new file mode 100644 index 000000000..b5c5245c7 --- /dev/null +++ b/app/src/main/res/layout/preference_footer.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/preference_list_item.xml b/app/src/main/res/layout/preference_list_item.xml new file mode 100644 index 000000000..58ce21a51 --- /dev/null +++ b/app/src/main/res/layout/preference_list_item.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/preference_material_switch.xml b/app/src/main/res/layout/preference_material_switch.xml new file mode 100644 index 000000000..86b74bf8c --- /dev/null +++ b/app/src/main/res/layout/preference_material_switch.xml @@ -0,0 +1,8 @@ + + diff --git a/app/src/main/res/layout/preference_selector_with_widget.xml b/app/src/main/res/layout/preference_selector_with_widget.xml new file mode 100644 index 000000000..2c030f839 --- /dev/null +++ b/app/src/main/res/layout/preference_selector_with_widget.xml @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/preference_widget_checkbox.xml b/app/src/main/res/layout/preference_widget_checkbox.xml new file mode 100644 index 000000000..c524adbd4 --- /dev/null +++ b/app/src/main/res/layout/preference_widget_checkbox.xml @@ -0,0 +1,24 @@ + + + + diff --git a/app/src/main/res/layout/preference_widget_radiobutton.xml b/app/src/main/res/layout/preference_widget_radiobutton.xml new file mode 100644 index 000000000..d229bf5f6 --- /dev/null +++ b/app/src/main/res/layout/preference_widget_radiobutton.xml @@ -0,0 +1,9 @@ + + \ No newline at end of file diff --git a/app/src/main/res/layout/preview_header_clock_9.xml b/app/src/main/res/layout/preview_header_clock_9.xml new file mode 100644 index 000000000..5d4f7fb55 --- /dev/null +++ b/app/src/main/res/layout/preview_header_clock_9.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/preview_lockscreen_clock_1.xml b/app/src/main/res/layout/preview_lockscreen_clock_1.xml index b4c234d45..c42625005 100644 --- a/app/src/main/res/layout/preview_lockscreen_clock_1.xml +++ b/app/src/main/res/layout/preview_lockscreen_clock_1.xml @@ -13,19 +13,39 @@ android:layout_marginHorizontal="20dp" android:orientation="vertical"> - + android:layout_gravity="center_horizontal" + android:orientation="vertical"> + + + + + + android:gravity="start|top" + android:layoutDirection="ltr"> - + android:layout_marginHorizontal="18dp" + android:background="@drawable/preview_lockscreen_clock_10_background" + android:orientation="vertical" + android:padding="18dp" + android:theme="@style/ConsolasFontTextAppearance" + tools:ignore="UselessParent"> + + + + + + + + + + + android:tag="nolineheight" + android:text="#include \u003Ciostream\u003E" + android:textColor="#54B5DB" + android:textSize="14sp" /> - + android:text="using namespace " + android:textColor="#E6CD69" + android:textSize="14sp" + android:theme="@style/ConsolasFontTextAppearance" /> + + + + + + + + + android:includeFontPadding="false" + android:text="()" + android:textColor="#CFD2D1" + android:textSize="14sp" + android:theme="@style/ConsolasFontTextAppearance" /> + android:textColor="#CFD2D1" + android:textSize="14sp" + android:theme="@style/ConsolasFontTextAppearance" /> - + android:includeFontPadding="false" + android:text="\t\tcout " + android:textColor="#A074C4" + android:textSize="14sp" + android:theme="@style/ConsolasFontTextAppearance" /> - + + android:text="\u0022" + android:textColor="#54B5DB" + android:textSize="14sp" + android:theme="@style/ConsolasFontTextAppearance" /> + android:textColor="#54B5DB" + android:textSize="14sp" + android:theme="@style/ConsolasFontTextAppearance" /> + android:text="\u0022" + android:textColor="#54B5DB" + android:textSize="14sp" + android:theme="@style/ConsolasFontTextAppearance" /> + + + + + + + android:includeFontPadding="false" + android:text="\u0022" + android:textColor="#54B5DB" + android:textSize="14sp" + android:theme="@style/ConsolasFontTextAppearance" /> + android:textColor="#54B5DB" + android:textSize="14sp" + android:theme="@style/ConsolasFontTextAppearance" /> + + + android:text=";" + android:textColor="#CFD2D1" + android:textSize="14sp" + android:theme="@style/ConsolasFontTextAppearance" /> + android:text="\t\tcout " + android:textColor="#A074C4" + android:textSize="14sp" + android:theme="@style/ConsolasFontTextAppearance" /> + + + + + + + android:text="\u0022" + android:textColor="#54B5DB" + android:textSize="14sp" + android:theme="@style/ConsolasFontTextAppearance" /> + android:text=";" + android:textColor="#CFD2D1" + android:textSize="14sp" + android:theme="@style/ConsolasFontTextAppearance" /> + android:text="\t\tcout " + android:textColor="#A074C4" + android:textSize="14sp" + android:theme="@style/ConsolasFontTextAppearance" /> + + + + + android:textColor="#54B5DB" + android:textSize="14sp" + android:theme="@style/ConsolasFontTextAppearance" /> + android:text="\u0022" + android:textColor="#54B5DB" + android:textSize="14sp" + android:theme="@style/ConsolasFontTextAppearance" /> + + + + + android:includeFontPadding="false" + android:text="0" + android:textColor="#CD3F45" + android:textSize="14sp" + android:theme="@style/ConsolasFontTextAppearance" /> + + + android:textColor="#CFD2D1" + android:textSize="14sp" + android:theme="@style/ConsolasFontTextAppearance" /> - + diff --git a/app/src/main/res/layout/preview_lockscreen_clock_11.xml b/app/src/main/res/layout/preview_lockscreen_clock_11.xml index b72cf9b8a..bd1e75baa 100644 --- a/app/src/main/res/layout/preview_lockscreen_clock_11.xml +++ b/app/src/main/res/layout/preview_lockscreen_clock_11.xml @@ -27,15 +27,16 @@ android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:fontFamily="@*android:string/config_clockFontFamily" - android:includeFontPadding="false" android:format12Hour="hh:mm" android:format24Hour="HH:mm" + android:includeFontPadding="false" + android:layoutDirection="locale" android:letterSpacing="0.02" + android:maxLines="1" android:paddingBottom="10dp" android:tag="text1|nolineheight" android:textColor="@android:color/white" android:textSize="50.0dip" - android:layoutDirection="locale" android:textStyle="bold" /> @@ -69,9 +71,9 @@ android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:fontFamily="@*android:string/config_clockFontFamily" - android:includeFontPadding="false" android:format12Hour="EEEE, " android:format24Hour="EEEE, " + android:includeFontPadding="false" android:tag="text1" android:textColor="@android:color/white" android:textSize="16dp" /> @@ -93,12 +95,12 @@ diff --git a/app/src/main/res/layout/preview_lockscreen_clock_15.xml b/app/src/main/res/layout/preview_lockscreen_clock_15.xml index 4fcdde228..7190c7a87 100644 --- a/app/src/main/res/layout/preview_lockscreen_clock_15.xml +++ b/app/src/main/res/layout/preview_lockscreen_clock_15.xml @@ -1,146 +1,157 @@ - + android:gravity="start|top" + android:orientation="vertical"> - + android:gravity="start|center" + android:orientation="horizontal"> - - - - - - - - - + + android:layout_marginStart="12dp" + android:orientation="vertical" + android:paddingVertical="6dp"> - + + + + - + android:layout_marginStart="20dp" + android:gravity="start|center" + android:orientation="horizontal"> - + + - + + android:layout_marginStart="12dp" + android:orientation="vertical" + android:paddingVertical="6dp"> + + + + + - + android:layout_marginStart="20dp" + android:gravity="start|center" + android:orientation="horizontal"> - + + - + - + android:layout_marginStart="12dp" + android:orientation="vertical" + android:paddingVertical="6dp"> - + + + + + + diff --git a/app/src/main/res/layout/preview_lockscreen_clock_18.xml b/app/src/main/res/layout/preview_lockscreen_clock_18.xml index 6cf00a195..893341ec2 100644 --- a/app/src/main/res/layout/preview_lockscreen_clock_18.xml +++ b/app/src/main/res/layout/preview_lockscreen_clock_18.xml @@ -1,87 +1,105 @@ - + android:gravity="center_horizontal|top" + android:orientation="vertical"> - - - - + android:layout_gravity="center" + android:gravity="start|center" + android:orientation="vertical" + tools:ignore="UselessParent"> - + - + - + + - + + + + + + + + + + - + + + + diff --git a/app/src/main/res/layout/preview_lockscreen_clock_19.xml b/app/src/main/res/layout/preview_lockscreen_clock_19.xml index a22eed896..96e647254 100644 --- a/app/src/main/res/layout/preview_lockscreen_clock_19.xml +++ b/app/src/main/res/layout/preview_lockscreen_clock_19.xml @@ -16,6 +16,7 @@ + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/preview_lockscreen_clock_23.xml b/app/src/main/res/layout/preview_lockscreen_clock_23.xml new file mode 100644 index 000000000..72f95c9c8 --- /dev/null +++ b/app/src/main/res/layout/preview_lockscreen_clock_23.xml @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/preview_lockscreen_clock_3.xml b/app/src/main/res/layout/preview_lockscreen_clock_3.xml index 8a38c1e1d..5c3dc0f96 100644 --- a/app/src/main/res/layout/preview_lockscreen_clock_3.xml +++ b/app/src/main/res/layout/preview_lockscreen_clock_3.xml @@ -15,10 +15,11 @@ diff --git a/app/src/main/res/layout/searchpreference_fragment.xml b/app/src/main/res/layout/searchpreference_fragment.xml new file mode 100644 index 000000000..bb7e4ca69 --- /dev/null +++ b/app/src/main/res/layout/searchpreference_fragment.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/searchpreference_list_item_history.xml b/app/src/main/res/layout/searchpreference_list_item_history.xml new file mode 100644 index 000000000..dc55be278 --- /dev/null +++ b/app/src/main/res/layout/searchpreference_list_item_history.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/searchpreference_list_item_result.xml b/app/src/main/res/layout/searchpreference_list_item_result.xml new file mode 100644 index 000000000..fd6a9b93b --- /dev/null +++ b/app/src/main/res/layout/searchpreference_list_item_result.xml @@ -0,0 +1,32 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/searchpreference_preference.xml b/app/src/main/res/layout/searchpreference_preference.xml new file mode 100644 index 000000000..73f86ca0c --- /dev/null +++ b/app/src/main/res/layout/searchpreference_preference.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/searchpreference_searchbar.xml b/app/src/main/res/layout/searchpreference_searchbar.xml new file mode 100644 index 000000000..1f957e6c7 --- /dev/null +++ b/app/src/main/res/layout/searchpreference_searchbar.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/view_bottom_sheet_dialog_layout.xml b/app/src/main/res/layout/view_bottom_sheet_dialog_layout.xml new file mode 100644 index 000000000..bfe3f48f1 --- /dev/null +++ b/app/src/main/res/layout/view_bottom_sheet_dialog_layout.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/view_current_weather.xml b/app/src/main/res/layout/view_current_weather.xml new file mode 100644 index 000000000..c90b57f64 --- /dev/null +++ b/app/src/main/res/layout/view_current_weather.xml @@ -0,0 +1,121 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/view_device_widget.xml b/app/src/main/res/layout/view_device_widget.xml new file mode 100644 index 000000000..54141f366 --- /dev/null +++ b/app/src/main/res/layout/view_device_widget.xml @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/view_edit_text_dialog.xml b/app/src/main/res/layout/view_edit_text_dialog.xml new file mode 100644 index 000000000..ca71dc350 --- /dev/null +++ b/app/src/main/res/layout/view_edit_text_dialog.xml @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/view_home_card.xml b/app/src/main/res/layout/view_home_card.xml index b74d4d9c9..f5bd13d43 100644 --- a/app/src/main/res/layout/view_home_card.xml +++ b/app/src/main/res/layout/view_home_card.xml @@ -1,12 +1,13 @@ diff --git a/app/src/main/res/layout/view_list_icon_item.xml b/app/src/main/res/layout/view_list_icon_item.xml index c0f2ca59e..8a0f7662c 100644 --- a/app/src/main/res/layout/view_list_icon_item.xml +++ b/app/src/main/res/layout/view_list_icon_item.xml @@ -3,7 +3,6 @@ xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="120dp" android:layout_height="wrap_content" - android:layout_gravity="center_horizontal" android:orientation="vertical"> - \ No newline at end of file diff --git a/app/src/main/res/layout/view_list_info_item.xml b/app/src/main/res/layout/view_list_info_item.xml index f7730656d..706eea94d 100644 --- a/app/src/main/res/layout/view_list_info_item.xml +++ b/app/src/main/res/layout/view_list_info_item.xml @@ -19,7 +19,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerVertical="true" - android:layout_marginVertical="22dp" + android:layout_marginVertical="16dp" android:layout_marginStart="18dp" android:layout_marginEnd="24dp" android:layout_toEndOf="@id/icon" diff --git a/app/src/main/res/layout/view_list_item_location_browse.xml b/app/src/main/res/layout/view_list_item_location_browse.xml new file mode 100644 index 000000000..6dd1aee5b --- /dev/null +++ b/app/src/main/res/layout/view_list_item_location_browse.xml @@ -0,0 +1,27 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/view_list_option_brightnessbar.xml b/app/src/main/res/layout/view_list_option_brightnessbar.xml index e1fbde3a0..6ed679c36 100644 --- a/app/src/main/res/layout/view_list_option_brightnessbar.xml +++ b/app/src/main/res/layout/view_list_option_brightnessbar.xml @@ -8,7 +8,7 @@ android:background="@drawable/item_background_material" android:orientation="vertical" android:paddingHorizontal="24dp" - android:paddingVertical="22dp"> + android:paddingVertical="16dp"> + android:paddingVertical="16dp"> @@ -122,7 +123,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginHorizontal="24dp" - android:layout_marginBottom="24dp" + android:layout_marginBottom="16dp" android:text="@string/btn_apply" android:visibility="gone" /> @@ -132,7 +133,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginHorizontal="24dp" - android:layout_marginBottom="24dp" + android:layout_marginBottom="16dp" android:text="@string/btn_disable" android:visibility="gone" /> diff --git a/app/src/main/res/layout/view_list_option_mediaplayer_icons.xml b/app/src/main/res/layout/view_list_option_mediaplayer_icons.xml index 16d1a09b8..4fc2eb6e2 100644 --- a/app/src/main/res/layout/view_list_option_mediaplayer_icons.xml +++ b/app/src/main/res/layout/view_list_option_mediaplayer_icons.xml @@ -8,7 +8,7 @@ android:clickable="true" android:orientation="vertical" android:paddingHorizontal="24dp" - android:paddingVertical="22dp"> + android:paddingVertical="16dp"> + android:paddingVertical="16dp"> + android:paddingVertical="16dp"> + android:paddingVertical="16dp"> + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/view_new_update.xml b/app/src/main/res/layout/view_new_update.xml index d408ad5f7..c1874f2b4 100644 --- a/app/src/main/res/layout/view_new_update.xml +++ b/app/src/main/res/layout/view_new_update.xml @@ -5,6 +5,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginHorizontal="18dp" + android:layout_marginTop="8dp" android:layout_marginBottom="@dimen/container_margin" android:background="@drawable/container_outline" android:orientation="horizontal" diff --git a/app/src/main/res/layout/view_onboarding_page.xml b/app/src/main/res/layout/view_onboarding_page.xml index e46ea359e..6e9f68f77 100644 --- a/app/src/main/res/layout/view_onboarding_page.xml +++ b/app/src/main/res/layout/view_onboarding_page.xml @@ -22,7 +22,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" - app:layout_constraintGuide_percent="0.8" /> + app:layout_constraintGuide_percent="0.84" /> + app:layout_constraintGuide_percent="0.84" /> \ No newline at end of file diff --git a/app/src/main/res/layout/view_reboot.xml b/app/src/main/res/layout/view_reboot.xml index 4bf1085ca..1ad915d83 100644 --- a/app/src/main/res/layout/view_reboot.xml +++ b/app/src/main/res/layout/view_reboot.xml @@ -5,6 +5,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginHorizontal="18dp" + android:layout_marginTop="8dp" android:layout_marginBottom="@dimen/container_margin" android:background="@drawable/container_outline" android:orientation="vertical" diff --git a/app/src/main/res/layout/view_status_bar_chip.xml b/app/src/main/res/layout/view_status_bar_chip.xml deleted file mode 100644 index e05f7fb0d..000000000 --- a/app/src/main/res/layout/view_status_bar_chip.xml +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/view_status_icons_chip.xml b/app/src/main/res/layout/view_status_icons_chip.xml deleted file mode 100644 index 19de0d898..000000000 --- a/app/src/main/res/layout/view_status_icons_chip.xml +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/view_toast_frame.xml b/app/src/main/res/layout/view_toast_frame.xml index dfd0ebcf0..b60ba536d 100644 --- a/app/src/main/res/layout/view_toast_frame.xml +++ b/app/src/main/res/layout/view_toast_frame.xml @@ -1,9 +1,13 @@ + android:layout_gravity="center_horizontal" + android:gravity="center_horizontal" + android:orientation="vertical" + android:paddingHorizontal="8dp" + android:paddingVertical="8dp"> diff --git a/app/src/main/res/layout/view_volume_style.xml b/app/src/main/res/layout/view_volume_style.xml index 39ce2cb5c..134544274 100644 --- a/app/src/main/res/layout/view_volume_style.xml +++ b/app/src/main/res/layout/view_volume_style.xml @@ -24,7 +24,7 @@ android:clickable="true" android:orientation="vertical" android:paddingHorizontal="24dp" - android:paddingTop="22dp"> + android:paddingTop="16dp"> diff --git a/app/src/main/res/layout/view_widget_colorpicker.xml b/app/src/main/res/layout/view_widget_colorpicker.xml index 5005d11d1..eddd2ba20 100644 --- a/app/src/main/res/layout/view_widget_colorpicker.xml +++ b/app/src/main/res/layout/view_widget_colorpicker.xml @@ -11,10 +11,10 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerVertical="true" - android:layout_marginVertical="22dp" + android:layout_marginVertical="16dp" android:layout_marginStart="24dp" android:layout_marginEnd="10dp" - android:layout_toStartOf="@id/color_widget" + android:layout_toStartOf="@id/color_widget_container" android:orientation="vertical"> - + android:background="@drawable/preview_color_picker_border" + android:padding="1dp"> + + + \ No newline at end of file diff --git a/app/src/main/res/layout/view_widget_filepicker.xml b/app/src/main/res/layout/view_widget_filepicker.xml index fc98aac69..4fe0a328d 100644 --- a/app/src/main/res/layout/view_widget_filepicker.xml +++ b/app/src/main/res/layout/view_widget_filepicker.xml @@ -9,7 +9,7 @@ android:clickable="true" android:orientation="vertical" android:paddingHorizontal="24dp" - android:paddingTop="22dp" + android:paddingTop="16dp" android:paddingBottom="16dp"> diff --git a/app/src/main/res/layout/view_widget_slider.xml b/app/src/main/res/layout/view_widget_slider.xml index f912bfe2c..3d1135213 100644 --- a/app/src/main/res/layout/view_widget_slider.xml +++ b/app/src/main/res/layout/view_widget_slider.xml @@ -5,10 +5,10 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/item_background_material" - android:clickable="true" + android:clickable="false" android:orientation="vertical" android:paddingHorizontal="24dp" - android:paddingTop="22dp" + android:paddingTop="16dp" android:paddingBottom="4dp"> - + android:orientation="horizontal"> + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/view_widget_switch.xml b/app/src/main/res/layout/view_widget_switch.xml index 1df25c87c..7bf3575fc 100644 --- a/app/src/main/res/layout/view_widget_switch.xml +++ b/app/src/main/res/layout/view_widget_switch.xml @@ -24,7 +24,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerVertical="true" - android:layout_marginVertical="22dp" + android:layout_marginVertical="16dp" android:layout_marginStart="18dp" android:layout_marginEnd="10dp" android:layout_toStartOf="@id/switch_widget" diff --git a/app/src/main/res/layout/view_widget_title.xml b/app/src/main/res/layout/view_widget_title.xml index 4f6e64546..a0f36b510 100644 --- a/app/src/main/res/layout/view_widget_title.xml +++ b/app/src/main/res/layout/view_widget_title.xml @@ -5,12 +5,12 @@ android:layout_height="wrap_content" android:orientation="vertical" android:paddingHorizontal="24dp" - android:paddingTop="22dp" + android:paddingTop="16dp" android:paddingBottom="8dp"> + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/view_xposed_battery_dimension.xml b/app/src/main/res/layout/view_xposed_battery_dimension.xml index c4233e85c..2fe1f324e 100644 --- a/app/src/main/res/layout/view_xposed_battery_dimension.xml +++ b/app/src/main/res/layout/view_xposed_battery_dimension.xml @@ -11,8 +11,8 @@ android:id="@+id/custom_dimensions" android:layout_width="match_parent" android:layout_height="wrap_content" - app:summaryText="@string/custom_dimensions_desc" - app:titleText="@string/custom_dimensions_title" /> + app:summaryText="@string/custom_margins_desc" + app:titleText="@string/custom_margins_title" /> + + + \ No newline at end of file diff --git a/app/src/main/res/menu/bottom_nav_menu.xml b/app/src/main/res/menu/bottom_nav_menu.xml index 508fc09ae..bc95734d0 100644 --- a/app/src/main/res/menu/bottom_nav_menu.xml +++ b/app/src/main/res/menu/bottom_nav_menu.xml @@ -10,6 +10,11 @@ android:enabled="true" android:icon="@drawable/ic_navbar_tweaks" android:title="@string/navbar_tweaks" /> + + android:icon="@drawable/ic_navbar_xposed" + android:title="@string/navbar_xposed" /> + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/monet_menu.xml b/app/src/main/res/menu/monet_menu.xml deleted file mode 100644 index f5c8ea7c0..000000000 --- a/app/src/main/res/menu/monet_menu.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/src/main/res/menu/search_menu.xml b/app/src/main/res/menu/search_menu.xml new file mode 100644 index 000000000..e88961655 --- /dev/null +++ b/app/src/main/res/menu/search_menu.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/search_more.xml b/app/src/main/res/menu/search_more.xml new file mode 100644 index 000000000..addf17a0f --- /dev/null +++ b/app/src/main/res/menu/search_more.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/settings_menu.xml b/app/src/main/res/menu/settings_menu.xml index e88961655..e06e08ef8 100644 --- a/app/src/main/res/menu/settings_menu.xml +++ b/app/src/main/res/menu/settings_menu.xml @@ -1,5 +1,12 @@ - + + + @@ -18,4 +25,8 @@ + + \ No newline at end of file diff --git a/app/src/main/res/menu/xposed_menu.xml b/app/src/main/res/menu/xposed_menu.xml deleted file mode 100644 index dd96b46eb..000000000 --- a/app/src/main/res/menu/xposed_menu.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/menu/xposed_only_menu.xml b/app/src/main/res/menu/xposed_only_menu.xml deleted file mode 100644 index 2998f7e62..000000000 --- a/app/src/main/res/menu/xposed_only_menu.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/navigation/nav_home_page.xml b/app/src/main/res/navigation/nav_home_page.xml deleted file mode 100644 index 2a7f8f54d..000000000 --- a/app/src/main/res/navigation/nav_home_page.xml +++ /dev/null @@ -1,695 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/navigation/nav_xposed_menu.xml b/app/src/main/res/navigation/nav_xposed_menu.xml deleted file mode 100644 index d850a3937..000000000 --- a/app/src/main/res/navigation/nav_xposed_menu.xml +++ /dev/null @@ -1,340 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/raw/com_drdisagree_iconify_keep.xml b/app/src/main/res/raw/com_drdisagree_iconify_keep.xml new file mode 100644 index 000000000..b1d1c8b46 --- /dev/null +++ b/app/src/main/res/raw/com_drdisagree_iconify_keep.xml @@ -0,0 +1,18 @@ + + diff --git a/app/src/main/res/values-af-rZA/strings.xml b/app/src/main/res/values-af-rZA/strings.xml index 0f6075b05..d0273f4a6 100644 --- a/app/src/main/res/values-af-rZA/strings.xml +++ b/app/src/main/res/values-af-rZA/strings.xml @@ -1,5 +1,5 @@ - + Customize Boring Android UI Initializing setup @@ -31,10 +31,22 @@ Oops Did Not Expect That Logs have been saved in documents folder. Logs + + Search + Search… + Clear + History entry + More + Clear history + No result Iconify Icon Pack Change system icon pack + Cellular Icons + Change system cellular icons + WiFi Icons + Change system WiFi icons Brightness Bar Customize progress slider QS Panel Tiles @@ -113,6 +125,8 @@ Some options like blur intensity doesn\'t take effect until systemui is restarted Show Home Page Card Show a beautiful card on the home page. + Haptic Feedback + Enhance touch feedback with interactive haptics. Clear App Cache Clear caches generated due to the usage of custom fonts, images, or gifs. Experimental @@ -122,6 +136,8 @@ About Github Repository Telegram Group + Translate Iconify + Help translate Iconify to your language. Credits Thanking those who made this possible. @@ -231,8 +247,8 @@ Misc. Minimal QS Panel Remove top shade of QS panel - Disable System Monet - Helps to retain custom colors\nSystemUI restart required + System Monet + Disable to retain custom colors\nSystemUI restart required Primary Color Pick primary accent color @@ -405,24 +421,93 @@ Tweaks related to QS panel Battery Style Customize battery icon view + Oneplus QS Header + OOS style quick settings header Header Image Add custom image on QS panel Header Clock Add custom clock on QS panel Lockscreen Clock Add custom clock on lockscreen + Lockscreen Weather + Add weather on lockscreen + Lockscreen Widgets + Add widgets on lockscreen Depth Wallpaper Show iOS like depth wallpaper Background Chip Add colored chip behind clock + Clock Chip Others Miscellaneous xposed tweaks - + Weather Settings + + Oneplus QS Header + Enable OOS style media player and tiles in QS + Haptic Feedback + Add haptic feedback on tiles + Hide Stock Media Player + Remove stock media player from QS panel + Blur Level + Fade Level + Top Margin + Expansion Amount + + Lockscreen Widgets + Enable Lockscreen Widgets + Add widgets to lockscreen + Device Info Widget + Show device info widget on lockscreen + Linear Progress Color + Circular Progress Color + Text Color + Custom Device Name + Set custom device name.\nKeep blank to disable. + Large Widgets + Large Widget 1 + Large Widget 2 + Mini Widgets + Mini Widget 1 + Mini Widget 2 + Mini Widget 3 + Mini Widget 4 + Custom Colors + Customize Widget Colors + Large Widget Active Color + Large Widget Inactive Color + Large Widget Icon Active Color + Large Widget Icon Inactive Color + Mini Widget Active Color + Mini Widget Inactive Color + Mini Widget Icon Active Color + Mini Widget Icon Inactive Color + Weather Settings + Widgets Scale + + Camera + Clock/Timer + Calculator + Gallery + Media Player + Torch + Play + Weather + Wifi + Data + Ringer + Bluetooth + Home Controls + Wallet + Hotspot + Ringer + Vibrate + Silent + Transparency Transparent QS Panel Make QS panel background transparent - Transparency Alpha - Transparent Notif Shade Only + Background Opacity + Transparent Notification Shade Make only notification shade transparent Dim Lockscreen Wallpaper Suitable for light-colored wallpapers @@ -432,7 +517,7 @@ Aggressive Blur Enabler Might bootloop in some roms Blur Intensity - + For Pixel Roms Light Theme Light QS theme in light mode\nMust use custom QS Shape @@ -449,21 +534,28 @@ Power Menu Transparency Power menu transparency for Fluid QS\nDo not use custom notification style Others + Fix QS Tile Color + Fix custom QS tile style on android 14 Fix Notification Color Fix custom notification style on android 14 - + Fix Notification Footer Button Color + Fix custom footer button style on android 14 + QS Tile Vertical QS Tile Show label below QS icon Hide QS Tile Label Use only with vertical tiles + Text Size Scaling QS Margin QS Elements + Hide QS on Lockscreen + Disable quick settings panel on secured lockscreen Hide Silent Text - Hide silent text shown as header of silent notifications (Requires SystemUI restart) + Hide silent text shown as header of silent notifications Hide Footer Buttons Hide footer buttons shown under notification stack - + Battery Style Battery Width Battery Height @@ -494,8 +586,8 @@ Change color of powersave battery Powersave Indicator Color Change color of powersave indicator - Custom Dimensions - Set custom dimensions for battery icon + Custom Margins + Set custom margins for battery icon Battery Margin Left Battery Margin Right Battery Margin Top @@ -546,17 +638,19 @@ Circle Battery Dotted Circle Battery Filled Circle Battery - + Volume Percentage Show percentage above volume slider Safety Warning Show warning on high volume - + Colored Ringer Icon + Enable if selected ringer icon is invisible + Pick Header Image Add header image on QS panel\nDo not select file from Recent Pick Image Image Height - Image Alpha + Image Opacity Bottom Fade Amount Zoom To Fit Image is stretched to fit by default @@ -564,35 +658,36 @@ Hide image in landscape mode Alpha Gradient Add faded effect to the header image - + Custom Header Clock Add a custom clock on QS panel Clock Style Clock Font - Use custom font for header clock\nDo not select file from Recent + Use custom font for header clock Custom Clock Color - Custom color instead of primary color + Custom colors instead of system colors Clock Color Picker Set color of header clock text + Expansion Amount Text Scaling - Clock Side Margin - Clock Top Margin + Side Margin + Top Margin White Text Force text colors to be white Center Clock Move clock to center of view Hide in Landscape Hide clock in landscape mode - + Custom Lockscreen Clock Enable custom lockscreen clock Auto Hide Clock Hide clock on incoming notification Clock Style Clock Font - Use custom font for lockscreen clock\nDo not select file from Recent + Use custom font for lockscreen clock Custom Clock Color - Custom color instead of primary color + Custom colors instead of system colors Clock Color Picker Set color of lockscreen clock text Text Scaling @@ -601,6 +696,13 @@ Bottom Margin White Text Force all colors to be white + Use Custom Image + Use custom image for lockscreen clock. + Custom Image Picker + Custom Device Name + Set custom device name for lockscreen clock.\nKeep blank to use System\'s Device Name. + Custom User Name + Set custom user name for lockscreen clock.\nKeep blank to use System\'s User Name. Select Battery Charging Battery Discharging @@ -608,14 +710,18 @@ Battery Level Welcome back! User - + Enable Depth Wallpaper - Show iOS like depth wallpaper\nMust use custom lockscreen clock + Show iOS like depth wallpaper\n%s + Custom Images + Set custom images as depth wallpaper + Show on AOD + Show subject on always on display Fade in AOD Animate wallpaper and fade away in AOD Foreground Image Foreground image for depth wallpaper - Foreground Image Alpha + Foreground Image Opacity Background Image Background image for depth wallpaper This feature is currently in beta stage. So bugs are expected.\n\nKnown Bug(s):\n• Tapping on lockscreen makes the wallpaper jump. @@ -623,23 +729,68 @@ Move background and foreground layers at different speeds Foreground Sensitivity Background Sensitivity - + AI model is downloaded on the device + AI model isn\'t available on the device (yet) + Extracting wallpaper subject… + Extracted wallpaper subject! + Failed to extract wallpaper subject! + AI model is not available! + Must use custom lockscreen clock + Status Bar Statusbar Clock Chip Display chip behind statusbar clock - Statusbar Clock Color + Customize Clock Chip + Custom colors, roundness, stroke etc. + Text + Clock Text Color Follow System Transparent Text Custom Color - Clock Color Picker - Set color of statubsar clock text + Text Color Picker + Set color of statubsar clock text Status Icons Chip Style Status Icons Chip Display chip behind status icons + Customize Status Icons Chip + Custom colors, roundness, stroke etc. Chip Style Top Margin Side Margin + Background + Accent Fill Color + Gradient Direction + Fill Start Color + Fill End Color + Border + Enable Border + Accent Border Color + Border Color + Dashed Border + Dash Width + Dash Gap + Border Thickness + Padding + Padding Left + Padding Right + Padding Top + Padding Bottom + Corner Radius + Top Left Radius + Top Right Radius + Bottom Left Radius + Bottom Right Radius + + Custom Statusbar Clock Size + Set a custom size for Statusbar Clock + Statusbar Clock Size + Colored Statusbar Icon + Show app icon as notification icon + Hide LS Carrier + Hide carrier name on lockscreen + Hide LS Statusbar + Hide statusbar on lockscreen QS Header Hide Carrier Group @@ -647,10 +798,6 @@ Hide Status Icons Remove time, date and battery icons Lock Screen - Hide LS Carrier - Hide carrier name on lockscreen - Hide LS Statusbar - Hide statusbar on lockscreen Hide LS Lock Icon Hide lock icon view on lockscreen Fixed Status Icons @@ -737,6 +884,7 @@ Home Tweaks + Xposed Settings Changelog @@ -752,37 +900,14 @@ Saved settings successfully None - Style 1 - Style 2 - Style 3 - Style 4 - Style 5 - Style 6 - Style 7 - Style 8 - Style 9 - Style 10 - Style 11 - Style 12 - Style 13 - Style 14 - Style 15 - Style 16 - Style 17 - Style 18 - Style 19 - Style 20 - Style 21 - Style 22 - Style 23 - Style 24 - Style 25 + Style %d Continue Restart Disable Enable Apply + Save Disable Custom Colors Apply Colors Reset @@ -851,10 +976,6 @@ Hey There! Icon Media Player Icons - Selected: - Selected: %s - Selected: %1$s%2$s - Selected: %1$s%2$s %3$s (Default) No Clock Clock Style %d @@ -923,4 +1044,124 @@ Tap on preview to select Don\'t show again To ensure proper functionality, enabling the Iconify module in LSPosed is mandatory for android 14 and above.\n\nAfter that, enable the fixes from: Tweaks > Xposed Menu > Themes > Others. + Do not select file from Recent + Dismiss + Restart Device + Pending + Accent Primary + Accent Secondary + Accent Tertiary + Text Color Primary + Text Color Inverse + + + Unit + Verifying location + Select location + Enter location + Location + Set custom location + Cannot retrieve location! + Network geolocation is disabled.\n\nSet a custom location or enable network location. + Enable + Settings + Automatic updates + Check for new versions once in a while + Check updates over WiFi only + Check for updates in background only when connected to wifi + Metric (\u00b0C) + Imperial (\u00b0F) + Update + Enable + Update interval + 1 hour + 2 hours + 4 hours + 6 hours + 12 hours + Weather + Condition Icon Pack + Find more icon packs + Disabled + Error + Waiting \u2026 + No weather data + Error loading weather data + Waiting\u2026 + Updating\u2026 + Service disabled + Now + Background shadow + Service settings + Unknown + Error loading weather data + Weather + Last update: + No location available + No network found + Location permissions not granted + Select location + Search for a location + Enable Location Permissions + Location permissions are required to fetch weather data. Click OK to open Settings. + + Cloudy + Rainy + Sunny + Stormy + Snowy + Windy + Misty + + Weather on Lockscreen + Show weather on lockscreen + Last Update Time + Weather Provider + OpenWeatherMap API Key + OpenWeatherMap API Key required + Please enter your OpenWeatherMap API key to fetch weather data. + Show Location + Show Location before icon + Show Condition + Show Condition after temperature + Show Humidity + Show Humidity in a new row + Show Wind + Show Wind in a new row + Text Size + Image Size + Text Color + Set custom color for text + Custom Color + Custom color for all text in weather view + Custom location + Set custom location for weather + Custom Margins + Set custom margins for weather + Top margin + Center Layout + Side Margin + Bottom Margin + Center Weather View + Move weather view to center horizontally + + Weather Background Style + Default + Semi-transparent box + Semi-transparent box (round) + Q-Beta pill + Rounded, simple and with accent + Rounded, transparent and with accent + Gradient + Dark with accented borders + Dark with gradient borders + + SystemUI Restart Needed + A SystemUI restart is needed for this change to take effect. + Device Restart Needed + A device restart is needed for this change to take effect. + Switch Device Theme + Switch between light and dark themes if unexpected behavior occurs. + Device Rotation Theme + Switch rotation of your device for this change to take effect. diff --git a/app/src/main/res/values-ar-rSA/strings.xml b/app/src/main/res/values-ar-rSA/strings.xml index c45108682..72ab79928 100644 --- a/app/src/main/res/values-ar-rSA/strings.xml +++ b/app/src/main/res/values-ar-rSA/strings.xml @@ -1,5 +1,5 @@ - + قم بتغيير واجهة المستخدم الممله جارٍ بدء الإعداد @@ -31,10 +31,22 @@ عفوا لم أتوقع ذلك تم حفظ السجلات في ذاكرة الجهاز. السجلات + + بحث + بحث… + مسح + History entry + More + Clear history + No result Iconify حزمة الأيقونات تغيير حزمة ايقونات النظام + Cellular Icons + Change system cellular icons + أيقونات WiFi + تغيير أيقونات WiFi النظام شريط السطوع تخصيص شريط التقدم QS بلاط لوحة @@ -113,6 +125,8 @@ لا تسري بعض الخيارات مثل كثافة التعتيم حتى يتم إعادة تشغيل SystemUI إظهار بطاقة الصفحة الرئيسية اعرض بطاقة جميلة على الصفحة الرئيسية. + Haptic Feedback + Enhance touch feedback with interactive haptics. مسح ذاكرة التخزين المؤقت للتطبيق مسح ذاكرة التخزين المؤقت التي تم إنشاؤها نتيجة لاستخدام الخطوط أو الصور أو صور GIF المخصصة. تجريبي @@ -122,6 +136,8 @@ حول مستودع Github مجموعة Telegram + Translate Iconify + Help translate Iconify to your language. الإئتمان أشكر أولئك الذين جعلوا هذا ممكنا. @@ -231,8 +247,8 @@ متنوعات. الحد الأدنى من لوحة QS إزالة الظل العلوي للوحة QS - تعطيل Monet النظام - يساعد على الاحتفاظ بالألوان المخصصة + System Monet + Disable to retain custom colors\nSystemUI restart required لون أولي اختر لون التمييز الأولي @@ -405,24 +421,93 @@ القرص المتعلق بلوحة QS نمط البطارية تخصيص عرض أيقونة البطارية + Oneplus QS Header + OOS style quick settings header صورة الرأس أضف صورة مخصصة على لوحة QS ساعة الرأس أضف ساعة مخصصة على لوحة QS ساعة قفل الشاشة أضف ساعة مخصصة على شاشة القفل + Lockscreen Weather + Add weather on lockscreen + Lockscreen Widgets + Add widgets on lockscreen خلفية العمق إظهار خلفية عمق شبيه بالتي في iOS رقاقة الخلفية أضف رقاقة ملونة خلف الساعة + Clock Chip آخر تعديلات Xposed المتنوعة - + Weather Settings + + Oneplus QS Header + Enable OOS style media player and tiles in QS + Haptic Feedback + Add haptic feedback on tiles + Hide Stock Media Player + Remove stock media player from QS panel + Blur Level + Fade Level + Top Margin + Expansion Amount + + Lockscreen Widgets + Enable Lockscreen Widgets + Add widgets to lockscreen + Device Info Widget + Show device info widget on lockscreen + Linear Progress Color + Circular Progress Color + Text Color + Custom Device Name + Set custom device name.\nKeep blank to disable. + Large Widgets + Large Widget 1 + Large Widget 2 + Mini Widgets + Mini Widget 1 + Mini Widget 2 + Mini Widget 3 + Mini Widget 4 + Custom Colors + Customize Widget Colors + Large Widget Active Color + Large Widget Inactive Color + Large Widget Icon Active Color + Large Widget Icon Inactive Color + Mini Widget Active Color + Mini Widget Inactive Color + Mini Widget Icon Active Color + Mini Widget Icon Inactive Color + Weather Settings + Widgets Scale + + Camera + Clock/Timer + Calculator + المعرض + Media Player + Torch + Play + Weather + Wifi + Data + Ringer + Bluetooth + Home Controls + Wallet + Hotspot + Ringer + Vibrate + Silent + شفافية لوحة QS الشفافة جعل خلفية لوحة QS شفافة - الشفافية ألفا - لون Notif الشفاف فقط + Background Opacity + Transparent Notification Shade اجعل غطاء الإشعارات فقط شفافًا تعتيم خلفية شاشة القفل مناسبة للخلفيات ذات الألوان الفاتحة @@ -432,7 +517,7 @@ تمكين التعتيم الضبابي العنيف قد يسبب في عدم الإقلاع في بعض الرومات كثافة التعتيم - + لرومات الـPixel مظهر فاتح سمة فاتحة QS في الوضع الفاتح \n يجب استخدام شكل QS المخصص @@ -449,21 +534,28 @@ شفافية قائمة الطاقة شفافية قائمة التشغيل للـQS السائلة\n لا تستخدم نمط اشعار مخصص آخر + Fix QS Tile Color + Fix custom QS tile style on android 14 إصلاح لون الإشعارات إصلاح نمط الإشعارات المخصص في Android 14 - + Fix Notification Footer Button Color + Fix custom footer button style on android 14 + بلاطة QS بلاط QS عمودي إظهار التسمية أسفل رمز QS إخفاء تسمية بلاط QS استخدم فقط مع البلاط العمودي + تحجيم النص هامش QS عناصر QS + Hide QS on Lockscreen + Disable quick settings panel on secured lockscreen إخفاء النص الصامت - إخفاء النص الصامت المعروض كرأس للإشعارات الصامتة (يتطلب إعادة تشغيل SystemUI) + Hide silent text shown as header of silent notifications إخفاء أزرار التذييل إخفاء أزرار تذييل الصفحة المعروضة تحت تكدس الإشعارات - + شكل البطاريه عرض البطاريه ارتفاع البطارية @@ -494,8 +586,8 @@ تغيير لون بطارية توفير الطاقة لون مؤشر توفير الطاقة تغيير لون مؤشر توفير الطاقة - أبعاد مخصصة - قم بتعيين أبعاد مخصصة لرمز البطارية + Custom Margins + Set custom margins for battery icon هامش البطارية الأيسر هامش البطارية الأيمن هامش البطارية العلوي @@ -545,18 +637,20 @@ بطارية أفقية O بطارية دائرة بطارية دائرة منقطة - Filled Circle Battery - + بطارية دائرية منقطة + حجم الصوت إظهار النسبة المئوية فوق شريط تمرير الصوت تحذير الأمان إظهار التحذير على مستوى الصوت العالي - + Colored Ringer Icon + Enable if selected ringer icon is invisible + اختر صورة الرأس أضف صورة العنوان على لوحة QS\nلا تحدد ملفًا من الحالي اختر صورة ارتفاع الصورة - صورة ألفا + Image Opacity كمية التلاشي السفلي تكبير للتناسب يتم تمديد الصورة لتناسب بشكل افتراضي @@ -564,35 +658,36 @@ إخفاء الصورة في الوضع الأفقي متدرج Alpha أضف تأثير التلاشي إلى صورة الرأس - + ساعة رأس مخصصة أضف ساعة مخصصة على لوحة QS نمط الساعة خط الساعة - استخدم خطًا مخصصًا لساعة شاشة القفل\n لا تحدد ملفاً من الحالي + Use custom font for header clock لون الساعة المخصص - لون مخصص بدلاً من اللون الأساسي + Custom colors instead of system colors منتقي لون الساعة تعيين لون نص ساعة الرأس + Expansion Amount تحجيم النص - هامش الساعة الجانبي - هامش الساعة العلوي + Side Margin + Top Margin نص أبيض فرض ألوان النص أن تكون بيضاء الساعة في المنتصف حرك الساعة إلى مركز العرض إخفاء في الوضع الأفقي إخفاء الساعة في الوضع الأفقي - + ساعة قفل الشاشة مخصصة تمكين ساعة شاشة القفل مخصصة إخفاء الساعة تلقائيًا إخفاء الساعة على الإشعار الوارد نمط الساعة خط الساعة - استخدم خطًا مخصصًا لساعة شاشة القفل\n لا تحدد ملفاً من الحالي + Use custom font for lockscreen clock لون الساعة المخصص - لون مخصص بدلاً من اللون الأساسي + Custom colors instead of system colors منتقي لون الساعة ضبط لون نص ساعة قفل الشاشة تحجيم النص @@ -601,6 +696,13 @@ الهامش السفليn نص أبيض إجبار كل الألوان على أن تكون بيضاء + استخدام صورة مخصصة + استخدم صورة مخصصة لساعة قفل الشاشة. + منتقي صورة مخصص + اسم جهاز مخصص + قم بتعيين اسم جهاز مخصص لساعة شاشة القفل.\nاتركه فارغًا لاستخدام اسم جهاز النظام. + اسم مستخدم مخصص + قم بتعيين اسم مستخدم مخصص لساعة شاشة القفل.\nاتركه فارغًا لاستخدام اسم مستخدم النظام. اختر شحن البطارية تفريغ البطارية @@ -608,14 +710,18 @@ مستوى البطارية مرحبًا مجددًا! المستخدم - + تمكين خلفية العمق - إظهار نظام التشغيل iOS كخلفية للعمق\n يجب استخدام ساعة قفل مخصصة + Show iOS like depth wallpaper\n%s + Custom Images + Set custom images as depth wallpaper + Show on AOD + Show subject on always on display التلاشي في AOD تحريك الخلفية والتلاشي في AOD الصورة الأمامية الصورة الأمامية لخلفية العمق - Foreground Image Alpha + Foreground Image Opacity صورة خلفية صورة خلفية لخلفية العمق هذه الميزة حالياً في المرحلة التجريبية. لذا من المتوقع حدوث أخطاء.\n\nأخطاء المعروفة:\n• النقر على شاشة القفل يجعل الخلفية تقفز. @@ -623,23 +729,68 @@ حرك الخلفية والطبقات الأمامية بسرعات مختلفة حساسية الطبقة حساسية الخلفية - + AI model is downloaded on the device + AI model isn\'t available on the device (yet) + Extracting wallpaper subject… + Extracted wallpaper subject! + Failed to extract wallpaper subject! + AI model is not available! + Must use custom lockscreen clock + شريط الحالة رقاقة ساعة شريط الحالة عرض رقاقة خلف ساعة شريط الحالة - لون ساعة شريط الحالة + Customize Clock Chip + Custom colors, roundness, stroke etc. + Text + Clock Text Color اتبع النظام نص شفاف لون مخصص - منتقي لون الساعة - ضبط لون نص ساعة شريط الحالة + Text Color Picker + Set color of statubsar clock text أيقونات الحالة نمط الرقاقة رقاقة أيقونات الحالة عرض الرقاقة خلف أيقونات الحالة + Customize Status Icons Chip + Custom colors, roundness, stroke etc. نمط الرقاقة الهامش العلوي الهامش الجانبي + Background + Accent Fill Color + Gradient Direction + Fill Start Color + Fill End Color + Border + Enable Border + Accent Border Color + Border Color + Dashed Border + Dash Width + Dash Gap + Border Thickness + Padding + Padding Left + Padding Right + Padding Top + Padding Bottom + Corner Radius + Top Left Radius + Top Right Radius + Bottom Left Radius + Bottom Right Radius + + Custom Statusbar Clock Size + Set a custom size for Statusbar Clock + حجم ساعة شريط الحالة + Colored Statusbar Icon + Show app icon as notification icon + إخفاء LS Carrier + إخفاء اسم الناقل على شاشة القفل + إخفاء LS Statusbar + إخفاء شريط الحالة على شاشة القفل رأس QS إخفاء عنوان شركة الإتصال @@ -647,12 +798,8 @@ إخفاء أيقونات الحالة قم بإزالة أيقونات الوقت والتاريخ والبطارية شاشة القفل - إخفاء LS Carrier - إخفاء اسم الناقل على شاشة القفل - إخفاء LS Statusbar - إخفاء شريط الحالة على شاشة القفل - Hide LS Lock Icon - Hide lock icon view on lockscreen + إخفاء أيقونة القفل + إخفاء عرض رمز القفل العلوي على شاشة القفل أيقونات الحالة ثابتة قم بتعيين أيقونات الحالة في موضع ثابت\n قد يكون هناك خطأ في بعض الرومات @@ -737,6 +884,7 @@ أشكال تعديلات + Xposed الإعدادات سجل التغيير @@ -752,37 +900,14 @@ تم حفظ الإعدادات بنجاح لا شيء - النمط 1 - النمط 2 - النمط 3 - النمط 4 - النمط 5 - النمط 6 - النمط 7 - النمط 8 - النمط 9 - النمط 10 - النمط 11 - النمط 12 - النمط 13 - النمط 14 - النمط 15 - النمط 16 - النمط 17 - النمط 18 - النمط 19 - النمط 20 - النمط 21 - النمط 22 - النمط 23 - النمط 24 - النمط 25 + النمط %d استمر إعداة تشغيل تعطيل تمكين تطبيق + Save تعطيل الألوان المخصصة تطبيق الألوان إعادة ضبط @@ -851,10 +976,6 @@ مرحباً! أيقونة أيقونات مشغل الوسائط - المحدد: - المحدد: %s - المحدد: %1$s%2$s - محدد: %%1$s%2$s %3$s (إفتراضي) لا توجد ساعة نمط ساعة %d @@ -923,4 +1044,124 @@ اضغط على معاينة للتحديد لا تظهر مرة أخرى لضمان الأداء الوظيفي المناسب، يعد تمكين إضافة Iconify في LSPosed أمرًا إلزاميًا لنظام التشغيل Android 14 والإصدارات الأحدث.\n\nبعد ذلك، قم بتمكين الإصلاحات من: Tweaks > قائمة Xposed > السمات > آخرون. + Do not select file from Recent + Dismiss + Restart Device + Pending + Accent Primary + Accent Secondary + Accent Tertiary + Text Color Primary + Text Color Inverse + + + Unit + Verifying location + Select location + Enter location + Location + Set custom location + Cannot retrieve location! + Network geolocation is disabled.\n\nSet a custom location or enable network location. + Enable + Settings + Automatic updates + Check for new versions once in a while + Check updates over WiFi only + Check for updates in background only when connected to wifi + Metric (\u00b0C) + Imperial (\u00b0F) + Update + Enable + Update interval + 1 hour + 2 hours + 4 hours + 6 hours + 12 hours + Weather + Condition Icon Pack + Find more icon packs + Disabled + Error + Waiting \u2026 + No weather data + Error loading weather data + Waiting\u2026 + Updating\u2026 + Service disabled + Now + Background shadow + Service settings + Unknown + Error loading weather data + Weather + Last update: + No location available + No network found + Location permissions not granted + Select location + Search for a location + Enable Location Permissions + Location permissions are required to fetch weather data. Click OK to open Settings. + + Cloudy + Rainy + Sunny + Stormy + Snowy + Windy + Misty + + Weather on Lockscreen + Show weather on lockscreen + Last Update Time + Weather Provider + OpenWeatherMap API Key + OpenWeatherMap API Key required + Please enter your OpenWeatherMap API key to fetch weather data. + Show Location + Show Location before icon + Show Condition + Show Condition after temperature + Show Humidity + Show Humidity in a new row + Show Wind + Show Wind in a new row + Text Size + Image Size + Text Color + Set custom color for text + Custom Color + Custom color for all text in weather view + Custom location + Set custom location for weather + Custom Margins + Set custom margins for weather + Top margin + Center Layout + Side Margin + Bottom Margin + Center Weather View + Move weather view to center horizontally + + Weather Background Style + Default + Semi-transparent box + Semi-transparent box (round) + Q-Beta pill + Rounded, simple and with accent + Rounded, transparent and with accent + Gradient + Dark with accented borders + Dark with gradient borders + + SystemUI Restart Needed + A SystemUI restart is needed for this change to take effect. + Device Restart Needed + A device restart is needed for this change to take effect. + Switch Device Theme + Switch between light and dark themes if unexpected behavior occurs. + Device Rotation Theme + Switch rotation of your device for this change to take effect. diff --git a/app/src/main/res/values-ca-rES/strings.xml b/app/src/main/res/values-ca-rES/strings.xml index 0f6075b05..d0273f4a6 100644 --- a/app/src/main/res/values-ca-rES/strings.xml +++ b/app/src/main/res/values-ca-rES/strings.xml @@ -1,5 +1,5 @@ - + Customize Boring Android UI Initializing setup @@ -31,10 +31,22 @@ Oops Did Not Expect That Logs have been saved in documents folder. Logs + + Search + Search… + Clear + History entry + More + Clear history + No result Iconify Icon Pack Change system icon pack + Cellular Icons + Change system cellular icons + WiFi Icons + Change system WiFi icons Brightness Bar Customize progress slider QS Panel Tiles @@ -113,6 +125,8 @@ Some options like blur intensity doesn\'t take effect until systemui is restarted Show Home Page Card Show a beautiful card on the home page. + Haptic Feedback + Enhance touch feedback with interactive haptics. Clear App Cache Clear caches generated due to the usage of custom fonts, images, or gifs. Experimental @@ -122,6 +136,8 @@ About Github Repository Telegram Group + Translate Iconify + Help translate Iconify to your language. Credits Thanking those who made this possible. @@ -231,8 +247,8 @@ Misc. Minimal QS Panel Remove top shade of QS panel - Disable System Monet - Helps to retain custom colors\nSystemUI restart required + System Monet + Disable to retain custom colors\nSystemUI restart required Primary Color Pick primary accent color @@ -405,24 +421,93 @@ Tweaks related to QS panel Battery Style Customize battery icon view + Oneplus QS Header + OOS style quick settings header Header Image Add custom image on QS panel Header Clock Add custom clock on QS panel Lockscreen Clock Add custom clock on lockscreen + Lockscreen Weather + Add weather on lockscreen + Lockscreen Widgets + Add widgets on lockscreen Depth Wallpaper Show iOS like depth wallpaper Background Chip Add colored chip behind clock + Clock Chip Others Miscellaneous xposed tweaks - + Weather Settings + + Oneplus QS Header + Enable OOS style media player and tiles in QS + Haptic Feedback + Add haptic feedback on tiles + Hide Stock Media Player + Remove stock media player from QS panel + Blur Level + Fade Level + Top Margin + Expansion Amount + + Lockscreen Widgets + Enable Lockscreen Widgets + Add widgets to lockscreen + Device Info Widget + Show device info widget on lockscreen + Linear Progress Color + Circular Progress Color + Text Color + Custom Device Name + Set custom device name.\nKeep blank to disable. + Large Widgets + Large Widget 1 + Large Widget 2 + Mini Widgets + Mini Widget 1 + Mini Widget 2 + Mini Widget 3 + Mini Widget 4 + Custom Colors + Customize Widget Colors + Large Widget Active Color + Large Widget Inactive Color + Large Widget Icon Active Color + Large Widget Icon Inactive Color + Mini Widget Active Color + Mini Widget Inactive Color + Mini Widget Icon Active Color + Mini Widget Icon Inactive Color + Weather Settings + Widgets Scale + + Camera + Clock/Timer + Calculator + Gallery + Media Player + Torch + Play + Weather + Wifi + Data + Ringer + Bluetooth + Home Controls + Wallet + Hotspot + Ringer + Vibrate + Silent + Transparency Transparent QS Panel Make QS panel background transparent - Transparency Alpha - Transparent Notif Shade Only + Background Opacity + Transparent Notification Shade Make only notification shade transparent Dim Lockscreen Wallpaper Suitable for light-colored wallpapers @@ -432,7 +517,7 @@ Aggressive Blur Enabler Might bootloop in some roms Blur Intensity - + For Pixel Roms Light Theme Light QS theme in light mode\nMust use custom QS Shape @@ -449,21 +534,28 @@ Power Menu Transparency Power menu transparency for Fluid QS\nDo not use custom notification style Others + Fix QS Tile Color + Fix custom QS tile style on android 14 Fix Notification Color Fix custom notification style on android 14 - + Fix Notification Footer Button Color + Fix custom footer button style on android 14 + QS Tile Vertical QS Tile Show label below QS icon Hide QS Tile Label Use only with vertical tiles + Text Size Scaling QS Margin QS Elements + Hide QS on Lockscreen + Disable quick settings panel on secured lockscreen Hide Silent Text - Hide silent text shown as header of silent notifications (Requires SystemUI restart) + Hide silent text shown as header of silent notifications Hide Footer Buttons Hide footer buttons shown under notification stack - + Battery Style Battery Width Battery Height @@ -494,8 +586,8 @@ Change color of powersave battery Powersave Indicator Color Change color of powersave indicator - Custom Dimensions - Set custom dimensions for battery icon + Custom Margins + Set custom margins for battery icon Battery Margin Left Battery Margin Right Battery Margin Top @@ -546,17 +638,19 @@ Circle Battery Dotted Circle Battery Filled Circle Battery - + Volume Percentage Show percentage above volume slider Safety Warning Show warning on high volume - + Colored Ringer Icon + Enable if selected ringer icon is invisible + Pick Header Image Add header image on QS panel\nDo not select file from Recent Pick Image Image Height - Image Alpha + Image Opacity Bottom Fade Amount Zoom To Fit Image is stretched to fit by default @@ -564,35 +658,36 @@ Hide image in landscape mode Alpha Gradient Add faded effect to the header image - + Custom Header Clock Add a custom clock on QS panel Clock Style Clock Font - Use custom font for header clock\nDo not select file from Recent + Use custom font for header clock Custom Clock Color - Custom color instead of primary color + Custom colors instead of system colors Clock Color Picker Set color of header clock text + Expansion Amount Text Scaling - Clock Side Margin - Clock Top Margin + Side Margin + Top Margin White Text Force text colors to be white Center Clock Move clock to center of view Hide in Landscape Hide clock in landscape mode - + Custom Lockscreen Clock Enable custom lockscreen clock Auto Hide Clock Hide clock on incoming notification Clock Style Clock Font - Use custom font for lockscreen clock\nDo not select file from Recent + Use custom font for lockscreen clock Custom Clock Color - Custom color instead of primary color + Custom colors instead of system colors Clock Color Picker Set color of lockscreen clock text Text Scaling @@ -601,6 +696,13 @@ Bottom Margin White Text Force all colors to be white + Use Custom Image + Use custom image for lockscreen clock. + Custom Image Picker + Custom Device Name + Set custom device name for lockscreen clock.\nKeep blank to use System\'s Device Name. + Custom User Name + Set custom user name for lockscreen clock.\nKeep blank to use System\'s User Name. Select Battery Charging Battery Discharging @@ -608,14 +710,18 @@ Battery Level Welcome back! User - + Enable Depth Wallpaper - Show iOS like depth wallpaper\nMust use custom lockscreen clock + Show iOS like depth wallpaper\n%s + Custom Images + Set custom images as depth wallpaper + Show on AOD + Show subject on always on display Fade in AOD Animate wallpaper and fade away in AOD Foreground Image Foreground image for depth wallpaper - Foreground Image Alpha + Foreground Image Opacity Background Image Background image for depth wallpaper This feature is currently in beta stage. So bugs are expected.\n\nKnown Bug(s):\n• Tapping on lockscreen makes the wallpaper jump. @@ -623,23 +729,68 @@ Move background and foreground layers at different speeds Foreground Sensitivity Background Sensitivity - + AI model is downloaded on the device + AI model isn\'t available on the device (yet) + Extracting wallpaper subject… + Extracted wallpaper subject! + Failed to extract wallpaper subject! + AI model is not available! + Must use custom lockscreen clock + Status Bar Statusbar Clock Chip Display chip behind statusbar clock - Statusbar Clock Color + Customize Clock Chip + Custom colors, roundness, stroke etc. + Text + Clock Text Color Follow System Transparent Text Custom Color - Clock Color Picker - Set color of statubsar clock text + Text Color Picker + Set color of statubsar clock text Status Icons Chip Style Status Icons Chip Display chip behind status icons + Customize Status Icons Chip + Custom colors, roundness, stroke etc. Chip Style Top Margin Side Margin + Background + Accent Fill Color + Gradient Direction + Fill Start Color + Fill End Color + Border + Enable Border + Accent Border Color + Border Color + Dashed Border + Dash Width + Dash Gap + Border Thickness + Padding + Padding Left + Padding Right + Padding Top + Padding Bottom + Corner Radius + Top Left Radius + Top Right Radius + Bottom Left Radius + Bottom Right Radius + + Custom Statusbar Clock Size + Set a custom size for Statusbar Clock + Statusbar Clock Size + Colored Statusbar Icon + Show app icon as notification icon + Hide LS Carrier + Hide carrier name on lockscreen + Hide LS Statusbar + Hide statusbar on lockscreen QS Header Hide Carrier Group @@ -647,10 +798,6 @@ Hide Status Icons Remove time, date and battery icons Lock Screen - Hide LS Carrier - Hide carrier name on lockscreen - Hide LS Statusbar - Hide statusbar on lockscreen Hide LS Lock Icon Hide lock icon view on lockscreen Fixed Status Icons @@ -737,6 +884,7 @@ Home Tweaks + Xposed Settings Changelog @@ -752,37 +900,14 @@ Saved settings successfully None - Style 1 - Style 2 - Style 3 - Style 4 - Style 5 - Style 6 - Style 7 - Style 8 - Style 9 - Style 10 - Style 11 - Style 12 - Style 13 - Style 14 - Style 15 - Style 16 - Style 17 - Style 18 - Style 19 - Style 20 - Style 21 - Style 22 - Style 23 - Style 24 - Style 25 + Style %d Continue Restart Disable Enable Apply + Save Disable Custom Colors Apply Colors Reset @@ -851,10 +976,6 @@ Hey There! Icon Media Player Icons - Selected: - Selected: %s - Selected: %1$s%2$s - Selected: %1$s%2$s %3$s (Default) No Clock Clock Style %d @@ -923,4 +1044,124 @@ Tap on preview to select Don\'t show again To ensure proper functionality, enabling the Iconify module in LSPosed is mandatory for android 14 and above.\n\nAfter that, enable the fixes from: Tweaks > Xposed Menu > Themes > Others. + Do not select file from Recent + Dismiss + Restart Device + Pending + Accent Primary + Accent Secondary + Accent Tertiary + Text Color Primary + Text Color Inverse + + + Unit + Verifying location + Select location + Enter location + Location + Set custom location + Cannot retrieve location! + Network geolocation is disabled.\n\nSet a custom location or enable network location. + Enable + Settings + Automatic updates + Check for new versions once in a while + Check updates over WiFi only + Check for updates in background only when connected to wifi + Metric (\u00b0C) + Imperial (\u00b0F) + Update + Enable + Update interval + 1 hour + 2 hours + 4 hours + 6 hours + 12 hours + Weather + Condition Icon Pack + Find more icon packs + Disabled + Error + Waiting \u2026 + No weather data + Error loading weather data + Waiting\u2026 + Updating\u2026 + Service disabled + Now + Background shadow + Service settings + Unknown + Error loading weather data + Weather + Last update: + No location available + No network found + Location permissions not granted + Select location + Search for a location + Enable Location Permissions + Location permissions are required to fetch weather data. Click OK to open Settings. + + Cloudy + Rainy + Sunny + Stormy + Snowy + Windy + Misty + + Weather on Lockscreen + Show weather on lockscreen + Last Update Time + Weather Provider + OpenWeatherMap API Key + OpenWeatherMap API Key required + Please enter your OpenWeatherMap API key to fetch weather data. + Show Location + Show Location before icon + Show Condition + Show Condition after temperature + Show Humidity + Show Humidity in a new row + Show Wind + Show Wind in a new row + Text Size + Image Size + Text Color + Set custom color for text + Custom Color + Custom color for all text in weather view + Custom location + Set custom location for weather + Custom Margins + Set custom margins for weather + Top margin + Center Layout + Side Margin + Bottom Margin + Center Weather View + Move weather view to center horizontally + + Weather Background Style + Default + Semi-transparent box + Semi-transparent box (round) + Q-Beta pill + Rounded, simple and with accent + Rounded, transparent and with accent + Gradient + Dark with accented borders + Dark with gradient borders + + SystemUI Restart Needed + A SystemUI restart is needed for this change to take effect. + Device Restart Needed + A device restart is needed for this change to take effect. + Switch Device Theme + Switch between light and dark themes if unexpected behavior occurs. + Device Rotation Theme + Switch rotation of your device for this change to take effect. diff --git a/app/src/main/res/values-cs-rCZ/strings.xml b/app/src/main/res/values-cs-rCZ/strings.xml index 17ee9cf37..21087df1c 100644 --- a/app/src/main/res/values-cs-rCZ/strings.xml +++ b/app/src/main/res/values-cs-rCZ/strings.xml @@ -1,5 +1,5 @@ - + Přizpůsobte si nudné Android prostředí Inicializace nastavení @@ -31,10 +31,22 @@ Oops Did Not Expect That Logs have been saved in documents folder. Logs + + Search + Search… + Clear + History entry + More + Clear history + No result Iconify Icon Pack Change system icon pack + Cellular Icons + Change system cellular icons + WiFi Icons + Change system WiFi icons Brightness Bar Customize progress slider QS Panel Tiles @@ -113,6 +125,8 @@ Some options like blur intensity doesn\'t take effect until systemui is restarted Show Home Page Card Show a beautiful card on the home page. + Haptic Feedback + Enhance touch feedback with interactive haptics. Clear App Cache Clear caches generated due to the usage of custom fonts, images, or gifs. Experimental @@ -122,6 +136,8 @@ About Github Repository Telegram Group + Translate Iconify + Help translate Iconify to your language. Credits Thanking those who made this possible. @@ -231,8 +247,8 @@ Misc. Minimal QS Panel Remove top shade of QS panel - Disable System Monet - Helps to retain custom colors\nSystemUI restart required + System Monet + Disable to retain custom colors\nSystemUI restart required Primary Color Pick primary accent color @@ -405,24 +421,93 @@ Tweaks related to QS panel Battery Style Customize battery icon view + Oneplus QS Header + OOS style quick settings header Header Image Add custom image on QS panel Header Clock Add custom clock on QS panel Lockscreen Clock Add custom clock on lockscreen + Lockscreen Weather + Add weather on lockscreen + Lockscreen Widgets + Add widgets on lockscreen Depth Wallpaper Show iOS like depth wallpaper Background Chip Add colored chip behind clock + Clock Chip Others Miscellaneous xposed tweaks - + Weather Settings + + Oneplus QS Header + Enable OOS style media player and tiles in QS + Haptic Feedback + Add haptic feedback on tiles + Hide Stock Media Player + Remove stock media player from QS panel + Blur Level + Fade Level + Top Margin + Expansion Amount + + Lockscreen Widgets + Enable Lockscreen Widgets + Add widgets to lockscreen + Device Info Widget + Show device info widget on lockscreen + Linear Progress Color + Circular Progress Color + Text Color + Custom Device Name + Set custom device name.\nKeep blank to disable. + Large Widgets + Large Widget 1 + Large Widget 2 + Mini Widgets + Mini Widget 1 + Mini Widget 2 + Mini Widget 3 + Mini Widget 4 + Custom Colors + Customize Widget Colors + Large Widget Active Color + Large Widget Inactive Color + Large Widget Icon Active Color + Large Widget Icon Inactive Color + Mini Widget Active Color + Mini Widget Inactive Color + Mini Widget Icon Active Color + Mini Widget Icon Inactive Color + Weather Settings + Widgets Scale + + Camera + Clock/Timer + Calculator + Gallery + Media Player + Torch + Play + Weather + Wifi + Data + Ringer + Bluetooth + Home Controls + Wallet + Hotspot + Ringer + Vibrate + Silent + Transparency Transparent QS Panel Make QS panel background transparent - Transparency Alpha - Transparent Notif Shade Only + Background Opacity + Transparent Notification Shade Make only notification shade transparent Dim Lockscreen Wallpaper Suitable for light-colored wallpapers @@ -432,7 +517,7 @@ Aggressive Blur Enabler Might bootloop in some roms Blur Intensity - + For Pixel Roms Light Theme Light QS theme in light mode\nMust use custom QS Shape @@ -449,21 +534,28 @@ Power Menu Transparency Power menu transparency for Fluid QS\nDo not use custom notification style Others + Fix QS Tile Color + Fix custom QS tile style on android 14 Fix Notification Color Fix custom notification style on android 14 - + Fix Notification Footer Button Color + Fix custom footer button style on android 14 + QS Tile Vertical QS Tile Show label below QS icon Hide QS Tile Label Use only with vertical tiles + Text Size Scaling QS Margin QS Elements + Hide QS on Lockscreen + Disable quick settings panel on secured lockscreen Hide Silent Text - Hide silent text shown as header of silent notifications (Requires SystemUI restart) + Hide silent text shown as header of silent notifications Hide Footer Buttons Hide footer buttons shown under notification stack - + Battery Style Battery Width Battery Height @@ -494,8 +586,8 @@ Change color of powersave battery Powersave Indicator Color Change color of powersave indicator - Custom Dimensions - Set custom dimensions for battery icon + Custom Margins + Set custom margins for battery icon Battery Margin Left Battery Margin Right Battery Margin Top @@ -546,17 +638,19 @@ Circle Battery Dotted Circle Battery Filled Circle Battery - + Volume Percentage Show percentage above volume slider Safety Warning Show warning on high volume - + Colored Ringer Icon + Enable if selected ringer icon is invisible + Pick Header Image Add header image on QS panel\nDo not select file from Recent Pick Image Image Height - Image Alpha + Image Opacity Bottom Fade Amount Zoom To Fit Image is stretched to fit by default @@ -564,35 +658,36 @@ Hide image in landscape mode Alpha Gradient Add faded effect to the header image - + Custom Header Clock Add a custom clock on QS panel Clock Style Clock Font - Use custom font for header clock\nDo not select file from Recent + Use custom font for header clock Custom Clock Color - Custom color instead of primary color + Custom colors instead of system colors Clock Color Picker Set color of header clock text + Expansion Amount Text Scaling - Clock Side Margin - Clock Top Margin + Side Margin + Top Margin White Text Force text colors to be white Center Clock Move clock to center of view Hide in Landscape Hide clock in landscape mode - + Custom Lockscreen Clock Enable custom lockscreen clock Auto Hide Clock Hide clock on incoming notification Clock Style Clock Font - Use custom font for lockscreen clock\nDo not select file from Recent + Use custom font for lockscreen clock Custom Clock Color - Custom color instead of primary color + Custom colors instead of system colors Clock Color Picker Set color of lockscreen clock text Text Scaling @@ -601,6 +696,13 @@ Bottom Margin White Text Force all colors to be white + Use Custom Image + Use custom image for lockscreen clock. + Custom Image Picker + Custom Device Name + Set custom device name for lockscreen clock.\nKeep blank to use System\'s Device Name. + Custom User Name + Set custom user name for lockscreen clock.\nKeep blank to use System\'s User Name. Select Battery Charging Battery Discharging @@ -608,14 +710,18 @@ Battery Level Welcome back! User - + Enable Depth Wallpaper - Show iOS like depth wallpaper\nMust use custom lockscreen clock + Show iOS like depth wallpaper\n%s + Custom Images + Set custom images as depth wallpaper + Show on AOD + Show subject on always on display Fade in AOD Animate wallpaper and fade away in AOD Foreground Image Foreground image for depth wallpaper - Foreground Image Alpha + Foreground Image Opacity Background Image Background image for depth wallpaper This feature is currently in beta stage. So bugs are expected.\n\nKnown Bug(s):\n• Tapping on lockscreen makes the wallpaper jump. @@ -623,23 +729,68 @@ Move background and foreground layers at different speeds Foreground Sensitivity Background Sensitivity - + AI model is downloaded on the device + AI model isn\'t available on the device (yet) + Extracting wallpaper subject… + Extracted wallpaper subject! + Failed to extract wallpaper subject! + AI model is not available! + Must use custom lockscreen clock + Status Bar Statusbar Clock Chip Display chip behind statusbar clock - Statusbar Clock Color + Customize Clock Chip + Custom colors, roundness, stroke etc. + Text + Clock Text Color Follow System Transparent Text Custom Color - Clock Color Picker - Set color of statubsar clock text + Text Color Picker + Set color of statubsar clock text Status Icons Chip Style Status Icons Chip Display chip behind status icons + Customize Status Icons Chip + Custom colors, roundness, stroke etc. Chip Style Top Margin Side Margin + Background + Accent Fill Color + Gradient Direction + Fill Start Color + Fill End Color + Border + Enable Border + Accent Border Color + Border Color + Dashed Border + Dash Width + Dash Gap + Border Thickness + Padding + Padding Left + Padding Right + Padding Top + Padding Bottom + Corner Radius + Top Left Radius + Top Right Radius + Bottom Left Radius + Bottom Right Radius + + Custom Statusbar Clock Size + Set a custom size for Statusbar Clock + Statusbar Clock Size + Colored Statusbar Icon + Show app icon as notification icon + Hide LS Carrier + Hide carrier name on lockscreen + Hide LS Statusbar + Hide statusbar on lockscreen QS Header Hide Carrier Group @@ -647,10 +798,6 @@ Hide Status Icons Remove time, date and battery icons Lock Screen - Hide LS Carrier - Hide carrier name on lockscreen - Hide LS Statusbar - Hide statusbar on lockscreen Hide LS Lock Icon Hide lock icon view on lockscreen Fixed Status Icons @@ -737,6 +884,7 @@ Home Tweaks + Xposed Settings Changelog @@ -752,37 +900,14 @@ Saved settings successfully None - Style 1 - Style 2 - Style 3 - Style 4 - Style 5 - Style 6 - Style 7 - Style 8 - Style 9 - Style 10 - Style 11 - Style 12 - Style 13 - Style 14 - Style 15 - Style 16 - Style 17 - Style 18 - Style 19 - Style 20 - Style 21 - Style 22 - Style 23 - Style 24 - Style 25 + Style %d Continue Restart Disable Enable Apply + Save Disable Custom Colors Apply Colors Reset @@ -851,10 +976,6 @@ Hey There! Icon Media Player Icons - Selected: - Selected: %s - Selected: %1$s%2$s - Selected: %1$s%2$s %3$s (Default) No Clock Clock Style %d @@ -923,4 +1044,124 @@ Tap on preview to select Don\'t show again To ensure proper functionality, enabling the Iconify module in LSPosed is mandatory for android 14 and above.\n\nAfter that, enable the fixes from: Tweaks > Xposed Menu > Themes > Others. + Do not select file from Recent + Dismiss + Restart Device + Pending + Accent Primary + Accent Secondary + Accent Tertiary + Text Color Primary + Text Color Inverse + + + Unit + Verifying location + Select location + Enter location + Location + Set custom location + Cannot retrieve location! + Network geolocation is disabled.\n\nSet a custom location or enable network location. + Enable + Settings + Automatic updates + Check for new versions once in a while + Check updates over WiFi only + Check for updates in background only when connected to wifi + Metric (\u00b0C) + Imperial (\u00b0F) + Update + Enable + Update interval + 1 hour + 2 hours + 4 hours + 6 hours + 12 hours + Weather + Condition Icon Pack + Find more icon packs + Disabled + Error + Waiting \u2026 + No weather data + Error loading weather data + Waiting\u2026 + Updating\u2026 + Service disabled + Now + Background shadow + Service settings + Unknown + Error loading weather data + Weather + Last update: + No location available + No network found + Location permissions not granted + Select location + Search for a location + Enable Location Permissions + Location permissions are required to fetch weather data. Click OK to open Settings. + + Cloudy + Rainy + Sunny + Stormy + Snowy + Windy + Misty + + Weather on Lockscreen + Show weather on lockscreen + Last Update Time + Weather Provider + OpenWeatherMap API Key + OpenWeatherMap API Key required + Please enter your OpenWeatherMap API key to fetch weather data. + Show Location + Show Location before icon + Show Condition + Show Condition after temperature + Show Humidity + Show Humidity in a new row + Show Wind + Show Wind in a new row + Text Size + Image Size + Text Color + Set custom color for text + Custom Color + Custom color for all text in weather view + Custom location + Set custom location for weather + Custom Margins + Set custom margins for weather + Top margin + Center Layout + Side Margin + Bottom Margin + Center Weather View + Move weather view to center horizontally + + Weather Background Style + Default + Semi-transparent box + Semi-transparent box (round) + Q-Beta pill + Rounded, simple and with accent + Rounded, transparent and with accent + Gradient + Dark with accented borders + Dark with gradient borders + + SystemUI Restart Needed + A SystemUI restart is needed for this change to take effect. + Device Restart Needed + A device restart is needed for this change to take effect. + Switch Device Theme + Switch between light and dark themes if unexpected behavior occurs. + Device Rotation Theme + Switch rotation of your device for this change to take effect. diff --git a/app/src/main/res/values-da-rDK/strings.xml b/app/src/main/res/values-da-rDK/strings.xml index 0f6075b05..d0273f4a6 100644 --- a/app/src/main/res/values-da-rDK/strings.xml +++ b/app/src/main/res/values-da-rDK/strings.xml @@ -1,5 +1,5 @@ - + Customize Boring Android UI Initializing setup @@ -31,10 +31,22 @@ Oops Did Not Expect That Logs have been saved in documents folder. Logs + + Search + Search… + Clear + History entry + More + Clear history + No result Iconify Icon Pack Change system icon pack + Cellular Icons + Change system cellular icons + WiFi Icons + Change system WiFi icons Brightness Bar Customize progress slider QS Panel Tiles @@ -113,6 +125,8 @@ Some options like blur intensity doesn\'t take effect until systemui is restarted Show Home Page Card Show a beautiful card on the home page. + Haptic Feedback + Enhance touch feedback with interactive haptics. Clear App Cache Clear caches generated due to the usage of custom fonts, images, or gifs. Experimental @@ -122,6 +136,8 @@ About Github Repository Telegram Group + Translate Iconify + Help translate Iconify to your language. Credits Thanking those who made this possible. @@ -231,8 +247,8 @@ Misc. Minimal QS Panel Remove top shade of QS panel - Disable System Monet - Helps to retain custom colors\nSystemUI restart required + System Monet + Disable to retain custom colors\nSystemUI restart required Primary Color Pick primary accent color @@ -405,24 +421,93 @@ Tweaks related to QS panel Battery Style Customize battery icon view + Oneplus QS Header + OOS style quick settings header Header Image Add custom image on QS panel Header Clock Add custom clock on QS panel Lockscreen Clock Add custom clock on lockscreen + Lockscreen Weather + Add weather on lockscreen + Lockscreen Widgets + Add widgets on lockscreen Depth Wallpaper Show iOS like depth wallpaper Background Chip Add colored chip behind clock + Clock Chip Others Miscellaneous xposed tweaks - + Weather Settings + + Oneplus QS Header + Enable OOS style media player and tiles in QS + Haptic Feedback + Add haptic feedback on tiles + Hide Stock Media Player + Remove stock media player from QS panel + Blur Level + Fade Level + Top Margin + Expansion Amount + + Lockscreen Widgets + Enable Lockscreen Widgets + Add widgets to lockscreen + Device Info Widget + Show device info widget on lockscreen + Linear Progress Color + Circular Progress Color + Text Color + Custom Device Name + Set custom device name.\nKeep blank to disable. + Large Widgets + Large Widget 1 + Large Widget 2 + Mini Widgets + Mini Widget 1 + Mini Widget 2 + Mini Widget 3 + Mini Widget 4 + Custom Colors + Customize Widget Colors + Large Widget Active Color + Large Widget Inactive Color + Large Widget Icon Active Color + Large Widget Icon Inactive Color + Mini Widget Active Color + Mini Widget Inactive Color + Mini Widget Icon Active Color + Mini Widget Icon Inactive Color + Weather Settings + Widgets Scale + + Camera + Clock/Timer + Calculator + Gallery + Media Player + Torch + Play + Weather + Wifi + Data + Ringer + Bluetooth + Home Controls + Wallet + Hotspot + Ringer + Vibrate + Silent + Transparency Transparent QS Panel Make QS panel background transparent - Transparency Alpha - Transparent Notif Shade Only + Background Opacity + Transparent Notification Shade Make only notification shade transparent Dim Lockscreen Wallpaper Suitable for light-colored wallpapers @@ -432,7 +517,7 @@ Aggressive Blur Enabler Might bootloop in some roms Blur Intensity - + For Pixel Roms Light Theme Light QS theme in light mode\nMust use custom QS Shape @@ -449,21 +534,28 @@ Power Menu Transparency Power menu transparency for Fluid QS\nDo not use custom notification style Others + Fix QS Tile Color + Fix custom QS tile style on android 14 Fix Notification Color Fix custom notification style on android 14 - + Fix Notification Footer Button Color + Fix custom footer button style on android 14 + QS Tile Vertical QS Tile Show label below QS icon Hide QS Tile Label Use only with vertical tiles + Text Size Scaling QS Margin QS Elements + Hide QS on Lockscreen + Disable quick settings panel on secured lockscreen Hide Silent Text - Hide silent text shown as header of silent notifications (Requires SystemUI restart) + Hide silent text shown as header of silent notifications Hide Footer Buttons Hide footer buttons shown under notification stack - + Battery Style Battery Width Battery Height @@ -494,8 +586,8 @@ Change color of powersave battery Powersave Indicator Color Change color of powersave indicator - Custom Dimensions - Set custom dimensions for battery icon + Custom Margins + Set custom margins for battery icon Battery Margin Left Battery Margin Right Battery Margin Top @@ -546,17 +638,19 @@ Circle Battery Dotted Circle Battery Filled Circle Battery - + Volume Percentage Show percentage above volume slider Safety Warning Show warning on high volume - + Colored Ringer Icon + Enable if selected ringer icon is invisible + Pick Header Image Add header image on QS panel\nDo not select file from Recent Pick Image Image Height - Image Alpha + Image Opacity Bottom Fade Amount Zoom To Fit Image is stretched to fit by default @@ -564,35 +658,36 @@ Hide image in landscape mode Alpha Gradient Add faded effect to the header image - + Custom Header Clock Add a custom clock on QS panel Clock Style Clock Font - Use custom font for header clock\nDo not select file from Recent + Use custom font for header clock Custom Clock Color - Custom color instead of primary color + Custom colors instead of system colors Clock Color Picker Set color of header clock text + Expansion Amount Text Scaling - Clock Side Margin - Clock Top Margin + Side Margin + Top Margin White Text Force text colors to be white Center Clock Move clock to center of view Hide in Landscape Hide clock in landscape mode - + Custom Lockscreen Clock Enable custom lockscreen clock Auto Hide Clock Hide clock on incoming notification Clock Style Clock Font - Use custom font for lockscreen clock\nDo not select file from Recent + Use custom font for lockscreen clock Custom Clock Color - Custom color instead of primary color + Custom colors instead of system colors Clock Color Picker Set color of lockscreen clock text Text Scaling @@ -601,6 +696,13 @@ Bottom Margin White Text Force all colors to be white + Use Custom Image + Use custom image for lockscreen clock. + Custom Image Picker + Custom Device Name + Set custom device name for lockscreen clock.\nKeep blank to use System\'s Device Name. + Custom User Name + Set custom user name for lockscreen clock.\nKeep blank to use System\'s User Name. Select Battery Charging Battery Discharging @@ -608,14 +710,18 @@ Battery Level Welcome back! User - + Enable Depth Wallpaper - Show iOS like depth wallpaper\nMust use custom lockscreen clock + Show iOS like depth wallpaper\n%s + Custom Images + Set custom images as depth wallpaper + Show on AOD + Show subject on always on display Fade in AOD Animate wallpaper and fade away in AOD Foreground Image Foreground image for depth wallpaper - Foreground Image Alpha + Foreground Image Opacity Background Image Background image for depth wallpaper This feature is currently in beta stage. So bugs are expected.\n\nKnown Bug(s):\n• Tapping on lockscreen makes the wallpaper jump. @@ -623,23 +729,68 @@ Move background and foreground layers at different speeds Foreground Sensitivity Background Sensitivity - + AI model is downloaded on the device + AI model isn\'t available on the device (yet) + Extracting wallpaper subject… + Extracted wallpaper subject! + Failed to extract wallpaper subject! + AI model is not available! + Must use custom lockscreen clock + Status Bar Statusbar Clock Chip Display chip behind statusbar clock - Statusbar Clock Color + Customize Clock Chip + Custom colors, roundness, stroke etc. + Text + Clock Text Color Follow System Transparent Text Custom Color - Clock Color Picker - Set color of statubsar clock text + Text Color Picker + Set color of statubsar clock text Status Icons Chip Style Status Icons Chip Display chip behind status icons + Customize Status Icons Chip + Custom colors, roundness, stroke etc. Chip Style Top Margin Side Margin + Background + Accent Fill Color + Gradient Direction + Fill Start Color + Fill End Color + Border + Enable Border + Accent Border Color + Border Color + Dashed Border + Dash Width + Dash Gap + Border Thickness + Padding + Padding Left + Padding Right + Padding Top + Padding Bottom + Corner Radius + Top Left Radius + Top Right Radius + Bottom Left Radius + Bottom Right Radius + + Custom Statusbar Clock Size + Set a custom size for Statusbar Clock + Statusbar Clock Size + Colored Statusbar Icon + Show app icon as notification icon + Hide LS Carrier + Hide carrier name on lockscreen + Hide LS Statusbar + Hide statusbar on lockscreen QS Header Hide Carrier Group @@ -647,10 +798,6 @@ Hide Status Icons Remove time, date and battery icons Lock Screen - Hide LS Carrier - Hide carrier name on lockscreen - Hide LS Statusbar - Hide statusbar on lockscreen Hide LS Lock Icon Hide lock icon view on lockscreen Fixed Status Icons @@ -737,6 +884,7 @@ Home Tweaks + Xposed Settings Changelog @@ -752,37 +900,14 @@ Saved settings successfully None - Style 1 - Style 2 - Style 3 - Style 4 - Style 5 - Style 6 - Style 7 - Style 8 - Style 9 - Style 10 - Style 11 - Style 12 - Style 13 - Style 14 - Style 15 - Style 16 - Style 17 - Style 18 - Style 19 - Style 20 - Style 21 - Style 22 - Style 23 - Style 24 - Style 25 + Style %d Continue Restart Disable Enable Apply + Save Disable Custom Colors Apply Colors Reset @@ -851,10 +976,6 @@ Hey There! Icon Media Player Icons - Selected: - Selected: %s - Selected: %1$s%2$s - Selected: %1$s%2$s %3$s (Default) No Clock Clock Style %d @@ -923,4 +1044,124 @@ Tap on preview to select Don\'t show again To ensure proper functionality, enabling the Iconify module in LSPosed is mandatory for android 14 and above.\n\nAfter that, enable the fixes from: Tweaks > Xposed Menu > Themes > Others. + Do not select file from Recent + Dismiss + Restart Device + Pending + Accent Primary + Accent Secondary + Accent Tertiary + Text Color Primary + Text Color Inverse + + + Unit + Verifying location + Select location + Enter location + Location + Set custom location + Cannot retrieve location! + Network geolocation is disabled.\n\nSet a custom location or enable network location. + Enable + Settings + Automatic updates + Check for new versions once in a while + Check updates over WiFi only + Check for updates in background only when connected to wifi + Metric (\u00b0C) + Imperial (\u00b0F) + Update + Enable + Update interval + 1 hour + 2 hours + 4 hours + 6 hours + 12 hours + Weather + Condition Icon Pack + Find more icon packs + Disabled + Error + Waiting \u2026 + No weather data + Error loading weather data + Waiting\u2026 + Updating\u2026 + Service disabled + Now + Background shadow + Service settings + Unknown + Error loading weather data + Weather + Last update: + No location available + No network found + Location permissions not granted + Select location + Search for a location + Enable Location Permissions + Location permissions are required to fetch weather data. Click OK to open Settings. + + Cloudy + Rainy + Sunny + Stormy + Snowy + Windy + Misty + + Weather on Lockscreen + Show weather on lockscreen + Last Update Time + Weather Provider + OpenWeatherMap API Key + OpenWeatherMap API Key required + Please enter your OpenWeatherMap API key to fetch weather data. + Show Location + Show Location before icon + Show Condition + Show Condition after temperature + Show Humidity + Show Humidity in a new row + Show Wind + Show Wind in a new row + Text Size + Image Size + Text Color + Set custom color for text + Custom Color + Custom color for all text in weather view + Custom location + Set custom location for weather + Custom Margins + Set custom margins for weather + Top margin + Center Layout + Side Margin + Bottom Margin + Center Weather View + Move weather view to center horizontally + + Weather Background Style + Default + Semi-transparent box + Semi-transparent box (round) + Q-Beta pill + Rounded, simple and with accent + Rounded, transparent and with accent + Gradient + Dark with accented borders + Dark with gradient borders + + SystemUI Restart Needed + A SystemUI restart is needed for this change to take effect. + Device Restart Needed + A device restart is needed for this change to take effect. + Switch Device Theme + Switch between light and dark themes if unexpected behavior occurs. + Device Rotation Theme + Switch rotation of your device for this change to take effect. diff --git a/app/src/main/res/values-de-rDE/strings.xml b/app/src/main/res/values-de-rDE/strings.xml index 6ed214c21..64f970d53 100644 --- a/app/src/main/res/values-de-rDE/strings.xml +++ b/app/src/main/res/values-de-rDE/strings.xml @@ -1,5 +1,5 @@ - + Personalisiere das langweilige Android UI Starte Einrichtung @@ -31,10 +31,22 @@ Oops Das War Unerwartet Logs wurden im Dokumente Ordner gespeichert. Logs + + Search + Search… + Clear + History entry + More + Clear history + No result Symbolpaket System Icons verändern + Cellular Icons + Change system cellular icons + WiFi Symbole + Ändere System WiFi Symbole Helligkeitsregler Verändere Fortschrittsbalken QS Kacheln @@ -113,6 +125,8 @@ Mache Einstellungen wie Blur-Intensität werden nicht übernommen bis SystemUI neu gestartet ist Zeige Home Page Karte Zeige eine schöne Karte auf der Hauptseite. + Haptic Feedback + Enhance touch feedback with interactive haptics. Lösche App Cache Leere Caches welche erstellt wurden aufgrund von eigenen Schriftarten, Bildern oder GIFs. Experimentell @@ -122,6 +136,8 @@ Über Github Repository Telegram Gruppe + Translate Iconify + Help translate Iconify to your language. Credits Danke an alle, die dieses Projekt ermöglicht haben. @@ -231,8 +247,8 @@ Verschiedenes Minimales QS-Panel Obere Schattierung des QS-Panels entfernen - Deaktiviere System Monet - Hilft benutzerdefinierte Farben beizubehalten\nSystemUI Neustart erforderlich + System Monet + Disable to retain custom colors\nSystemUI restart required Primärfarbe Wähle primäre Akzentfarbe @@ -405,24 +421,93 @@ Optimierungen für das QS-Panel Batteriestil Passe das Batteriesymbol an + Oneplus QS Header + OOS style quick settings header Headerbild Füge eigenes Bild zum QS-Panel hinzu Headeruhr Füge eigene Headeruhr zum QS-Panel hinzu Sperrbildschirmuhr Füge eigne Uhr auf den Sperrbildschirm hinzu + Lockscreen Weather + Add weather on lockscreen + Lockscreen Widgets + Add widgets on lockscreen Tiefes Hintergrundbild Verwende iOS-mäßiges Tiefenhintergrundbild Hintergrund-Chip Füge einen farbigen Chip hinter der Uhr hinzu + Clock Chip Anderes Sonstige Xposed Anpassungen - + Weather Settings + + Oneplus QS Header + Enable OOS style media player and tiles in QS + Haptic Feedback + Add haptic feedback on tiles + Hide Stock Media Player + Remove stock media player from QS panel + Blur Level + Fade Level + Top Margin + Expansion Amount + + Lockscreen Widgets + Enable Lockscreen Widgets + Add widgets to lockscreen + Device Info Widget + Show device info widget on lockscreen + Linear Progress Color + Circular Progress Color + Text Color + Custom Device Name + Set custom device name.\nKeep blank to disable. + Large Widgets + Large Widget 1 + Large Widget 2 + Mini Widgets + Mini Widget 1 + Mini Widget 2 + Mini Widget 3 + Mini Widget 4 + Custom Colors + Customize Widget Colors + Large Widget Active Color + Large Widget Inactive Color + Large Widget Icon Active Color + Large Widget Icon Inactive Color + Mini Widget Active Color + Mini Widget Inactive Color + Mini Widget Icon Active Color + Mini Widget Icon Inactive Color + Weather Settings + Widgets Scale + + Camera + Clock/Timer + Calculator + Gallery + Media Player + Torch + Play + Weather + Wifi + Data + Ringer + Bluetooth + Home Controls + Wallet + Hotspot + Ringer + Vibrate + Silent + Transparenz Transparentes QS-Panel Macht den QS-Panel-Hintergrund transparent - Transparenz Alpha - Nur transparentes Benachrichtigungsfeld + Background Opacity + Transparent Notification Shade Nur das Feld hinter den Benachrichtigungen transparent machen Sperrbildschirmhintergrund abdunkeln @@ -433,7 +518,7 @@ transparent machen Aggressiver Blur-Aktivierer Kann in manchen ROMs zu Bootlooping führen Blurintensität - + Für Pixel ROMs Helles Design Helles QS im Light-Mode\nEs müssen eigene QS Formen benutzt werden @@ -450,21 +535,28 @@ transparent machen Power-Menü Transparenz Power-Menü für flüssiges QS\nBenutze keinen angepassten Benachrichtigungsstil Anderes + Fix QS Tile Color + Fix custom QS tile style on android 14 Repariere Benachrichtungsfarbe Repariere benutzerdefinierten Benachrichtungsstil auf Android 14 - + Fix Notification Footer Button Color + Fix custom footer button style on android 14 + QS Kachel Vertikale QS Kacheln Zeige Text unter QS Symbol Verstecke QS Beschreibung Nur mit vertikalen Kachen benutzen + Text Größe Skalierung QS Abstand QS Elemente + Hide QS on Lockscreen + Disable quick settings panel on secured lockscreen Lautloser Text ausblenden - Hide silent text shown as header of silent notifications (Requires SystemUI restart) + Hide silent text shown as header of silent notifications Fußzeilentasten verbergen Hide footer buttons shown under notification stack - + Akku Stil Akku Breite Akku Höhe @@ -495,8 +587,8 @@ transparent machen Ändere Farbe des Energiesparmodus Akkus Energiesparmodus Indikator Farbe Ändere Farbe des Energiesparmodus Indikators - Benutzerdefinierte Größe - Setze benutzerdefinierte Größe für Akkusymbol + Custom Margins + Set custom margins for battery icon Akku Abstand links Akku Abstand rechts Akku Abstand oben @@ -547,17 +639,19 @@ transparent machen Kreissymbol Gepunktetes Kreissymbol Filled Circle Battery - - Volume Percentage - Show percentage above volume slider + + Lautstärke Prozentsatz + Zeige Prozentsatz über dem Lautstärkeregler Sicherheitswarnung Warnung bei hoher Lautstärke anzeigen - + Colored Ringer Icon + Enable if selected ringer icon is invisible + Header-Bild auswählen Headerbild aufs QS-Panel hinzufügen\nNicht \"Zuletzt benutzt\" verwenden Bild auswählen Bildhöhe - Bildtransparenz + Image Opacity Höhe des unteren Ausblendens Passend vergrößern Bild ist standardmäßig gestreckt um zu passen @@ -565,35 +659,36 @@ transparent machen Bild im Querformat verbergen Transparenzverlauf \"Verblassen\"-Effekt zum Header-Bild hinzufügen - + Benutzerdefinierte Kopfzeilen Uhr Füge eine angepasste Uhr zum QS-Panel hinzu Uhren Stil Uhren Schriftart - Benutze eigene Schriftart für die Uhr\n Nicht von den zuletzt benutzten Dateien auswählen + Use custom font for header clock Benutzerdefinierte Uhren Farbe - Benutzerdefinierte Farbe anstelle der Primärfarbe + Custom colors instead of system colors Uhrfarbwähler Setze Farbe für den Text der Header-Uhr + Expansion Amount Text Skalierung - Seitlicher Abstand der Uhr - Oberer Abstand der Uhr + Side Margin + Top Margin Weißer Text Zwinge Textfarbe weiß zu sein Zentrierte Uhr Bewege die Uhr zur Mitte Verstecke im Querformat Uhr im Querformat verbergen - + Benutzerdefinierte Sperrbildschirm Uhr Aktiviere benutzerdefinierte Sperrbildschirm Uhr Verstecke Uhr automatisch Verstecke Uhr bei eingehenden Benachrichtigungen Uhren Stil Uhren Schriftart - Nutze benutzerdefinierte Schriftart für die Sperrbildschirm Uhr\nWähle keine Datei von den Kürzlich verwendeten + Use custom font for lockscreen clock Benutzerdefinierte Uhren Farbe - Benutzerdefinierte Farbe anstelle der Primärfarbe + Custom colors instead of system colors Uhrfarbwähler Wähle Farbe des Textes der Sperrbildschirmuhr Text Skalierung @@ -602,6 +697,13 @@ transparent machen Unterer Abstand Weißer Text Zwinge alle Farben weiß zu sein + Nutze benutzerdefiniertes Bild + Nutze benutzerdefiniertes Bild für Sperrbildschirm Uhr. + Benutzerdefinierte Bildauswahlmenü + Benutzerdefinierter Gerätename + Legen Sie einen benutzerdefinierten Gerätenamen für die Sperrbildschirm Uhr fest.\nLeer lassen, um den Gerätenamen des Systems zu verwenden. + Benutzerdefinierter Benutzername + Legen Sie einen benutzerdefinierten Gerätenamen für die Sperrbildschirm Uhr fest.\nLeer lassen, um den Gerätenamen des Systems zu verwenden. Auswählen Akku ladend Akku entladend @@ -609,14 +711,18 @@ transparent machen Akkustand Wilkommen zurück! Benutzer - + Aktiviere Tiefenwallpaper - Zeige ein Wallpaper mit iOS ähnlichem Tiefeneffekt\nEs muss eine angepasste Uhr für den Sperrbildschirm verwendet werden + Show iOS like depth wallpaper\n%s + Custom Images + Set custom images as depth wallpaper + Show on AOD + Show subject on always on display Einblenden AOD Animiere Hintergrundbild und verblassen im AOD Vordergrund Bild Vordergrundbild für Tiefeneffekt - Foreground Image Alpha + Foreground Image Opacity Hintergrund Bild Hintergrundbild für Tiefeneffekt Diese Funktion befindet sich derzeit in der Beta-Phase. Daher werden Fehler erwartet.\n\nBekannte Bug(s):\n• Tippen auf den Sperrbildschirm lässt das Hintergrundbild springen. @@ -624,23 +730,68 @@ transparent machen Move background and foreground layers at different speeds Foreground Sensitivity Background Sensitivity - + AI model is downloaded on the device + AI model isn\'t available on the device (yet) + Extracting wallpaper subject… + Extracted wallpaper subject! + Failed to extract wallpaper subject! + AI model is not available! + Must use custom lockscreen clock + Statusleiste Statusleiste Uhr-Chip Chip hinter der Statusleisten-Uhr anzeigen - Statusleisten Uhr Farbe + Customize Clock Chip + Custom colors, roundness, stroke etc. + Text + Clock Text Color Folge System Transparenter Text Benutzerdefinierte Farbe - Uhrfarbwähler - Farbe der Statusbar Uhr setzen + Text Color Picker + Set color of statubsar clock text Statussymbole Chip-Stil Statussymbole Chip Zeige einen Chip hinter den Statussymbolen + Customize Status Icons Chip + Custom colors, roundness, stroke etc. Chip Stil Oberer Rand Seitlicher Rand + Background + Accent Fill Color + Gradient Direction + Fill Start Color + Fill End Color + Border + Enable Border + Accent Border Color + Border Color + Dashed Border + Dash Width + Dash Gap + Border Thickness + Padding + Padding Left + Padding Right + Padding Top + Padding Bottom + Corner Radius + Top Left Radius + Top Right Radius + Bottom Left Radius + Bottom Right Radius + + Custom Statusbar Clock Size + Set a custom size for Statusbar Clock + Statusbar Clock Size + Colored Statusbar Icon + Show app icon as notification icon + Verstecke Netzanbieter + Netzanbieter auf Sperrbildschirm verbergen + Verstecke Statusleiste + Statusleiste auf Sperrbildschirm ausblenden SE-Header Mobilfunkanbieter verbergen @@ -648,10 +799,6 @@ transparent machen Statussymbole verbergen Zeit, Datum und Batteriesymbole verbergen Sperrbildschirm - Verstecke Netzanbieter - Netzanbieter auf Sperrbildschirm verbergen - Verstecke Statusleiste - Statusleiste auf Sperrbildschirm ausblenden Hide LS Lock Icon Hide lock icon view on lockscreen Fixierte Statussymbole @@ -738,6 +885,7 @@ transparent machen Start Optimierungen + Xposed Einstellungen Änderungsprotokoll @@ -753,37 +901,14 @@ transparent machen Einstellungen Speichern erfolgreich Nichts - Stil 1 - Stil 2 - Stil 3 - Stil 4 - Stil 5 - Stil 6 - Stil 7 - Stil 8 - Stil 9 - Stil 10 - Stil 11 - Stil 12 - Stil 13 - Stil 14 - Stil 15 - Stil 16 - Stil 17 - Stil 18 - Stil 19 - Stil 20 - Stil 21 - Stil 22 - Stil 23 - Stil 24 - Stil 25 + Stil %d Weiter Neustart Deaktivieren Aktivieren Anwenden + Save Benutzerdefinierte Farbe deaktivieren Farben anpassen Reset @@ -852,10 +977,6 @@ transparent machen Hallo da! Symbol Medienspieler Symbol - Ausgewählt: - Ausgewählt: %s - Ausgewählt: %1$s%2$s - Ausgewählt: %1$s%2$s %3$s (Standard) Keine Uhr Uhrenstil %d @@ -924,4 +1045,124 @@ transparent machen Tippe auf Vorschau um auszuwählen Nicht erneut zeigen Um eine korrekte Funktionalität zu gewährleisten, ist die Aktivierung des Iconify Moduls in LSPosed für Android 14 und höher zwingend.\n\nDanach aktivieren Sie die Anpassungen von: Tweaks > Xposed-Menü > Themen > Andere. + Do not select file from Recent + Dismiss + Restart Device + Pending + Accent Primary + Accent Secondary + Accent Tertiary + Text Color Primary + Text Color Inverse + + + Unit + Verifying location + Select location + Enter location + Location + Set custom location + Cannot retrieve location! + Network geolocation is disabled.\n\nSet a custom location or enable network location. + Enable + Settings + Automatic updates + Check for new versions once in a while + Check updates over WiFi only + Check for updates in background only when connected to wifi + Metric (\u00b0C) + Imperial (\u00b0F) + Update + Enable + Update interval + 1 hour + 2 hours + 4 hours + 6 hours + 12 hours + Weather + Condition Icon Pack + Find more icon packs + Disabled + Error + Waiting \u2026 + No weather data + Error loading weather data + Waiting\u2026 + Updating\u2026 + Service disabled + Now + Background shadow + Service settings + Unknown + Error loading weather data + Weather + Last update: + No location available + No network found + Location permissions not granted + Select location + Search for a location + Enable Location Permissions + Location permissions are required to fetch weather data. Click OK to open Settings. + + Cloudy + Rainy + Sunny + Stormy + Snowy + Windy + Misty + + Weather on Lockscreen + Show weather on lockscreen + Last Update Time + Weather Provider + OpenWeatherMap API Key + OpenWeatherMap API Key required + Please enter your OpenWeatherMap API key to fetch weather data. + Show Location + Show Location before icon + Show Condition + Show Condition after temperature + Show Humidity + Show Humidity in a new row + Show Wind + Show Wind in a new row + Text Size + Image Size + Text Color + Set custom color for text + Custom Color + Custom color for all text in weather view + Custom location + Set custom location for weather + Custom Margins + Set custom margins for weather + Top margin + Center Layout + Side Margin + Bottom Margin + Center Weather View + Move weather view to center horizontally + + Weather Background Style + Default + Semi-transparent box + Semi-transparent box (round) + Q-Beta pill + Rounded, simple and with accent + Rounded, transparent and with accent + Gradient + Dark with accented borders + Dark with gradient borders + + SystemUI Restart Needed + A SystemUI restart is needed for this change to take effect. + Device Restart Needed + A device restart is needed for this change to take effect. + Switch Device Theme + Switch between light and dark themes if unexpected behavior occurs. + Device Rotation Theme + Switch rotation of your device for this change to take effect. diff --git a/app/src/main/res/values-el-rGR/strings.xml b/app/src/main/res/values-el-rGR/strings.xml index 2e00fff91..e7ab08419 100644 --- a/app/src/main/res/values-el-rGR/strings.xml +++ b/app/src/main/res/values-el-rGR/strings.xml @@ -1,5 +1,5 @@ - + Προσαρμογή Βαρετού Android UI Αρχικοποίηση ρύθμισης @@ -31,10 +31,22 @@ Ουπς Δεν το Περιμέναμε Αυτό Τα αρχεία καταγραφής έχουν αποθηκευτεί στο φάκελο εγγράφων. Αρχεία καταγραφής + + Search + Search… + Clear + History entry + More + Clear history + No result Iconify Πακέτο Εικονιδίων Αλλαγή πακέτου εικονιδίων συστήματος + Cellular Icons + Change system cellular icons + WiFi Icons + Change system WiFi icons Μπάρα Φωτεινότητας Προσαρμογή ρυθμιστικού προόδου Πλακίδια Πίνακα Γρήγορων Ρυθμίσεων @@ -113,6 +125,8 @@ Some options like blur intensity doesn\'t take effect until systemui is restarted Show Home Page Card Show a beautiful card on the home page. + Haptic Feedback + Enhance touch feedback with interactive haptics. Clear App Cache Clear caches generated due to the usage of custom fonts, images, or gifs. Experimental @@ -122,6 +136,8 @@ About Github Repository Telegram Group + Translate Iconify + Help translate Iconify to your language. Credits Thanking those who made this possible. @@ -231,8 +247,8 @@ Misc. Minimal QS Panel Remove top shade of QS panel - Disable System Monet - Helps to retain custom colors\nSystemUI restart required + System Monet + Disable to retain custom colors\nSystemUI restart required Primary Color Pick primary accent color @@ -405,24 +421,93 @@ Tweaks related to QS panel Battery Style Customize battery icon view + Oneplus QS Header + OOS style quick settings header Header Image Add custom image on QS panel Header Clock Add custom clock on QS panel Lockscreen Clock Add custom clock on lockscreen + Lockscreen Weather + Add weather on lockscreen + Lockscreen Widgets + Add widgets on lockscreen Depth Wallpaper Show iOS like depth wallpaper Background Chip Add colored chip behind clock + Clock Chip Others Miscellaneous xposed tweaks - + Weather Settings + + Oneplus QS Header + Enable OOS style media player and tiles in QS + Haptic Feedback + Add haptic feedback on tiles + Hide Stock Media Player + Remove stock media player from QS panel + Blur Level + Fade Level + Top Margin + Expansion Amount + + Lockscreen Widgets + Enable Lockscreen Widgets + Add widgets to lockscreen + Device Info Widget + Show device info widget on lockscreen + Linear Progress Color + Circular Progress Color + Text Color + Custom Device Name + Set custom device name.\nKeep blank to disable. + Large Widgets + Large Widget 1 + Large Widget 2 + Mini Widgets + Mini Widget 1 + Mini Widget 2 + Mini Widget 3 + Mini Widget 4 + Custom Colors + Customize Widget Colors + Large Widget Active Color + Large Widget Inactive Color + Large Widget Icon Active Color + Large Widget Icon Inactive Color + Mini Widget Active Color + Mini Widget Inactive Color + Mini Widget Icon Active Color + Mini Widget Icon Inactive Color + Weather Settings + Widgets Scale + + Camera + Clock/Timer + Calculator + Gallery + Media Player + Torch + Play + Weather + Wifi + Data + Ringer + Bluetooth + Home Controls + Wallet + Hotspot + Ringer + Vibrate + Silent + Transparency Transparent QS Panel Make QS panel background transparent - Transparency Alpha - Transparent Notif Shade Only + Background Opacity + Transparent Notification Shade Make only notification shade transparent Dim Lockscreen Wallpaper Suitable for light-colored wallpapers @@ -432,7 +517,7 @@ Aggressive Blur Enabler Might bootloop in some roms Blur Intensity - + For Pixel Roms Light Theme Light QS theme in light mode\nMust use custom QS Shape @@ -449,21 +534,28 @@ Power Menu Transparency Power menu transparency for Fluid QS\nDo not use custom notification style Others + Fix QS Tile Color + Fix custom QS tile style on android 14 Fix Notification Color Fix custom notification style on android 14 - + Fix Notification Footer Button Color + Fix custom footer button style on android 14 + QS Tile Vertical QS Tile Show label below QS icon Hide QS Tile Label Use only with vertical tiles + Text Size Scaling QS Margin QS Elements + Hide QS on Lockscreen + Disable quick settings panel on secured lockscreen Hide Silent Text - Hide silent text shown as header of silent notifications (Requires SystemUI restart) + Hide silent text shown as header of silent notifications Hide Footer Buttons Hide footer buttons shown under notification stack - + Battery Style Battery Width Battery Height @@ -494,8 +586,8 @@ Change color of powersave battery Powersave Indicator Color Change color of powersave indicator - Custom Dimensions - Set custom dimensions for battery icon + Custom Margins + Set custom margins for battery icon Battery Margin Left Battery Margin Right Battery Margin Top @@ -546,17 +638,19 @@ Circle Battery Dotted Circle Battery Filled Circle Battery - + Volume Percentage Show percentage above volume slider Safety Warning Show warning on high volume - + Colored Ringer Icon + Enable if selected ringer icon is invisible + Pick Header Image Add header image on QS panel\nDo not select file from Recent Pick Image Image Height - Image Alpha + Image Opacity Bottom Fade Amount Zoom To Fit Image is stretched to fit by default @@ -564,35 +658,36 @@ Hide image in landscape mode Alpha Gradient Add faded effect to the header image - + Custom Header Clock Add a custom clock on QS panel Clock Style Clock Font - Use custom font for header clock\nDo not select file from Recent + Use custom font for header clock Custom Clock Color - Custom color instead of primary color + Custom colors instead of system colors Clock Color Picker Set color of header clock text + Expansion Amount Text Scaling - Clock Side Margin - Clock Top Margin + Side Margin + Top Margin White Text Force text colors to be white Center Clock Move clock to center of view Hide in Landscape Hide clock in landscape mode - + Custom Lockscreen Clock Enable custom lockscreen clock Auto Hide Clock Hide clock on incoming notification Clock Style Clock Font - Use custom font for lockscreen clock\nDo not select file from Recent + Use custom font for lockscreen clock Custom Clock Color - Custom color instead of primary color + Custom colors instead of system colors Clock Color Picker Set color of lockscreen clock text Text Scaling @@ -601,6 +696,13 @@ Bottom Margin White Text Force all colors to be white + Use Custom Image + Use custom image for lockscreen clock. + Custom Image Picker + Custom Device Name + Set custom device name for lockscreen clock.\nKeep blank to use System\'s Device Name. + Custom User Name + Set custom user name for lockscreen clock.\nKeep blank to use System\'s User Name. Select Battery Charging Battery Discharging @@ -608,14 +710,18 @@ Battery Level Welcome back! User - + Enable Depth Wallpaper - Show iOS like depth wallpaper\nMust use custom lockscreen clock + Show iOS like depth wallpaper\n%s + Custom Images + Set custom images as depth wallpaper + Show on AOD + Show subject on always on display Fade in AOD Animate wallpaper and fade away in AOD Foreground Image Foreground image for depth wallpaper - Foreground Image Alpha + Foreground Image Opacity Background Image Background image for depth wallpaper This feature is currently in beta stage. So bugs are expected.\n\nKnown Bug(s):\n• Tapping on lockscreen makes the wallpaper jump. @@ -623,23 +729,68 @@ Move background and foreground layers at different speeds Foreground Sensitivity Background Sensitivity - + AI model is downloaded on the device + AI model isn\'t available on the device (yet) + Extracting wallpaper subject… + Extracted wallpaper subject! + Failed to extract wallpaper subject! + AI model is not available! + Must use custom lockscreen clock + Status Bar Statusbar Clock Chip Display chip behind statusbar clock - Statusbar Clock Color + Customize Clock Chip + Custom colors, roundness, stroke etc. + Text + Clock Text Color Follow System Transparent Text Custom Color - Clock Color Picker - Set color of statubsar clock text + Text Color Picker + Set color of statubsar clock text Status Icons Chip Style Status Icons Chip Display chip behind status icons + Customize Status Icons Chip + Custom colors, roundness, stroke etc. Chip Style Top Margin Side Margin + Background + Accent Fill Color + Gradient Direction + Fill Start Color + Fill End Color + Border + Enable Border + Accent Border Color + Border Color + Dashed Border + Dash Width + Dash Gap + Border Thickness + Padding + Padding Left + Padding Right + Padding Top + Padding Bottom + Corner Radius + Top Left Radius + Top Right Radius + Bottom Left Radius + Bottom Right Radius + + Custom Statusbar Clock Size + Set a custom size for Statusbar Clock + Statusbar Clock Size + Colored Statusbar Icon + Show app icon as notification icon + Hide LS Carrier + Hide carrier name on lockscreen + Hide LS Statusbar + Hide statusbar on lockscreen QS Header Hide Carrier Group @@ -647,10 +798,6 @@ Hide Status Icons Remove time, date and battery icons Lock Screen - Hide LS Carrier - Hide carrier name on lockscreen - Hide LS Statusbar - Hide statusbar on lockscreen Hide LS Lock Icon Hide lock icon view on lockscreen Fixed Status Icons @@ -737,6 +884,7 @@ Home Tweaks + Xposed Settings Changelog @@ -752,37 +900,14 @@ Saved settings successfully None - Style 1 - Style 2 - Style 3 - Style 4 - Style 5 - Style 6 - Style 7 - Style 8 - Style 9 - Style 10 - Style 11 - Style 12 - Style 13 - Style 14 - Style 15 - Style 16 - Style 17 - Style 18 - Style 19 - Style 20 - Style 21 - Style 22 - Style 23 - Style 24 - Style 25 + Style %d Continue Restart Disable Enable Apply + Save Disable Custom Colors Apply Colors Reset @@ -851,10 +976,6 @@ Hey There! Icon Media Player Icons - Selected: - Selected: %s - Selected: %1$s%2$s - Selected: %1$s%2$s %3$s (Default) No Clock Clock Style %d @@ -923,4 +1044,124 @@ Tap on preview to select Don\'t show again To ensure proper functionality, enabling the Iconify module in LSPosed is mandatory for android 14 and above.\n\nAfter that, enable the fixes from: Tweaks > Xposed Menu > Themes > Others. + Do not select file from Recent + Dismiss + Restart Device + Pending + Accent Primary + Accent Secondary + Accent Tertiary + Text Color Primary + Text Color Inverse + + + Unit + Verifying location + Select location + Enter location + Location + Set custom location + Cannot retrieve location! + Network geolocation is disabled.\n\nSet a custom location or enable network location. + Enable + Settings + Automatic updates + Check for new versions once in a while + Check updates over WiFi only + Check for updates in background only when connected to wifi + Metric (\u00b0C) + Imperial (\u00b0F) + Update + Enable + Update interval + 1 hour + 2 hours + 4 hours + 6 hours + 12 hours + Weather + Condition Icon Pack + Find more icon packs + Disabled + Error + Waiting \u2026 + No weather data + Error loading weather data + Waiting\u2026 + Updating\u2026 + Service disabled + Now + Background shadow + Service settings + Unknown + Error loading weather data + Weather + Last update: + No location available + No network found + Location permissions not granted + Select location + Search for a location + Enable Location Permissions + Location permissions are required to fetch weather data. Click OK to open Settings. + + Cloudy + Rainy + Sunny + Stormy + Snowy + Windy + Misty + + Weather on Lockscreen + Show weather on lockscreen + Last Update Time + Weather Provider + OpenWeatherMap API Key + OpenWeatherMap API Key required + Please enter your OpenWeatherMap API key to fetch weather data. + Show Location + Show Location before icon + Show Condition + Show Condition after temperature + Show Humidity + Show Humidity in a new row + Show Wind + Show Wind in a new row + Text Size + Image Size + Text Color + Set custom color for text + Custom Color + Custom color for all text in weather view + Custom location + Set custom location for weather + Custom Margins + Set custom margins for weather + Top margin + Center Layout + Side Margin + Bottom Margin + Center Weather View + Move weather view to center horizontally + + Weather Background Style + Default + Semi-transparent box + Semi-transparent box (round) + Q-Beta pill + Rounded, simple and with accent + Rounded, transparent and with accent + Gradient + Dark with accented borders + Dark with gradient borders + + SystemUI Restart Needed + A SystemUI restart is needed for this change to take effect. + Device Restart Needed + A device restart is needed for this change to take effect. + Switch Device Theme + Switch between light and dark themes if unexpected behavior occurs. + Device Rotation Theme + Switch rotation of your device for this change to take effect. diff --git a/app/src/main/res/values-es-rES/strings.xml b/app/src/main/res/values-es-rES/strings.xml index f94faded9..eacbd1dc9 100644 --- a/app/src/main/res/values-es-rES/strings.xml +++ b/app/src/main/res/values-es-rES/strings.xml @@ -1,10 +1,10 @@ - + Personaliza la aburrida interfaz de Android Iniciando la configuración Paso - Step %1$d/%2$d + Paso %1$d/%2$d Creando estructura del módulo Extrayendo archivos necesarios Creando APKs de superposición @@ -12,18 +12,18 @@ Firmando APKs de superposición Limpiando directorios ¿Cansado de la IU de Stock? - Let\'s customize everything to our likings. - Ditch the stock UI monotony – personalize every tech detail to match your style and preferences. + Personalicemos todo a nuestros gustos. + Abandona la monotonía de la IU de stock - personaliza cada detalle tecnológico para coincidir con tu estilo y preferencias. ¿Mi Dispositivo es Compatible? - Iconify supports all Pixel and AOSP ROMs. - Compatible with all Pixel and AOSP-based ROMs, ensuring broad support for Android devices. + Iconify es compatible con todas las ROMs de Pixel y AOSP. + Compatible con todas las ROMs basadas en Pixel y OOS, garantizando un amplio soporte para dispositivos Android. ¿Empezamos Ahora? - It is time for iconify to do some internal work. - Starting internal tasks, marking the initiation of essential work. Ready to begin? + Es momento de que Iconify haga algo de trabajo interno. + Iniciando tareas internas, marcando el inicio del trabajo escencial. ¿Listo para comenzar? Se Requiere Permiso de Almacenamiento Se requiere permiso de almacenamiento para generar los archivos necesarios. - Could Not Find Compatible Root Method - Use any popular root solutions to proceed. + No se pudo encontrar un método de root compatible + Usa cualquier solución root popular para continuar. No se Puede Acceder al Root ¡Parece que tu dispositivo no tiene acceso root! Se Requiere Reinicio del Dispositivo @@ -31,10 +31,22 @@ ¡Ups! No Esperaba Eso Se han guardado los registros en la carpeta de documentos. Registros + + Search + Search… + Clear + History entry + More + Clear history + No result Iconify Paquete de iconos Cambia el paquete de iconos del sistema + Cellular Icons + Change system cellular icons + Iconos WiFi + Cambiar los iconos WiFi del sistema Barra de brillo Personalizar barra de progreso Panel de Ajustes Rápidos @@ -52,9 +64,9 @@ ¡Iconify se ha actualizado! Reinicia tu teléfono para utilizar las últimas funciones y opciones añadidas. - Design It Your Way - Unleash Your Imagination, Make It Yours - Hide + Diseñalo a tu manera + Desata tu imaginación, hazlo tuyo + Ocultar Motor de color Ten el control de los colores @@ -93,37 +105,41 @@ Tema Claro Tema Oscuro Seguir el Sistema - Update - Check For Update - Current version: %s - Auto Update - Check for new versions in background. - Check Over WiFi Only - Check for updates over wifi only. + Actualizar + Buscar actualizaciones + Versión actual: %s + Actualizaciones automáticas + Buscar nuevas versiones en segundo plano. + Buscar solo con WiFi + Buscar actualizaciones solo con WiFi. Xposed Mostrar Advertencia Mostrar advertencia sobre cómo reoptimizar el módulo en el menú de Xposed - Mod Applying Method - Automatically restart SystemUI - Automatically force reload UI - Notify for manual SystemUI restart - SystemUI restart required - Miscellaneous + Método de aplicación de mods + Reiniciar automáticamente la IU del sistema + Forzar automáticamente el reinicio de la IU + Notificar el reinicio manual de la UI del sistema + Se requiere un reinicio de la UI del sistema + Misceláneo Reiniciar SystemUI después del Arranque Algunas opciones como la intensidad del desenfoque no surtirán efecto hasta que se reinicie SystemUI - Show Home Page Card - Show a beautiful card on the home page. + Mostrar tarjeta de página de inicio + Mostrar una hermosa tarjeta en la página de inicio. + Haptic Feedback + Enhance touch feedback with interactive haptics. Borrar Caché de Aplicación Borrar las cachés generadas por el uso de fuentes, imágenes o GIFs personalizados. Experimental - Try out experimental functionalities. + Probar funcionalidades experimentales. Deshabilitar todo Deshabilita todas las superposiciones, colores y cambios variados de Iconify. - About - Github Repository - Telegram Group - Credits - Thanking those who made this possible. + Acerca de + Repositorio de GitHub + Grupo de Telegram + Translate Iconify + Help translate Iconify to your language. + Créditos + Gracias a quienes hicieron esto posible. Batería coloreada Cambia el color del icono de batería @@ -131,7 +147,7 @@ Cambia los iconos del reproductor de medios Iconos de Ajustes Cambia el paquete de iconos para Ajustes - Icon Pack Styles + Estilos de paquete de iconos Paquete de iconos lineales de dos tonos Paquete de iconos rellenos con sombreado degradado Paquete de iconos lineales gruesos @@ -168,7 +184,7 @@ Neumorph Forma Círculo - Squircle + Cuadrado redondeado Cuadrado Tamaño de Icono 0.5x @@ -183,16 +199,16 @@ Paquete de iconos con contorno multicolor Variante Pixel - For roms with black QS panel + Para ROMs con el panel de AR negro - Brightness Bar Styles + Estilos de la barra de brillo - QS Panel Tile Styles + Estilos de mosaico del panel de AR - Notification Styles + Estilos de notificaciones Vista previa de notificación.\nHaz clic para aplicar este estilo. - Click to enable or disable + Haz clic para habilitar o deshabilitar Ninguno Piedra @@ -212,27 +228,27 @@ Cuadrado cortado Vaso Rohie Meow - Force Round + Forzar redondeo Colores básicos Cambia el color primario y el secundado Motor de Monet Reemplazar la paleta de colores de Monet - Stock Colors + Colores de stock Acento Monet Usar Monet del sistema como color acento Gradiente Monet Usar Monet del sistema como color gradiente - Dark Theme + Tema oscuro Pitch Black (Oscuro) Habilita el tema oscuro pitch black - Pitch Black (Amoled) + Negro puro (Amoled) Habilita el tema amoled de pitch black Misc. Panel Ajustes Rápidos minimalista Eliminar la sombra superior del panel Ajustes Rápidos - Desactivar Monet del Sistema - Ayuda a mantener colores personalizados\nSe requiere reiniciar SystemUI + System Monet + Disable to retain custom colors\nSystemUI restart required Color primario Selecciona el color de acento principal @@ -271,7 +287,7 @@ Filas del panel de Ajustes Rápidos Columnas del panel de Ajustes Rápidos - Size and Position + Tamaño y posición Ocultar etiqueta Quita las etiquetas del panel de Ajustes Rápidos Tamaño del texto @@ -290,8 +306,8 @@ Título sistema, subtitulo acento Arreglar color de texto Usar si los de arriba no funcionan - Follow Accent - Title accent, subtitle accent + Seguir acento + Acento del título, acento del subtítulo Vertical Horizontal @@ -301,10 +317,10 @@ Margen superior del panel de Ajustes Rápidos minimizado Margen superior del panel de Ajustes Rápidos - Spacing + Espaciado Relleno izquierdo Relleno derecho - Height + Altura Color Tinte de color Tintar iconos y textos de la barra de estado @@ -312,7 +328,7 @@ Tinte Monet/Acento Tinte Personalizado (Selector de Color) - Display Mode + Modo de visualización Pantalla completa Ocultar píxel de navegación y espaciado del teclado Modo inmersivo @@ -321,41 +337,41 @@ Espaciado de teclado más pequeño Modo inmersivo v3 Espaciado de teclado más pequeño - Gcam Lag Fix - Fix lag in gcam with gesture navigation - Buttons + Corregir retraso de Gcam + Corregir retraso de Gcam con navegación de gestos + Botones Ocultar botones del teclado Ocultar botones de retroceso/cambio de teclado - Gesture + Gesto Sensibilidad reducida Reducir la sensibilidad de los gestos Deshabilitar gesto izquierdo Deshabilitar gesto de retroceso del lado izquierdo Deshabilitar gesto derecho Deshabilitar gesto de retroceso del lado derecho - Pill Navigation + Navegación de píldora Ocultar botón Ocultar botón de navegación Botón de Monet Vincular el color de acento al botón - Pill Appearance + Apariencia de píldora Ancho de la Píldora Grosor de la Píldora Espacio Inferior de la Píldora - Volume Slider Track - Thin - Thick - None + Control del deslizador del volumen + Delgado + Grueso + Ninguno Fondo delgado - Make track of volume slider thin + Hacer control del deslizador del volumen delgado Fondo grueso - Make track of volume slider thick + Hacer control del deslizador del volumen grueso Sin fondo - Remove track of volume slider - Custom Magisk Module + Eliminar control del deslizador del volumen + Módulo de Magisk personalizado Estilo de volumen - Creates a magisk flashable module for this style + Crea un módulo flashable de Magisk para este estilo Degradado Doble capa Capa sombreada @@ -365,234 +381,313 @@ Crear módulo Módulo creado con éxito ¡Lee con atención! - This option will create a magisk module inside Download folder in your Internal Storage. Flash the module named IconifyCompanion.zip in Magisk. Always uninstall previous Iconify Companion module (if installed) and reboot before flashing new one.\n\nNote:\n• Uninstall the module before updating rom.\n• Recreate the module if you change or update rom.\n• Do not flash a module which wasn\'t created based on your rom. + Esta opción creará un módulo de Magisk en la carpeta de Descargas de tu Almacenamiento interno. Flashea el módulo llamado IconifyCompanion.zip en Magisk. Siempre desinstala el módulo Iconify Companion anterior (si está instalado) y reinicia antes de flashear el nuevo.\n\nNota:\n• Desinstala el módulo antes de actualizar la ROM.\n• Vuelve a crear el módulo si cambias o actualizas la ROM.\n• No flashees un módulo que no haya sido creado en base a tu ROM. Vista previa del Reproductor de medios Título de la Música Nombre del Artista Altavoz del teléfono - Background Color + Color de fondo Fondo de acento - Make background follow accent + Hacer que el fondo siga el acento Fondo del sistema - Make background follow system + Hacer que el fondo siga el sistema Fondo Pitch Black - Make background pitch black + Hacer que el fondo sea negro puro - Tablet Mode + Modo de Tablet Pantalla de Tablet en Horizontal - Also known as Better QS + También conocido como Better QS Eliminador de Barra de Notch Eliminar el espacio vacío de la barra de notch Encabezado de Tablet Habilitar encabezado de sombra de gran pantalla - Privacy Chip + Chip de privacidad Chip de Privacidad de Acento Hace que el chip de privacidad tenga el color de acento - Media Player - Disable Progress Wave - Disable progress bar wave animation + Reproductor multimedia + Deshabilitar onda de progreso + Deshabilitar animación de onda de barra de progreso Antes de habilitar Iconify desde los módulos de LSPosed, mantén presionado Iconify y haz clic en Reoptimizar. Luego habilita Iconify y reinicia tu SystemUI. Esto es necesario para una experiencia más fluida. - You are currently in Xposed Only mode. This requires iconify to be enabled in LSPosed app. Also make sure that Iconify module is shown in Magisk manager. To get access to all features, clear data of iconify app and go through the installation process! - Module Not Activated - System service not running + Actualmente solo estás en el modo Xposed. Esto requiere que Iconify esté habilitado en la aplicación LSPosed. También asegúrate de que el módulo Iconify se muestre en el administrador de Magisk. Para acceder a todas las funciones, ¡limpia los datos de la aplicación Iconify y sigue el proceso de instalación! + Módulo deshabilitado + El servicio del sistema no se está ejecutando Transparencia & Desenfoque Habilitar la transparencia y desenfoque en el panel - Themes - Personalize with themes + Temas + Personalizar con temas Ajustes Rápidos Retoques relacionados con el panel de ajustes rápidos Estilo de batería Personaliza el icono de batería + Oneplus QS Header + OOS style quick settings header Imagen de cabecera Añade una imagen personalizada en el panel Reloj de la cabecera Añade un reloj personalizado en el panel Reloj de la pantalla de bloqueo Añade un reloj personalizado en la pantalla de bloqueo - Depth Wallpaper - Show iOS like depth wallpaper + Información meteorológica en la pantalla de bloqueo + Añadir clima en la pantalla de bloqueo + Lockscreen Widgets + Add widgets on lockscreen + Fondo de pantalla con profundidad + Mostrar fondo de pantalla con profundidad parecido a iOS Reloj con fondo Añade un fondo de color detrás del reloj + Clock Chip Otros Retoques variados de Xposed - - Transparency + Weather Settings + + Oneplus QS Header + Enable OOS style media player and tiles in QS + Haptic Feedback + Add haptic feedback on tiles + Hide Stock Media Player + Remove stock media player from QS panel + Blur Level + Fade Level + Top Margin + Expansion Amount + + Lockscreen Widgets + Enable Lockscreen Widgets + Add widgets to lockscreen + Device Info Widget + Show device info widget on lockscreen + Linear Progress Color + Circular Progress Color + Text Color + Custom Device Name + Set custom device name.\nKeep blank to disable. + Large Widgets + Large Widget 1 + Large Widget 2 + Mini Widgets + Mini Widget 1 + Mini Widget 2 + Mini Widget 3 + Mini Widget 4 + Custom Colors + Customize Widget Colors + Large Widget Active Color + Large Widget Inactive Color + Large Widget Icon Active Color + Large Widget Icon Inactive Color + Mini Widget Active Color + Mini Widget Inactive Color + Mini Widget Icon Active Color + Mini Widget Icon Inactive Color + Weather Settings + Widgets Scale + + Camera + Clock/Timer + Calculator + Gallery + Media Player + Torch + Play + Weather + Wifi + Data + Ringer + Bluetooth + Home Controls + Wallet + Hotspot + Ringer + Vibrate + Silent + + Transparencia Panel Ajustes Rápidos transparente Hacer transparente el fondo del panel de Ajustes Rápidos - Transparencia alfa - Solo Sombra de Notificaciones Transparente + Background Opacity + Transparent Notification Shade Hace que solo la sombra de las notificaciones sea transparente - Dim Lockscreen Wallpaper - Suitable for light-colored wallpapers - Blur + Atenuar fondo de pantalla de bloqueo + Adecuado para fondos de pantalla de color claro + Desenfoque Desenfoque de nivel de ventana Requiere reinicio para funcionar - Aggressive Blur Enabler - Might bootloop in some roms + Habilitador de enfoque agresivo + Puede que ocasione un bucle de arranque en algunas ROMs Intensidad del desenfoque - - For Pixel Roms + + Para ROMs de Pixel Tema Claro Tema de Ajustes Rápidos claro en modo claro\nDebe usar Forma de Ajustes Rápidos personalizada Tono Dual Usar un color diferente para el encabezado - For Custom Roms + Para ROMs personalizadas Tema Negro Pixel Tema negro de Ajustes Rápidos en modo claro\nDebes usar la forma de Ajustes Rápidos de Pixel\nCambia al tema oscuro para arreglar el color del texto - Translucent Theme + Tema translúcido Tema Fluid QS Tema Ajustes Rápidos translúcido de dos tonos\nCambia el tema para arreglar el color\nNo uses formas personalizadas Transparencia de Notificaciones Transparencia de notificaciones para Fluid QS\nNo uses un estilo de notificación personalizado Transparencia del Menú de Energía Transparencia del menú de energía para Fluid QS\nNo uses un estilo de notificación personalizado - Others - Fix Notification Color - Fix custom notification style on android 14 - - QS Tile + Otros + Fix QS Tile Color + Fix custom QS tile style on android 14 + Corregir color de las notificaciones + Corregir estilo de notificaciones personalizado en Android 14 + Corregir el color del botón de notificación del pie de página + Corregir estilo de botón personalizado de pie de página en android 14 + + Mosaico de AR Botones de Ajustes Rápidos verticales Mostrar etiqueta debajo del icono de Ajustes Rápidos Ocultar etiqueta en botones de Ajustes Rápidos Usar solo con botones verticales - QS Margin - QS Elements - Hide Silent Text - Hide silent text shown as header of silent notifications (Requires SystemUI restart) - Hide Footer Buttons - Hide footer buttons shown under notification stack - + Escala del tamaño del texto + Margen de AR + Elementos de AR + Ocultar QS en pantalla de bloqueo + Deshabilitar los ajustes rápidos en la pantalla de bloqueo segura + Ocultar texto silencioso + Ocultar texto silencioso mostrado como encabezado de las notificaciones silenciosas + Ocultar botones del pie de página + Ocultar los botones de pie de página mostrados en la lista de notificaciones + Estilo de Batería Ancho de Batería Altura de Batería Margen de Batería - Hide Battery - Keep only charging icon and percentage - Custom Charging Icon - Change charging icon to custom icon - Charging Icon Style - Charging Icon Margin Left - Charging Icon Margin Right - Charging Icon Size - Perimeter Alpha - Make battery perimeter semi transparent - Fill Alpha - Make battery fill semi transparent - Rainbow Color - Show different color based on battery level - Blend Color - Blend battery color with custom color - Fill Color - Fill battery with custom color - Fill Gradient Color - Fill battery with gradient color - Charging Fill Color - Change color of charging battery - Powersave Fill Color - Change color of powersave battery - Powersave Indicator Color - Change color of powersave indicator - Custom Dimensions - Set custom dimensions for battery icon - Battery Margin Left - Battery Margin Right - Battery Margin Top - Battery Margin Bottom - Reverse Layout - Show percentage on the opposite side - Rotate Layout - Rotate battery layout 180 degrees - Hide Percentage - Hide battery percentage text - Inside Percentage - Move percentage to inside battery icon - Default - Landscape R Default - Landscape L Default - Landscape R Custom - Landscape L Custom - Portrait Capsule - Portrait Lorn - Portrait Mx - Portrait Airoo - Landscape R Style A - Landscape L Style A - Landscape R Style B - Landscape L Style B - Landscape iOS 15 - Landscape iOS 16 - Portrait Origami - Landscape Smiley - Landscape MIUI Pill - Landscape L ColorOS - Landscape R ColorOS - Landscape Battery A - Landscape Battery B - Landscape Battery C - Landscape Battery D - Landscape Battery E - Landscape Battery F - Landscape Battery G - Landscape Battery H - Landscape Battery I - Landscape Battery J - Landscape Battery K - Landscape Battery L - Landscape Battery M - Landscape Battery N - Landscape Battery O - Circle Battery - Dotted Circle Battery - Filled Circle Battery - - Volume Percentage - Show percentage above volume slider - Safety Warning - Show warning on high volume - + Ocultar batería + Mantener solo el ícono y porcentaje de carga + Icono de carga personalizado + Cambiar icono de carga a icono personalizado + Estilo del icono de carga + Izquierda del margen del icono de carga + Derecha del margen del icono de carga + Tamaño del ícono de carga + Perímetro alfa + Hacer el perímetro de la batería semitransparente + Relleno alfa + Hacer el relleno de la batería semitransparente + Color arcoíris + Mostrar colores diferentes en base al nivel de batería + Color de mezcla + Mezclar color de batería con color personalizado + Color del relleno + Rellenar batería con color personalizado + Rellenar color de degradado + Rellenar batería con color del degradado + Color de relleno de carga + Cambiar el color de la batería de carga + Color de relleno de ahorro de energía + Cambiar el color de la batería de ahorro de energía + Color del indicador de ahorro de batería + Cambiar el color del indicador de ahorro de batería + Custom Margins + Set custom margins for battery icon + Margen izquierdo de la batería + Margen derecho de la batería + Margen superior de la batería + Margen inferior de la batería + Invertir diseño + Mostrar porcentaje en el lado opuesto + Rotar diseño + Rotar diseño de la batería 180 grados + Ocultar porcentaje + Ocultar texto de porcentaje de batería + Porcentaje interior + Mover porcentaje a dentro del icono de la batería + Predeterminado + Horizontal D predeterminado + Horizontal I predeterminado + Horizontal D personalizado + Horizontal I personalizado + Cápsula vertical + Lorn vertical + Mx vertical + Airoo vertical + Estilo horizontal D A + Estilo horizontal I A + Estilo horizontal D B + Estilo horizontal I B + iOS 15 horizontal + iOS 16 horizontal + Origami vertical + Smiley horizontal + Píldora MIUI horizontal + ColorOS I horizontal + ColorOS D horizontal + Batería horizontal A + Batería horizontal B + Batería horizontal C + Batería horizontal D + Batería horizontal E + Batería horizontal F + Batería horizontal G + Batería horizontal H + Batería horizontal I + Batería horizontal J + Batería horizontal K + Batería horizontal L + Batería horizontal M + Batería horizontal N + Batería horizontal O + Batería circular + Batería circular punteada + Batería circular rellena + + Porcentaje de volumen + Mostrar porcentaje sobre el deslizador del volumen + Advertencia de seguridad + Mostrar advertencia en volumen alto + Icono de tono colorido + Activar si el icono del tono seleccionado es invisible + Seleccionar imagen de encabezado Añadir imagen de encabezado en el panel de Ajustes Rápidos\nNo selecciones archivos de \"Recientes\" Seleccionar imagen Altura de la imagen - Alfa de la imagen - Bottom Fade Amount + Image Opacity + Cantidad de desvanecimiento inferior Ajustar al zoom La imagen se estira para ajustarse por defecto Ocultar en Modo Horizontal Ocultar la imagen en modo horizontal - Alpha Gradient - Add faded effect to the header image - + Gradiente alfa + Añadir efecto desvanecido a la imagen del encabezado + Reloj de encabezado personalizado Agregar un reloj personalizado en el panel de Ajustes Rápidos Estilo del reloj Fuente del Reloj - Usar fuente personalizada para el reloj del encabezado\nNo seleccionar archivo reciente + Use custom font for header clock Color Personalizado del Reloj - Color personalizado en lugar del color primario + Custom colors instead of system colors Selector de Color del Reloj Establecer el color del texto del reloj del encabezado + Expansion Amount Ajuste de Tamaño de Texto del Reloj en Encabezado - Margen lateral del reloj - Margen superior del reloj + Side Margin + Top Margin Texto blanco Forzar los colores del texto en blanco Reloj en el Centro Mover el reloj al centro de la vista Ocultar en Paisaje Ocultar el reloj en modo apaisado - + Reloj personalizado de la pantalla de bloqueo Habilitar el reloj personalizado de la pantalla de bloqueo Ocultar Reloj Automáticamente Ocultar el reloj al recibir una notificación Estilo del reloj Fuente del reloj - Usar fuente personalizada para el reloj de la pantalla de bloqueo\nNo selecciones archivos de \"Recientes\" + Use custom font for lockscreen clock Color Personalizado del Reloj - Color personalizado en lugar del color primario + Custom colors instead of system colors Selector de Color del Reloj Establecer el color del texto del reloj de la pantalla de bloqueo Ajuste de Tamaño de Texto en Pantalla de Bloqueo @@ -601,60 +696,112 @@ Margen inferior del reloj Texto blanco Forzar todos los colores en blanco - Select - Battery Charging - Battery Discharging - Battery Full - Battery Level - Welcome back! - User - - Enable Depth Wallpaper - Show iOS like depth wallpaper\nMust use custom lockscreen clock - Fade in AOD - Animate wallpaper and fade away in AOD - Foreground Image - Foreground image for depth wallpaper - Foreground Image Alpha - Background Image - Background image for depth wallpaper - This feature is currently in beta stage. So bugs are expected.\n\nKnown Bug(s):\n• Tapping on lockscreen makes the wallpaper jump. - Parallax Effect - Move background and foreground layers at different speeds - Foreground Sensitivity - Background Sensitivity - - Status Bar + Usar imagen personalizada + Usar imagen personalizada para el reloj de la pantalla de bloqueo. + Selector de imagen personalizado + Nombre del dispositivo personalizado + Establece el nombre del dispositivo personalizado para el reloj de la pantalla de bloqueo.\nMantenga en blanco para usar el nombre del dispositivo del sistema. + Nombre de usuario personalizado + Establece el nombre del dispositivo personalizado para el reloj de la pantalla de bloqueo.\nMantenga en blanco para usar el nombre del dispositivo del sistema. + Seleccionar + Batería cargándose + Batería descargándose + Batería llena + Nivel de batería + ¡Te damos la bienvenida de vuelta! + Usuario + + Habilitar fondo de pantalla con profundidad + Mostrar fondo de pantalla con profundidad parecido a iOS\n%s + Imágenes personalizadas + Establecer imágenes personalizadas como fondo de pantalla de profundidad + Mostrar en pantalla ambiente + Mostrar tema en pantalla ambiente + Desvanecer en AOD + Anima el fondo de pantalla y desvanecer en AOD + Imagen del primer plano + Imagen del primer plano para fondo de pantalla con profundidad + Foreground Image Opacity + Imagen del fondo + Imagen del fondo para fondo de pantalla con profundidad + Esta característica se encuentra actualmente en fase beta, así que se esperan errores.\n\nBug(s) conocidos:\n• Pulsar en la pantalla de bloqueo hace que el fondo de pantalla salte. + Efecto de paralaje + Mover capas de fondo y primer plano a diferentes velocidades + Sensibilidad del primer plano + Sensibilidad del fondo + El modelo de IA está descargado en el dispositivo + El modelo de IA no está disponible en el dispositivo (aún) + Extrayendo el tema del fondo de pantalla… + Tema de fondo de pantalla extraído! + ¡No se pudo extraer el tema del fondo de pantalla! + ¡El modelo de IA no está disponible! + Debe usar un reloj personalizado en pantalla de bloqueo + + Barra de estado Ficha de reloj de la barra de estado Mostrar ficha detrás del reloj de la barra de estado - Color del Reloj de la Barra de Estado + Customize Clock Chip + Custom colors, roundness, stroke etc. + Text + Clock Text Color Seguir el Sistema Texto Transparente Color Personalizado - Selector de Color del Reloj - Establecer el color del texto del reloj de la barra de estado - Status Icons + Text Color Picker + Set color of statubsar clock text + Iconos de estado Estilo de la ficha Ficha de los iconos de estado Mostrar ficha detrás de los iconos de estado + Customize Status Icons Chip + Custom colors, roundness, stroke etc. Estilo de Chip de Iconos de Estado Margen Superior Margen Lateral + Background + Accent Fill Color + Gradient Direction + Fill Start Color + Fill End Color + Border + Enable Border + Accent Border Color + Border Color + Dashed Border + Dash Width + Dash Gap + Border Thickness + Padding + Padding Left + Padding Right + Padding Top + Padding Bottom + Corner Radius + Top Left Radius + Top Right Radius + Bottom Left Radius + Bottom Right Radius + + Tamaño del reloj de la barra de estado + Establecer un tamaño personalizado para el reloj de la barra de estado + Tamaño del reloj de la barra de estado + Iconos de la barra de estado coloreados + Mostrar icono de aplicación como icono de notificación + Ocultar Transportista en Pantalla de Bloqueo + Ocultar el nombre del transportista en la pantalla de bloqueo + Ocultar Barra de Estado en Pantalla de Bloqueo + Ocultar la barra de estado en la pantalla de bloqueo - QS Header + Encabezado de AR Ocultar grupo del operador Ocultar el grupo del operador del panel de Ajustes Rápidos Ocultar iconos de estado Quitar la hora, la fecha y los iconos de la batería - Lock Screen - Ocultar Transportista en Pantalla de Bloqueo - Ocultar el nombre del transportista en la pantalla de bloqueo - Ocultar Barra de Estado en Pantalla de Bloqueo - Ocultar la barra de estado en la pantalla de bloqueo - Hide LS Lock Icon - Hide lock icon view on lockscreen + Pantalla de bloqueo + Ocultar icono de bloqueo de Pantalla de Bloqueo + Ocultar icono de bloqueo en pantalla de bloqueo Iconos de Estado Fijos - Set status icons in fixed position\nMight be buggy on some rom + Establece los iconos de estado en una posición fija\nPuede presentar errores en algunas ROMs Registro de cambios ¡No se pudo conectar al servidor!\nPodría haber un problema con tu conexión a Internet o el servidor podría estar caído en este momento. Por favor, inténtalo de nuevo más tarde. @@ -671,7 +818,7 @@ Última versión: No se pudo verificar la actualización. No disponible - Schedule + Horario Programar actualizaciones Cuándo buscar actualizaciones Cada 6 horas @@ -679,64 +826,65 @@ Cada día Cada semana Nunca - Current Version: %s - Latest Version: %s + Versión actual: %s + Última versión: %s Creditos - Special Thanks + Agradecimientos especiales Por los iconos Plumpy & Fluency. Por los iconos de la aplicación. Por ayudarme con el script de Shell. Por ayudarme con RRO. - For helping me with Xposed. + Por ayudarme con Xposed. Por probar la aplicación. Por el permiso para usar un mejor QS. - For android executable binaries. + Por los ejecutables binarios de Android. Colaboradores Por contribuir en GitHub. Por ayudarme en Telegram. Traductores - Afrikaans translation. + Traducción al afrikáans. Traducción al árabe. - Catalan translation. - Chinese translation. - Chinese translation. - Czech translation. - Danish translation. - Dutch translation. - Finnish translation. + Traducción al catalán. + Traducción al chino. + Traducción al chino. + Traducción al checo. + Traducción al danés. + Traducción al holandés. + Traducción al finlandés. Traducción al francés. - German translation. - Greek translation. - Hungarian translation. + Traducción al alemán. + Traducción al griego. + Traducción al húngaro. Traducción al indonesio. - Italian translation. - Japanese translation. - Korean translation. - Norwegian translation. + Traducción al italiano. + Traducción al japonés. + Traducción al coreano. + Traducción al noruego. Traducción al persa. - Polish translation. + Traducción al polaco. Traducción al portugués. - Portuguese (Brazilian) translation. - Romanian translation. + Traducción al portugués (brasileño). + Traducción al rumano. Traducción al ruso. - Serbian (Cyrillic) translation. - Spanish translation. - Swedish translation. + Traducción al serbio (cirílico). + Traducción al español. + Traducción al sueco. Traducción al turco. - Ukrainian translation. + Traducción al ucraniano. Traducción al vietnamita. Funciones experimentales - Overlap Header Image - Overlap header image on expanded QS - Unzoom Depth Wallpaper - Remove the zoom effect on depth wallpaper + Superponer imagen del encabezado + Superponer imagen de cabezera en AR expandidos + Deshacer zoom de fondo de pantalla con profundidad + Elimina el efecto de zoom del fondo de pantalla con profundidad Ocultar Icono de Datos Desactivados Ocultar el indicador de datos desactivados Estilos Retoques + Xposed Configuración Registro de cambios @@ -745,44 +893,21 @@ Importar configuración Reiniciar SystemUI ¿Estás seguro? - You will lose your current setup and settings. + Perderás tu configuración y ajustes actuales. Restablecer configuración Configuración importada con éxito Configuración guardada con éxito Ninguno - Estilo 1 - Estilo 2 - Estilo 3 - Estilo 4 - Estilo 5 - Estilo 6 - Estilo 7 - Estilo 8 - Estilo 9 - Estilo 10 - Estilo 11 - Estilo 12 - Estilo 13 - Estilo 14 - Estilo 15 - Estilo 16 - Estilo 17 - Estilo 18 - Estilo 19 - Estilo 20 - Estilo 21 - Estilo 22 - Estilo 23 - Estilo 24 - Estilo 25 + Estilo %d CONTINUAR Reiniciar Deshabilitar Habilitar APLICAR + Save Deshabilitar los colores personalizados Aplicar Colores RESTABLECER @@ -813,21 +938,21 @@ Lorn utiliza el color de batería por defecto Plumpy utiliza el color de batería por defecto Selecciona primero un estilo - KernelSU is currently not supported - Only magisk is supported currently + KernelSU no está soportado actualmente + Solo Magisk está soportado actualmente Se requiere reinicio ¡No se encontró LSPosed! ¿Cómo sabías eso? ¿Por qué sigues haciendo eso? - You have restarted SystemUI too frequently. Please try again later. + Has reiniciado la IU del sistema con demasiada frecuencia. Por favor, inténtalo de nuevo más tarde. Abriendo la página \"Acceso a Todos los Archivos\" Caché de Iconify borrada Instalación omitida. Algunas funciones pueden no funcionar correctamente. Configuraciones importadas exitosamente Configuraciones exportadas exitosamente - Selected successfully - Unavailable - Use this feature from Xposed Menu + Selccionado con éxito + No disponible + Usar esta característica del menú de Xposed Actualización disponible Hay una nueva versión de Iconify disponible. @@ -843,7 +968,7 @@ Vista previa selector de color Selector de color - Pitch Black + Negro puro Oscuro Amoled Advertencia @@ -851,13 +976,9 @@ Hola! Iconos Iconos del Reproductor de medios - Seleccionado: - Selected: %s - Selected: %1$s%2$s - Selected: %1$s%2$s %3$s (Predeterminado) - No Clock - Clock Style %d + Sin reloj + Estilo del reloj %d Por favor espera Reiniciando en 5 segundos Versión de Iconify @@ -877,7 +998,7 @@ Actualizaciones de la aplicación No - Understood + Entendido Menajes emergentes personalizados Habilitar mensajes emergentes con estilo personalizado Barra de progreso personalizada @@ -893,7 +1014,7 @@ Margen Ajustes Rápidos personalizado Habilitar margen personalizado para el panel de Ajustes Rápidos Forzar habilitación de desenfoque - Force enable blur for unsupported roms + Forzar habilitación de desenfoque para ROMs no soportadas Selecciona imagen de encabezado Selecciona fuente del reloj Elige un estilo de tu preferencia @@ -920,7 +1041,127 @@ Encendido Apagado ¡Reinicia tu dispositivo! - Tap on preview to select - Don\'t show again - To ensure proper functionality, enabling the Iconify module in LSPosed is mandatory for android 14 and above.\n\nAfter that, enable the fixes from: Tweaks > Xposed Menu > Themes > Others. + Pulsa en vista previa para seleccionar + No mostrar de nuevo + Para asegurar una funcionalidad adecuada, habilitar el módulo de Iconify en LSPosed es obligatorio para Android 14 o superior.\n\nDespués de eso, habilita las correcciones de: Ajustes > Menu de Xposed > Temas > Otros. + Do not select file from Recent + Dismiss + Restart Device + Pending + Accent Primary + Accent Secondary + Accent Tertiary + Text Color Primary + Text Color Inverse + + + Unidad + Verificando ubicación + Seleccione ubicación + Introducir ubicación + Ubicación + Establecer ubicación personalizada + ¡No se puede encontrar la ubicación! + La geolocalización por red está desactivada.\n\nEstablezca una ubicación personalizada o active la geolocalización por red. + Habilitar + Ajustes + Actualizaciones automáticas + Buscar nuevas versiones de vez en cuando + Comprobar actualizaciones solo por WiFi + Buscar actualizaciones en segundo plano solo cuando se está conectado a WiFi + Métrico (\u00b0C) + Imperial (\u00b0F) + Actualizar + Habilitar + Intervalo de actualización + 1 hora + 2 horas + 4 horas + 6 horas + 12 horas + Clima + Paquete de iconos de condición + Encuentra más paquetes de iconos + Deshabilitado + Error + Esperando \u2026 + No hay datos del clima + Error cargando datos del clima + Esperando\u2026 + Actualizando\u2026 + Servicio deshabilitado + Ahora + Sombra de fondo + Configuración del servicio + Desconocido + Error cargando datos del clima + Clima + Última actualización: + Sin ubicación disponible + No se encontró una red + Permiso de ubicación no concedido + Seleccione ubicación + Buscar una ubicación + Habilitar permisos de ubicación + Se requieren permisos de ubicación para obtener datos del clima. Haz clic en Ok para abrir Ajustes. + + Nublado + Lluvioso + Soleado + Tormentoso + Nevado + Ventoso + Nublado + + Clima en la pantalla de bloqueo + Mostrar el clima en la pantalla de bloqueo + Tiempo de la última actualización + Proveedor del clima + Clave de la API OpenWeatherMap + Clave API de OpenWeatherMap requerida + Por favor, introduzca su clave de API de OpenWeatherMap para obtener los datos meteorológicos. + Mostrar Ubicación + Mostrar ubicación antes del icono + Mostrar condiciones + Mostrar condición después de la temperatura + Mostrar humedad + Mostrar humedad en una nueva fila + Mostrar viento + Mostrar viento en una nueva fila + Tamaño del texto + Tamaño de Imagen + Color del texto + Establecer color personalizado para el texto + Color Personalizado + Color personalizado para todo el texto en la vista del tiempo + Ubicación personalizada + Establecer ubicación personalizada para el clima + Márgenes personalizados + Establecer márgenes personalizados para el clima + Margen superior + Diseño central + Margen lateral + Margen Inferior + Centrar vista del clima + Mover la vista del clima al centro horizontalmente + + Estilo de fondo del clima + Predeterminado + Cajón semitransparente + Cajón semitransparente (redondeado) + Píldora Q-Beta + Redondeado, simple y con acento + Redondeado, transparente y con acento + Degradado + Oscuro con bordes acentuados + Oscuro con bordes degradados + + SystemUI Restart Needed + A SystemUI restart is needed for this change to take effect. + Device Restart Needed + A device restart is needed for this change to take effect. + Switch Device Theme + Switch between light and dark themes if unexpected behavior occurs. + Device Rotation Theme + Switch rotation of your device for this change to take effect. diff --git a/app/src/main/res/values-fa-rIR/strings.xml b/app/src/main/res/values-fa-rIR/strings.xml index 4f13de299..391e1c184 100644 --- a/app/src/main/res/values-fa-rIR/strings.xml +++ b/app/src/main/res/values-fa-rIR/strings.xml @@ -1,60 +1,72 @@ - + شخصی سازی رابط‌ کاربری خسته کننده اندروید - Initializing setup - Step - Step %1$d/%2$d - Creating module shell - Extracting necessary files - Creating overlay APKs - Aligning overlay APKs - Signing overlay APKs - Cleaning directories - Got Bored of Stock UI ? - Let\'s customize everything to our likings. - Ditch the stock UI monotony – personalize every tech detail to match your style and preferences. - Is My Device Supported ? - Iconify supports all Pixel and AOSP ROMs. - Compatible with all Pixel and AOSP-based ROMs, ensuring broad support for Android devices. - Shall We Begin Now ? - It is time for iconify to do some internal work. - Starting internal tasks, marking the initiation of essential work. Ready to begin? - Need Storage Permission - Storage permission is required to build the necessary files. - Could Not Find Compatible Root Method - Use any popular root solutions to proceed. - Root Is Not Accessible + راه‌اندازی اولیه + قدم + قدم %1$d/%2$d + در حال ساخت ماژول واسط(شِل) + استخراج پرونده های مورد نیاز + ساخت APK های پوششی + هماهنگ سازی APK ها + امضا کردن APK های پوششی + پاکسازی پوشه ها + از رابط کاربری پیشفرض زده شدی؟ + بیایید همه چیز را به دلخواه خود سفارشی کنیم. + یکنواختی رابط کاربری پیشفرض را کنار بگذارید – تمام جزئیات فناوری را شخصی سازی کنید تا با سبک و ترجیحات شما مطابقت داشته باشند. + دستگاه من پشتیبانی میشه؟ + آیکونیفای از تمام پیکسل ها و رام های بر پایه اندروید متن باز(AOSP) پشتیبانی میکند. + سازگار با تمام رام های مبتنی بر پیکسل و AOSP، اطمینان از پشتیبانی گسترده از دستگاه های اندرویدی. + اکنون شروع کنیم؟ + اکنون زمان آن است که آیکونیفای یک سری کار های داخلی انجام دهد. + شروع وظایف داخلی، علامت گذاری شروع کار ضروری. آماده آغاز هستید؟ + دسترسی حافظه مورد نیاز است + دسترسی به حافظه برای ساخت برخی پرونده های ضروری لازم است. + روش روت سازگار یافت نشد + برای ادامه از هر کدام از روش های محبوب روت استفاده کنید. + روت در دسترس نیست ظاهرا دستگاه شما روت نشده است! - Need Device Reboot - Reboot your device to put all files in place. - Oops Did Not Expect That + نیازمند بازراه‌اندازی دستگاه + دستگاهتان را بازراه‌اندازی کنید تا پرونده های مورد نیاز در مکان باید قرار گیرند. + اوه انتظار این را نداشتیم ظاهرا مشکلی پیش آمده است.\nبرای کمک به حل مشکل لاگ برنامه را برای سازنده ارسال کنید. - Logs + گزارش‌ها + + Search + Search… + Clear + History entry + More + Clear history + No result آیکونیفای آیکون‌ها تغییر ظاهر آیکون‌های سیستم + Cellular Icons + Change system cellular icons + WiFi Icons + Change system WiFi icons نوار تنظیم نور صفحه تغییر ظاهر نوار تنظیم نور صفحه کلید‌های نوار‌ابزار تغییر ظاهر کلید‌های نوار‌ابزار نوتیفیکیشن‌ها تغییر ظاهر نوتیفیکیشن‌ها - Progress Bar - Use different progress style - Switch - Customize switch appearance - Toast Frame + نوار پیشرفت + بهره‌وری از سبک متفاوت پیشرفت + کلید + شخصی‌سازی کلید + Change toast notification style - Icon Shape - Change system icon shapes + حالت نماد + تغییر شکل نماد های سامانه برنامه آیکونیفای آپدیت شد! برای استفاده از گزینه‌های جدید اضافه شده به برنامه ابتدا دستگاه خود را ریستارت کنید. - Design It Your Way - Unleash Your Imagination, Make It Yours - Hide + هر طور میخوای طراحیش کن + تخیل تان را رها کنید، آن را از آن خود کنید + پنهان کردن انتخاب رنگبندی تغییر رنگبندی بخش‌های مختلف @@ -64,10 +76,10 @@ تغییر تعداد ردیف و ستون در نوارابزار آیکون و متن گزینه‌های نوار‌ابزار تغییر تنظیمات مربوط به آیکون‌ها و متن - QS Tile Size - Change height of QS panel tile - QS Panel Margin - Modify quick settings margins + اندازه کاشی تنظیمات سریع + تنظیم ارتفاع کاشی تنظیمات سریع + حاشیه تنظیمات سریع + تنظیم حاشیه تنظیمات سریع نوار اعلان تغییر ظاهر نوار اعلان نوار ناوبری @@ -83,58 +95,62 @@ موارد بیشتر تنظیمات و گزینه‌های اضافه - General - Language - App Icon - Default Icon - Themed Icon - Retro Icon - App Theme - Light Theme - Dark Theme - Follow System - Update - Check For Update - Current version: %s - Auto Update - Check for new versions in background. - Check Over WiFi Only - Check for updates over wifi only. + عمومی + زبان + نماد برنامه + نماد پیشفرض + نماد پویا + نماد رترو + پوسته برنامه + پوسته روشن + پوسته تیره + پیروی از سیستم + به‌روزرسانی + بررسی برای بروزرسانی + نسخه کنونی: %s + به‌روزرسانی خودکار + بررسی برای نسخه جدید در پس‌زمینه. + تنها با وای‌فای بررسی کن + به‌روزرسانی ها را تنها با وای‌فای بررسی کن. Xposed - Show Warning - Show warning on how to re-optimize module in Xposed Menu. - Mod Applying Method - Automatically restart SystemUI - Automatically force reload UI - Notify for manual SystemUI restart - SystemUI restart required - Miscellaneous - Restart SystemUI After Boot - Some options like blur intensity doesn\'t take effect until systemui is restarted - Show Home Page Card - Show a beautiful card on the home page. - Clear App Cache - Clear caches generated due to the usage of custom fonts, images, or gifs. + نمایش هشدارها + نمایش هشدار در مورد نحوه باز-بهینه‌سازی ماژول در منوی Xposed. + روش به‌کارگیری مود + بازراه‌اندازی خودکار رابط کاربری + اجبار خودکارخودکار به بازراه‌اندازی رابط کاربری + آگاه‌سازی برای بازراه‌اندازی دستی رابط کاربری + رابط کاربری نیازمندِ راه‌اندازی مجدد است + متفرقه + بازراه‌اندازی خودکار رابط کاربری پس از راه‌اندازی + برخی از گزینه‌ها مانند شدت تاری تا زمانی که رابط کاربری بازراه‌اندازی نشود، به کار گرفته نمیشوند + نمایش برگه خانه + نمایش یک برگه زیبا در بخش خانه برنامه. + Haptic Feedback + Enhance touch feedback with interactive haptics. + پاک‌سازی حافظه پنهان برنامه + پاک کردن حافظه پنهان ایجاد شده به دلیل استفاده از فونت های سفارشی، تصاویر یا گیف ها. گزینه‌های آزمایشی - Try out experimental functionalities. + عملکرد های آزمایشی را امتحان کنید. غیرفعال کردن همه چیز تمام مواردی که توسط آیکونفای تغییر پیدا کرده به حالت اولیه باز می‌گردد. - About - Github Repository - Telegram Group - Credits - Thanking those who made this possible. + درباره + منبع GitHub + گروه تلگرام + Translate Iconify + Help translate Iconify to your language. + دست‌اندرکاران + قدردانی از کسانی که این امکان را فراهم کردند. رنگی کردن آیکون باتری تغییر رنگ آیکون باتری - Media Icons - Change media player icons - Settings Icons - Change settings icon pack - Icon Pack Styles - Dual tone linear icon pack - Gradient shaded filled icon pack - Thick linear icon pack + نماد های رسانه + تغییر نماد های رسانه + نماد های تنظیمات + تنظیم بسته نماد های تنظیمات + چگونگی بسته های نماد + بسته نماد خطی دو تُن + بسته نماد شیب گونه + بسته نماد خطی ضخیم Dual tone filled icon pack Acherus sub icon pack Thin line icon pack @@ -155,8 +171,8 @@ تغییر رنگ نمایشگر میزان باتری Supported Music Player Not Found - Android 13 Default Player - Application not found! + پخش کننده پیشفرض اندروید ۱۳ + برنامه یافت نشد! Aurora Gradicon Plumpy @@ -192,22 +208,22 @@ Notification Styles پیش‌نمایش نوتیفیکشن.\nبرای اعمال این گزینه آن را لمس کنید. - Click to enable or disable + برای روشن و خاموش شدن ضربه بزنید - None + هیچکدام Pebble Hexagon Samsung Scroll Square Teardrop - Rounded\nRectangle + گرد\nمستطیل iOS - Cloudy - Cylinder - Flower - Heart - Leaf + ابری + سیلندر + گل + قلب + برگ Streteched Tapered\nRectangle Vessel @@ -228,11 +244,11 @@ فعال‌سازی تم سیاه برای تمام پس‌زمینه‌ها Pitch Black (Amoled) Enable pitch black amoled theme - Misc. + سایر. مینیمال کردن ظاهر نوارابزار حذف سایه بخش بالایی نوارابزار - Disable System Monet - Helps to retain custom colors\nSystemUI restart required + System Monet + Disable to retain custom colors\nSystemUI restart required رنگ اولیه انتخاب رنگ آکسان اولیه @@ -241,7 +257,7 @@ سایه‌های دقیق در رنگ‌ها برای پررنگ تر شدن رنگ‌ها این گزینه را غیرفعال کنید - Monet Style + چگونگی مونت Neutral Monochrome Tonal Spot @@ -403,26 +419,95 @@ Personalize with themes تنظیمات سریع ترفندهای مربوط به نوار ابزار - Battery Style + سبک باتری Customize battery icon view + Oneplus QS Header + OOS style quick settings header عکس هدر نوارابزار اضافه کردن تصویر سفارشی به هدر نوار‌ابزار ساعت هدر نوارابزار اصافه کردن ساعت سفارشی به نوارابزار قفل صفحه تغییر ظاهر قفل صفحه + Lockscreen Weather + Add weather on lockscreen + Lockscreen Widgets + Add widgets on lockscreen Depth Wallpaper Show iOS like depth wallpaper پس‌زمینه رنگی اضافه کردن پس‌زمینه رنگی به پشت ساعت + Clock Chip تنظیمات بیشتر تنظیمات متفرقه و شخصی‌سازی بیشتر - + Weather Settings + + Oneplus QS Header + Enable OOS style media player and tiles in QS + Haptic Feedback + Add haptic feedback on tiles + Hide Stock Media Player + Remove stock media player from QS panel + Blur Level + Fade Level + Top Margin + Expansion Amount + + Lockscreen Widgets + Enable Lockscreen Widgets + Add widgets to lockscreen + Device Info Widget + Show device info widget on lockscreen + Linear Progress Color + Circular Progress Color + Text Color + Custom Device Name + Set custom device name.\nKeep blank to disable. + Large Widgets + Large Widget 1 + Large Widget 2 + Mini Widgets + Mini Widget 1 + Mini Widget 2 + Mini Widget 3 + Mini Widget 4 + Custom Colors + Customize Widget Colors + Large Widget Active Color + Large Widget Inactive Color + Large Widget Icon Active Color + Large Widget Icon Inactive Color + Mini Widget Active Color + Mini Widget Inactive Color + Mini Widget Icon Active Color + Mini Widget Icon Inactive Color + Weather Settings + Widgets Scale + + Camera + Clock/Timer + Calculator + Gallery + Media Player + Torch + Play + Weather + Wifi + Data + Ringer + Bluetooth + Home Controls + Wallet + Hotspot + Ringer + Vibrate + Silent + Transparency شفاف کردن پنل نوارابزار با استفاده از این قسمت پیش‌زمینه نوارابزار خود را شفاف (محو) کنید - میزان شفافیت - Transparent Notif Shade Only + Background Opacity + Transparent Notification Shade Make only notification shade transparent Dim Lockscreen Wallpaper Suitable for light-colored wallpapers @@ -432,7 +517,7 @@ Aggressive Blur Enabler Might bootloop in some roms شعاع شفاف شدن - + For Pixel Roms Light Theme Light QS theme in light mode\nMust use custom QS Shape @@ -449,26 +534,33 @@ Power Menu Transparency Power menu transparency for Fluid QS\nDo not use custom notification style Others + Fix QS Tile Color + Fix custom QS tile style on android 14 Fix Notification Color Fix custom notification style on android 14 - + Fix Notification Footer Button Color + Fix custom footer button style on android 14 + QS Tile عمودی کردن کلید‌های نوارابزار نمایش دادن عنوان کلید نوارابزار در زیر آیکون آن مخفی کردن عنوان کلید نوارابزار فقط در صورت عمودی بودن کلید‌ها از این گزینه استفاده کنید + Text Size Scaling QS Margin QS Elements + Hide QS on Lockscreen + Disable quick settings panel on secured lockscreen Hide Silent Text - Hide silent text shown as header of silent notifications (Requires SystemUI restart) + Hide silent text shown as header of silent notifications Hide Footer Buttons Hide footer buttons shown under notification stack - - Battery Style - Battery Width - Battery Height - Battery Margin - Hide Battery + + سبک باتری + طول باتری + عرض باتری + حاشیه باتری + پنهان کردن باتری Keep only charging icon and percentage Custom Charging Icon Change charging icon to custom icon @@ -494,12 +586,12 @@ Change color of powersave battery Powersave Indicator Color Change color of powersave indicator - Custom Dimensions - Set custom dimensions for battery icon - Battery Margin Left - Battery Margin Right - Battery Margin Top - Battery Margin Bottom + Custom Margins + Set custom margins for battery icon + حاشیه چپ باتری + حاشیه راست باتری + حاشیه بالا باتری + حاشیه پایین باتری Reverse Layout Show percentage on the opposite side Rotate Layout @@ -508,7 +600,7 @@ Hide battery percentage text Inside Percentage Move percentage to inside battery icon - Default + پیشفرض Landscape R Default Landscape L Default Landscape R Custom @@ -546,17 +638,19 @@ Circle Battery Dotted Circle Battery Filled Circle Battery - - Volume Percentage - Show percentage above volume slider - Safety Warning - Show warning on high volume - + + درصد صدا + نمایش درصد باتری بالای نوار تنظیم صدا + هشدار ایمنی + هشدار ایمنی در حجم صدای بالا + Colored Ringer Icon + Enable if selected ringer icon is invisible + انتخاب فایل تصویر هدر اصافه کردن تصویر به هدر نوارابزار\nفایل تصویر را از بخش فایل‌های اخیر انتخاب نکنید انتخاب فایل تصویر ارتفاع تصویر - میزان شفافیت تصویر هدر + Image Opacity Bottom Fade Amount بزرگنمایی تصویر هدر به صورت پیش‌فرض توصیر کشیده می‌شود تا به درستی قرار بگیرد @@ -564,35 +658,36 @@ Hide image in landscape mode Alpha Gradient Add faded effect to the header image - + سفارشی کردن ساعت هدر نوارابزار اضافه کردن ساعت سفارشی به هدر نوارابزار استایل ساعت Clock Font - Use custom font for header clock\nDo not select file from Recent + Use custom font for header clock Custom Clock Color - Custom color instead of primary color + Custom colors instead of system colors Clock Color Picker Set color of header clock text + Expansion Amount Text Scaling - تنظیم حاشیه جانبی ساعت - تنظیم حاشیه بالای ساعت + Side Margin + Top Margin سفید کردن متن متن ساعت همیشه سفید باشد Center Clock Move clock to center of view Hide in Landscape Hide clock in landscape mode - + شخصی سازی ساعت صفحه قفل فعال کردن ساعت سفارشی برای صفحه قفل Auto Hide Clock Hide clock on incoming notification ظاهر ساعت فونت ساعت - استفاده از فونت سفارشی برای ساعت صفحه قفل\nفایل را از قسمت فایل‌های اخیر انتخاب نکنید + Use custom font for lockscreen clock Custom Clock Color - Custom color instead of primary color + Custom colors instead of system colors Clock Color Picker Set color of lockscreen clock text Text Scaling @@ -601,21 +696,32 @@ تنظیم حاشیه پایین ساعت سفید کردن فونت ساعت فونت ساعت همیشه سفید رنگ باشد + Use Custom Image + Use custom image for lockscreen clock. + Custom Image Picker + Custom Device Name + Set custom device name for lockscreen clock.\nKeep blank to use System\'s Device Name. + Custom User Name + Set custom user name for lockscreen clock.\nKeep blank to use System\'s User Name. Select - Battery Charging - Battery Discharging - Battery Full - Battery Level + باتری در حال شارژ + باتری خارج از شارژ + باتری کامل + سطح باتری Welcome back! User - + Enable Depth Wallpaper - Show iOS like depth wallpaper\nMust use custom lockscreen clock + Show iOS like depth wallpaper\n%s + Custom Images + Set custom images as depth wallpaper + Show on AOD + Show subject on always on display Fade in AOD Animate wallpaper and fade away in AOD Foreground Image Foreground image for depth wallpaper - Foreground Image Alpha + Foreground Image Opacity Background Image Background image for depth wallpaper This feature is currently in beta stage. So bugs are expected.\n\nKnown Bug(s):\n• Tapping on lockscreen makes the wallpaper jump. @@ -623,23 +729,68 @@ Move background and foreground layers at different speeds Foreground Sensitivity Background Sensitivity - + AI model is downloaded on the device + AI model isn\'t available on the device (yet) + Extracting wallpaper subject… + Extracted wallpaper subject! + Failed to extract wallpaper subject! + AI model is not available! + Must use custom lockscreen clock + Status Bar پیش‌زمینه رنگی برای ساعت نوار اعلان نمایش دادن پیش‌زمینه رنگی پشت ساعت نوار اعلان - Statusbar Clock Color + Customize Clock Chip + Custom colors, roundness, stroke etc. + Text + Clock Text Color Follow System Transparent Text Custom Color - Clock Color Picker - Set color of statubsar clock text + Text Color Picker + Set color of statubsar clock text Status Icons استایل پیش‌زمینه پیش‌زمینه رنگی برای آیکون‌های نوار اعلان نمایش پیش‌زمینه رنگی برای آیکون‌های نوار اعلان + Customize Status Icons Chip + Custom colors, roundness, stroke etc. Chip Style Top Margin Side Margin + Background + Accent Fill Color + Gradient Direction + Fill Start Color + Fill End Color + Border + Enable Border + Accent Border Color + Border Color + Dashed Border + Dash Width + Dash Gap + Border Thickness + Padding + Padding Left + Padding Right + Padding Top + Padding Bottom + Corner Radius + Top Left Radius + Top Right Radius + Bottom Left Radius + Bottom Right Radius + + Custom Statusbar Clock Size + Set a custom size for Statusbar Clock + Statusbar Clock Size + Colored Statusbar Icon + Show app icon as notification icon + Hide LS Carrier + Hide carrier name on lockscreen + Hide LS Statusbar + Hide statusbar on lockscreen QS Header مخفی کردن اپراتور @@ -647,10 +798,6 @@ مخفی کردن آیکون‌های نوار اعلان مخفی کردن آیکون ساعت و تارخ و باتری Lock Screen - Hide LS Carrier - Hide carrier name on lockscreen - Hide LS Statusbar - Hide statusbar on lockscreen Hide LS Lock Icon Hide lock icon view on lockscreen Fixed Status Icons @@ -686,7 +833,7 @@ Special Thanks For Plumpy & Fluency icons. For in-app icon set. - For helping me with Shell Script. + برای کمک به من با اسکریپت شِل. For helping me with RRO. For helping me with Xposed. For testing the app. @@ -737,6 +884,7 @@ Home Tweaks + Xposed Settings تغییرات اخیر برنامه @@ -752,37 +900,14 @@ پشتیبان گیری از تنظیمات با موفقیت انجام شد None - Style 1 - Style 2 - Style 3 - Style 4 - Style 5 - Style 6 - Style 7 - Style 8 - Style 9 - Style 10 - Style 11 - Style 12 - Style 13 - Style 14 - Style 15 - Style 16 - Style 17 - Style 18 - Style 19 - Style 20 - Style 21 - Style 22 - Style 23 - Style 24 - Style 25 + Style %d ادامه دادن ریستارت غیرفعال کردن فعال‌سازی اعمال کردن + Save غیرفعال کردن رنگ‌های انتخاب شده فعال کردن رنگ‌های انتخاب شده بازنشانی به حالت اولیه @@ -851,10 +976,6 @@ توجه! آيکون آیکون‌های مدیا پلیر - اندازه انتخابی: - Selected: %s - Selected: %1$s%2$s - Selected: %1$s%2$s %3$s (مقدار پیش‌فرض) No Clock Clock Style %d @@ -910,7 +1031,7 @@ Use light accent color in light mode Disable Animation Disable scrolling animation of Iconify - Custom Battery + باتری سفارشی Enable custom battery style Toast Message Made with \u2764\uFE0E by DrDisagree @@ -923,4 +1044,124 @@ Tap on preview to select Don\'t show again To ensure proper functionality, enabling the Iconify module in LSPosed is mandatory for android 14 and above.\n\nAfter that, enable the fixes from: Tweaks > Xposed Menu > Themes > Others. + Do not select file from Recent + Dismiss + Restart Device + Pending + Accent Primary + Accent Secondary + Accent Tertiary + Text Color Primary + Text Color Inverse + + + Unit + Verifying location + Select location + Enter location + Location + Set custom location + Cannot retrieve location! + Network geolocation is disabled.\n\nSet a custom location or enable network location. + Enable + Settings + Automatic updates + Check for new versions once in a while + Check updates over WiFi only + Check for updates in background only when connected to wifi + Metric (\u00b0C) + Imperial (\u00b0F) + Update + Enable + Update interval + 1 hour + 2 hours + 4 hours + 6 hours + 12 hours + Weather + Condition Icon Pack + Find more icon packs + Disabled + Error + Waiting \u2026 + No weather data + Error loading weather data + Waiting\u2026 + Updating\u2026 + Service disabled + Now + Background shadow + Service settings + Unknown + Error loading weather data + Weather + Last update: + No location available + No network found + Location permissions not granted + Select location + Search for a location + Enable Location Permissions + Location permissions are required to fetch weather data. Click OK to open Settings. + + Cloudy + Rainy + Sunny + Stormy + Snowy + Windy + Misty + + Weather on Lockscreen + Show weather on lockscreen + Last Update Time + Weather Provider + OpenWeatherMap API Key + OpenWeatherMap API Key required + Please enter your OpenWeatherMap API key to fetch weather data. + Show Location + Show Location before icon + Show Condition + Show Condition after temperature + Show Humidity + Show Humidity in a new row + Show Wind + Show Wind in a new row + Text Size + Image Size + Text Color + Set custom color for text + Custom Color + Custom color for all text in weather view + Custom location + Set custom location for weather + Custom Margins + Set custom margins for weather + Top margin + Center Layout + Side Margin + Bottom Margin + Center Weather View + Move weather view to center horizontally + + Weather Background Style + Default + Semi-transparent box + Semi-transparent box (round) + Q-Beta pill + Rounded, simple and with accent + Rounded, transparent and with accent + Gradient + Dark with accented borders + Dark with gradient borders + + SystemUI Restart Needed + A SystemUI restart is needed for this change to take effect. + Device Restart Needed + A device restart is needed for this change to take effect. + Switch Device Theme + Switch between light and dark themes if unexpected behavior occurs. + Device Rotation Theme + Switch rotation of your device for this change to take effect. diff --git a/app/src/main/res/values-fi-rFI/strings.xml b/app/src/main/res/values-fi-rFI/strings.xml index 0f6075b05..d0273f4a6 100644 --- a/app/src/main/res/values-fi-rFI/strings.xml +++ b/app/src/main/res/values-fi-rFI/strings.xml @@ -1,5 +1,5 @@ - + Customize Boring Android UI Initializing setup @@ -31,10 +31,22 @@ Oops Did Not Expect That Logs have been saved in documents folder. Logs + + Search + Search… + Clear + History entry + More + Clear history + No result Iconify Icon Pack Change system icon pack + Cellular Icons + Change system cellular icons + WiFi Icons + Change system WiFi icons Brightness Bar Customize progress slider QS Panel Tiles @@ -113,6 +125,8 @@ Some options like blur intensity doesn\'t take effect until systemui is restarted Show Home Page Card Show a beautiful card on the home page. + Haptic Feedback + Enhance touch feedback with interactive haptics. Clear App Cache Clear caches generated due to the usage of custom fonts, images, or gifs. Experimental @@ -122,6 +136,8 @@ About Github Repository Telegram Group + Translate Iconify + Help translate Iconify to your language. Credits Thanking those who made this possible. @@ -231,8 +247,8 @@ Misc. Minimal QS Panel Remove top shade of QS panel - Disable System Monet - Helps to retain custom colors\nSystemUI restart required + System Monet + Disable to retain custom colors\nSystemUI restart required Primary Color Pick primary accent color @@ -405,24 +421,93 @@ Tweaks related to QS panel Battery Style Customize battery icon view + Oneplus QS Header + OOS style quick settings header Header Image Add custom image on QS panel Header Clock Add custom clock on QS panel Lockscreen Clock Add custom clock on lockscreen + Lockscreen Weather + Add weather on lockscreen + Lockscreen Widgets + Add widgets on lockscreen Depth Wallpaper Show iOS like depth wallpaper Background Chip Add colored chip behind clock + Clock Chip Others Miscellaneous xposed tweaks - + Weather Settings + + Oneplus QS Header + Enable OOS style media player and tiles in QS + Haptic Feedback + Add haptic feedback on tiles + Hide Stock Media Player + Remove stock media player from QS panel + Blur Level + Fade Level + Top Margin + Expansion Amount + + Lockscreen Widgets + Enable Lockscreen Widgets + Add widgets to lockscreen + Device Info Widget + Show device info widget on lockscreen + Linear Progress Color + Circular Progress Color + Text Color + Custom Device Name + Set custom device name.\nKeep blank to disable. + Large Widgets + Large Widget 1 + Large Widget 2 + Mini Widgets + Mini Widget 1 + Mini Widget 2 + Mini Widget 3 + Mini Widget 4 + Custom Colors + Customize Widget Colors + Large Widget Active Color + Large Widget Inactive Color + Large Widget Icon Active Color + Large Widget Icon Inactive Color + Mini Widget Active Color + Mini Widget Inactive Color + Mini Widget Icon Active Color + Mini Widget Icon Inactive Color + Weather Settings + Widgets Scale + + Camera + Clock/Timer + Calculator + Gallery + Media Player + Torch + Play + Weather + Wifi + Data + Ringer + Bluetooth + Home Controls + Wallet + Hotspot + Ringer + Vibrate + Silent + Transparency Transparent QS Panel Make QS panel background transparent - Transparency Alpha - Transparent Notif Shade Only + Background Opacity + Transparent Notification Shade Make only notification shade transparent Dim Lockscreen Wallpaper Suitable for light-colored wallpapers @@ -432,7 +517,7 @@ Aggressive Blur Enabler Might bootloop in some roms Blur Intensity - + For Pixel Roms Light Theme Light QS theme in light mode\nMust use custom QS Shape @@ -449,21 +534,28 @@ Power Menu Transparency Power menu transparency for Fluid QS\nDo not use custom notification style Others + Fix QS Tile Color + Fix custom QS tile style on android 14 Fix Notification Color Fix custom notification style on android 14 - + Fix Notification Footer Button Color + Fix custom footer button style on android 14 + QS Tile Vertical QS Tile Show label below QS icon Hide QS Tile Label Use only with vertical tiles + Text Size Scaling QS Margin QS Elements + Hide QS on Lockscreen + Disable quick settings panel on secured lockscreen Hide Silent Text - Hide silent text shown as header of silent notifications (Requires SystemUI restart) + Hide silent text shown as header of silent notifications Hide Footer Buttons Hide footer buttons shown under notification stack - + Battery Style Battery Width Battery Height @@ -494,8 +586,8 @@ Change color of powersave battery Powersave Indicator Color Change color of powersave indicator - Custom Dimensions - Set custom dimensions for battery icon + Custom Margins + Set custom margins for battery icon Battery Margin Left Battery Margin Right Battery Margin Top @@ -546,17 +638,19 @@ Circle Battery Dotted Circle Battery Filled Circle Battery - + Volume Percentage Show percentage above volume slider Safety Warning Show warning on high volume - + Colored Ringer Icon + Enable if selected ringer icon is invisible + Pick Header Image Add header image on QS panel\nDo not select file from Recent Pick Image Image Height - Image Alpha + Image Opacity Bottom Fade Amount Zoom To Fit Image is stretched to fit by default @@ -564,35 +658,36 @@ Hide image in landscape mode Alpha Gradient Add faded effect to the header image - + Custom Header Clock Add a custom clock on QS panel Clock Style Clock Font - Use custom font for header clock\nDo not select file from Recent + Use custom font for header clock Custom Clock Color - Custom color instead of primary color + Custom colors instead of system colors Clock Color Picker Set color of header clock text + Expansion Amount Text Scaling - Clock Side Margin - Clock Top Margin + Side Margin + Top Margin White Text Force text colors to be white Center Clock Move clock to center of view Hide in Landscape Hide clock in landscape mode - + Custom Lockscreen Clock Enable custom lockscreen clock Auto Hide Clock Hide clock on incoming notification Clock Style Clock Font - Use custom font for lockscreen clock\nDo not select file from Recent + Use custom font for lockscreen clock Custom Clock Color - Custom color instead of primary color + Custom colors instead of system colors Clock Color Picker Set color of lockscreen clock text Text Scaling @@ -601,6 +696,13 @@ Bottom Margin White Text Force all colors to be white + Use Custom Image + Use custom image for lockscreen clock. + Custom Image Picker + Custom Device Name + Set custom device name for lockscreen clock.\nKeep blank to use System\'s Device Name. + Custom User Name + Set custom user name for lockscreen clock.\nKeep blank to use System\'s User Name. Select Battery Charging Battery Discharging @@ -608,14 +710,18 @@ Battery Level Welcome back! User - + Enable Depth Wallpaper - Show iOS like depth wallpaper\nMust use custom lockscreen clock + Show iOS like depth wallpaper\n%s + Custom Images + Set custom images as depth wallpaper + Show on AOD + Show subject on always on display Fade in AOD Animate wallpaper and fade away in AOD Foreground Image Foreground image for depth wallpaper - Foreground Image Alpha + Foreground Image Opacity Background Image Background image for depth wallpaper This feature is currently in beta stage. So bugs are expected.\n\nKnown Bug(s):\n• Tapping on lockscreen makes the wallpaper jump. @@ -623,23 +729,68 @@ Move background and foreground layers at different speeds Foreground Sensitivity Background Sensitivity - + AI model is downloaded on the device + AI model isn\'t available on the device (yet) + Extracting wallpaper subject… + Extracted wallpaper subject! + Failed to extract wallpaper subject! + AI model is not available! + Must use custom lockscreen clock + Status Bar Statusbar Clock Chip Display chip behind statusbar clock - Statusbar Clock Color + Customize Clock Chip + Custom colors, roundness, stroke etc. + Text + Clock Text Color Follow System Transparent Text Custom Color - Clock Color Picker - Set color of statubsar clock text + Text Color Picker + Set color of statubsar clock text Status Icons Chip Style Status Icons Chip Display chip behind status icons + Customize Status Icons Chip + Custom colors, roundness, stroke etc. Chip Style Top Margin Side Margin + Background + Accent Fill Color + Gradient Direction + Fill Start Color + Fill End Color + Border + Enable Border + Accent Border Color + Border Color + Dashed Border + Dash Width + Dash Gap + Border Thickness + Padding + Padding Left + Padding Right + Padding Top + Padding Bottom + Corner Radius + Top Left Radius + Top Right Radius + Bottom Left Radius + Bottom Right Radius + + Custom Statusbar Clock Size + Set a custom size for Statusbar Clock + Statusbar Clock Size + Colored Statusbar Icon + Show app icon as notification icon + Hide LS Carrier + Hide carrier name on lockscreen + Hide LS Statusbar + Hide statusbar on lockscreen QS Header Hide Carrier Group @@ -647,10 +798,6 @@ Hide Status Icons Remove time, date and battery icons Lock Screen - Hide LS Carrier - Hide carrier name on lockscreen - Hide LS Statusbar - Hide statusbar on lockscreen Hide LS Lock Icon Hide lock icon view on lockscreen Fixed Status Icons @@ -737,6 +884,7 @@ Home Tweaks + Xposed Settings Changelog @@ -752,37 +900,14 @@ Saved settings successfully None - Style 1 - Style 2 - Style 3 - Style 4 - Style 5 - Style 6 - Style 7 - Style 8 - Style 9 - Style 10 - Style 11 - Style 12 - Style 13 - Style 14 - Style 15 - Style 16 - Style 17 - Style 18 - Style 19 - Style 20 - Style 21 - Style 22 - Style 23 - Style 24 - Style 25 + Style %d Continue Restart Disable Enable Apply + Save Disable Custom Colors Apply Colors Reset @@ -851,10 +976,6 @@ Hey There! Icon Media Player Icons - Selected: - Selected: %s - Selected: %1$s%2$s - Selected: %1$s%2$s %3$s (Default) No Clock Clock Style %d @@ -923,4 +1044,124 @@ Tap on preview to select Don\'t show again To ensure proper functionality, enabling the Iconify module in LSPosed is mandatory for android 14 and above.\n\nAfter that, enable the fixes from: Tweaks > Xposed Menu > Themes > Others. + Do not select file from Recent + Dismiss + Restart Device + Pending + Accent Primary + Accent Secondary + Accent Tertiary + Text Color Primary + Text Color Inverse + + + Unit + Verifying location + Select location + Enter location + Location + Set custom location + Cannot retrieve location! + Network geolocation is disabled.\n\nSet a custom location or enable network location. + Enable + Settings + Automatic updates + Check for new versions once in a while + Check updates over WiFi only + Check for updates in background only when connected to wifi + Metric (\u00b0C) + Imperial (\u00b0F) + Update + Enable + Update interval + 1 hour + 2 hours + 4 hours + 6 hours + 12 hours + Weather + Condition Icon Pack + Find more icon packs + Disabled + Error + Waiting \u2026 + No weather data + Error loading weather data + Waiting\u2026 + Updating\u2026 + Service disabled + Now + Background shadow + Service settings + Unknown + Error loading weather data + Weather + Last update: + No location available + No network found + Location permissions not granted + Select location + Search for a location + Enable Location Permissions + Location permissions are required to fetch weather data. Click OK to open Settings. + + Cloudy + Rainy + Sunny + Stormy + Snowy + Windy + Misty + + Weather on Lockscreen + Show weather on lockscreen + Last Update Time + Weather Provider + OpenWeatherMap API Key + OpenWeatherMap API Key required + Please enter your OpenWeatherMap API key to fetch weather data. + Show Location + Show Location before icon + Show Condition + Show Condition after temperature + Show Humidity + Show Humidity in a new row + Show Wind + Show Wind in a new row + Text Size + Image Size + Text Color + Set custom color for text + Custom Color + Custom color for all text in weather view + Custom location + Set custom location for weather + Custom Margins + Set custom margins for weather + Top margin + Center Layout + Side Margin + Bottom Margin + Center Weather View + Move weather view to center horizontally + + Weather Background Style + Default + Semi-transparent box + Semi-transparent box (round) + Q-Beta pill + Rounded, simple and with accent + Rounded, transparent and with accent + Gradient + Dark with accented borders + Dark with gradient borders + + SystemUI Restart Needed + A SystemUI restart is needed for this change to take effect. + Device Restart Needed + A device restart is needed for this change to take effect. + Switch Device Theme + Switch between light and dark themes if unexpected behavior occurs. + Device Rotation Theme + Switch rotation of your device for this change to take effect. diff --git a/app/src/main/res/values-fr-rFR/strings.xml b/app/src/main/res/values-fr-rFR/strings.xml index f1ffbbb0e..26cfc4b10 100644 --- a/app/src/main/res/values-fr-rFR/strings.xml +++ b/app/src/main/res/values-fr-rFR/strings.xml @@ -1,10 +1,10 @@ - + Personnaliser l\'interface utilisateur ennuyeuse d\'Android Initialisation de la configuration Étape - Step %1$d/%2$d + Étape %1$d/%2$d Création du module Extraction des fichiers nécessaires Création des APK des surcouches @@ -23,7 +23,7 @@ Besoin de l\'autorisation d\'accès au stockage L\'autorisation d\'accès au stockage est requise pour créer les fichiers nécessaires. Impossible de trouver une méthode root compatible - Use any popular root solutions to proceed. + Vous devez rooter votre appareil. Root non accessible On dirait que votre appareil n\'est pas rooté ! Vous devez redémarrer votre appareil @@ -31,10 +31,22 @@ Oups, je ne m\'attendais pas à ça Les journaux ont été enregistrés dans le dossier des documents. Journaux + + Rechercher + Rechercher… + Effacer + Historique des entrées + Plus + Vider l\'historique + Aucun résultat Iconify Pack d\'icônes Modifier le pack d\'icônes système + Icônes Cellulaire + Modifier les icônes cellulaires + Icônes WiFi + Modifier les icônes WiFi Barre de luminosité Personnalisation du curseur de luminosité Tuiles de panneaux QS @@ -113,6 +125,8 @@ Certaines options, comme l\'intensité du flou, ne prennent effet qu\'au redémarrage du système Afficher l\'image de la page d\'accueil Montrez une belle carte sur la page d\'accueil. + Haptic Feedback + Enhance touch feedback with interactive haptics. Vider le cache de l\'application Effacez le cache généré en raison de l\'utilisation de polices, d\'images ou de gifs personnalisés. Expérimental @@ -122,6 +136,8 @@ À propos Github Groupe Telegram + Traduire Iconify + Aidez-nous à traduire Iconify dans votre langue. Crédits Merci à ceux qui ont rendu cela possible. @@ -183,7 +199,7 @@ Pack d\'icônes multicolores de contour Variante Pixel - For roms with black QS panel + Pour roms avec panneau QS noir Styles de la barre de luminosité @@ -231,8 +247,8 @@ Divers. Panneau QS minimal Retirer le store supérieur du panneau QS - Désactiver le système monet - Aide à conserver les couleurs personnalisées \n Redémarrage de l\'interface utilisateur système requis + System Monet + Disable to retain custom colors\nSystemUI restart required Couleur primaire Choisissez la couleur d’accent principale @@ -290,8 +306,8 @@ Titres système, accent des sous-titres Corriger la couleur des textes À utiliser si ceux ci-dessus n\'ont pas fonctionné - Follow Accent - Title accent, subtitle accent + Suivre l\'accent + Titre accentué, sous-titre accentué Mode portrait Mode paysage @@ -365,7 +381,7 @@ Créer le module Module créé avec succès Lisez attentivement ! - This option will create a magisk module inside Download folder in your Internal Storage. Flash the module named IconifyCompanion.zip in Magisk. Always uninstall previous Iconify Companion module (if installed) and reboot before flashing new one.\n\nNote:\n• Uninstall the module before updating rom.\n• Recreate the module if you change or update rom.\n• Do not flash a module which wasn\'t created based on your rom. + Cette option créera un module magisk dans le dossier de téléchargement de votre stockage interne. Flashez le module nommé IconifyCompanion.zip dans Magisk. Désinstallez toujours le module Iconify Companion précédent (s\'il est installé) et redémarrez avant d\'en flasher un nouveau.\n\nRemarque :\n• Désinstallez le module avant de mettre à jour la ROM.\n• Recréez le module si vous modifiez ou mettre à jour la rom.\n• Ne flashez pas un module qui n\'a pas été créé en fonction de votre rom. Aperçu du lecteur multimédia Titre @@ -373,56 +389,125 @@ Haut-parleur du téléphone Couleur du fond Fond d\'accentuation - Make background follow accent + Faire suivre l\'accent sur l\'arrière plan Fond du système - Make background follow system + Faire suivre l\'arrière plan sur le système Fond Pitch Black - Make background pitch black + Arrière-plan noir Mode tablette - Tablet Landscape - Also known as Better QS - Notch Bar Killer - Kill empty space of notch bar - Tablet Header - Enable large screen shade header - Privacy Chip - Accent Privacy Chip - Make privacy chip accent colored - Media Player - Disable Progress Wave - Disable progress bar wave animation + Paysage en mode \"tablette\" + Aussi connu sous le nom de \"Better QS\" + Tuer l\'encoche + Tuer l\'espace vide de l\'encoche + En-tête en mode \"tablette\" + Activer l\'ombre large de l\'en-tête + Puce de confidentialité + Puce de confidentialité colorée + Rendre la puce de confidentialité colorée + Lecteur multimédia + Désactiver la vague de progression + Désactiver l\'animation de la vague de progression - Before enabling Iconify from LSPosed modules, long press on Iconify and click on Re-optimize. After that enable Iconify and restart your SystemUI. This is necessary for a smoother experience. - You are currently in Xposed Only mode. This requires iconify to be enabled in LSPosed app. Also make sure that Iconify module is shown in Magisk manager. To get access to all features, clear data of iconify app and go through the installation process! - Module Not Activated - System service not running + Avant d\'activer Iconify depuis les modules LSPosed, appuyez longuement sur Iconify et cliquez sur Re-optimize. Après ça activez Iconify et redémarrez votre SystemUI. Ceci est nécessaire pour une expérience plus fluide. + Vous êtes actuellement en mode Xposed Only . Cela nécessite que iconify soit activé dans l\'application LSPosed. Assurez-vous également que le module Iconify est affiché dans le gestionnaire Magisk. Pour accéder à toutes les fonctionnalités, effacez les données de l\'application iconify et passez par le processus d\'installation ! + Module non activé + Le service système n\'est pas en cours d\'exécution Transparence & flou Activez le flou et la transparence de QS Thèmes - Personalize with themes + Personnaliser avec des thèmes Paramètres rapides Ajustements liés au panneau QS Style de la batterie - Customize battery icon view + Personnaliser la vue de l\'icône de la batterie + Oneplus QS Header + OOS style quick settings header Image d\'en-tête Ajouter une image personnalisée sur le panneau QS Horloge d\'en-tête Ajout d\'une horloge personnalisée sur le panneau QS Horloge de l\'écran de verrouillage Ajouter une horloge personnalisée sur l\'écran de verrouillage - Depth Wallpaper - Show iOS like depth wallpaper + Météo sur l\'écran de verrouillage + Ajouter la météo sur l\'écran de verrouillage + Widgets de l\'écran de verrouillage + Ajouter des widgets sur l\'écran de verrouillage + Fond d\'écran avec profondeur + Afficher le fond d\'écran en profondeur comme dans iOS Puce de fond Ajouter un jeton coloré derrière l\'horloge + Puce d\'horloge Autres Autres modifications et personnalisation xposed - + Paramètres de la météo + + Oneplus QS Header + Enable OOS style media player and tiles in QS + Haptic Feedback + Add haptic feedback on tiles + Hide Stock Media Player + Remove stock media player from QS panel + Blur Level + Fade Level + Top Margin + Expansion Amount + + Widgets de l\'écran de verrouillage + Activer les widgets de l\'écran de verrouillage + Ajouter des widgets sur l\'écran de verrouillage + Widget infos de l\'appareil + Afficher le widget d\'informations de l\'appareil sur l\'écran de verrouillage + Couleur de progression linéaire + Couleur de progression circulaire + Couleur du texte + Nom de l\'appareil personnalisé + Définissez un nom de l\'appareil personnalisé.\nGardez vide pour le désactiver. + Gros widgets + Gros widgets 1 + Gros widgets 2 + Mini widgets + Mini widget 1 + Mini widget 2 + Mini widget 3 + Mini widget 4 + Couleurs personnalisées + Personnaliser les couleurs du widget + Couleur active du gros widget + Couleur inactive du gros widget + Couleur active de l\'icône du gros widget + Couleur inactive de l\'icône du gros widget + Couleur active du mini widget + Couleur inactive du mini widget + Couleur active de l\'icône du mini widget + Couleur inactive de l\'icône du mini widget + Paramètres de la météo + Widgets Scale + + Caméra + Horloge/Minuterie + Calculatrice + Gallery + Media Player + Torch + Play + Weather + Wifi + Data + Ringer + Bluetooth + Home Controls + Wallet + Hotspot + Ringer + Vibrate + Silent + Transparency Transparent QS Panel Make QS panel background transparent - Transparency Alpha - Transparent Notif Shade Only + Background Opacity + Transparent Notification Shade Make only notification shade transparent Dim Lockscreen Wallpaper Suitable for light-colored wallpapers @@ -432,7 +517,7 @@ Aggressive Blur Enabler Might bootloop in some roms Blur Intensity - + For Pixel Roms Thème clair Light QS theme in light mode\nMust use custom QS Shape @@ -449,21 +534,28 @@ Transparence du menu d\'alimentation Transparence du menu d\'alimentation pour le style Fluid QS\nNe pas utiliser de style de notification personnalisé Autres + Fix QS Tile Color + Fix custom QS tile style on android 14 Correction de la couleur des notifications Correction du style de notification personnalisé sur Android 14 - + Fix Notification Footer Button Color + Fix custom footer button style on android 14 + Tuiles QS Tuiles QS verticales Afficher l\'étiquette sous l\'icône QS Masquer l’étiquette des tuiles QS Utiliser uniquement avec des tuiles verticales + Text Size Scaling Marges QS QS Elements + Hide QS on Lockscreen + Disable quick settings panel on secured lockscreen Hide Silent Text - Hide silent text shown as header of silent notifications (Requires SystemUI restart) + Hide silent text shown as header of silent notifications Hide Footer Buttons Hide footer buttons shown under notification stack - + Style de la batterie Largeur de la batterie Hauteur de la batterie @@ -494,8 +586,8 @@ Changer la couleur de la batterie en économiseur de batterie Couleur de l’indicateur d’économie d’énergie Changer la couleur de l\'indicateur d\'économie d\'énergie - Dimensions personnalisées - Définir des dimensions personnalisées pour l\'icône de la batterie + Custom Margins + Set custom margins for battery icon Marge gauche de la batterie Marge droite de la batterie Battery Margin Top @@ -503,60 +595,62 @@ Reverse Layout Show percentage on the opposite side Rotate Layout - Rotate battery layout 180 degrees - Hide Percentage - Hide battery percentage text - Inside Percentage - Move percentage to inside battery icon - Default - Landscape R Default - Landscape L Default - Landscape R Custom - Landscape L Custom - Portrait Capsule + Pivoter la batterie de 180 degrés + Cacher le pourcentage + Masquer le pourcentage de batterie + Pourcentage à l\'intérieur + Déplacer le pourcentage à l\'intérieur de la batterie + Défaut + Landscape droite défaut + Landscape gauche défaut + Paysage droite custom + Paysage gauche custom + Portrait capsule Portrait Lorn Portrait Mx Portrait Airoo - Landscape R Style A - Landscape L Style A - Landscape R Style B - Landscape L Style B - Landscape iOS 15 - Landscape iOS 16 + Paysage style A + Paysage gauche style A + Paysage droite style B + Paysage gauche style B + Paysage iOS 15 + Paysage iOS 16 Portrait Origami - Landscape Smiley - Landscape MIUI Pill - Landscape L ColorOS - Landscape R ColorOS - Landscape Battery A - Landscape Battery B - Landscape Battery C - Landscape Battery D - Landscape Battery E - Landscape Battery F - Landscape Battery G - Landscape Battery H - Landscape Battery I - Landscape Battery J - Landscape Battery K - Landscape Battery L - Landscape Battery M - Landscape Battery N - Landscape Battery O - Circle Battery - Dotted Circle Battery - Filled Circle Battery - - Volume Percentage - Show percentage above volume slider - Safety Warning - Show warning on high volume - - Pick Header Image + Paysage smiley + Paysage pilule Miui + Paysage gauche ColorOS + Paysage droite ColorOS + Paysage batterie A + Paysage batterie B + Paysage batterie C + Paysage batterie D + Paysage batterie E + Paysage batterie F + Paysage batterie G + Paysage batterie H + Paysage batterie I + Paysage batterie J + Paysage batterie K + Paysage batterie L + Paysage batterie M + Paysage batterie N + Paysage batterie O + Batterie circulaire + Batterie circulaire en pointillés + Batterie circulaire remplie + + Pourcentage du volume + Afficher le pourcentage au-dessus du curseur de volume + Avertissement de sécurité + Afficher l\'avertissement de volume élevé + Icône de sonnerie coloré + Activer si l\'icône de sonnerie sélectionnée est invisible + + Sélectionner l\'image d\'en-tête Add header image on QS panel\nDo not select file from Recent Pick Image Image Height - Image Alpha + Image Opacity Bottom Fade Amount Zoomer pour s\'adapter L\'image est étirée pour s\'adapter par défaut @@ -564,35 +658,36 @@ Cacher l\'image en mode paysage Alpha des dégradés Ajouter un effet dégradé à l\'image d\'en-tête - + Horloge d\'en-tête personnalisée Ajouter une horloge personnalisée sur le panneau QS Style de l\'horloge Police de l\'horloge - Utiliser une police personnalisée pour l\'horloge d\'en-tête\nNe sélectionnez pas le fichier dans \"Récent\" + Use custom font for header clock Couleur de l\'horloge personnalisée - Couleur personnalisée au lieu de la couleur primaire + Custom colors instead of system colors Sélecteur de couleurs d\'horloge Définir la couleur du texte de l\'horloge d\'en-tête + Expansion Amount Mise à l\'échelle du texte - Marge du côté gauche de l\'horloge - Marge supérieure de l\'horloge + Side Margin + Top Margin Texte blanc Forcer le texte à être blanc Centrer l\'horloge Déplacer l\'horloge au centre de l\'écran Masquer en mode paysage Masquer l\'horloge en mode paysage - + Horloge d\'écran de verrouillage personnalisée Activer l\'horloge personnalisée de l\'écran de verrouillage Cacher automatiquement l\'horloge Masquer l\'horloge lors d\'une notification entrante Style de l\'horloge Police de l\'horloge - Utiliser une police personnalisée pour l\'horloge de l\'écran de verrouillage\nNe sélectionnez pas le fichier dans \"Récent\" + Use custom font for lockscreen clock Couleur de l\'horloge personnalisée - Couleur personnalisée au lieu de la couleur primaire + Custom colors instead of system colors Sélecteur de couleurs d\'horloge Définir la couleur du texte de l\'horloge de l\'écran de verrouillage Mise à l\'échelle du texte @@ -601,6 +696,13 @@ Marge inférieure Texte blanc Forcer toutes les couleurs à être blanches + Use Custom Image + Use custom image for lockscreen clock. + Custom Image Picker + Custom Device Name + Set custom device name for lockscreen clock.\nKeep blank to use System\'s Device Name. + Custom User Name + Set custom user name for lockscreen clock.\nKeep blank to use System\'s User Name. Select Battery Charging Battery Discharging @@ -608,14 +710,18 @@ Battery Level Welcome back! User - + Activer le fond d\'écran en profondeur - Afficher un fond d\'écran comme dans iOS en profondeur.\nVous devez utiliser une horloge d\'écran de verrouillage personnalisée + Show iOS like depth wallpaper\n%s + Custom Images + Set custom images as depth wallpaper + Show on AOD + Show subject on always on display Fondu en AOD Animer le fond d\'écran et le faire disparaître dans AOD Image de devant Image de premier plan pour le papier peint en profondeur - Foreground Image Alpha + Foreground Image Opacity Image de fond Image de second plan pour le papier peint en profondeur This feature is currently in beta stage. So bugs are expected.\n\nKnown Bug(s):\n• Tapping on lockscreen makes the wallpaper jump. @@ -623,23 +729,68 @@ Move background and foreground layers at different speeds Foreground Sensitivity Background Sensitivity - + AI model is downloaded on the device + AI model isn\'t available on the device (yet) + Extracting wallpaper subject… + Extracted wallpaper subject! + Failed to extract wallpaper subject! + AI model is not available! + Must use custom lockscreen clock + Status Bar Statusbar Clock Chip Display chip behind statusbar clock - Statusbar Clock Color + Customize Clock Chip + Custom colors, roundness, stroke etc. + Text + Clock Text Color Follow System Transparent Text - Custom Color - Clock Color Picker - Set color of statubsar clock text - Status Icons - Chip Style + Couleurs personnalisées + Sélecteur de couleur du texte + Définir la couleur du texte de l\'horloge de la barre de statut + Icônes de la barre d’état + Style de la puce Status Icons Chip Display chip behind status icons + Customize Status Icons Chip + Custom colors, roundness, stroke etc. Chip Style Top Margin Side Margin + Background + Accent Fill Color + Gradient Direction + Fill Start Color + Fill End Color + Border + Enable Border + Accent Border Color + Border Color + Dashed Border + Dash Width + Dash Gap + Border Thickness + Padding + Padding Left + Padding Right + Padding Top + Padding Bottom + Corner Radius + Top Left Radius + Top Right Radius + Bottom Left Radius + Bottom Right Radius + + Custom Statusbar Clock Size + Set a custom size for Statusbar Clock + Statusbar Clock Size + Colored Statusbar Icon + Show app icon as notification icon + Hide LS Carrier + Hide carrier name on lockscreen + Hide LS Statusbar + Hide statusbar on lockscreen QS Header Hide Carrier Group @@ -647,10 +798,6 @@ Hide Status Icons Remove time, date and battery icons Lock Screen - Hide LS Carrier - Hide carrier name on lockscreen - Hide LS Statusbar - Hide statusbar on lockscreen Hide LS Lock Icon Hide lock icon view on lockscreen Fixed Status Icons @@ -737,6 +884,7 @@ Home Tweaks + Xposed Settings Changelog @@ -752,37 +900,14 @@ Saved settings successfully None - Style 1 - Style 2 - Style 3 - Style 4 - Style 5 - Style 6 - Style 7 - Style 8 - Style 9 - Style 10 - Style 11 - Style 12 - Style 13 - Style 14 - Style 15 - Style 16 - Style 17 - Style 18 - Style 19 - Style 20 - Style 21 - Style 22 - Style 23 - Style 24 - Style 25 + Style %d CONTINUER Redémarrer Désactiver Activer APPLIQUER + Save Désactiver les couleurs personnalisées Appliquer les couleurs Reset @@ -851,10 +976,6 @@ Salut! Icon Icônes du lecteur multimédia - Selectionné: - Selected: %s - Selected: %1$s%2$s - Selected: %1$s%2$s %3$s (Par défaut) No Clock Clock Style %d @@ -923,4 +1044,124 @@ Tap on preview to select Don\'t show again To ensure proper functionality, enabling the Iconify module in LSPosed is mandatory for android 14 and above.\n\nAfter that, enable the fixes from: Tweaks > Xposed Menu > Themes > Others. + Do not select file from Recent + Dismiss + Restart Device + Pending + Accent Primary + Accent Secondary + Accent Tertiary + Text Color Primary + Text Color Inverse + + + Unit + Verifying location + Select location + Enter location + Location + Set custom location + Cannot retrieve location! + Network geolocation is disabled.\n\nSet a custom location or enable network location. + Enable + Settings + Automatic updates + Check for new versions once in a while + Check updates over WiFi only + Check for updates in background only when connected to wifi + Metric (\u00b0C) + Imperial (\u00b0F) + Update + Enable + Update interval + 1 hour + 2 hours + 4 hours + 6 hours + 12 hours + Weather + Condition Icon Pack + Find more icon packs + Disabled + Error + Waiting \u2026 + No weather data + Error loading weather data + Waiting\u2026 + Updating\u2026 + Service disabled + Now + Background shadow + Service settings + Unknown + Error loading weather data + Weather + Last update: + No location available + No network found + Location permissions not granted + Select location + Search for a location + Enable Location Permissions + Location permissions are required to fetch weather data. Click OK to open Settings. + + Cloudy + Rainy + Sunny + Stormy + Snowy + Windy + Misty + + Weather on Lockscreen + Show weather on lockscreen + Last Update Time + Weather Provider + OpenWeatherMap API Key + OpenWeatherMap API Key required + Please enter your OpenWeatherMap API key to fetch weather data. + Show Location + Show Location before icon + Show Condition + Show Condition after temperature + Show Humidity + Show Humidity in a new row + Show Wind + Show Wind in a new row + Text Size + Image Size + Text Color + Set custom color for text + Custom Color + Custom color for all text in weather view + Custom location + Set custom location for weather + Custom Margins + Set custom margins for weather + Top margin + Center Layout + Side Margin + Bottom Margin + Center Weather View + Move weather view to center horizontally + + Weather Background Style + Default + Semi-transparent box + Semi-transparent box (round) + Q-Beta pill + Rounded, simple and with accent + Rounded, transparent and with accent + Gradient + Dark with accented borders + Dark with gradient borders + + SystemUI Restart Needed + A SystemUI restart is needed for this change to take effect. + Device Restart Needed + A device restart is needed for this change to take effect. + Switch Device Theme + Switch between light and dark themes if unexpected behavior occurs. + Device Rotation Theme + Switch rotation of your device for this change to take effect. diff --git a/app/src/main/res/values-hu-rHU/strings.xml b/app/src/main/res/values-hu-rHU/strings.xml index a7dac5b18..5a15783f9 100644 --- a/app/src/main/res/values-hu-rHU/strings.xml +++ b/app/src/main/res/values-hu-rHU/strings.xml @@ -1,5 +1,5 @@ - + Az unalmas Android testreszabása A beállítások előkészítése @@ -31,10 +31,22 @@ Hoppá, itt valami meghiúsult A Dokumentumok mappában találhatja az elmentett hibajegyeket. Hibajegyek + + Keresés + Keresem… + Törlés + Előzmény-bejegyzések + Továbbiak + Az Előzmények törlése + Nincs eredmény Ikonizáló (Iconify) Ikoncsomag Lecserélheti a rendszerikonokat + Mobiladatt-ikonok + Itt változtathatja meg a rendszer térerő-kijelzését + Wi-Fi ikonok + Itt változtathatja meg a rendszer Wi-Fi kijelzését Fényerőszabályozó-sáv Testre szabhatja a csúszkát A Gyorsbeállítások csempéi @@ -113,6 +125,8 @@ Néhány beállítás (például az elmosódás intenzitása) a rendszerfelület újraindításáig nem lép életbe A Kezdőlap-kártya megjelenítése Megjelenít egy gyönyörű kártyát a kezdőlapon. + Rezgő visszajelzés + Fejlesztett visszajelzés a képernyő érintésekor. Az alkalmazás-gyorsítótár törlése Törölje az egyedi betűtípusok, képek vagy GIF-ek használatakor generált gyorsítótárakat. Kisérleti szakasz @@ -122,6 +136,8 @@ Rólunk Github adattár Telegram-csoport + Fordítson Ön is + Segíthetr a saját nyelvére lefordítani az Iconify-t. Stáblista Köszönet azoknak, akik ezt lehetővé tették. @@ -231,8 +247,8 @@ Egyéb. Minimális Gyorsbeállítások A Gyorsbeállítások minimalizálása - A rendszer-monet kikapcsolása - Segít megőrizni az egyedi színeket\nRendszerfelület-újraindítás kell hozzá + A rendszer Monet-motorja + Az egyéni színek megőrzéséhez tiltsa le.\nA rendszerfelület újraindítása szükséges Fő szín Válasszon fő kiemelőszínt @@ -405,24 +421,93 @@ A Gyorsbeállítások-panelhez kapcsolódó trükkök Akkustílus Szabja személyre az Akku-ikon megjelenését + One+ Gyorsbeállítások + OxygenOS stílusú gyorsbeállításfejléc Fejléckép Hozzáadhat egyéni képet is Fejléc-óra Hozzáadhat egyéni órát is a panelhez A Képernyőzár órája Hozzáadhat egyéni órát is a záróképernyőhöz + Időjárás a záróképernyőn + Adja hozzá az időjárást a záróképernyőhöz + A záróképernyő kisalkalmazásai + Kisalkalmazásokat adhat hozzá a záróképernyőhöz Mélységi háttérkép Az iOS-ban megimert funkciót is használhatja Háttérlap Színezett hátteret rakhat az óra mögé + Óraháttér Egyebek További Xposed trükkök - + Időjárás-beállítások + + One+ Gyorsbeállítások + Bekapcsolhatja az Oxygen-stílusú médialejátszót és csempéket + Rezgő visszajelzés + A csempék rezgésének hozzáadása + Rejtett Médialejátszó + Eltávolítja a gyári médialejátszót a gyorsbeállítások paneljéről + Az elmosás erőssége + A halványítás erőssége + Felső margó + A bővítés mértéke + + A záróképernyő kisalkalmazásai + Engedélyezi a kisalkalmazásokat a záróképernyőn + Új kisalkalmazás hozzáadása + Készülékinfó-kisalkalmazás + Megjeleníti a készülékinfót a záróképernyőn + A lineáris haladás színe + A körkörös haladás színe + Betűszín + Egyéni Készüléknév + Beállíthat egyedi nevet.\nHagyja üresen a kikapcsoláshoz. + Nagyok + Kisalkalmazás 1 + Kisalkalmazás 2 + Minik + Kisalkalmazás 1 + Kisalkalmazás 2 + Kisalkalmazás 3 + Kisalkalmazás 4 + Egyedi színek + A kisalkalmazás színeinek testreszabása + A nagy színe, mikor aktív + A nagy színe, mikor inaktív + A nagy ikon színe, mikor aktív + A nagy ikon színe, mikor inaktív + A mini színe, mikor aktív + A mini színe, mikor inaktív + A mini ikon színe, mikor aktív + A mini ikon színe, mikor inaktív + Időjárás-beállítások + Kisalkalmazások méretskálázása + + Kamera + Óra/Időzítő + Számológép + Galéria + Médialejátszó + Zseblámpa + Lejátszás + Időjárás + Wi-Fi + Mobiladat + Csengés + Bluetooth + Főképernyő-vezérlők + Pénztárca + Hotspot + Csengés + Rezgés + Néma + Átlátszóság Átlátszó Gyorsbeállítások-panel A panel hátterét átlátszóvá teheti - Átlátszósági érték - Csak az értesítés árnyéka + Háttér áttetszőség + Átlátszó értesítési árnyék Kizárólag az értesítési árnyék lesz átlátszó Homályos Záróképernyő-háttér Világos színű háttérképeken alkalmazható @@ -432,7 +517,7 @@ Agresszív elmosás Sajnos néhány ROM-on bootloopot okoz Az elmosás intenzitása - + Pixel ROM-okhoz Világos téma Világos Gyorsbeállítások-téma világos módban\nEgyedi Gyorsbeállítások alakzatot kell használni @@ -449,21 +534,28 @@ A Kikapcsolási menü átlátszósága Az áramvonalas Gyorsbeállítások kikapcsolási átláthatósága\nNe használjon egyéni értesítési stílust Egyebek + Csempeszín-javítás + Egyéni gyorsbeállítási stílus javítása Android 14 rendszeren Értesítési színek rögzítése Egyéni értesítési stílus javítása Android 14 rendszeren - + Az értesítési lábléc gombjának színe + Android 14 rendszeren fixálja az egyéni láblécgomb stílusát + Gyorsbeállítások-csempe Függőleges csempe Címke megjelenítése az ikon alatt Csempefelirat elrejtése Csak függőleges csempék esetében + Szövegméretezés Csempemargók Gyorsbeállítások elemei + Nincs gyorsbeállítás a záróképernyőn + Letiltja a gyorbeállítások panelét a biztonságos záróképernyőn Szövegelrejtés - A néma értesítések fejléceként megjelenő szöveg elrejtése (A Rendszerfelület újraindítása szükséges) + Elrejti a néma értesítések fejléceként megjelenő szöveget Láblécgombok rejtése Az értesítések alatt látható láblécgombok elrejtése - + Akkustílus Akku-szélesség Akku-magasság @@ -494,8 +586,8 @@ Az akkukímélő színének megváltoztatása Az akkukímélő-indikátor színe Az akkukímélő-indikátor színének módosítása - Egyéni méretek - Egyedi akkumulátor-ikon méreteket is beállíthat + Egyéni margók + Egyedi akkumulátor-ikon méreteket is beállíthat Akku-margó bal Akku-margó jobb Akku-margó felül @@ -545,18 +637,20 @@ Fekvő akkumulátor O Kör akkumulátor Pontozott kör akkumulátor - Filled Circle Battery - + Kitöltött kör akkumulátor + Százalékos hangerő Megjeleníti a százalékértéket a hangerőcsúszka felett Biztonsági figyelmeztetés Figyelmeztetés, ha túl hangos - + Színes csengőikon + Engedélyezze, ha a kiválasztott csengőikon láthatatlan + Fejléckép-választó Adjon hozzá fejlécképet a panelen\nNe válasszon fájlt az Előzményekből Képválasztó Képmagasság - A kép alfája + Kép-áttetszőség Az alsó halványítás erőssége Nagyítás kitöltéssel A kép alapértelmezés szerinti illesztése @@ -564,35 +658,36 @@ A kép elrejtése tájkép-módban Halványuló színátmenet Halványuló effekt hozzáadása a fejlécképhez - + Egyéni fejléc-óra Hozzáadhat egyéni órát is a panelhez Órastílus Az óra betűtipusa - Használjon egyéni betűtípust a fejléc-órához\nNe válasszon fájlt az Előzményekből + Használjon egyéni betűtípust a fejléc-órához Egyéni óraszín - Egyedi szín az eddigi fő szín helyett + Egyedi szín az eddigi rendszer-színek helyett Óraszín-választó Állítsa be a fejléc-óra szövegének színét + A bővítés mértéke Szövegméretezés - Az óra oldalmargója - Az óra felső margója + Oldalsó margó + Felső margó Fehér szöveg Kényszeríti a minél fehérebb szövegszínt Középre helyezett óra Mozgassa az órát közepére Fekvőmódban ne látszódjon Az óra elrejtése tájkép-módban - + Egyéni záróképernyő-óra Engedélyezi a képernyőzár-óra testreszabását Az óra automatikus elrejtése Bejövő üzeneteknél nem látszik az óra Órastílus Az óra betűtipusa - Használjon egyéni betűtípust a záróképernyő-órához\nNe válasszon fájlt az Előzményekből + Saját betűtípust használhat a záróképernyő órájához Egyéni óraszín - Egyedi szín az eddigi fő szín helyett + Egyedi szín az eddigi rendszer-színek helyett Óraszín-választó Állítsa be a záróképernyő-óra szövegének színét Szövegméretezés @@ -601,6 +696,13 @@ Alsó margó Fehér szöveg Az összes színt a fehér felé kényszeríti + Egyéni kép használata + Saját képet használhat a záróképernyő órájához. + Egyéni kép-kijelölés + Egyéni Készüléknév + Állítson be egyéni nevet a zárolási képernyő órájához.\nHagyja üresen, ha a rendszer nevezze el. + Egyéni Felhasználónév + Állítson be egyéni nevet a zárolási képernyő órájához.\nHagyja üresen, ha a rendszer nevezze el. Választás Az akku töltödik Az akku nem töltödik @@ -608,9 +710,13 @@ Akkumulátorszint Üdv újra itt! Felhasználó - + A mélységi háttérkép engedélyezése - Az iOS-hez hasonló mélységi háttérképet jelenít meg\nEgyéni zárképernyő-órát kell használni + iOS-ban megismert mélységi háttérkép\n%s + Egyedi képek + Az egyedi kép beállítása mint mélységi háttérkép + \'Mindig bekapcsolva\' (AOD) esetén is + Téma megjelenítése mindig a kijelzőn Átúszás \'Mindig bekapcsolvá\'-ra Animálja a háttérképet, és áttűnik az AOD-ba Előtérkép @@ -623,23 +729,68 @@ A háttér és az előtér rétegeit különböző sebességgel mozgatja Az előtér érzékenysége A háttér érzékenysége - + Az AI-modell letöltődik a készülékére + Az AI-modell (még) nem elérhető erre a készülékre + A háttérkép-téma kibontása… + A háttérkép-téma kibontásra került! + Nem sikerült kibontani a háttérkép-témát! + Nem érhető el AI-modell! + Egyéni képernyőzár-órát kell használni + Állapotsor Állapotsori óralap Óralap kijelzése az állapotikonok mögött - Az állapotsori óra színe + Óraháttér személyre szabása + Egyedi színek, kerekítés, körvonal stb. + Szöveg + Az Óra betűszíne Rendszerkövetés Áttetsző szöveg Egyéni szín - Óraszín-választó - Állítsa be az állapotsor-óra szövegének színét + Betűszín-választó + Állítsa be az állapotsor-óra szövegének színét Állapotikonok A háttér-lap stílusa Állapotikonok háttérlapja Óralap kijelzése az állapotikonok mögött + Az Állapot-ikonok háttere + Egyedi színek, kerekítés, körvonal stb. Az óralap stílusa Felső margó Oldal margó + Háttér + Kiemelőszínes kitöltés + Színátmeneti irány + A kitöltés kezdőszíne + A kitöltés zárószíne + Szegély + A szegélyezés bekapcsolása + Kiemelő szegélyszín + Szegélyszín + Szaggatott szegély + A szegély szélessége + A szegély térköze + Szegélyvastagság + Helykitöltés + Balra + Jobbra + Felül + Alul + Sarok-lekerekítés + Bal felső sugár + Jobb felső sugár + Bal alsó sugár + Jobb alsó sugár + + Az egyedi állapotsori Óra mérete + Állítson be egyéni méretet az állapotsor órájához + Az állapotsori Óra mérete + Színezett állapotsor-ikon + Alkalmazásikon megjelenítése értesítési ikonként + Nincs Szolgáltató a képernyőzáron + A záróképernyőről eltűnik a Szolgáltató neve + Nincs Állapotsor a képernyőzáron + A záróképernyőről eltűnik az Állapotsor Gyorsbeállítások-fejléc Szolgáltatói csoport elrejtése @@ -647,12 +798,8 @@ Az Állapotikonok elrejtése Az Idő, a Dátum és az Akkujelzés sem látható Záróképernyő - Nincs Szolgáltató a képernyőzáron - A záróképernyőről eltűnik a Szolgáltató neve - Nincs Állapotsor a képernyőzáron - A záróképernyőről eltűnik az Állapotsor - Hide LS Lock Icon - Hide lock icon view on lockscreen + Zárolásikon elrejtése + A zárikon elrejtése a záróképernyőn Rögzített Állapotikonok Az állapotikonok rögzített pozícióba kerülnek\nJónéhány ROM-on buggolást okoz @@ -737,6 +884,7 @@ Kezdőlap Trükkök + Xposed Beállítások Változáslista @@ -752,37 +900,14 @@ A beállítások mentése sikeres volt Nincs - 1.stílus - 2.stílus - 3.stílus - 4.stílus - 5.stílus - 6.stílus - 7.stílus - 8.stílus - 9.stílus - 10.stílus - 11.stílus - 12.stílus - 13.stílus - 14.stílus - 15.stílus - 16.stílus - 17.stílus - 18.stílus - 19.stílus - 20.stílus - 21.stílus - 22.stílus - 23.stílus - 24.stílus - 25.stílus + %d stílus Folytatás Újraindítás Letiltás Engedélyezés Alkalmazás + Mentés Az egyéni színek letiltása A színek alkalmazása Visszaállítás @@ -851,10 +976,6 @@ Hé mindenki! Ikon Médialejátszó-ikonok - Kiválasztva: - Kiválasztva: %s - Kiválasztva: %1$s%2$s - Kiválasztva: %1$s%2$s %3$s (Alapértelmezett) Nincs óra Órastílus %d @@ -923,4 +1044,124 @@ A kiválasztáshoz érintse meg az előképet Ez ne jelenjen meg újra A megfelelő működés érdekében az Iconify modul engedélyezése kötelező az LSPosedben Android 14 és újabb verziók esetén.\n\nEzt követően engedélyezze a javításokat innen: Trükkök > Xposed-menü > Témák > Egyebek + Ne válasszon fájlt az Előzményekből + Elvetés + A készülék újraindítása + Folyamatban + Elsődleges kiemelés + Másodlagos kiemelés + Harmadfokú kiemelés + A szöveg elsődleges színe + A szöveg fordított színe + + + Egység + Tartózkodásihely-ellenőrzés + Válasszon tartózkodási helyet + Adja meg a tartózkodás helyet + Tartózkodási hely + Egyéni hely beállítása + Hely meghatározása sikertelen! + Hálózati helymeghatározás letiltva.\n\nÁllítson be egyéni helyet, vagy engedélyezze a hálózati helymeghatározást + Engedélyezés + Beállítások + Automatikus frissítések + Időközönként ellenőrizze az új verziókat + Csak Wi-Fi-n ellenőrizze a frissítéseket + Ha Wi-Fi-hez csatlakozik, a háttérben ellenőrzi a frissítéseket + Metrikus (\u00b0C) + Angolszász (\u00b0F) + Frissítés + Engedélyezés + Frissítési gyakoriság + 1 óra + 2 óra + 4 óra + 6 óra + 12 óra + Időjárás + Állapot ikoncsomag + Találjon további ikoncsomagokat + Letiltva + Hiba + Várjon egy kicsit \u2026 + Nincsenek időjárási adatok + Hiba az időjárásadatok betöltésekor + Számoljunk el ezerig \u2026 + Frissítés \u2026 + A szolgáltatás letiltva + Most + Háttér-árnyék + Szolgáltatás-beállítások + Ismeretlen + Hiba az időjárásadatok betöltésekor + Időjárás + Utolsó frissítés: + Nincs helymeghatározás + Nincs hálózat + Nincs engedélyezve a helymeghatározás + Válasszon tartózkodási helyet + Tartózkodási hely keresése + Helymeghatározási jogosultságok megadása + Az időjárási adatok lekéréséhez tartózkodási helymeghatározásra van szükség. Kattintson az OK gombra a Beállítások megnyitásához. + + Felhős + Esős + Napos + Viharos + Havas + Szeles + Ködös + + Időjárás a Záróképernyőn + Az Időjárás megjelenítése a Záróképernyőn + Az utolsó frissítés időpontja + Időjárás-szolgáltató + OpenWeatherMap API-kulcs + OpenWeatherMap API-kulcs szükséges + Kérjük, adja meg az OpenWeatherMap API-kulcsot az időjárási adatok lekéréséhez. + Tartózkodási hely kijelzése + Az ikon elé írja ki a tartózkodási helyet + Időjárási viszonyok kijelzése + A hőmérséklet után írja ki a viszonyokat + Páratartalom kijelzése + Új sorban jeleníti meg a páratartalmat + Széljárás kijelzése + Új sorban jeleníti meg a széljárást + Szövegméret + Képméret + Betűszín + Új színt adhat meg a szöveghez + Egyéni szín + Egyedi szín minden szöveghez az időjárás-nézetben + Egyéni tartózkodási hely + Egyedi hely megadása az időjáráshoz + Egyéni margók + Egyedi margók beállítása az időjáráshoz + Felső margó + Középre rendezett + Oldalsó margó + Alsó margó + Az időjárás középen + A nézet mozgatása vízszintesen középre + + Az Időjárás háttérstílusa + Alapértelmezett + Félig átlátszó doboz + Félig átlátszó doboz (lekerekített) + Q-ßeta kapszula + Lekerekített, egyszerű és kiemelőszínű + Lekerekített, átlátszó és kiemelőszínű + Színátmenetes + Sötét, kiemelt szegéllyel + Sötét, színátmenetes szegéllyel + + Rendszerfelület-újraindítás szükséges + A változtatás életbe lépéséhez rendszerfelület-újraindítás szükséges. + Készülék-újraindítás szükséges + A változtatás életbe lépéséhez újra kell indítani a készüléket. + A készülék témakapcsolója + Nem várt viselkedés esetén váltson a világos és sötét témák között. + Forgatás szükséges + Kapcsolja a készülék forgását, hogy ez a változás érvénybe lépjen. diff --git a/app/src/main/res/values-in-rID/strings.xml b/app/src/main/res/values-in-rID/strings.xml index 9ecff6b7f..594b0f35b 100644 --- a/app/src/main/res/values-in-rID/strings.xml +++ b/app/src/main/res/values-in-rID/strings.xml @@ -1,10 +1,10 @@ - + Kustomisasi UI Android yang Membosankan - Initializing setup - Step - Step %1$d/%2$d + Memulai setup + Langkah + Langkah %1$d/%2$d Membuat modul shell Mengekstrak file yang diperlukan Membuat APK overlay @@ -12,18 +12,18 @@ Tanda tangan APK overlay Membersihkan direktori Bosan dengan Stock UI? - Let\'s customize everything to our likings. - Ditch the stock UI monotony – personalize every tech detail to match your style and preferences. + Ayo kita oprek segalanya sesuai keinginan kita. + Tinggalkan UI stock monoton — personalisasikan sesuai selera anda. Apakah Perangkat Saya Didukung? - Iconify supports all Pixel and AOSP ROMs. - Compatible with all Pixel and AOSP-based ROMs, ensuring broad support for Android devices. + Iconify support semua ROM berbasis Pixel dan AOSP. + Compatible dengan semua ROM berbasis Pixel dan AOSP, memastikan dukungan yang luas untuk perangkat Android. BIsa Kita Mulai Sekarang? - It is time for iconify to do some internal work. - Starting internal tasks, marking the initiation of essential work. Ready to begin? + Waktunya Iconify nyiapin. + Mulai persiapan, gasken? Perlu Izin Penyimpanan Izin penyimpanan diperlukan untuk membuat file yang diperlukan. - Could Not Find Compatible Root Method - Use any popular root solutions to proceed. + Yah, gak nemu metode root yang kompatibel + Pake solusi root popular apapun (contohnya Magisk). Root Tidak Dapat Diakses Sepertinya perangkat Anda belum di-root! Perlu Reboot Perangkat @@ -31,19 +31,31 @@ Ups Tidak Mengharapkan Itu Log telah disimpan di folder dokumen. Logs + + Search + Search… + Clear + History entry + More + Clear history + No result Iconify Icon Pack Mengubah sistem ikon pack - Brightness Bar + Cellular Icons + Change system cellular icons + Ikon WiFi + Mengubah ikon WiFi sistem + Mengubah progress slider - QS Panel Tiles + Ubin Panel Setelan Cepat Mengubah QS panel tiles Notifikasi Mengubah gaya notifikasi - Progress Bar + Bilah Kemajuan Mengubah gaya progress bar - Switch + Tombol ganti Mengubah tampilan switch Toast Frame Mengubah gaya notifikasi toast @@ -113,6 +125,8 @@ Beberapa opsi seperti intensitas buram tidak berpengaruh hingga systemui dimulai ulang Show Home Page Card Show a beautiful card on the home page. + Haptic Feedback + Enhance touch feedback with interactive haptics. Clear App Cache Clear caches generated due to the usage of custom fonts, images, or gifs. Eksperimental @@ -122,6 +136,8 @@ About Github Repository Telegram Group + Translate Iconify + Help translate Iconify to your language. Credits Thanking those who made this possible. @@ -231,8 +247,8 @@ Misc. Minimal QS Panel Hapus bayangan diatas QS panel - Disable System Monet - Membantu mempertahankan warna khusus + System Monet + Disable to retain custom colors\nSystemUI restart required Warna Primer Pilih warna aksen utama @@ -405,24 +421,93 @@ Tweak untuk QS panel Battery Style Ubah tampilan ikon baterai + Oneplus QS Header + OOS style quick settings header Header Image Menambahkan kustom gambar dalam QS panel Header Clock Menambahkan kustom jam dalam QS panel Lockscreen Clock Menambahkan kustom jam layar kunci + Lockscreen Weather + Add weather on lockscreen + Lockscreen Widgets + Add widgets on lockscreen Depth Wallpaper Show iOS like depth wallpaper Background Chip Menambahkan chip berwarna di belakang jam + Clock Chip Lainnya Tweak xposed lainnya - + Weather Settings + + Oneplus QS Header + Enable OOS style media player and tiles in QS + Haptic Feedback + Add haptic feedback on tiles + Hide Stock Media Player + Remove stock media player from QS panel + Blur Level + Fade Level + Top Margin + Expansion Amount + + Lockscreen Widgets + Enable Lockscreen Widgets + Add widgets to lockscreen + Device Info Widget + Show device info widget on lockscreen + Linear Progress Color + Circular Progress Color + Text Color + Custom Device Name + Set custom device name.\nKeep blank to disable. + Large Widgets + Large Widget 1 + Large Widget 2 + Mini Widgets + Mini Widget 1 + Mini Widget 2 + Mini Widget 3 + Mini Widget 4 + Custom Colors + Customize Widget Colors + Large Widget Active Color + Large Widget Inactive Color + Large Widget Icon Active Color + Large Widget Icon Inactive Color + Mini Widget Active Color + Mini Widget Inactive Color + Mini Widget Icon Active Color + Mini Widget Icon Inactive Color + Weather Settings + Widgets Scale + + Camera + Clock/Timer + Calculator + Gallery + Media Player + Torch + Play + Weather + Wifi + Data + Ringer + Bluetooth + Home Controls + Wallet + Hotspot + Ringer + Vibrate + Silent + Transparency QS Panel Transparan Jadikan latar belakang QS panel transparan - Transparansi Alpha - Transparent Notif Shade Only + Background Opacity + Transparent Notification Shade Make only notification shade transparent Dim Lockscreen Wallpaper Suitable for light-colored wallpapers @@ -432,7 +517,7 @@ Aggressive Blur Enabler Might bootloop in some roms Blur Intensity - + For Pixel Roms Light Theme Light QS theme in light mode\nMust use custom QS Shape @@ -449,21 +534,28 @@ Power Menu Transparency Power menu transparency for Fluid QS\nDo not use custom notification style Others + Fix QS Tile Color + Fix custom QS tile style on android 14 Fix Notification Color Fix custom notification style on android 14 - + Fix Notification Footer Button Color + Fix custom footer button style on android 14 + QS Tile QS Tile Vertikal Tampilkan label di bawah ikon QS Sembunyikan QS Tile Label Gunakan hanya dengan tile vertikal + Text Size Scaling QS Margin QS Elements + Hide QS on Lockscreen + Disable quick settings panel on secured lockscreen Hide Silent Text - Hide silent text shown as header of silent notifications (Requires SystemUI restart) + Hide silent text shown as header of silent notifications Hide Footer Buttons Hide footer buttons shown under notification stack - + Battery Style Battery Width Battery Height @@ -494,8 +586,8 @@ Change color of powersave battery Powersave Indicator Color Change color of powersave indicator - Custom Dimensions - Set custom dimensions for battery icon + Custom Margins + Set custom margins for battery icon Battery Margin Left Battery Margin Right Battery Margin Top @@ -546,17 +638,19 @@ Circle Battery Dotted Circle Battery Filled Circle Battery - + Volume Percentage Show percentage above volume slider Safety Warning Show warning on high volume - + Colored Ringer Icon + Enable if selected ringer icon is invisible + Pilih Gambar Header Tambahkan gambar header pada panel QS\nJangan pilih file dari Terbaru Ambil Gambar Tinggi Gambar - Gambar Alpha + Image Opacity Bottom Fade Amount Zoom To Fit Gambar direntangkan agar pas secara default @@ -564,35 +658,36 @@ Sembunyikan gambar di mode landscape Alpha Gradient Add faded effect to the header image - + Custom Header Clock Tambahkan jam khusus di panel QS Clock Style Clock Font - Use custom font for header clock\nDo not select file from Recent + Use custom font for header clock Custom Clock Color - Custom color instead of primary color + Custom colors instead of system colors Clock Color Picker Set color of header clock text + Expansion Amount Text Scaling - Clock Side Margin - Clock Top Margin + Side Margin + Top Margin Teks Putih Paksa warna teks menjadi putih Center Clock Move clock to center of view Hide in Landscape Hide clock in landscape mode - + Kustom Jam Layar Kunci Aktifkan custom jam layar kunci Auto Hide Clock Hide clock on incoming notification Clock Style Font Jam - Gunakan font khusus untuk jam layar kunci\nJangan pilih file dari Terbaru + Use custom font for lockscreen clock Custom Clock Color - Custom color instead of primary color + Custom colors instead of system colors Clock Color Picker Set color of lockscreen clock text Text Scaling @@ -601,6 +696,13 @@ Bottom Margin Teks Putih Paksa semua warna menjadi putih + Use Custom Image + Use custom image for lockscreen clock. + Custom Image Picker + Custom Device Name + Set custom device name for lockscreen clock.\nKeep blank to use System\'s Device Name. + Custom User Name + Set custom user name for lockscreen clock.\nKeep blank to use System\'s User Name. Select Battery Charging Battery Discharging @@ -608,14 +710,18 @@ Battery Level Welcome back! User - + Enable Depth Wallpaper - Show iOS like depth wallpaper\nMust use custom lockscreen clock + Show iOS like depth wallpaper\n%s + Custom Images + Set custom images as depth wallpaper + Show on AOD + Show subject on always on display Fade in AOD Animate wallpaper and fade away in AOD Foreground Image Foreground image for depth wallpaper - Foreground Image Alpha + Foreground Image Opacity Background Image Background image for depth wallpaper This feature is currently in beta stage. So bugs are expected.\n\nKnown Bug(s):\n• Tapping on lockscreen makes the wallpaper jump. @@ -623,23 +729,68 @@ Move background and foreground layers at different speeds Foreground Sensitivity Background Sensitivity - + AI model is downloaded on the device + AI model isn\'t available on the device (yet) + Extracting wallpaper subject… + Extracted wallpaper subject! + Failed to extract wallpaper subject! + AI model is not available! + Must use custom lockscreen clock + Status Bar Chip Jam Statusbar Tampilkan chip di belakang jam statusbar - Statusbar Clock Color + Customize Clock Chip + Custom colors, roundness, stroke etc. + Text + Clock Text Color Follow System Transparent Text Custom Color - Clock Color Picker - Set color of statubsar clock text + Text Color Picker + Set color of statubsar clock text Status Icons Chip Style Status Icons Chip Tampilkan chip di belakang ikon status + Customize Status Icons Chip + Custom colors, roundness, stroke etc. Chip Style Top Margin Side Margin + Background + Accent Fill Color + Gradient Direction + Fill Start Color + Fill End Color + Border + Enable Border + Accent Border Color + Border Color + Dashed Border + Dash Width + Dash Gap + Border Thickness + Padding + Padding Left + Padding Right + Padding Top + Padding Bottom + Corner Radius + Top Left Radius + Top Right Radius + Bottom Left Radius + Bottom Right Radius + + Custom Statusbar Clock Size + Set a custom size for Statusbar Clock + Statusbar Clock Size + Colored Statusbar Icon + Show app icon as notification icon + Sembunyikan Carrier LS + Sembunyikan nama carrier di layar kunci + Sembunyikan Statusbar LS + Sembunyikan statusbar di layar kunci QS Header Sembunyikan Carrier Group @@ -647,10 +798,6 @@ Sembunyikan Ikon Status Hapus ikon waktu, tanggal, dan baterai Lock Screen - Sembunyikan Carrier LS - Sembunyikan nama carrier di layar kunci - Sembunyikan Statusbar LS - Sembunyikan statusbar di layar kunci Hide LS Lock Icon Hide lock icon view on lockscreen Fixed Status Icons @@ -737,6 +884,7 @@ Home Tweaks + Xposed Settings Changelog @@ -752,37 +900,14 @@ Pengaturan berhasil disimpan None - Style 1 - Style 2 - Style 3 - Style 4 - Style 5 - Style 6 - Style 7 - Style 8 - Style 9 - Style 10 - Style 11 - Style 12 - Style 13 - Style 14 - Style 15 - Style 16 - Style 17 - Style 18 - Style 19 - Style 20 - Style 21 - Style 22 - Style 23 - Style 24 - Style 25 + Style %d LANJUTKAN Restart Nonaktifkan Aktifkan TERAPKAN + Save Nonaktifkan Warna Kustom Terapkan Warna ATUR ULANG @@ -851,10 +976,6 @@ Hai Kamu! Icon Media Player Icons - Terpilih: - Selected: %s - Selected: %1$s%2$s - Selected: %1$s%2$s %3$s (Default) No Clock Clock Style %d @@ -923,4 +1044,124 @@ Tap on preview to select Don\'t show again To ensure proper functionality, enabling the Iconify module in LSPosed is mandatory for android 14 and above.\n\nAfter that, enable the fixes from: Tweaks > Xposed Menu > Themes > Others. + Do not select file from Recent + Dismiss + Restart Device + Pending + Accent Primary + Accent Secondary + Accent Tertiary + Text Color Primary + Text Color Inverse + + + Unit + Verifying location + Select location + Enter location + Location + Set custom location + Cannot retrieve location! + Network geolocation is disabled.\n\nSet a custom location or enable network location. + Enable + Settings + Automatic updates + Check for new versions once in a while + Check updates over WiFi only + Check for updates in background only when connected to wifi + Metric (\u00b0C) + Imperial (\u00b0F) + Update + Enable + Update interval + 1 hour + 2 hours + 4 hours + 6 hours + 12 hours + Weather + Condition Icon Pack + Find more icon packs + Disabled + Error + Waiting \u2026 + No weather data + Error loading weather data + Waiting\u2026 + Updating\u2026 + Service disabled + Now + Background shadow + Service settings + Unknown + Error loading weather data + Weather + Last update: + No location available + No network found + Location permissions not granted + Select location + Search for a location + Enable Location Permissions + Location permissions are required to fetch weather data. Click OK to open Settings. + + Cloudy + Rainy + Sunny + Stormy + Snowy + Windy + Misty + + Weather on Lockscreen + Show weather on lockscreen + Last Update Time + Weather Provider + OpenWeatherMap API Key + OpenWeatherMap API Key required + Please enter your OpenWeatherMap API key to fetch weather data. + Show Location + Show Location before icon + Show Condition + Show Condition after temperature + Show Humidity + Show Humidity in a new row + Show Wind + Show Wind in a new row + Text Size + Image Size + Text Color + Set custom color for text + Custom Color + Custom color for all text in weather view + Custom location + Set custom location for weather + Custom Margins + Set custom margins for weather + Top margin + Center Layout + Side Margin + Bottom Margin + Center Weather View + Move weather view to center horizontally + + Weather Background Style + Default + Semi-transparent box + Semi-transparent box (round) + Q-Beta pill + Rounded, simple and with accent + Rounded, transparent and with accent + Gradient + Dark with accented borders + Dark with gradient borders + + SystemUI Restart Needed + A SystemUI restart is needed for this change to take effect. + Device Restart Needed + A device restart is needed for this change to take effect. + Switch Device Theme + Switch between light and dark themes if unexpected behavior occurs. + Device Rotation Theme + Switch rotation of your device for this change to take effect. diff --git a/app/src/main/res/values-it-rIT/strings.xml b/app/src/main/res/values-it-rIT/strings.xml index 5468892a2..56b9882b5 100644 --- a/app/src/main/res/values-it-rIT/strings.xml +++ b/app/src/main/res/values-it-rIT/strings.xml @@ -1,5 +1,5 @@ - + Personalizza la noiosa interfaccia di Android Inizializzazione della configurazione @@ -31,10 +31,22 @@ Ops, non era previsto Log salvati nella cartella documenti. Logs + + Search + Search… + Clear + History entry + More + Clear history + No result Iconify Pacchetto Icone Cambia le icone di sistema + Cellular Icons + Change system cellular icons + WiFi Icons + Change system WiFi icons Barra Luminosità Personalizza il cursore di avanzamento Pannello Riquadri QS @@ -113,6 +125,8 @@ Alcune opzioni come l\'intensità di sfocatura non hanno effetto finchè SystemUI non verrà riavviato Mostra la Scheda sulla Pagina Principale Mostra una bellissima scheda nella pagina principale. + Haptic Feedback + Enhance touch feedback with interactive haptics. Svuota Cache dell\'App Svuota la cache generata dall\'utilizzo di font personalizzati, immagini o gif. Sperimentale @@ -122,6 +136,8 @@ Info Repository GitHub Gruppo Telegram + Translate Iconify + Help translate Iconify to your language. Crediti Grazie a coloro che hanno reso tutto questo possibile. @@ -231,8 +247,8 @@ Varie. Pannello QS Minimale Rimuovi l\'ombra superiore del pannello QS - Disabilita Monet di Sistema - Aiuta a mantenere i colori personalizzati\nRiavvio SystemUI richiesto + System Monet + Disable to retain custom colors\nSystemUI restart required Colore Primario Scegli il colore di accento primario @@ -405,24 +421,93 @@ Modifiche relative al pannello QS Stile Batteria Personalizza la visualizzazione dell\'icona batteria + Oneplus QS Header + OOS style quick settings header Immagine Intestazione Aggiungi immagine personalizzata sul pannello QS Orologio Intestazione Aggiungi orologio personalizzato sul pannello QS Orologio Schermata di Blocco Aggiungi orologio personalizzato sulla schermata di blocco + Lockscreen Weather + Add weather on lockscreen + Lockscreen Widgets + Add widgets on lockscreen Sfondo di Profondità Mostra sfondo di profondità come iOS Sfondo Chip Aggiungi chip colorato dietro l\'orologio + Clock Chip Altro Vari aggiustamenti xposed - + Weather Settings + + Oneplus QS Header + Enable OOS style media player and tiles in QS + Haptic Feedback + Add haptic feedback on tiles + Hide Stock Media Player + Remove stock media player from QS panel + Blur Level + Fade Level + Top Margin + Expansion Amount + + Lockscreen Widgets + Enable Lockscreen Widgets + Add widgets to lockscreen + Device Info Widget + Show device info widget on lockscreen + Linear Progress Color + Circular Progress Color + Text Color + Custom Device Name + Set custom device name.\nKeep blank to disable. + Large Widgets + Large Widget 1 + Large Widget 2 + Mini Widgets + Mini Widget 1 + Mini Widget 2 + Mini Widget 3 + Mini Widget 4 + Custom Colors + Customize Widget Colors + Large Widget Active Color + Large Widget Inactive Color + Large Widget Icon Active Color + Large Widget Icon Inactive Color + Mini Widget Active Color + Mini Widget Inactive Color + Mini Widget Icon Active Color + Mini Widget Icon Inactive Color + Weather Settings + Widgets Scale + + Camera + Clock/Timer + Calculator + Gallery + Media Player + Torch + Play + Weather + Wifi + Data + Ringer + Bluetooth + Home Controls + Wallet + Hotspot + Ringer + Vibrate + Silent + Trasparenza Pannello QS Trasparente Rendi trasparente lo sfondo del pannello QS - Trasparenza Alfa - Solo Area Notifica Trasparente + Background Opacity + Transparent Notification Shade Rendi trasparente solo l\'area notifiche Oscura Sfondo Schermata di Blocco Adatto per sfondi di colore chiaro @@ -432,7 +517,7 @@ Abilita Sfocatura Aggressiva Potrebbe causare bootloop in alcune rom Intensità Sfocatura - + Per Rom Pixel Tema Chiaro Tema QS chiaro in modalità chiaro\nRichiede l\'utilizzo dei modelli QS personalizzati @@ -449,21 +534,28 @@ Trasparenza Menù Accensione Trasparenza del menu accensione per QS Fluido\nNon utilizzare lo stile di notifica personalizzato Altro + Fix QS Tile Color + Fix custom QS tile style on android 14 Correggi Colore Notifiche Correggi lo stile di notifica personalizzato su Android 14 - + Fix Notification Footer Button Color + Fix custom footer button style on android 14 + Riquadro QS Riquadro QS Verticale Mostra etichetta sotto l\'icona QS Nascondi Etichetta Riquadro QS Usa solo con riquadri verticali + Text Size Scaling Margine QS Elementi QS + Hide QS on Lockscreen + Disable quick settings panel on secured lockscreen Nascondi Testo Silenzioso - Nascondi il testo silenzioso mostrato come intestazione delle notifiche silenziose (richiede il riavvio del SystemUI) + Hide silent text shown as header of silent notifications Nascondi Pulsanti Piè Pagina Nascondi i pulsanti a piè pagina mostrati sotto la finestra delle notifiche - + Stile Batteria Larghezza Batteria Altezza Batteria @@ -494,8 +586,8 @@ Cambia il colore della batteria in risparmio energetico Colore Indicatore Risparmio Energetico Cambia il colore dell\'indicatore in risparmio energetico - Dimensioni Personalizzate - Imposta dimensioni personalizzate per l\'icona della batteria + Custom Margins + Set custom margins for battery icon Margine Sinistro Batteria Margine Destro Batteria Margine Superiore Batteria @@ -546,17 +638,19 @@ Batteria Circolare Batteria Circolare Tratteggiata Filled Circle Battery - + Percentuale Volume Mostra percentuale sopra il cursore del volume Avvertimento di Sicurezza Mostra avvertimento su volume elevato - + Colored Ringer Icon + Enable if selected ringer icon is invisible + Scegli Immagine Intestazione Aggiungi immagine intestazione nel pannello QS\nNon selezionare il file dai Recenti Scegli Immagine Altezza Immagine - Immagine Alfa + Image Opacity Quantità Dissolvenza Inferiore Zoom Per Adattare L\'immagine è allungata per adattarsi in modo predefinito @@ -564,35 +658,36 @@ Nascondi immagine in modalità orizzontale Gradiente Alfa Aggiungi un effetto sbiadito all\'immagine nell\'intestazione - + Orologio Intestazione Personalizzato Aggiungi orologio personalizzato sul pannello QS Stile Orologio Carattere Orologio - Usa carattere personalizzato per l\'orologio nell\'intestazione\nNon selezionare il file dai Recenti + Use custom font for header clock Colore Orologio Personalizzato - Colore personalizzato invece del colore primario + Custom colors instead of system colors Selettore Colore Orologio Imposta il colore del testo dell\'orologio nell\'intestazione + Expansion Amount Ridimensionamento Testo - Margine Laterale Orologio - Margine Superiore Orologio + Side Margin + Top Margin Testo Bianco Forza i colori del testo per essere bianco Orologio Centrato Sposta l\'orologio al centro della visualizzazione Nascondi in Modalità Orizzontale Nascondi l\'orologio in modalità orizzontale - + Orologio Schermata di Blocco Personalizzato Abilita orologio personalizzato nella schermata di blocco Nascondi Orologio Automaticamente Nascondi l\'orologio nella notifica in arrivo Stile Orologio Carattere Orologio - Usa carattere personalizzato per l\'orologio nella schermata di blocco\nNon selezionare il file dai Recenti + Use custom font for lockscreen clock Colore Orologio Personalizzato - Colore personalizzato invece del colore primario + Custom colors instead of system colors Selettore Colore Orologio Imposta il colore del testo dell\'orologio nella schermata di blocco Ridimensionamento Testo @@ -601,6 +696,13 @@ Margine Inferiore Testo Bianco Forza tutti i colori per essere bianchi + Use Custom Image + Use custom image for lockscreen clock. + Custom Image Picker + Custom Device Name + Set custom device name for lockscreen clock.\nKeep blank to use System\'s Device Name. + Custom User Name + Set custom user name for lockscreen clock.\nKeep blank to use System\'s User Name. Seleziona Batteria in Carica Batteria in Scaricamento @@ -608,14 +710,18 @@ Livello Batteria Bentornato! Utente - + Abilita Sfondo Di Profondità - Mostra sfondo di profondità come iOS\nRichiede l\'utilizzo dell\'orologio personalizzato nella schermata di blocco + Show iOS like depth wallpaper\n%s + Custom Images + Set custom images as depth wallpaper + Show on AOD + Show subject on always on display Dissolvenza AOD Anima lo sfondo e sfuma in AOD Immagine in Primo Piano Immagine in primo piano per lo sfondo di profondità - Foreground Image Alpha + Foreground Image Opacity Immagine Sfondo Immagine di sfondo per lo sfondo di profondità Questa funzione è attualmente in fase beta. Quindi sono previsti bug.\n\nBug Conosciuto:\n• Toccare la schermata di blocco fa saltare lo sfondo. @@ -623,23 +729,68 @@ Sposta i livelli di sfondo e di primo piano a velocità diverse Sensibilità Primo Piano Sensibilità Sfondo - + AI model is downloaded on the device + AI model isn\'t available on the device (yet) + Extracting wallpaper subject… + Extracted wallpaper subject! + Failed to extract wallpaper subject! + AI model is not available! + Must use custom lockscreen clock + Barra di Stato Chip Orologio Barra di Stato Visualizza chip dietro l\'orologio della barra di stato - Colore Orologio Barra Di Stato + Customize Clock Chip + Custom colors, roundness, stroke etc. + Text + Clock Text Color Segui Sistema Testo Trasparente Colore Personalizzato - Selettore Colore Orologio - Imposta il colore del testo dell\'orologio nella barra di stato + Text Color Picker + Set color of statubsar clock text Icone di Stato Stile Chip Icone di Stato Chip Visualizza chip dietro le icone di stato + Customize Status Icons Chip + Custom colors, roundness, stroke etc. Stile Chip Margine Superiore Margine Laterale + Background + Accent Fill Color + Gradient Direction + Fill Start Color + Fill End Color + Border + Enable Border + Accent Border Color + Border Color + Dashed Border + Dash Width + Dash Gap + Border Thickness + Padding + Padding Left + Padding Right + Padding Top + Padding Bottom + Corner Radius + Top Left Radius + Top Right Radius + Bottom Left Radius + Bottom Right Radius + + Custom Statusbar Clock Size + Set a custom size for Statusbar Clock + Statusbar Clock Size + Colored Statusbar Icon + Show app icon as notification icon + Nascondi Operatore LS + Nascondi nome operatore nella schermata di blocco + Nascondi Barra Di Stato LS + Nascondi barra di stato nella schermata di blocco Intestazione QS Nascondi Gruppo Operatore @@ -647,10 +798,6 @@ Nascondi Icone Di Stato Rimuovi le icone di ora, data e batteria Schermata di Blocco - Nascondi Operatore LS - Nascondi nome operatore nella schermata di blocco - Nascondi Barra Di Stato LS - Nascondi barra di stato nella schermata di blocco Hide LS Lock Icon Hide lock icon view on lockscreen Icone di Stato Fisse @@ -737,6 +884,7 @@ Home Aggiustamenti + Xposed Impostazioni Changelog @@ -752,37 +900,14 @@ Impostazioni salvate con successo Nessuno - Stile 1 - Stile 2 - Stile 3 - Stile 4 - Stile 5 - Stile 6 - Stile 7 - Stile 8 - Stile 9 - Stile 10 - Stile 11 - Stile 12 - Stile 13 - Stile 14 - Stile 15 - Stile 16 - Stile 17 - Stile 18 - Stile 19 - Stile 20 - Stile 21 - Stile 22 - Stile 23 - Stile 24 - Stile 25 + Style %d Continua Riavvia Disabilita Abilita Applica + Save Disabilita Colori Personalizzati Applica Colori Reimposta @@ -851,10 +976,6 @@ Ehilà! Icona Icone Lettore Multimediale - Selezionato: - Selezionato: %s - Selezionato: %1$s%2$s - Selezionato: %1$s%2$s %3$s (Predefinito) Nessun Orologio Stile Orologio %d @@ -923,4 +1044,124 @@ Tocca l\'anteprima per selezionare Non mostrare di nuovo Per garantire una funzionalità adeguata, è obbligatorio abilitare il modulo Iconify in LSPosed per android 14 e superiori.\n\nDopo di che, abilita le correzioni da: Ritocchi > Menu Xposed > Temi > Altro. + Do not select file from Recent + Dismiss + Restart Device + Pending + Accent Primary + Accent Secondary + Accent Tertiary + Text Color Primary + Text Color Inverse + + + Unit + Verifying location + Select location + Enter location + Location + Set custom location + Cannot retrieve location! + Network geolocation is disabled.\n\nSet a custom location or enable network location. + Enable + Settings + Automatic updates + Check for new versions once in a while + Check updates over WiFi only + Check for updates in background only when connected to wifi + Metric (\u00b0C) + Imperial (\u00b0F) + Update + Enable + Update interval + 1 hour + 2 hours + 4 hours + 6 hours + 12 hours + Weather + Condition Icon Pack + Find more icon packs + Disabled + Error + Waiting \u2026 + No weather data + Error loading weather data + Waiting\u2026 + Updating\u2026 + Service disabled + Now + Background shadow + Service settings + Unknown + Error loading weather data + Weather + Last update: + No location available + No network found + Location permissions not granted + Select location + Search for a location + Enable Location Permissions + Location permissions are required to fetch weather data. Click OK to open Settings. + + Cloudy + Rainy + Sunny + Stormy + Snowy + Windy + Misty + + Weather on Lockscreen + Show weather on lockscreen + Last Update Time + Weather Provider + OpenWeatherMap API Key + OpenWeatherMap API Key required + Please enter your OpenWeatherMap API key to fetch weather data. + Show Location + Show Location before icon + Show Condition + Show Condition after temperature + Show Humidity + Show Humidity in a new row + Show Wind + Show Wind in a new row + Text Size + Image Size + Text Color + Set custom color for text + Custom Color + Custom color for all text in weather view + Custom location + Set custom location for weather + Custom Margins + Set custom margins for weather + Top margin + Center Layout + Side Margin + Bottom Margin + Center Weather View + Move weather view to center horizontally + + Weather Background Style + Default + Semi-transparent box + Semi-transparent box (round) + Q-Beta pill + Rounded, simple and with accent + Rounded, transparent and with accent + Gradient + Dark with accented borders + Dark with gradient borders + + SystemUI Restart Needed + A SystemUI restart is needed for this change to take effect. + Device Restart Needed + A device restart is needed for this change to take effect. + Switch Device Theme + Switch between light and dark themes if unexpected behavior occurs. + Device Rotation Theme + Switch rotation of your device for this change to take effect. diff --git a/app/src/main/res/values-iw-rIL/strings.xml b/app/src/main/res/values-iw-rIL/strings.xml index fa1c8701f..16facc434 100644 --- a/app/src/main/res/values-iw-rIL/strings.xml +++ b/app/src/main/res/values-iw-rIL/strings.xml @@ -230,8 +230,8 @@ Misc. Minimal QS Panel Remove top shade of QS panel - Disable System Monet - Helps to retain custom colors\nSystemUI restart required + Disable System Monet + Helps to retain custom colors\nSystemUI restart required Primary Color Pick primary accent color @@ -420,7 +420,7 @@ Transparency Transparent QS Panel Make QS panel background transparent - Transparency Alpha + Transparency Alpha Transparent Notif Shade Only Make only notification shade transparent Dim Lockscreen Wallpaper @@ -493,8 +493,8 @@ Change color of powersave battery Powersave Indicator Color Change color of powersave indicator - Custom Dimensions - Set custom dimensions for battery icon + Custom Dimensions + Set custom dimensions for battery icon Battery Margin Left Battery Margin Right Battery Margin Top @@ -549,7 +549,7 @@ Add header image on QS panel\nDo not select file from Recent Pick Image Image Height - Image Alpha + Image Alpha Zoom To Fit Image is stretched to fit by default Hide in Landscape @@ -595,7 +595,7 @@ Force all colors to be white Enable Depth Wallpaper - Show iOS like depth wallpaper\nMust use custom lockscreen clock + Show iOS like depth wallpaper\n%s Fade in AOD Animate wallpaper and fade away in AOD Foreground Image @@ -607,12 +607,12 @@ Status Bar Statusbar Clock Chip Display chip behind statusbar clock - Statusbar Clock Color + Statusbar Clock Color Follow System Transparent Text Custom Color - Clock Color Picker - Set color of statubsar clock text + Clock Color Picker + Set color of statubsar clock text Status Icons Chip Style Status Icons Chip @@ -711,31 +711,7 @@ Saved settings successfully None - Style 1 - Style 2 - Style 3 - Style 4 - Style 5 - Style 6 - Style 7 - Style 8 - Style 9 - Style 10 - Style 11 - Style 12 - Style 13 - Style 14 - Style 15 - Style 16 - Style 17 - Style 18 - Style 19 - Style 20 - Style 21 - Style 22 - Style 23 - Style 24 - Style 25 + Style %d Continue Restart diff --git a/app/src/main/res/values-ja-rJP/strings.xml b/app/src/main/res/values-ja-rJP/strings.xml index ec768a6a2..163b2f3eb 100644 --- a/app/src/main/res/values-ja-rJP/strings.xml +++ b/app/src/main/res/values-ja-rJP/strings.xml @@ -1,10 +1,10 @@ - + 退屈な Android の UI をカスタマイズ セットアップの初期化中 ステップ - Step %1$d/%2$d + ステップ %1$d/%2$d モジュール シェルを作成しています 必要なファイルを抽出中 オーバーレイ APK を作成中 @@ -23,7 +23,7 @@ ストレージ権限が必要です 必要なファイルをビルドするために、ストレージ権限が必要です。 互換性のあるルート化方法が見つかりませんでした。 - Use any popular root solutions to proceed. + 一般的な root ソリューションを使用して続行します。 ルートにアクセスできません お使いのデバイスはルート化されていないようです! デバイスの再起動が必要です @@ -31,10 +31,22 @@ 予期しない事態が発生しました ログはドキュメント フォルダに保存されました。 ログ + + Search + Search… + Clear + History entry + More + Clear history + No result Iconify アイコンパック システム アイコンパックを変更 + Cellular Icons + Change system cellular icons + WiFi Icons + Change system WiFi icons 明るさ調節バー 進捗スライダーをカスタマイズ クイック設定パネルタイル @@ -113,6 +125,8 @@ ぼかしの強さなどのいくつかのオプションはシステム UI を再起動するまで効きません ホームページにカードを表示 ホームページに素晴らしいカードを表示します。 + Haptic Feedback + Enhance touch feedback with interactive haptics. アプリのキャッシュをクリア カスタムフォント、画像、GIF の作成に必要なキャッシュをクリアします。 実験的 @@ -122,6 +136,8 @@ 情報 GitHub リポジトリ Telegram グループ + Translate Iconify + Help translate Iconify to your language. クレジット このアプリを実現できた彼らに感謝します。 @@ -183,7 +199,7 @@ マルチカラーアウトライン アイコンパック Pixel バリアント - For roms with black QS panel + ブラック QS パネルのある ROM 向け 明るさ調節バーのスタイル @@ -231,8 +247,8 @@ その他 小さいクイック設定パネル クイック設定パネル上部の影を削除します - システム Monet を無効化 - カスタム色の保持に役立ちます\nシステム UI の再起動が必要 + System Monet + Disable to retain custom colors\nSystemUI restart required プライマリ カラー プライマリのアクセントカラーを選択 @@ -290,8 +306,8 @@ タイトルシステム、サブタイトルアクセント 文字色を修正 機能しない場合のみ使用 - Follow Accent - Title accent, subtitle accent + アクセントに従う + タイトルのアクセントとサブタイトルのアクセント 縦画面 横画面 @@ -348,11 +364,11 @@ 太め なし 背景の色合い - Make track of volume slider thin - Thick Background - Make track of volume slider thick - No Background - Remove track of volume slider + 音量のスライダーを細くします + 太い背景 + 音量のスライダーを太くします + 背景なし + 音量スライダーのトラックを削除します カスタム Magisk モジュール 音量のスタイル このスタイルのフラッシュ可能な Magisk モジュールを作成します @@ -368,14 +384,14 @@ This option will create a magisk module inside Download folder in your Internal Storage. Flash the module named IconifyCompanion.zip in Magisk. Always uninstall previous Iconify Companion module (if installed) and reboot before flashing new one.\n\nNote:\n• Uninstall the module before updating rom.\n• Recreate the module if you change or update rom.\n• Do not flash a module which wasn\'t created based on your rom. メディアプレーヤー プレビュー - Music Title - Artist Name - Phone speaker + 音楽のタイトル + アーティスト名 + デバイスのスピーカー 背景の色 背景のアクセント - Make background follow accent - System Background - Make background follow system + アクセントに従って背景を作成します + システムの背景 + システムに従って背景を作成します Pitch Black Background Make background pitch black @@ -385,7 +401,7 @@ ノッチ バー キラー ノッチ バーの空白を削除します タブレット ヘッダー - Enable large screen shade header + 大画面のシェードヘッダーを有効化します プライバシー チップ アクセント プライバシー チップ プライバシー チップにアクセントカラーを適用する @@ -395,34 +411,103 @@ LSPosed から Iconify モジュールを有効化する前に、Iconify を長押しして最適化をクリックしてください。その後 Iconify を有効にしてシステム UI を再起動してください。これは滑らかな動作に必要なことです。 現在 Xposed 限定モードです。これには LSPosed アプリで Iconify を有効にする必要があります。また、Magisk マネージャーで Iconify モジュールが表示されていることを確認してください。すべての機能にアクセスするには、Iconify アプリのデータを削除した後、インストールプロセスを実行してください。 - Module Not Activated - System service not running + モジュールが有効化されていません + システムサービスが実行されていません 透過とぼかし クイック設定のぼかしと透過を有効化します テーマ - Personalize with themes + テーマでパーソナライズします クイック設定 クイック設定に関する調整 バッテリースタイル - Customize battery icon view + バッテリーアイコンの表示をカスタマイズします + Oneplus QS Header + OOS style quick settings header ヘッダー画像 クイック設定パネルにカスタム画像を追加します ヘッダー時計 クイック設定パネルにカスタム時計を追加します ロック画面時計 ロック画面にカスタム時計を追加します + Lockscreen Weather + Add weather on lockscreen + Lockscreen Widgets + Add widgets on lockscreen 深度のある背景 iOS のような深度のある背景を表示します - Background Chip - Add colored chip behind clock - Others + 背景チップ + 時計の後ろに色付きのチップを追加します + Clock Chip + その他 その他の Xposed での調整 - + Weather Settings + + Oneplus QS Header + Enable OOS style media player and tiles in QS + Haptic Feedback + Add haptic feedback on tiles + Hide Stock Media Player + Remove stock media player from QS panel + Blur Level + Fade Level + Top Margin + Expansion Amount + + Lockscreen Widgets + Enable Lockscreen Widgets + Add widgets to lockscreen + Device Info Widget + Show device info widget on lockscreen + Linear Progress Color + Circular Progress Color + Text Color + Custom Device Name + Set custom device name.\nKeep blank to disable. + Large Widgets + Large Widget 1 + Large Widget 2 + Mini Widgets + Mini Widget 1 + Mini Widget 2 + Mini Widget 3 + Mini Widget 4 + Custom Colors + Customize Widget Colors + Large Widget Active Color + Large Widget Inactive Color + Large Widget Icon Active Color + Large Widget Icon Inactive Color + Mini Widget Active Color + Mini Widget Inactive Color + Mini Widget Icon Active Color + Mini Widget Icon Inactive Color + Weather Settings + Widgets Scale + + Camera + Clock/Timer + Calculator + Gallery + Media Player + Torch + Play + Weather + Wifi + Data + Ringer + Bluetooth + Home Controls + Wallet + Hotspot + Ringer + Vibrate + Silent + 透明効果 クイック設定パネルを透過する クイック設定パネルの背景を透過します - 透明度 - 通知シェードのみ透過する + Background Opacity + Transparent Notification Shade 通知シェードのみ透過するようにします ロック画面の壁紙を暗くする 明るい壁紙に適しています @@ -430,40 +515,47 @@ ウインドウ レベルのぼかし 動作には再起動が必要です 積極的なぼかしを有効化 - Might bootloop in some roms + 一部の ROM でブートループが発生する可能性があります ぼかしの強さ - - For Pixel Roms + + Pixel ROM 向け ライト テーマ ライト モードで明るいクイック設定を使用します\nカスタムクイック設定形状の使用が必要です - Dual Tone + デュアルトーン Use different color for header - For Custom Roms - Pixel Black Theme + カスタム ROM 向け + Pixel Black テーマ Black QS theme in light mode\nMust use Pixel QS Shape\nSwitch dark theme to fix text color - Translucent Theme - Fluid QS Theme + 半透明なテーマ + Fluid QS テーマ Two tone translucent QS theme\nSwitch theme to fix color\nDo not use custom shapes 通知の透過 Notification transparency for Fluid QS\nDo not use custom notification style 電源メニューの透過 Power menu transparency for Fluid QS\nDo not use custom notification style その他 + Fix QS Tile Color + Fix custom QS tile style on android 14 通知の色を修正 Android 14 でのカスタム通知スタイルを修正します - + Fix Notification Footer Button Color + Fix custom footer button style on android 14 + クイック設定タイル 垂直クイック設定タイル クイック設定アイコンの下にラベルを表示します クイック設定タイルのラベルを非表示 垂直タイルの時のみ使用してください + テキストサイズの大きさ クイック設定マージン クイック設定の要素 + Hide QS on Lockscreen + Disable quick settings panel on secured lockscreen サイレント テキストを非表示 - サイレント通知のヘッダーとして表示される サイレント を非表示にします (システム UI の再起動が必要) + Hide silent text shown as header of silent notifications フッターのボタンを非表示 通知一覧の下に表示されるボタンを非表示にします - + バッテリースタイル バッテリー横幅 バッテリー縦幅 @@ -480,22 +572,22 @@ Make battery perimeter semi transparent Fill Alpha Make battery fill semi transparent - Rainbow Color - Show different color based on battery level - Blend Color - Blend battery color with custom color + レインボーカラー + バッテリーレベルに応じて異なる色を表示します + ブレンドカラー + バッテリーカラーをカスタムカラーとブレンドします Fill Color Fill battery with custom color - Fill Gradient Color - Fill battery with gradient color - Charging Fill Color - Change color of charging battery - Powersave Fill Color - Change color of powersave battery - Powersave Indicator Color - Change color of powersave indicator - カスタムディメンション - バッテリーアイコンにカスタムディメンションを設定します + グラデーションカラーで塗りつぶす + バッテリーをグラデーションカラーで塗りつぶします + 充電中のカラーを塗りつぶす + 充電時のバッテリーの色を変更します + バッテリーセーバーの塗りつぶしの色 + バッテリーセーバーの色を変更します + バッテリーセーバーのインジケーターの色 + バッテリーセーバーのインジケーターの色を変更します + Custom Margins + Set custom margins for battery icon バッテリー左マージン バッテリー右マージン バッテリー上部マージン @@ -543,56 +635,59 @@ 横向き バッテリー M 横向き バッテリー N 横向き バッテリー O - Circle Battery - Dotted Circle Battery - Filled Circle Battery - - Volume Percentage - Show percentage above volume slider - Safety Warning - Show warning on high volume - + サークルバッテリー + ドットサークルバッテリー + 塗りつぶされたサークルバッテリー + + 音量のパーセンテージ + 音量スライダーの上にパーセンテージを表示します + 安全上の警告 + 大音量の場合に警告を表示します + Colored Ringer Icon + Enable if selected ringer icon is invisible + ヘッダー画像を選択 クイック設定パネルのヘッダー画像を追加します\n「最近」からファイルを選択しないでください 画像を選択 画像の縦幅 - 画像の透明度 - Bottom Fade Amount + Image Opacity + 下部のフェード量 画面に合わせる 画像はデフォルトで拡大縮小します 横画面では非表示 横画面モードでは画像を非表示にします 透明度グラデーション ヘッダー画像にフェード エフェクトを追加します - + カスタムヘッダー時計 クイック設定パネルにカスタム時計を追加します 時計スタイル 時計フォント - ヘッダー時計にカスタムフォントを使用します\n「最近」からファイルを選択しないでください + Use custom font for header clock カスタム時計色 - プライマリ色の代わりに色をカスタムします + Custom colors instead of system colors 時計カラーピッカー ヘッダー時計の色を設定します + Expansion Amount テキストスケーリング - 時計横マージン - 時計上部マージン + Side Margin + Top Margin ホワイト テキスト テキスト色を白に強制します 中央に時計 画面の中央に時計を移動します 横画面では非表示 横画面モードでは時計を非表示にします - + カスタムロック画面時計 カスタムロック画面時計を有効化します 自動的に時計を非表示 通知が来たとき時計を隠します 時計スタイル 時計フォント - ロック画面時計にカスタムフォントを使用します\n「最近」からファイルを選択しないでください + Use custom font for lockscreen clock カスタム時計色 - プライマリ色の代わりに色をカスタムします + Custom colors instead of system colors 時計カラーピッカー ロック画面時計の色を設定します テキストスケーリング @@ -601,45 +696,101 @@ 下部マージン ホワイト テキスト すべての色を白に強制します - Select - Battery Charging - Battery Discharging - Battery Full - Battery Level - Welcome back! - User - - Enable Depth Wallpaper - Show iOS like depth wallpaper\nMust use custom lockscreen clock - Fade in AOD - Animate wallpaper and fade away in AOD + Use Custom Image + Use custom image for lockscreen clock. + Custom Image Picker + Custom Device Name + Set custom device name for lockscreen clock.\nKeep blank to use System\'s Device Name. + Custom User Name + Set custom user name for lockscreen clock.\nKeep blank to use System\'s User Name. + 選択 + バッテリー充電中 + バッテリー放電中 + バッテリー満充電 + バッテリーレベル + おかえりなさい! + ユーザー + + 奥行きのある壁紙を有効化 + Show iOS like depth wallpaper\n%s + Custom Images + Set custom images as depth wallpaper + Show on AOD + Show subject on always on display + AOD をフェードイン + AOD で壁紙をアニメーション化してフェードアウトさせます 前景の画像 深度のある壁紙の前景画像 - Foreground Image Alpha + Foreground Image Opacity 背景の画像 深度のある壁紙の背景画像 This feature is currently in beta stage. So bugs are expected.\n\nKnown Bug(s):\n• Tapping on lockscreen makes the wallpaper jump. - Parallax Effect - Move background and foreground layers at different speeds + 視差効果 + 背景レイヤーと前景レイヤーを異なる速度で移動します Foreground Sensitivity Background Sensitivity - + AI model is downloaded on the device + AI model isn\'t available on the device (yet) + Extracting wallpaper subject… + Extracted wallpaper subject! + Failed to extract wallpaper subject! + AI model is not available! + Must use custom lockscreen clock + ステータスバー ステータスバー時計チップ ステータスバー時計の後ろにチップを表示します - ステータスバー時計色 + Customize Clock Chip + Custom colors, roundness, stroke etc. + Text + Clock Text Color システムに従う 透過テキスト カスタムカラー - 時計カラーピッカー - ステータスバー時計の色を設定します + Text Color Picker + Set color of statubsar clock text ステータスアイコン チップ スタイル ステータスアイコンチップ ステータスバーアイコンの後ろにチップを表示します + Customize Status Icons Chip + Custom colors, roundness, stroke etc. チップ スタイル 上部マージン 横マージン + Background + Accent Fill Color + Gradient Direction + Fill Start Color + Fill End Color + Border + Enable Border + Accent Border Color + Border Color + Dashed Border + Dash Width + Dash Gap + Border Thickness + Padding + Padding Left + Padding Right + Padding Top + Padding Bottom + Corner Radius + Top Left Radius + Top Right Radius + Bottom Left Radius + Bottom Right Radius + + Custom Statusbar Clock Size + Set a custom size for Statusbar Clock + Statusbar Clock Size + Colored Statusbar Icon + Show app icon as notification icon + ロック画面のキャリアを非表示 + ロック画面のキャリア名を非表示にします + ロック画面のステータスバーを非表示 + ロック画面のステータスバーを非表示にします クイック設定ヘッダー キャリア名を非表示 @@ -647,14 +798,10 @@ ステータス アイコンを非表示 時間、日付、バッテリーアイコンを削除します ロック画面 - ロック画面のキャリアを非表示 - ロック画面のキャリア名を非表示にします - ロック画面のステータスバーを非表示 - ロック画面のステータスバーを非表示にします - Hide LS Lock Icon - Hide lock icon view on lockscreen + LS ロックアイコンを非表示 + ロック画面でロックアイコンの表示を非表示にします ステータス アイコンを固定 - Set status icons in fixed position\nMight be buggy on some rom + ステータスアイコンを固定された位置に設定します\n一部の ROM でバグを起こす可能性があります 変更履歴 サーバーに接続できませんでした!\nインターネット接続に問題があるか、一時的にサーバーダウンしている可能性があります。あとでもう一度やり直してください。 @@ -679,8 +826,8 @@ 毎日 毎週 しない - Current Version: %s - Latest Version: %s + 現在のバージョン: %s + 最新のバージョン: %s クレジット スペシャル サンクス @@ -691,52 +838,53 @@ Xposed 制作補助。 アプリのテスト。 より良いクイック設定の使用許可。 - For android executable binaries. + Android 実行可能バイナリ用です。 貢献者 GitHub での貢献。 Telegram での補助。 翻訳者 - Afrikaans translation. + アフリカーンス語訳 アラビア後翻訳。 - Catalan translation. - Chinese translation. - Chinese translation. - Czech translation. - Danish translation. - Dutch translation. - Finnish translation. + カタロニア語訳 + 中国語訳 + 中国語訳 + チェコ語訳 + デンマーク語訳 + オランダ語訳 + フィンランド語訳 フランス語翻訳。 - German translation. - Greek translation. - Hungarian translation. + ドイツ語訳 + ギリシャ語訳 + ハンガリー語訳 インドネシア語翻訳。 イタリア語翻訳。 - Japanese translation. - Korean translation. - Norwegian translation. + 日本語訳 + 韓国語訳 + ノルウェー語訳 ペルシア語翻訳。 ポーランド語翻訳。 ポルトガル語翻訳。 - Portuguese (Brazilian) translation. - Romanian translation. + ポルトガル語 (ブラジル) 訳 + ルーマニア語訳 ロシア語翻訳。 - Serbian (Cyrillic) translation. + セルビア語 (キリル文字) 訳 スペイン語翻訳。 - Swedish translation. + スウェーデン語訳 トルコ語翻訳。 - Ukrainian translation. + ウクライナ語訳 ベトナム語翻訳。 実験的 - Overlap Header Image - Overlap header image on expanded QS + ヘッダー画像の重複 + 展開されたクイック設定にヘッダー画像を重ねます Unzoom Depth Wallpaper Remove the zoom effect on depth wallpaper - Hide Data Disabled Icon - Hide data disabled indicator + データ通信無効アイコンを非表示 + データ通信インジケーターを非表示 ホーム 調整 + Xposed 設定 変更履歴 @@ -752,37 +900,14 @@ 設定の保存が完了しました なし - スタイル 1 - スタイル 2 - スタイル 3 - スタイル 4 - スタイル 5 - スタイル 6 - スタイル 7 - スタイル 8 - スタイル 9 - スタイル 10 - スタイル 11 - スタイル 12 - スタイル 13 - スタイル 14 - スタイル 15 - スタイル 16 - スタイル 17 - スタイル 18 - スタイル 19 - スタイル 20 - スタイル 21 - スタイル 22 - スタイル 23 - スタイル 24 - スタイル 25 + Style %d 続ける 再起動 無効化 有効化 適用 + Save カスタム色を無効化 色を適用 リセット @@ -814,7 +939,7 @@ Plumpy uses colored battery by default はじめにスタイルを選択して下さい KernelSU は現在サポートされていません - Only magisk is supported currently + 現在は Magisk でのみサポートされています 再起動が必要です LSPosed が見つかりません! どうやってこれ知ったの? @@ -827,7 +952,7 @@ 設定のエクスポートが完了しました 選択が完了しました 利用不可能 - Use this feature from Xposed Menu + Xposed メニューからこの機能を使用する アップデートがあります 新しいバージョンの Iconify が利用可能です。 @@ -850,14 +975,10 @@ Iconify ロゴ こんにちは! アイコン - Media Player Icons - 選択: - 選択: %s - Selected: %1$s%2$s - Selected: %1$s%2$s %3$s + メディアプレーヤーアイコン (デフォルト) - No Clock - Clock Style %d + 時計なし + 時計のスタイル %d お待ちください 5 秒以内に再起動します Iconify バージョン @@ -880,8 +1001,8 @@ 理解した カスタム トースト カスタムされたスタイルのトーストを有効化します - Custom Progressbar - Enable gradient progress bar + カスタムプログレスバー + グラデーションなプログレスバーを有効化 カスタム シークバー カスタムされたスタイルのシークバーを有効化します システム UI の再起動が必要です @@ -893,17 +1014,17 @@ カスタムクイック設定マージン クイック設定のカスタムマージンを有効化します ぼかしの有効化を強制 - Force enable blur for unsupported roms + サポートされていない ROM でぼかし効果を強制的に有効化します ヘッダー画像を選択 時計フォントを選択 - Pick a style of your choice + お好みのスタイルを選択してください 注意! - Double Toggle Dark Mode + ダブルでダークモードに切り替え システム UI を再起動 - Do Nothing (I will do it myself) + 何もしない (自分で行う) Xposed 設定 - Force Apply Method - Method to force apply the changes in xposed menu + 強制適用方式 + Xposed メニューの変更を強制的に適用します その他の設定 一般設定 明るいアクセントを使用 @@ -923,4 +1044,124 @@ プレビューをタップして選択 次回から表示しない To ensure proper functionality, enabling the Iconify module in LSPosed is mandatory for android 14 and above.\n\nAfter that, enable the fixes from: Tweaks > Xposed Menu > Themes > Others. + Do not select file from Recent + Dismiss + Restart Device + Pending + Accent Primary + Accent Secondary + Accent Tertiary + Text Color Primary + Text Color Inverse + + + Unit + Verifying location + Select location + Enter location + Location + Set custom location + Cannot retrieve location! + Network geolocation is disabled.\n\nSet a custom location or enable network location. + Enable + Settings + Automatic updates + Check for new versions once in a while + Check updates over WiFi only + Check for updates in background only when connected to wifi + Metric (\u00b0C) + Imperial (\u00b0F) + Update + Enable + Update interval + 1 hour + 2 hours + 4 hours + 6 hours + 12 hours + Weather + Condition Icon Pack + Find more icon packs + Disabled + Error + Waiting \u2026 + No weather data + Error loading weather data + Waiting\u2026 + Updating\u2026 + Service disabled + Now + Background shadow + Service settings + Unknown + Error loading weather data + Weather + Last update: + No location available + No network found + Location permissions not granted + Select location + Search for a location + Enable Location Permissions + Location permissions are required to fetch weather data. Click OK to open Settings. + + Cloudy + Rainy + Sunny + Stormy + Snowy + Windy + Misty + + Weather on Lockscreen + Show weather on lockscreen + Last Update Time + Weather Provider + OpenWeatherMap API Key + OpenWeatherMap API Key required + Please enter your OpenWeatherMap API key to fetch weather data. + Show Location + Show Location before icon + Show Condition + Show Condition after temperature + Show Humidity + Show Humidity in a new row + Show Wind + Show Wind in a new row + Text Size + Image Size + Text Color + Set custom color for text + Custom Color + Custom color for all text in weather view + Custom location + Set custom location for weather + Custom Margins + Set custom margins for weather + Top margin + Center Layout + Side Margin + Bottom Margin + Center Weather View + Move weather view to center horizontally + + Weather Background Style + Default + Semi-transparent box + Semi-transparent box (round) + Q-Beta pill + Rounded, simple and with accent + Rounded, transparent and with accent + Gradient + Dark with accented borders + Dark with gradient borders + + SystemUI Restart Needed + A SystemUI restart is needed for this change to take effect. + Device Restart Needed + A device restart is needed for this change to take effect. + Switch Device Theme + Switch between light and dark themes if unexpected behavior occurs. + Device Rotation Theme + Switch rotation of your device for this change to take effect. diff --git a/app/src/main/res/values-ko-rKR/strings.xml b/app/src/main/res/values-ko-rKR/strings.xml index b0fab439a..fb8b03482 100644 --- a/app/src/main/res/values-ko-rKR/strings.xml +++ b/app/src/main/res/values-ko-rKR/strings.xml @@ -1,5 +1,5 @@ - + 따분한 Android UI를 맞춤 설정 설치 초기화 중 @@ -31,10 +31,22 @@ 이런! 예상치 못한 일이 발생했어요 문서 폴더에 로그 파일이 저장되었어요. 로그 + + Search + Search… + Clear + History entry + More + Clear history + No result Iconify 아이콘 팩 시스템 아이콘 팩 변경 + Cellular Icons + Change system cellular icons + WiFi Icons + Change system WiFi icons 밝기 막대 진행 슬라이더 맞춤 설정 빠른 설정창 타일 @@ -113,6 +125,8 @@ 흐림 세기와 같은 일부 설정은 시스템 UI를 다시 시작할 때까지 적용되지 않아요 홈페이지 카드 표시 홈페이지에 멋진 카드를 표시해요. + Haptic Feedback + Enhance touch feedback with interactive haptics. 앱 캐시 지우기 사용자 지정 글꼴, 이미지 또는 GIF를 쓸 때 생성된 캐시를 지워요. 실험 @@ -122,6 +136,8 @@ 정보 Github 저장소 텔레그램 그룹 + Translate Iconify + Help translate Iconify to your language. 크레딧 앱을 구현할 수 있게 도와주신 분들께 감사드려요. @@ -231,8 +247,8 @@ Misc. Minimal QS Panel Remove top shade of QS panel - Disable System Monet - Helps to retain custom colors\nSystemUI restart required + System Monet + Disable to retain custom colors\nSystemUI restart required Primary Color Pick primary accent color @@ -405,24 +421,93 @@ Tweaks related to QS panel Battery Style Customize battery icon view + Oneplus QS Header + OOS style quick settings header Header Image Add custom image on QS panel Header Clock Add custom clock on QS panel Lockscreen Clock Add custom clock on lockscreen + Lockscreen Weather + Add weather on lockscreen + Lockscreen Widgets + Add widgets on lockscreen Depth Wallpaper Show iOS like depth wallpaper Background Chip Add colored chip behind clock + Clock Chip Others Miscellaneous xposed tweaks - + Weather Settings + + Oneplus QS Header + Enable OOS style media player and tiles in QS + Haptic Feedback + Add haptic feedback on tiles + Hide Stock Media Player + Remove stock media player from QS panel + Blur Level + Fade Level + Top Margin + Expansion Amount + + Lockscreen Widgets + Enable Lockscreen Widgets + Add widgets to lockscreen + Device Info Widget + Show device info widget on lockscreen + Linear Progress Color + Circular Progress Color + Text Color + Custom Device Name + Set custom device name.\nKeep blank to disable. + Large Widgets + Large Widget 1 + Large Widget 2 + Mini Widgets + Mini Widget 1 + Mini Widget 2 + Mini Widget 3 + Mini Widget 4 + Custom Colors + Customize Widget Colors + Large Widget Active Color + Large Widget Inactive Color + Large Widget Icon Active Color + Large Widget Icon Inactive Color + Mini Widget Active Color + Mini Widget Inactive Color + Mini Widget Icon Active Color + Mini Widget Icon Inactive Color + Weather Settings + Widgets Scale + + Camera + Clock/Timer + Calculator + Gallery + Media Player + Torch + Play + Weather + Wifi + Data + Ringer + Bluetooth + Home Controls + Wallet + Hotspot + Ringer + Vibrate + Silent + Transparency Transparent QS Panel Make QS panel background transparent - Transparency Alpha - Transparent Notif Shade Only + Background Opacity + Transparent Notification Shade Make only notification shade transparent Dim Lockscreen Wallpaper Suitable for light-colored wallpapers @@ -432,7 +517,7 @@ Aggressive Blur Enabler Might bootloop in some roms Blur Intensity - + For Pixel Roms Light Theme Light QS theme in light mode\nMust use custom QS Shape @@ -449,21 +534,28 @@ Power Menu Transparency Power menu transparency for Fluid QS\nDo not use custom notification style Others + Fix QS Tile Color + Fix custom QS tile style on android 14 Fix Notification Color Fix custom notification style on android 14 - + Fix Notification Footer Button Color + Fix custom footer button style on android 14 + QS Tile Vertical QS Tile Show label below QS icon Hide QS Tile Label Use only with vertical tiles + Text Size Scaling QS Margin QS Elements + Hide QS on Lockscreen + Disable quick settings panel on secured lockscreen Hide Silent Text - Hide silent text shown as header of silent notifications (Requires SystemUI restart) + Hide silent text shown as header of silent notifications Hide Footer Buttons Hide footer buttons shown under notification stack - + Battery Style Battery Width Battery Height @@ -494,8 +586,8 @@ Change color of powersave battery Powersave Indicator Color Change color of powersave indicator - Custom Dimensions - Set custom dimensions for battery icon + Custom Margins + Set custom margins for battery icon Battery Margin Left Battery Margin Right Battery Margin Top @@ -546,17 +638,19 @@ Circle Battery Dotted Circle Battery Filled Circle Battery - + Volume Percentage Show percentage above volume slider Safety Warning Show warning on high volume - + Colored Ringer Icon + Enable if selected ringer icon is invisible + Pick Header Image Add header image on QS panel\nDo not select file from Recent Pick Image Image Height - Image Alpha + Image Opacity Bottom Fade Amount Zoom To Fit Image is stretched to fit by default @@ -564,35 +658,36 @@ Hide image in landscape mode Alpha Gradient Add faded effect to the header image - + Custom Header Clock Add a custom clock on QS panel Clock Style Clock Font - Use custom font for header clock\nDo not select file from Recent + Use custom font for header clock Custom Clock Color - Custom color instead of primary color + Custom colors instead of system colors Clock Color Picker Set color of header clock text + Expansion Amount Text Scaling - Clock Side Margin - Clock Top Margin + Side Margin + Top Margin White Text Force text colors to be white Center Clock Move clock to center of view Hide in Landscape Hide clock in landscape mode - + Custom Lockscreen Clock Enable custom lockscreen clock Auto Hide Clock Hide clock on incoming notification Clock Style Clock Font - Use custom font for lockscreen clock\nDo not select file from Recent + Use custom font for lockscreen clock Custom Clock Color - Custom color instead of primary color + Custom colors instead of system colors Clock Color Picker Set color of lockscreen clock text Text Scaling @@ -601,6 +696,13 @@ Bottom Margin White Text Force all colors to be white + Use Custom Image + Use custom image for lockscreen clock. + Custom Image Picker + Custom Device Name + Set custom device name for lockscreen clock.\nKeep blank to use System\'s Device Name. + Custom User Name + Set custom user name for lockscreen clock.\nKeep blank to use System\'s User Name. Select Battery Charging Battery Discharging @@ -608,14 +710,18 @@ Battery Level Welcome back! User - + Enable Depth Wallpaper - Show iOS like depth wallpaper\nMust use custom lockscreen clock + Show iOS like depth wallpaper\n%s + Custom Images + Set custom images as depth wallpaper + Show on AOD + Show subject on always on display Fade in AOD Animate wallpaper and fade away in AOD Foreground Image Foreground image for depth wallpaper - Foreground Image Alpha + Foreground Image Opacity Background Image Background image for depth wallpaper This feature is currently in beta stage. So bugs are expected.\n\nKnown Bug(s):\n• Tapping on lockscreen makes the wallpaper jump. @@ -623,23 +729,68 @@ Move background and foreground layers at different speeds Foreground Sensitivity Background Sensitivity - + AI model is downloaded on the device + AI model isn\'t available on the device (yet) + Extracting wallpaper subject… + Extracted wallpaper subject! + Failed to extract wallpaper subject! + AI model is not available! + Must use custom lockscreen clock + Status Bar Statusbar Clock Chip Display chip behind statusbar clock - Statusbar Clock Color + Customize Clock Chip + Custom colors, roundness, stroke etc. + Text + Clock Text Color Follow System Transparent Text Custom Color - Clock Color Picker - Set color of statubsar clock text + Text Color Picker + Set color of statubsar clock text Status Icons Chip Style Status Icons Chip Display chip behind status icons + Customize Status Icons Chip + Custom colors, roundness, stroke etc. Chip Style Top Margin Side Margin + Background + Accent Fill Color + Gradient Direction + Fill Start Color + Fill End Color + Border + Enable Border + Accent Border Color + Border Color + Dashed Border + Dash Width + Dash Gap + Border Thickness + Padding + Padding Left + Padding Right + Padding Top + Padding Bottom + Corner Radius + Top Left Radius + Top Right Radius + Bottom Left Radius + Bottom Right Radius + + Custom Statusbar Clock Size + Set a custom size for Statusbar Clock + Statusbar Clock Size + Colored Statusbar Icon + Show app icon as notification icon + Hide LS Carrier + Hide carrier name on lockscreen + Hide LS Statusbar + Hide statusbar on lockscreen QS Header Hide Carrier Group @@ -647,10 +798,6 @@ Hide Status Icons Remove time, date and battery icons Lock Screen - Hide LS Carrier - Hide carrier name on lockscreen - Hide LS Statusbar - Hide statusbar on lockscreen Hide LS Lock Icon Hide lock icon view on lockscreen Fixed Status Icons @@ -737,6 +884,7 @@ Home Tweaks + Xposed Settings Changelog @@ -752,37 +900,14 @@ Saved settings successfully None - Style 1 - Style 2 - Style 3 - Style 4 - Style 5 - Style 6 - Style 7 - Style 8 - Style 9 - Style 10 - Style 11 - Style 12 - Style 13 - Style 14 - Style 15 - Style 16 - Style 17 - Style 18 - Style 19 - Style 20 - Style 21 - Style 22 - Style 23 - Style 24 - Style 25 + Style %d Continue Restart Disable Enable Apply + Save Disable Custom Colors Apply Colors Reset @@ -851,10 +976,6 @@ Hey There! Icon Media Player Icons - Selected: - Selected: %s - Selected: %1$s%2$s - Selected: %1$s%2$s %3$s (Default) No Clock Clock Style %d @@ -923,4 +1044,124 @@ Tap on preview to select Don\'t show again To ensure proper functionality, enabling the Iconify module in LSPosed is mandatory for android 14 and above.\n\nAfter that, enable the fixes from: Tweaks > Xposed Menu > Themes > Others. + Do not select file from Recent + Dismiss + Restart Device + Pending + Accent Primary + Accent Secondary + Accent Tertiary + Text Color Primary + Text Color Inverse + + + Unit + Verifying location + Select location + Enter location + Location + Set custom location + Cannot retrieve location! + Network geolocation is disabled.\n\nSet a custom location or enable network location. + Enable + Settings + Automatic updates + Check for new versions once in a while + Check updates over WiFi only + Check for updates in background only when connected to wifi + Metric (\u00b0C) + Imperial (\u00b0F) + Update + Enable + Update interval + 1 hour + 2 hours + 4 hours + 6 hours + 12 hours + Weather + Condition Icon Pack + Find more icon packs + Disabled + Error + Waiting \u2026 + No weather data + Error loading weather data + Waiting\u2026 + Updating\u2026 + Service disabled + Now + Background shadow + Service settings + Unknown + Error loading weather data + Weather + Last update: + No location available + No network found + Location permissions not granted + Select location + Search for a location + Enable Location Permissions + Location permissions are required to fetch weather data. Click OK to open Settings. + + Cloudy + Rainy + Sunny + Stormy + Snowy + Windy + Misty + + Weather on Lockscreen + Show weather on lockscreen + Last Update Time + Weather Provider + OpenWeatherMap API Key + OpenWeatherMap API Key required + Please enter your OpenWeatherMap API key to fetch weather data. + Show Location + Show Location before icon + Show Condition + Show Condition after temperature + Show Humidity + Show Humidity in a new row + Show Wind + Show Wind in a new row + Text Size + Image Size + Text Color + Set custom color for text + Custom Color + Custom color for all text in weather view + Custom location + Set custom location for weather + Custom Margins + Set custom margins for weather + Top margin + Center Layout + Side Margin + Bottom Margin + Center Weather View + Move weather view to center horizontally + + Weather Background Style + Default + Semi-transparent box + Semi-transparent box (round) + Q-Beta pill + Rounded, simple and with accent + Rounded, transparent and with accent + Gradient + Dark with accented borders + Dark with gradient borders + + SystemUI Restart Needed + A SystemUI restart is needed for this change to take effect. + Device Restart Needed + A device restart is needed for this change to take effect. + Switch Device Theme + Switch between light and dark themes if unexpected behavior occurs. + Device Rotation Theme + Switch rotation of your device for this change to take effect. diff --git a/app/src/main/res/values-night/styles.xml b/app/src/main/res/values-night/styles.xml index 5a1083e9d..2737e9011 100644 --- a/app/src/main/res/values-night/styles.xml +++ b/app/src/main/res/values-night/styles.xml @@ -16,7 +16,6 @@ @color/colorAccent @color/colorAccent @color/colorAccent - @color/text_color_primary + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index 39535d805..76f02362f 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -90,6 +90,11 @@ @style/ShapeAppearance.Material3.LargeComponent + + + @style/ThemeOverlay.App.MaterialAlertDialog.Monet + + @style/ThemeOverlay.App.MaterialAlertDialog.Monet