Compare commits

..
Author SHA1 Message Date
gdlbo cdaf7909d4 fix old android crash accenting 2023-07-04 23:23:18 +03:00
gdlbo c70ab388c1 fixed account saving 2023-07-04 22:55:22 +03:00
gdlbo 50c66c2703 fix music metrics 2023-07-04 19:56:12 +03:00
gdlbo 357e520bb0 some code fixes 2023-07-04 18:57:06 +03:00
gdlbo 6379ce5741 cleanup code 2023-07-04 13:42:04 +03:00
Vologhat 02807739a1 fix #1394 2023-07-02 22:32:26 +03:00
gdlbo 40635ab75a fix #1388 2023-07-02 13:44:47 +03:00
gdlbo 32e1bfe6fd fix messages color accent 2023-07-02 00:04:10 +03:00
gdlbo 281a0e8499 updated translations 2023-07-01 18:45:45 +03:00
gdlbo 220c61afe1 Update preferences_themes.xml 2023-07-01 18:33:46 +03:00
Vologhat 7a632d5224 Update preferences_themes.xml 2023-07-01 18:31:23 +03:00
Vologhat 3218c1a46b add optionally theme cache invalidation every update 2023-07-01 18:29:47 +03:00
Vologhat b2028d86ba add optionally theme cache invalidation every update 2023-07-01 18:24:42 +03:00
gdlbo 45ed5879e6 Update build.gradle 2023-07-01 17:46:06 +03:00
gdlbo 48479dd064 removed old color engine prefs 2023-07-01 17:33:45 +03:00
gdlbo 3b556b81a1 Update StandartFilter.txt 2023-07-01 17:33:05 +03:00
gdlbo 526c9a607a auto refactor imports 2023-07-01 16:42:33 +03:00
Vologhat 81752895ab Revert "auto refactor code"
This reverts commit ad970d097a.
2023-07-01 16:39:36 +03:00
gdlbo ad970d097a auto refactor code 2023-07-01 16:38:42 +03:00
gdlbo bc2010b49d gradle downgrade 2023-07-01 16:34:27 +03:00
Vologhat ff4a4094ff add type validating of resource value 2023-07-01 16:15:20 +03:00
abslike 3629e71098 Update monet dark and amoled theme (nomilkshake) (#1378) 2023-06-27 22:21:45 +03:00
Vologhat b955ac355f fix #1386 2023-06-27 22:17:43 +03:00
Vologhat 409279eca0 fix apk path building 2023-06-27 17:32:28 +03:00
Vologhat ea0a0f1d93 Optimize build scripts
- rewrite the"exportDex" task group
- move  the logic of deleting temporary files into a gradle script
- fix "APPCENTER_KEY" property defining while debug building
2023-06-27 16:42:07 +03:00
62 changed files with 629 additions and 676 deletions
+51 -71
View File
@@ -1,8 +1,6 @@
import org.apache.tools.ant.taskdefs.condition.Os import org.apache.tools.ant.taskdefs.condition.Os
import java.util.zip.ZipEntry
import java.util.zip.ZipFile import java.util.zip.ZipFile
import java.util.zip.ZipInputStream
plugins { plugins {
id 'com.android.application' id 'com.android.application'
@@ -21,6 +19,10 @@ cargo {
def smaliFolder = projectDir.toPath().resolve("../smali").normalize() def smaliFolder = projectDir.toPath().resolve("../smali").normalize()
def scriptsFolder = projectDir.toPath().resolve("../scripts").normalize() def scriptsFolder = projectDir.toPath().resolve("../scripts").normalize()
//you can add own folders with decompiled smali code
def dexes=smaliFolder.toFile()
.listFiles( { f -> f.isDirectory() && f.name.startsWith("smali") } as FileFilter)
.size()
versionFile { versionFile {
file = projectDir.toPath().resolve("src/main/assets/version.properties").toFile() file = projectDir.toPath().resolve("src/main/assets/version.properties").toFile()
@@ -50,19 +52,24 @@ android {
} }
buildTypes { buildTypes {
release {
minifyEnabled true
buildConfigField 'String', 'APPCENTER_KEY', '""'
proguardFile 'proguard-rules.pro'
}
rc {
minifyEnabled true
buildConfigField 'String', 'APPCENTER_KEY', '""'
proguardFile 'proguard-rules.pro'
}
dev { dev {
initWith release minifyEnabled false
buildConfigField 'String', 'APPCENTER_KEY', '""' buildConfigField 'String', 'APPCENTER_KEY', '""'
} }
beta { beta {
initWith release minifyEnabled false
buildConfigField 'String', 'APPCENTER_KEY', '""' buildConfigField 'String', 'APPCENTER_KEY', '""'
} }
release {
buildConfigField 'String', 'APPCENTER_KEY', '""'
minifyEnabled true
proguardFile 'proguard-rules.pro'
}
} }
compileOptions { compileOptions {
@@ -82,70 +89,44 @@ dependencies {
implementation 'com.microsoft.appcenter:appcenter-crashes:5.0.1' implementation 'com.microsoft.appcenter:appcenter-crashes:5.0.1'
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.3' coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.3'
implementation 'net.sourceforge.streamsupport:streamsupport-minifuture:1.7.4' implementation 'net.sourceforge.streamsupport:streamsupport-minifuture:1.7.4'
implementation 'com.google.guava:guava:23.3-android'
implementation fileTree(dir: 'libs', include: ['*.aar']) implementation fileTree(dir: 'libs', include: ['*.aar'])
compileOnly fileTree(dir: 'libs', include: ['*.jar']) compileOnly fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.google.guava:guava:23.3-android'
} }
task generateBuildTasks() { task generateBuildTasks() {
android.applicationVariants.all { variant -> android.applicationVariants.all { variant ->
variant.outputs.each { output -> variant.outputs.each { output ->
def buildType = output.name.toString().capitalize() def buildType = output.name.toString().capitalize()
def lowerBuildType = buildType.toLowerCase() if(buildType=="Base")return
task "exportDex$buildType"() { task "exportDex$buildType"() {
dependsOn('assemble' + buildType) dependsOn('assemble' + buildType)
doLast { doLast {
try { try {
var z = "" def suffix=buildType.toLowerCase()
if (lowerBuildType != "debug") { String apkPath=projectDir.getAbsolutePath()+"/build/outputs/apk/$suffix/app-$suffix"
z = "-unsigned" def apk=new File(apkPath+"-unsigned.apk")
} if(!apk.exists())apk=new File(apkPath+".apk")
def zip=new ZipFile(apk)
File moduleDir = projectDir def entries=zip.entries()
ZipInputStream inputStream = new ZipInputStream(new FileInputStream(moduleDir.getAbsolutePath() + "/build/outputs/apk/$lowerBuildType/app-$lowerBuildType${z}.apk")) def dexCounter=dexes
ZipFile file = new ZipFile(moduleDir.getAbsolutePath() + "/build/outputs/apk/$lowerBuildType/app-$lowerBuildType${z}.apk"); while(entries.hasMoreElements())
ZipEntry entry {
while ((entry = inputStream.nextEntry) != null) { def entry=entries.nextElement()
if (entry.getName().equals("classes.dex")) { String filename
print('classes.dex found!') if(entry.name.matches("^classes(?:(?=\\d)2|)\\.dex\$"))filename="classes${++dexCounter}.dex"
else if(entry.name=="assets/version.properties")filename="version.properties"
FileOutputStream outputStream = new FileOutputStream(new File(moduleDir.getAbsoluteFile(), "classes6.dex")) else continue
println("Exporting "+entry.name)
byte[] buffer = new byte[1024] def tmpFile=new File(projectDir,filename)
int len = 0 def is=zip.getInputStream(entry)
while ((len = inputStream.read(buffer)) > 0) { def fos=new FileOutputStream(tmpFile)
outputStream.write(buffer, 0, len) def buff=new byte[0x800]
} int len
outputStream.close() while((len=is.read(buff))>0)fos.write(buff,0,len)
} is.close()
if (entry.getName().equals("classes2.dex")) { fos.close()
print('\nclasses2.dex found!')
FileOutputStream outputStream = new FileOutputStream(new File(moduleDir.getAbsoluteFile(), "classes7.dex"))
byte[] buffer = new byte[1024]
int len = 0
while ((len = inputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, len)
}
outputStream.close()
}
}
for (ZipEntry e : Collections.list(file.entries())) {
if (e.getName().endsWith("assets/version.properties")) {
var is = file.getInputStream(e)
FileOutputStream outputStream = new FileOutputStream(new File(moduleDir.getAbsoluteFile(), "version.properties"))
byte[] buffer = new byte[1024]
int len = 0
while ((len = is.read(buffer)) > 0) {
outputStream.write(buffer, 0, len)
}
outputStream.close()
print('\nversion.properties found!')
}
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace() e.printStackTrace()
@@ -155,17 +136,16 @@ task generateBuildTasks() {
task "prepareDexForMerge$buildType"(type: Copy) { task "prepareDexForMerge$buildType"(type: Copy) {
dependsOn('exportDex' + buildType) dependsOn('exportDex' + buildType)
// Remove comment for native lib build // Remove comment for native lib build
dependsOn('cargoBuild') //dependsOn('cargoBuild')
into smaliFolder.toString() into smaliFolder.toString()
from(projectDir) { from(projectDir) {
include 'classes6.dex' into '../smali'
include 'classes7.dex' include "classes*.dex"
} }
from(projectDir) { from(projectDir) {
include 'version.properties' include 'version.properties'
into 'assets' into 'assets'
} }
// Remove comment for native lib build
from('../native-effects/target/aarch64-linux-android/release'){ from('../native-effects/target/aarch64-linux-android/release'){
include 'libnative_effects.so' include 'libnative_effects.so'
into 'lib/arm64-v8a' into 'lib/arm64-v8a'
@@ -174,15 +154,16 @@ task generateBuildTasks() {
include 'libnative_effects.so' include 'libnative_effects.so'
into 'lib/armeabi-v7a' into 'lib/armeabi-v7a'
} }
doLast { }
new File(projectDir, "classes6.dex").delete() task "cleanTemporaryFiles$buildType"(type:Delete)
new File(projectDir, "classes7.dex").delete() {
new File(projectDir, "version.properties").delete() delete fileTree(dir:projectDir,include:["*.dex","version.properties"])
} delete fileTree(dir:smaliFolder,include:['*.dex',"assets/version.properties"])
} }
task "buildVTL$buildType"(type: Exec) { task "buildVTL$buildType"(type: Exec) {
dependsOn('prepareDexForMerge' + buildType) dependsOn('prepareDexForMerge' + buildType)
workingDir(projectDir.parentFile) workingDir(projectDir.parentFile)
finalizedBy "cleanTemporaryFiles$buildType"
if (Os.isFamily("unix") || Os.isFamily("mac")) { if (Os.isFamily("unix") || Os.isFamily("mac")) {
commandLine 'bash', '-c', './scripts/build.sh' commandLine 'bash', '-c', './scripts/build.sh'
} else { } else {
@@ -210,7 +191,6 @@ task generateBuildTasks() {
} }
} }
task generateRjava(type: Exec) { task generateRjava(type: Exec) {
workingDir(projectDir.parentFile) workingDir(projectDir.parentFile)
if (Os.isFamily("unix") || Os.isFamily("mac")) if (Os.isFamily("unix") || Os.isFamily("mac"))
@@ -130,9 +130,9 @@ public class BinaryResourceValue implements SerializableResource {
*/ */
public static final int SIZE = 8; public static final int SIZE = 8;
private final int size; public int size;
private final Type type; public Type type;
private final int data; public int data;
public static BinaryResourceValue create(ByteBuffer buffer) { public static BinaryResourceValue create(ByteBuffer buffer) {
int size = (buffer.getShort() & 0xFFFF); int size = (buffer.getShort() & 0xFFFF);
@@ -19661,6 +19661,9 @@ public final class R {
public static final int cache_size = 0x7f12188d; // 2131892365 public static final int cache_size = 0x7f12188d; // 2131892365
public static final int cache_size_summ = 0x7f12188e; // 2131892366 public static final int cache_size_summ = 0x7f12188e; // 2131892366
public static final int clear_all_cache = 0x7f12188f; // 2131892367 public static final int clear_all_cache = 0x7f12188f; // 2131892367
public static final int invalidate_theme_cache_each_update_title = 0x7f121890; // 2131892368
public static final int invertFilters = 0x7f121891; // 2131892369
public static final int invertFilters_summ = 0x7f121892; // 2131892370
} }
public static final class style { public static final class style {
@@ -22,7 +22,7 @@ public class GcmHook {
private static final String agent = String.format("Android-GCM/1.5 (%s %s)", Build.MODEL, Build.MODEL); private static final String agent = String.format("Android-GCM/1.5 (%s %s)", Build.MODEL, Build.MODEL);
private static KeyPair pair; private static KeyPair pair;
private static int rid = 0; private static int rid = 0;
static { static {
genNewKey(); genNewKey();
} }
@@ -46,7 +46,10 @@ public class MainActivityInjector {
NotificationChannels.createChannels(); NotificationChannels.createChannels();
} }
if (Preferences.isNewBuild() && !ThemesUtils.isMonetTheme() && ThemesManager.canApplyCustomAccent() && ThemesUtils.useNewColorEngine()) { if (Preferences.isNewBuild()
&&!ThemesUtils.isMonetTheme()
&&ThemesManager.canApplyCustomAccent())
{
Preferences.updateBuildNumber(); Preferences.updateBuildNumber();
updateBinsAndTmpArchive(activity); updateBinsAndTmpArchive(activity);
} }
@@ -6,7 +6,9 @@ import androidx.recyclerview.widget.RecyclerView;
import com.vk.core.preference.Preference; import com.vk.core.preference.Preference;
import com.vk.discover.DiscoverItemDecorator; import com.vk.discover.DiscoverItemDecorator;
import java.util.*; import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import static java.lang.Long.MAX_VALUE; import static java.lang.Long.MAX_VALUE;
import static ru.vtosters.hooks.other.Preferences.*; import static ru.vtosters.hooks.other.Preferences.*;
@@ -1,9 +1,7 @@
package ru.vtosters.hooks; package ru.vtosters.hooks;
import androidx.core.util.Pair;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import ru.vtosters.lite.utils.RenameTool;
public class RenameHook { public class RenameHook {
public static void injectIntoJson(JSONObject obj) throws JSONException { public static void injectIntoJson(JSONObject obj) throws JSONException {
@@ -292,12 +292,16 @@ public class Preferences {
} }
public static boolean isNewBuild() { public static boolean isNewBuild() {
try { if(Preferences.getBoolValue("invalidate_theme_cache_each_update",true))
return getPreferences().getLong("setupTime", 0L) != AndroidUtils.getGlobalContext().getPackageManager().getPackageInfo(AndroidUtils.getPackageName(), 0).lastUpdateTime; try {
} catch (PackageManager.NameNotFoundException e) { return AndroidUtils.getGlobalContext()
e.printStackTrace(); .getPackageManager()
return false; .getPackageInfo(AndroidUtils.getPackageName(), 0)
} .lastUpdateTime != getPreferences().getLong("setupTime", 0L);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
return false;
} }
public static void updateBuildNumber() { public static void updateBuildNumber() {
@@ -16,12 +16,10 @@ import android.webkit.WebView;
import android.widget.EditText; import android.widget.EditText;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import androidx.core.graphics.ColorUtils; import androidx.core.graphics.ColorUtils;
import com.vk.articles.preload.WebCachePreloader; import com.vk.articles.preload.WebCachePreloader;
import com.vk.core.drawable.RecoloredDrawable; import com.vk.core.drawable.RecoloredDrawable;
import com.vk.core.preference.Preference;
import com.vk.core.ui.themes.MilkshakeHelper; import com.vk.core.ui.themes.MilkshakeHelper;
import com.vk.core.ui.themes.VKTheme; import com.vk.core.ui.themes.VKTheme;
import com.vk.core.ui.themes.VKThemeHelper; import com.vk.core.ui.themes.VKThemeHelper;
@@ -30,6 +28,7 @@ import com.vtosters.lite.data.ThemeTracker;
import ru.vtosters.lite.deviceinfo.OEMDetector; import ru.vtosters.lite.deviceinfo.OEMDetector;
import ru.vtosters.lite.themes.ThemesCore; import ru.vtosters.lite.themes.ThemesCore;
import ru.vtosters.lite.themes.ThemesHacks; import ru.vtosters.lite.themes.ThemesHacks;
import ru.vtosters.lite.themes.ThemesManager;
import ru.vtosters.lite.ui.wallpapers.WallpapersHooks; import ru.vtosters.lite.ui.wallpapers.WallpapersHooks;
import ru.vtosters.lite.utils.LifecycleUtils; import ru.vtosters.lite.utils.LifecycleUtils;
import ru.vtosters.lite.utils.WebViewColoringUtils; import ru.vtosters.lite.utils.WebViewColoringUtils;
@@ -48,10 +47,6 @@ public class ThemesUtils {
} }
} // Apply VKTheme and ImTheme (hard applying without dynamic theme changing) } // Apply VKTheme and ImTheme (hard applying without dynamic theme changing)
public static boolean isCustomAccentEnabled() {
return ThemesUtils.isMonetTheme() || !useNewColorEngine();
}
public static ColorStateList getAccenedColorStateList() { public static ColorStateList getAccenedColorStateList() {
return ColorStateList.valueOf(getAccentColor()); return ColorStateList.valueOf(getAccentColor());
} }
@@ -65,7 +60,7 @@ public class ThemesUtils {
activity = LifecycleUtils.getCurrentActivity(); activity = LifecycleUtils.getCurrentActivity();
} }
VKThemeHelper.theme(theme, activity, fl); VKThemeHelper.theme(theme, activity, fl);
if (isMonetTheme()) ThemesCore.clear(); if (isMonetTheme() || ThemesManager.canApplyCustomAccent()) ThemesCore.clear();
if (restartActivity) activity.recreate(); if (restartActivity) activity.recreate();
ThemeTracker.a(); ThemeTracker.a();
WebViewColoringUtils.isLoaded = false; WebViewColoringUtils.isLoaded = false;
@@ -85,13 +80,8 @@ public class ThemesUtils {
return getBoolValue("amoledtheme", false); return getBoolValue("amoledtheme", false);
} }
public static boolean useNewColorEngine() {
return getBoolValue("useNewColorEngine", false);
}
public static int getAccentColor() { public static int getAccentColor() {
var color = Preferences.getPreferences().getInt("accent_color", getColorFromAttr(R.attr.accent)); return getColorFromAttr(R.attr.accent);
return color == 0 || useNewColorEngine() || isMonetTheme() ? getColorFromAttr(R.attr.accent) : color;
} // Color accent } // Color accent
//region Used for migrating accent color to new version //region Used for migrating accent color to new version
@@ -309,7 +299,7 @@ public class ThemesUtils {
} // Recolor drawable to accent color } // Recolor drawable to accent color
public static Drawable recolorToolbarDrawable(Drawable drawable) { public static Drawable recolorToolbarDrawable(Drawable drawable) {
if (!ThemesUtils.isCustomAccentEnabled()) return drawable; if (!ThemesUtils.isMonetTheme()) return drawable;
if (drawable == null) return null; if (drawable == null) return null;
return new RecoloredDrawable(drawable, (ThemesUtils.isMilkshake() && !ThemesUtils.isDarkTheme()) ? ThemesUtils.getAccentColor() : ThemesUtils.getHeaderText()); return new RecoloredDrawable(drawable, (ThemesUtils.isMilkshake() && !ThemesUtils.isDarkTheme()) ? ThemesUtils.getAccentColor() : ThemesUtils.getHeaderText());
} }
@@ -1,7 +1,6 @@
package ru.vtosters.hooks.ssfs; package ru.vtosters.hooks.ssfs;
import com.vk.core.dialogs.alert.VkAlertDialog; import com.vk.core.dialogs.alert.VkAlertDialog;
import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import ru.vtosters.hooks.other.Preferences; import ru.vtosters.hooks.other.Preferences;
import ru.vtosters.lite.ssfs.ImBanner; import ru.vtosters.lite.ssfs.ImBanner;
@@ -4,8 +4,8 @@ import android.text.TextUtils;
public class TransportStream { public class TransportStream {
private String mKeyUri;
private final String mMediaSegmentUri; private final String mMediaSegmentUri;
private String mKeyUri;
private String mMediaSegmentName; private String mMediaSegmentName;
public TransportStream(String baseURI, String mediaSegmentName) { public TransportStream(String baseURI, String mediaSegmentName) {
@@ -15,10 +15,9 @@ public class VKM3UParser {
//Playlist types //Playlist types
static public int PLAYLIST_TYPE_VOD = 0; static public int PLAYLIST_TYPE_VOD = 0;
static public int PLAYLIST_TYPE_EVENT = 1; static public int PLAYLIST_TYPE_EVENT = 1;
private final String mData;
//region Extended M3U global extensions //region Extended M3U global extensions
public List<TransportStream> mTransportStreams = new ArrayList<>(); public List<TransportStream> mTransportStreams = new ArrayList<>();
private final String mData;
/** /**
* @see <a href="https://datatracker.ietf.org/doc/html/rfc8216#section-4.3.1.2">EXT-X-VERSION</a> * @see <a href="https://datatracker.ietf.org/doc/html/rfc8216#section-4.3.1.2">EXT-X-VERSION</a>
**/ **/
@@ -19,8 +19,8 @@ import ru.vtosters.lite.utils.AndroidUtils;
import java.io.IOException; import java.io.IOException;
import static ru.vtosters.hooks.DateHook.getLocale; import static ru.vtosters.hooks.DateHook.getLocale;
import static ru.vtosters.hooks.other.Preferences.getBoolValue;
import static ru.vtosters.hooks.GroupsCatalogInjector.injectIntoCatalog; import static ru.vtosters.hooks.GroupsCatalogInjector.injectIntoCatalog;
import static ru.vtosters.hooks.other.Preferences.getBoolValue;
import static ru.vtosters.lite.music.cache.helpers.PlaylistHelper.*; import static ru.vtosters.lite.music.cache.helpers.PlaylistHelper.*;
import static ru.vtosters.lite.proxy.ProxyUtils.getApi; import static ru.vtosters.lite.proxy.ProxyUtils.getApi;
import static ru.vtosters.lite.utils.AccountManagerUtils.getUserId; import static ru.vtosters.lite.utils.AccountManagerUtils.getUserId;
@@ -11,15 +11,15 @@ public class ImBanner {
private static final String TAG = "ImBanner"; private static final String TAG = "ImBanner";
public static JSONObject convertToBanner(JSONObject original) { public static JSONObject convertToBanner(JSONObject original) {
final String PEER = "peer"; String PEER = "peer";
final String ID = "id"; String ID = "id";
final String PICTURE = "picture"; String PICTURE = "picture";
final String TEXT = "text"; String TEXT = "text";
final String LINK = "link"; String LINK = "link";
final String LINK_TEXT = "link_text"; String LINK_TEXT = "link_text";
final String NAME = "name"; String NAME = "name";
final String BUTTONS = "buttons"; String BUTTONS = "buttons";
final String ICON = "icon"; String ICON = "icon";
Optional<JSONObject> user = Optional.ofNullable(original.optJSONObject(PEER)); Optional<JSONObject> user = Optional.ofNullable(original.optJSONObject(PEER));
int userId = user.map(u -> u.optInt(ID)).orElse(0); int userId = user.map(u -> u.optInt(ID)).orElse(0);
@@ -166,26 +166,25 @@ public class ThemesCore {
} }
public static boolean hasThemedAttr(Context context, int attrID) { public static boolean hasThemedAttr(Context context, int attrID) {
if (ThemesUtils.isCustomAccentEnabled()) { if (Preferences.getBoolValue("logColors", false)) {
if (Preferences.getBoolValue("logColors", false)) { try {
try { Log.d(TAG, "Requesting color by attr " + context.getResources().getResourceName(attrID));
Log.d(TAG, "Requesting color by attr " + context.getResources().getResourceName(attrID)); } catch (Exception ignored) {
} catch (Exception ignored) {
}
} }
}
if (ThemesUtils.isMonetTheme() || ThemesManager.canApplyCustomAccent()) {
if (isCachedAccents()) { if (isCachedAccents()) {
if (ThemesUtils.isDarkTheme()) { boolean isDark = ThemesUtils.isDarkTheme();
return (themedColors.get(attrID) != 0 && ACCENT_THEME_ONLY_DARK.get(attrID, true) && ( boolean isMilkshake = ThemesUtils.isMilkshake();
ThemesUtils.isMilkshake() ? SparseBooleanArray themeOnlyMap = isDark ? ACCENT_THEME_ONLY_DARK : ACCENT_THEME_ONLY_LIGHT;
ACCENT_THEME_ONLY_MILK_DARK.get(attrID, true) : SparseBooleanArray milkshakeMap = isDark ? ACCENT_THEME_ONLY_MILK_DARK : ACCENT_THEME_ONLY_MILK_LIGHT;
ACCENT_THEME_ONLY_NOMILK_DARK.get(attrID, true))); SparseBooleanArray noMilkshakeMap = isDark ? ACCENT_THEME_ONLY_NOMILK_DARK : ACCENT_THEME_ONLY_NOMILK_LIGHT;
} else {
return (themedColors.get(attrID) != 0 && ACCENT_THEME_ONLY_LIGHT.get(attrID, true) && ( return (themedColors.get(attrID) != 0 && themeOnlyMap.get(attrID, true) && (
ThemesUtils.isMilkshake() ? isMilkshake ?
ACCENT_THEME_ONLY_MILK_LIGHT.get(attrID, true) : milkshakeMap.get(attrID, true) :
ACCENT_THEME_ONLY_NOMILK_LIGHT.get(attrID, true))); noMilkshakeMap.get(attrID, true)));
}
} else { } else {
return themedColors.get(attrID) != 0; return themedColors.get(attrID) != 0;
} }
@@ -194,7 +193,6 @@ public class ThemesCore {
} }
} }
public static void clear() { public static void clear() {
cachedAccents = false; cachedAccents = false;
themedColors.clear(); themedColors.clear();
@@ -23,7 +23,7 @@ public class ThemesHacks {
} }
public static int getHackedColor(@NonNull Context context, @ColorRes int color) { public static int getHackedColor(@NonNull Context context, @ColorRes int color) {
if (ThemesUtils.isCustomAccentEnabled()) { if (ThemesUtils.isMonetTheme()) {
if (Preferences.getBoolValue("logColors", false)) { if (Preferences.getBoolValue("logColors", false)) {
try { try {
Log.d("ThemesCore", "Requesting color by color " + context.getResources().getResourceName(color)); Log.d("ThemesCore", "Requesting color by color " + context.getResources().getResourceName(color));
@@ -20,7 +20,7 @@ import java.util.zip.ZipOutputStream;
public class ThemesManager { public class ThemesManager {
private final static int[] ACCENT_COLORS = { private static final int[] ACCENT_COLORS = {
R.color.vk_sky_300, R.color.vk_sky_300,
R.color.sky_300, R.color.sky_300,
R.color.viewer_retry_button_text_color, R.color.viewer_retry_button_text_color,
@@ -96,7 +96,7 @@ public class ThemesManager {
R.color.header_blue_opacity40 R.color.header_blue_opacity40
}; };
// modify it if "doNotCompress" in apktool.yml has been edited // modify it if "doNotCompress" in apktool.yml has been edited
private final static String[] DO_NOT_COMPRESS = { private static final String[] DO_NOT_COMPRESS = {
".png", ".png",
".jpg", ".jpg",
".mp3", ".mp3",
@@ -119,19 +119,18 @@ public class ThemesManager {
initPaths(app); initPaths(app);
validateModApk(); validateModApk();
if (!Preferences.isNewBuild() && !ThemesUtils.isMonetTheme() && canApplyCustomAccent() && ThemesUtils.useNewColorEngine()) { if (!Preferences.isNewBuild() && !ThemesUtils.isMonetTheme() && canApplyCustomAccent()) {
ResourcesLoader.init(app); ResourcesLoader.init(app);
ResourcesLoader.load(app, modApk.getAbsolutePath(), false); ResourcesLoader.load(app, modApk.getAbsolutePath(), false);
} }
} catch (Exception e) { } catch (Exception e) {
Log.e("ThemesManager", e.getMessage()); e.printStackTrace();
} }
} }
// validate modded apk before loading // validate modded apk before loading
private static void validateModApk() private static void validateModApk() throws IOException {
throws IOException { var apk = new ZipFile(modApk);
final var apk = new ZipFile(modApk);
apk.close(); apk.close();
validated = true; validated = true;
@@ -153,24 +152,18 @@ public class ThemesManager {
return validated && modApk.exists() && ThemesUtils.getReservedAccent() != Color.TRANSPARENT; return validated && modApk.exists() && ThemesUtils.getReservedAccent() != Color.TRANSPARENT;
} }
public static void generateModApk(int accentColor) public static void generateModApk(int accentColor) throws Throwable {
throws Throwable { try (var apk = new ZipFile(baseApkPath)) {
try ( var arscEntry = apk.getEntry("resources.arsc");
final var apk = new ZipFile(baseApkPath) var arscBis = new BufferedInputStream(apk.getInputStream(arscEntry));
) { var arsc = BinaryResourceFile.fromInputStream(arscBis);
final var arscEntry = apk.getEntry("resources.arsc"); ArscEditor.changeColors(arsc, ACCENT_COLORS, accentColor);
final var arscBis = new BufferedInputStream(apk.getInputStream(arscEntry));
final var arsc = BinaryResourceFile.fromInputStream(arscBis);
if (!ArscEditor.changeColors(arsc, ACCENT_COLORS, accentColor))
throw new IllegalStateException("Not all colors have been changed");
try ( try (var zos = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(modApk)))) {
final var zos = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(modApk))) var arscBuff = arsc.toByteArray();
) { var newArscEntry = new ZipEntry("resources.arsc");
final var arscBuff = arsc.toByteArray();
final var newArscEntry = new ZipEntry("resources.arsc");
final var crc = new CRC32(); var crc = new CRC32();
crc.update(arscBuff); crc.update(arscBuff);
newArscEntry.setSize(arscBuff.length); newArscEntry.setSize(arscBuff.length);
@@ -181,10 +174,10 @@ public class ThemesManager {
zos.write(arscBuff); zos.write(arscBuff);
zos.closeEntry(); zos.closeEntry();
final var entries = apk.entries(); var entries = apk.entries();
while (entries.hasMoreElements()) { while (entries.hasMoreElements()) {
final var entry = entries.nextElement(); var entry = entries.nextElement();
final var name = entry.getName(); var name = entry.getName();
if (!name.startsWith("res/") && !name.startsWith("assets/") || name.equals("resources.arsc")) if (!name.startsWith("res/") && !name.startsWith("assets/") || name.equals("resources.arsc"))
continue; continue;
@@ -197,8 +190,8 @@ public class ThemesManager {
} }
} }
final var entryBis = new BufferedInputStream(apk.getInputStream(entry)); var entryBis = new BufferedInputStream(apk.getInputStream(entry));
final var newEntry = new ZipEntry(name); var newEntry = new ZipEntry(name);
if (doNotCompress) { if (doNotCompress) {
newEntry.setMethod(ZipEntry.STORED); newEntry.setMethod(ZipEntry.STORED);
@@ -21,7 +21,7 @@ public class ViewInjector {
} }
public static View inject(View view, int i, boolean z) { public static View inject(View view, int i, boolean z) {
if (ThemesUtils.isCustomAccentEnabled()) { if (ThemesUtils.isMonetTheme()) {
for (BaseHook hook : hooks) { for (BaseHook hook : hooks) {
hook.inject(view, i, z); hook.inject(view, i, z);
} }
@@ -1,59 +1,44 @@
package ru.vtosters.lite.themes.loaders; package ru.vtosters.lite.themes.loaders;
import android.annotation.SuppressLint;
import android.content.res.AssetManager; import android.content.res.AssetManager;
import android.util.Log;
import ru.vtosters.lite.utils.ReflectionUtils; import ru.vtosters.lite.utils.ReflectionUtils;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
@SuppressLint("PrivateApi")
public class AssetManagerHelper { public class AssetManagerHelper {
public static String getApkPath(Object assetManager, String packagename) throws InvocationTargetException, IllegalAccessException, ClassNotFoundException, NoSuchMethodException {
Object[] apkAssetsArr = (Object[]) ReflectionUtils.findMethod(Class.forName("android.content.res.ApkAssets"), "getAssetPath").invoke(assetManager);
// methods
private final static Method getAssetPathMtd;
private final static Method getApkAssetsMtd;
private final static Method addAssetPathMtd;
private final static Method addAssetPathAsSharedLibraryMtd;
private final static Method addOverlayPathMtd;
static {
try {
getAssetPathMtd = ReflectionUtils.findMethod(Class.forName("android.content.res.ApkAssets"), "getAssetPath");
getApkAssetsMtd = ReflectionUtils.findMethod(AssetManager.class, "getApkAssets");
addAssetPathMtd = AssetManager.class.getMethod("addAssetPath", String.class);
addAssetPathAsSharedLibraryMtd = AssetManager.class.getMethod("addAssetPathAsSharedLibrary", String.class);
addOverlayPathMtd = AssetManager.class.getMethod("addOverlayPath", String.class);
} catch (ClassNotFoundException | NoSuchMethodException e) {
throw new RuntimeException();
}
}
public static String getApkPath(Object assetManager, String packagename)
throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Object[] apkAssetsArr = (Object[]) getAssetPathMtd.invoke(assetManager);
// By default, base apk is the last element of array if is not, for execution speed, we should iterate array from the end to the beginning // By default, base apk is the last element of array if is not, for execution speed, we should iterate array from the end to the beginning
for (int i = apkAssetsArr.length - 1; i >= 0; i--) { for (int i = apkAssetsArr.length - 1; i >= 0; i--) {
final String pathname = (String) getApkAssetsMtd.invoke(apkAssetsArr[i]); String pathname = (String) ReflectionUtils.findMethod(AssetManager.class, "getApkAssets").invoke(apkAssetsArr[i]);
if (pathname.contains(packagename)) return pathname; if (pathname != null && pathname.contains(packagename)) return pathname;
} }
throw new NullPointerException(); throw new NullPointerException();
} }
//region Uses for adding own assets or getting existing cookies //region Uses for adding own assets or getting existing cookies
public static int addAssetPath(AssetManager manager, String path) public static void addAssetPath(AssetManager manager, String path) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { manager.getClass().getMethod("addAssetPath", String.class).invoke(manager, path);
return (int) addAssetPathMtd.invoke(manager, path);
} }
public static int addAssetPathAsSharedLibrary(AssetManager manager, String path) public static int addAssetPathAsSharedLibrary(AssetManager manager, String path) {
throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { try {
return (int) addAssetPathAsSharedLibraryMtd.invoke(manager, path); return (int) AssetManager.class.getMethod("addAssetPathAsSharedLibrary", String.class).invoke(manager, path);
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
throw new RuntimeException(e);
}
} }
public static int addOverlayPath(AssetManager manager, String path) public static int addOverlayPath(AssetManager manager, String path) {
throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { try {
return (int) addOverlayPathMtd.invoke(manager, path); return (int) AssetManager.class.getMethod("addOverlayPath", String.class).invoke(manager, path);
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
throw new RuntimeException(e);
}
} }
//endregion
} }
@@ -1,5 +1,6 @@
package ru.vtosters.lite.themes.loaders; package ru.vtosters.lite.themes.loaders;
import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.content.pm.ApplicationInfo; import android.content.pm.ApplicationInfo;
import android.content.res.AssetManager; import android.content.res.AssetManager;
@@ -13,17 +14,19 @@ import ru.vtosters.lite.utils.ReflectionUtils;
import java.io.File; import java.io.File;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.lang.reflect.Array;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@SuppressLint("PrivateApi")
public class ResourcesLoader { public class ResourcesLoader {
private static Collection<WeakReference<Resources>> sResourceReferences = null; private static Collection<WeakReference<Resources>> sResourceReferences = null;
private static Object sCurrentActivityThread = null; private static Object sCurrentActivityThread = null;
private static AssetManager sAssetManager = null;
// methods // methods
private static Method ensureStringBlocksMtd = null; private static Method ensureStringBlocksMtd = null;
@@ -42,7 +45,7 @@ public class ResourcesLoader {
static { static {
try { try {
// API version 8 has PackageInfo, 10 has LoadedApk. Needs to check 9 // API version 8 has PackageInfo, 10 has LoadedApk. Needs to check 9
final Class<?> activityThreadClz = Class.forName("android.app.ActivityThread"); Class<?> activityThreadClz = Class.forName("android.app.ActivityThread");
Class<?> loadedApkClz; Class<?> loadedApkClz;
try { try {
loadedApkClz = Class.forName("android.app.LoadedApk"); loadedApkClz = Class.forName("android.app.LoadedApk");
@@ -87,43 +90,40 @@ public class ResourcesLoader {
} }
} }
public static void init(Context context) public static void init(Context context) throws Exception {
throws Exception {
sCurrentActivityThread = ReflectionUtils.getActivityThread(context, null); sCurrentActivityThread = ReflectionUtils.getActivityThread(context, null);
//pre-N //pre-N
// Find the singleton instance of ResourcesManager // Find the singleton instance of ResourcesManager
final Class<?> resourcesManagerClass = Class.forName("android.app.ResourcesManager"); Class<?> resourcesManagerClass = Class.forName("android.app.ResourcesManager");
final Method mGetInstance = ReflectionUtils.findMethod(resourcesManagerClass, "getInstance"); Method mGetInstance = ReflectionUtils.findMethod(resourcesManagerClass, "getInstance");
final Object resourcesManager = mGetInstance.invoke(null); Object resourcesManager = mGetInstance.invoke(null);
try { try {
Field fMActiveResources = ReflectionUtils.findField(resourcesManagerClass, "mActiveResources"); Field fMActiveResources = ReflectionUtils.findField(resourcesManagerClass, "mActiveResources");
final ArrayMap<?, WeakReference<Resources>> activeResources19 = ArrayMap<?, WeakReference<Resources>> activeResources19 =
(ArrayMap<?, WeakReference<Resources>>) fMActiveResources.get(resourcesManager); (ArrayMap<?, WeakReference<Resources>>) fMActiveResources.get(resourcesManager);
sResourceReferences = activeResources19.values(); sResourceReferences = activeResources19.values();
} catch (NoSuchFieldException ignore) { } catch (NoSuchFieldException ignore) {
// N moved the resources to mResourceReferences // N moved the resources to mResourceReferences
final Field mResourceReferences = ReflectionUtils.findField(resourcesManagerClass, "mResourceReferences"); Field mResourceReferences = ReflectionUtils.findField(resourcesManagerClass, "mResourceReferences");
sResourceReferences = (Collection<WeakReference<Resources>>) mResourceReferences.get(resourcesManager); sResourceReferences = (Collection<WeakReference<Resources>>) mResourceReferences.get(resourcesManager);
} }
} }
public static void load(Context context, String resPath, boolean reinject) public static void load(Context context, String resPath, boolean reinject) throws IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchFieldException, NoSuchMethodException {
throws Exception { ApplicationInfo appInfo = context.getApplicationInfo();
final ApplicationInfo appInfo = context.getApplicationInfo();
final Field[] packagesFlds = Build.VERSION.SDK_INT < Build.VERSION_CODES.O_MR1 Field[] packagesFlds = Build.VERSION.SDK_INT < Build.VERSION_CODES.O_MR1
? new Field[]{packagesFld, resourcePackagesFld} ? new Field[]{packagesFld, resourcePackagesFld}
: new Field[]{packagesFld}; : new Field[]{packagesFld};
for (var fld : packagesFlds) { for (var fld : packagesFlds) {
final var value = fld.get(sCurrentActivityThread); var value = fld.get(sCurrentActivityThread);
for (var entry for (var entry : ((Map<String, WeakReference<?>>) value).entrySet()) {
: ((Map<String, WeakReference<?>>) value).entrySet()) { var loadedApk = entry.getValue().get();
final var loadedApk = entry.getValue().get();
if (loadedApk == null) continue; if (loadedApk == null) continue;
final var resDirPath = (String) resDirFld.get(loadedApk); var resDirPath = (String) resDirFld.get(loadedApk);
if (appInfo.sourceDir.equals(resDirPath)) if (appInfo.sourceDir.equals(resDirPath))
resDirFld.set(loadedApk, resPath); resDirFld.set(loadedApk, resPath);
} }
@@ -134,10 +134,10 @@ public class ResourcesLoader {
return; return;
} }
sAssetManager = AssetManager.class.newInstance();
// Create a new AssetManager instance and point it to the resources installed under // Create a new AssetManager instance and point it to the resources installed under
if (AssetManagerHelper.addAssetPath(sAssetManager, resPath) == 0) AssetManager sAssetManager = AssetManager.class.newInstance();
throw new IllegalStateException("Could not create new AssetManager");
AssetManagerHelper.addAssetPath(sAssetManager, resPath);
// Add SharedLibraries to AssetManager for resolve system resources not found issue // Add SharedLibraries to AssetManager for resolve system resources not found issue
// This influence SharedLibrary Package ID // This influence SharedLibrary Package ID
@@ -157,7 +157,7 @@ public class ResourcesLoader {
ensureStringBlocksMtd.invoke(sAssetManager); ensureStringBlocksMtd.invoke(sAssetManager);
} }
for (var wr : sResourceReferences) { for (var wr : sResourceReferences) {
final var resources = wr.get(); var resources = wr.get();
if (resources == null) continue; if (resources == null) continue;
// Set the AssetManager of the Resources instance to our brand new one // Set the AssetManager of the Resources instance to our brand new one
@@ -166,9 +166,9 @@ public class ResourcesLoader {
assetsFld.set(resources, sAssetManager); assetsFld.set(resources, sAssetManager);
} catch (Throwable ignore) { } catch (Throwable ignore) {
// N // N
final var resourceImpl = resourcesImplFld.get(resources); var resourceImpl = resourcesImplFld.get(resources);
// for Huawei HwResourcesImpl // for Huawei HwResourcesImpl
final Field implAssets = ReflectionUtils.findField(resourceImpl, "mAssets"); Field implAssets = ReflectionUtils.findField(resourceImpl, "mAssets");
implAssets.set(resourceImpl, sAssetManager); implAssets.set(resourceImpl, sAssetManager);
} }
@@ -196,13 +196,13 @@ public class ResourcesLoader {
private static void installResourceInsuranceHacks(Context context, String patchedResApkPath) { private static void installResourceInsuranceHacks(Context context, String patchedResApkPath) {
try { try {
final Object activityThread = ReflectionUtils.getActivityThread(context, null); Object activityThread = ReflectionUtils.getActivityThread(context, null);
final Field mHField = ReflectionUtils.findField(activityThread, "mH"); Field mHField = ReflectionUtils.findField(activityThread, "mH");
final Handler mH = (Handler) mHField.get(activityThread); Handler mH = (Handler) mHField.get(activityThread);
final Field mCallbackField = ReflectionUtils.findField(Handler.class, "mCallback"); Field mCallbackField = ReflectionUtils.findField(Handler.class, "mCallback");
final Handler.Callback originCallback = (Handler.Callback) mCallbackField.get(mH); Handler.Callback originCallback = (Handler.Callback) mCallbackField.get(mH);
if (!(originCallback instanceof ResourceInsuranceHandlerCallback)) { if (!(originCallback instanceof ResourceInsuranceHandlerCallback)) {
final ResourceInsuranceHandlerCallback hackCallback = new ResourceInsuranceHandlerCallback( ResourceInsuranceHandlerCallback hackCallback = new ResourceInsuranceHandlerCallback(
context, patchedResApkPath, originCallback, mH.getClass()); context, patchedResApkPath, originCallback, mH.getClass());
mCallbackField.set(mH, hackCallback); mCallbackField.set(mH, hackCallback);
} else { } else {
@@ -250,9 +250,9 @@ public class ResourcesLoader {
Log.w("ResourcesLoader", "try to clear typedArray cache!"); Log.w("ResourcesLoader", "try to clear typedArray cache!");
// Clear typedArray cache. // Clear typedArray cache.
try { try {
final Field typedArrayPoolField = ReflectionUtils.findField(Resources.class, "mTypedArrayPool"); Field typedArrayPoolField = ReflectionUtils.findField(Resources.class, "mTypedArrayPool");
final Object origTypedArrayPool = typedArrayPoolField.get(resources); Object origTypedArrayPool = typedArrayPoolField.get(resources);
final Method acquireMethod = ReflectionUtils.findMethod(origTypedArrayPool, "acquire"); Method acquireMethod = ReflectionUtils.findMethod(origTypedArrayPool, "acquire");
while (true) { while (true) {
if (acquireMethod.invoke(origTypedArrayPool) == null) { if (acquireMethod.invoke(origTypedArrayPool) == null) {
break; break;
@@ -268,9 +268,8 @@ public class ResourcesLoader {
applicationInfo.sharedLibraryFiles != null; applicationInfo.sharedLibraryFiles != null;
} }
private static final class ResourceInsuranceHandlerCallback implements Handler.Callback { private static class ResourceInsuranceHandlerCallback implements Handler.Callback {
private static final String LAUNCH_ACTIVITY_LIFECYCLE_ITEM_CLASSNAME = "android.app.servertransaction.LaunchActivityItem"; private static final String LAUNCH_ACTIVITY_LIFECYCLE_ITEM_CLASSNAME = "android.app.servertransaction.LaunchActivityItem";
private final Context mContext; private final Context mContext;
private final String mPatchResApkPath; private final String mPatchResApkPath;
private final Handler.Callback mOriginalCallback; private final Handler.Callback mOriginalCallback;
@@ -319,48 +318,56 @@ public class ResourcesLoader {
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private boolean hackMessage(Message msg) { // A method to check if the message requires re-injecting patched resources
boolean shouldReInjectPatchedResources = false; private boolean shouldReInjectPatchedResources(Message msg) {
if (!isPatchedResModifiedAfterLastLoad(mPatchResApkPath)) { if (!isPatchedResModifiedAfterLastLoad(mPatchResApkPath)) {
shouldReInjectPatchedResources = false; return false;
} else { }
if (msg.what == LAUNCH_ACTIVITY || msg.what == RELAUNCH_ACTIVITY) { if (msg.what == LAUNCH_ACTIVITY || msg.what == RELAUNCH_ACTIVITY) {
shouldReInjectPatchedResources = true; return true;
} else if (msg.what == EXECUTE_TRANSACTION) { }
do { // If the message is executing a transaction, check the callbacks
if (mSkipInterceptExecuteTransaction) { if (msg.what == EXECUTE_TRANSACTION) {
break; // Skip the logic if the method is not found or an error occurs
} if (mSkipInterceptExecuteTransaction) {
final Object transaction = msg.obj; return false;
if (transaction == null) { }
Log.w("ResourcesLoader", "transaction is null, skip rest insurance logic."); // Get the transaction object from the message
break; Object transaction = msg.obj;
} if (transaction == null) {
if (mGetCallbacksMethod == null) { Log.w("ResourcesLoader", "transaction is null, skip rest insurance logic.");
try { return false;
mGetCallbacksMethod = ReflectionUtils.findMethod(transaction, "getCallbacks"); }
} catch (Throwable ignored) { // Get the getCallbacks method from the transaction class
// Ignored. if (mGetCallbacksMethod == null) {
} try {
} mGetCallbacksMethod = ReflectionUtils.findMethod(transaction, "getCallbacks");
if (mGetCallbacksMethod == null) { } catch (Throwable ignored) {
Log.e("ResourcesLoader", "fail to find getLifecycleStateRequest method, skip rest insurance logic."); // Ignored.
mSkipInterceptExecuteTransaction = true; }
break; }
} if (mGetCallbacksMethod == null) {
try { Log.e("ResourcesLoader", "fail to find getCallbacks method, skip rest insurance logic.");
final List<Object> req = (List<Object>) mGetCallbacksMethod.invoke(transaction); mSkipInterceptExecuteTransaction = true;
if (req != null && req.size() > 0) { return false;
final Object cb = req.get(0); }
shouldReInjectPatchedResources = cb != null && cb.getClass().getName().equals(LAUNCH_ACTIVITY_LIFECYCLE_ITEM_CLASSNAME); try {
} List<Object> callbacks = (List<Object>) mGetCallbacksMethod.invoke(transaction);
} catch (Throwable ignored) { if (callbacks != null && !callbacks.isEmpty()) {
Log.e("ResourcesLoader", "fail to call getLifecycleStateRequest method, skip rest insurance logic."); Object cb = callbacks.get(0);
} return cb != null && cb.getClass().getName().equals(LAUNCH_ACTIVITY_LIFECYCLE_ITEM_CLASSNAME);
} while (false); }
} catch (Throwable ignored) {
Log.e("ResourcesLoader", "fail to call getCallbacks method, skip rest insurance logic.");
} }
} }
if (shouldReInjectPatchedResources) { return false;
}
// A method to hack the message and re-inject patched resources if needed
@SuppressWarnings("unchecked")
private boolean hackMessage(Message msg) {
if (shouldReInjectPatchedResources(msg)) {
try { try {
load(mContext, mPatchResApkPath, true); load(mContext, mPatchResApkPath, true);
} catch (Throwable thr) { } catch (Throwable thr) {
@@ -23,8 +23,8 @@ import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext;
public class PalettesManager { public class PalettesManager {
private final static File PALETTES_DIR = new File(Environment.getExternalStorageDirectory(), "VTL/palettes"); private static final File PALETTES_DIR = new File(Environment.getExternalStorageDirectory(), "VTL/palettes");
private final static String ASSETS_DIR = "vtl_themes/palettes/"; private static final String ASSETS_DIR = "vtl_themes/palettes/";
private static PalettesManager sInstance; private static PalettesManager sInstance;
@@ -51,17 +51,17 @@ public class PalettesManager {
return; return;
} }
final var palettes = PALETTES_DIR.listFiles((dir, name) -> name.endsWith(".json")); var palettes = PALETTES_DIR.listFiles((dir, name) -> name.endsWith(".json"));
if (palettes == null || palettes.length == 0) if (palettes == null || palettes.length == 0)
copyPaletteFromAssets(); copyPaletteFromAssets();
parsePalettes(); parsePalettes();
} }
private boolean copyPaletteFromAssets() { private void copyPaletteFromAssets() {
try { try {
final var manager = AndroidUtils.getGlobalContext().getAssets(); var manager = AndroidUtils.getGlobalContext().getAssets();
final var assets = manager.list(ASSETS_DIR); var assets = manager.list(ASSETS_DIR);
if (assets == null || assets.length == 0) return false; if (assets == null || assets.length == 0) return;
for (var asset : assets) { for (var asset : assets) {
try { try {
IOUtils.copy(manager.open(ASSETS_DIR + asset), new File(PALETTES_DIR, asset)); IOUtils.copy(manager.open(ASSETS_DIR + asset), new File(PALETTES_DIR, asset));
@@ -69,11 +69,9 @@ public class PalettesManager {
e.printStackTrace(); e.printStackTrace();
} }
} }
return true;
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
return false;
} }
private void parsePalettes() { private void parsePalettes() {
@@ -1,37 +1,38 @@
package ru.vtosters.lite.themes.utils; package ru.vtosters.lite.themes.utils;
import com.google.devrel.gmscore.tools.apk.arsc.*; import com.google.devrel.gmscore.tools.apk.arsc.BinaryResourceFile;
import com.google.devrel.gmscore.tools.apk.arsc.BinaryResourceValue;
import com.google.devrel.gmscore.tools.apk.arsc.ResourceTableChunk;
public class ArscEditor { public class ArscEditor {
public static boolean changeColors(BinaryResourceFile arsc, int[] colorIds, int color /*int[] colors*/) { public static void changeColors(BinaryResourceFile arsc, int[] colorIds, int color) {
int q = 0;
for (var chunk : arsc.getChunks()) { for (var chunk : arsc.getChunks()) {
final var resourceTableChunk = (ResourceTableChunk) chunk; var resTableChunk = (ResourceTableChunk) chunk;
for (var packageChunk : resTableChunk.getPackages()) {
for (PackageChunk packageChunk : resourceTableChunk.getPackages()) { for (var typeChunk : packageChunk.getTypeChunks("color")) {
for (TypeSpecChunk typeSpecChunk : packageChunk.getTypeSpecChunks()) { for (var entry : typeChunk.getEntries().entrySet()) {
for (TypeChunk typeChunk : packageChunk.getTypeChunks(typeSpecChunk.getId())) { var value = entry.getValue();
if (!"color".equals(typeChunk.getTypeName())) continue; if (value.isComplex()) continue;
var binValue = value.value();
for (var entry : typeChunk.getEntries().entrySet()) { if (!isColorResourceValue(binValue)) continue;
if (entry.getValue().isComplex()) continue; var resId = packageChunk.getId() << 24 | typeChunk.getId() << 16 | entry.getKey();
for (var colodId : colorIds) {
final var id = BinaryResourceIdentifier.create(packageChunk.getId(), typeSpecChunk.getId(), entry.getKey()); if (resId == colodId) {
binValue.data = color;
for (int colorId : colorIds) { break;
if (colorId != id.resId()) continue;
final var value = entry.getValue();
value.updateValue(new BinaryResourceValue(8, value.value().type(), color /*colors[i]*/));
++q;
} }
} }
} }
} }
} }
} }
}
return q == colorIds.length; private static boolean isColorResourceValue(BinaryResourceValue value) {
return value.type == BinaryResourceValue.Type.INT_COLOR_ARGB8
|| value.type == BinaryResourceValue.Type.INT_COLOR_RGB8
|| value.type == BinaryResourceValue.Type.INT_COLOR_ARGB4
|| value.type == BinaryResourceValue.Type.INT_COLOR_RGB4;
} }
} }
@@ -43,7 +43,7 @@ public class RecolorUtils {
} }
public static int recolorHexColor(int i) { public static int recolorHexColor(int i) {
if (!ThemesUtils.isCustomAccentEnabled()) return i; if (!ThemesUtils.isMonetTheme()) return i;
var accented = ColorReferences.isAccentedColor(i); var accented = ColorReferences.isAccentedColor(i);
var mutedaccented = ColorReferences.isMutedAccentedColor(i); var mutedaccented = ColorReferences.isMutedAccentedColor(i);
return (accented || mutedaccented) ? (accented ? ThemesUtils.getAccentColor() : ThemesUtils.getMutedAccentColor()) : i; return (accented || mutedaccented) ? (accented ? ThemesUtils.getAccentColor() : ThemesUtils.getMutedAccentColor()) : i;
@@ -57,7 +57,7 @@ public class RecolorUtils {
@SuppressLint("UseCompatLoadingForColorStateLists") @SuppressLint("UseCompatLoadingForColorStateLists")
public static ColorStateList themeCSL(Context context, int color) { public static ColorStateList themeCSL(Context context, int color) {
if (!ThemesUtils.isCustomAccentEnabled()) { if (!ThemesUtils.isMonetTheme()) {
if (Build.VERSION.SDK_INT >= 23) { if (Build.VERSION.SDK_INT >= 23) {
return context.getColorStateList(color); return context.getColorStateList(color);
} else { } else {
@@ -83,7 +83,7 @@ public class RecolorUtils {
} // Recolor ColorStateList } // Recolor ColorStateList
public static ColorStateList themeCSL(ColorStateList csl) { public static ColorStateList themeCSL(ColorStateList csl) {
if (!ThemesUtils.isCustomAccentEnabled()) return csl; if (!ThemesUtils.isMonetTheme()) return csl;
try { try {
int unsel = csl.getColorForState(new int[]{-android.R.attr.state_selected}, Color.BLACK); int unsel = csl.getColorForState(new int[]{-android.R.attr.state_selected}, Color.BLACK);
@@ -301,7 +301,7 @@ public class PreferenceFragmentUtils {
return addPreference(screen, key, title, null, null, preference -> { return addPreference(screen, key, title, null, null, preference -> {
LinearLayout linearLayout = new LinearLayout(screen.getContext()); LinearLayout linearLayout = new LinearLayout(screen.getContext());
final EditText editText = new EditText(screen.getContext()); EditText editText = new EditText(screen.getContext());
editText.setText(PreferenceManager.getDefaultSharedPreferences(screen.getContext()).getString(key, "")); editText.setText(PreferenceManager.getDefaultSharedPreferences(screen.getContext()).getString(key, ""));
editText.setHint(title); editText.setHint(title);
editText.setTextColor(ThemesUtils.getTextAttr()); editText.setTextColor(ThemesUtils.getTextAttr());
@@ -18,6 +18,7 @@ import ru.vtosters.lite.utils.AndroidUtils;
import ru.vtosters.lite.utils.LayoutUtils; import ru.vtosters.lite.utils.LayoutUtils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@@ -35,6 +36,7 @@ public class CategorizedAdapter<T> extends RecyclerView.Adapter<CategorizedAdapt
private final List<T> mSelectedItems; private final List<T> mSelectedItems;
private final List<T> mDisabledItems; private final List<T> mDisabledItems;
private final List<T> mUnmovedItems; private final List<T> mUnmovedItems;
private final List<T> mExceptions = new ArrayList<>();
private final IViewHolderBinder mBinder; private final IViewHolderBinder mBinder;
// Min and max counts // Min and max counts
@@ -48,6 +50,12 @@ public class CategorizedAdapter<T> extends RecyclerView.Adapter<CategorizedAdapt
this.mBinder = binder; this.mBinder = binder;
} }
@SafeVarargs
public final void setExceptions(T... exceptions) {
mExceptions.clear();
mExceptions.addAll(Arrays.asList(exceptions));
}
public void setMinAndMaxCounts(int min, int max) { public void setMinAndMaxCounts(int min, int max) {
this.mMinSelectedItems = min; this.mMinSelectedItems = min;
this.mMaxSelectedItems = max; this.mMaxSelectedItems = max;
@@ -173,16 +181,25 @@ public class CategorizedAdapter<T> extends RecyclerView.Adapter<CategorizedAdapt
public boolean onItemMove(int fromPosition, int toPosition) { public boolean onItemMove(int fromPosition, int toPosition) {
if (toPosition == 0 || isUnmovedItem(toPosition)) if (toPosition == 0 || isUnmovedItem(toPosition))
return false; return false;
switch (getTabType(fromPosition)) { switch (getTabType(fromPosition)) {
case SELECTED_STATE -> { case SELECTED_STATE -> {
if (getTabType(toPosition) == DISABLED_STATE if ((getTabType(toPosition) == DISABLED_STATE
&& mSelectedItems.size() == mMinSelectedItems) && mSelectedItems.size() == mMinSelectedItems))
return false; return false;
if (getItemViewType(toPosition) == CATEGORY_TITLE) if (getItemViewType(toPosition) == CATEGORY_TITLE) {
if (!mExceptions.isEmpty()) {
boolean except = false;
int q = 0;
for (var ex : mExceptions) {
var i = mSelectedItems.indexOf(ex);
if (i == -1) continue;
if (i + 1 == fromPosition) except = true;
++q;
}
if (except && q == 1) return false;
}
mDisabledItems.add(0, mSelectedItems.remove(fromPosition - 1)); mDisabledItems.add(0, mSelectedItems.remove(fromPosition - 1));
else } else Collections.swap(mSelectedItems, fromPosition - 1, toPosition - 1);
Collections.swap(mSelectedItems, fromPosition - 1, toPosition - 1);
} }
case DISABLED_STATE -> { case DISABLED_STATE -> {
if (getTabType(toPosition) == SELECTED_STATE if (getTabType(toPosition) == SELECTED_STATE
@@ -198,7 +215,6 @@ public class CategorizedAdapter<T> extends RecyclerView.Adapter<CategorizedAdapt
); );
} }
} }
notifyItemMoved(fromPosition, toPosition); notifyItemMoved(fromPosition, toPosition);
return true; return true;
} }
@@ -208,7 +224,6 @@ public class CategorizedAdapter<T> extends RecyclerView.Adapter<CategorizedAdapt
} }
public static class CategorizedViewHolder extends RecyclerView.ViewHolder { public static class CategorizedViewHolder extends RecyclerView.ViewHolder {
private final LinearLayout mMovingItemContainer; private final LinearLayout mMovingItemContainer;
private final ImageView mIcon; private final ImageView mIcon;
private final TextView mName; private final TextView mName;
@@ -18,7 +18,6 @@ import ru.vtosters.hooks.other.ThemesUtils;
import ru.vtosters.lite.utils.AndroidUtils; import ru.vtosters.lite.utils.AndroidUtils;
public class MessagesPreviewAdapter extends RecyclerView.Adapter<MessagesPreviewAdapter.MessagePreviewViewHolder> { public class MessagesPreviewAdapter extends RecyclerView.Adapter<MessagesPreviewAdapter.MessagePreviewViewHolder> {
private final String[] mMessages; private final String[] mMessages;
public MessagesPreviewAdapter(String... messages) { public MessagesPreviewAdapter(String... messages) {
@@ -35,9 +34,9 @@ public class MessagesPreviewAdapter extends RecyclerView.Adapter<MessagesPreview
public MessagePreviewViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) { public MessagePreviewViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {
Context context = viewGroup.getContext(); Context context = viewGroup.getContext();
final var inflater = LayoutInflater.from(context); var inflater = LayoutInflater.from(context);
final var bubbleFluidLayout = (BubbleFluidLayout) inflater.inflate(R.layout.vkim_msg_list_item_msg_from_user, viewGroup, false); var bubbleFluidLayout = (BubbleFluidLayout) inflater.inflate(R.layout.vkim_msg_list_item_msg_from_user, viewGroup, false);
bubbleFluidLayout.setPadding(0, AndroidUtils.dp2px(4), 0, 0); bubbleFluidLayout.setPadding(0, AndroidUtils.dp2px(4), 0, 0);
bubbleFluidLayout.setGravity(viewType); bubbleFluidLayout.setGravity(viewType);
@@ -47,7 +46,7 @@ public class MessagesPreviewAdapter extends RecyclerView.Adapter<MessagesPreview
bubbleFluidLayout.findViewById(R.id.status).setVisibility(View.GONE); bubbleFluidLayout.findViewById(R.id.status).setVisibility(View.GONE);
bubbleFluidLayout.findViewById(R.id.status_space).setVisibility(View.GONE); bubbleFluidLayout.findViewById(R.id.status_space).setVisibility(View.GONE);
final var messageBubbleView = (MsgBubbleView) bubbleFluidLayout.findViewById(R.id.bubble); var messageBubbleView = (MsgBubbleView) bubbleFluidLayout.findViewById(R.id.bubble);
messageBubbleView.setContentPaddingLeft(AndroidUtils.dp2px(10)); messageBubbleView.setContentPaddingLeft(AndroidUtils.dp2px(10));
messageBubbleView.setContentPaddingTop(AndroidUtils.dp2px(4)); messageBubbleView.setContentPaddingTop(AndroidUtils.dp2px(4));
messageBubbleView.setContentPaddingRight(AndroidUtils.dp2px(4)); messageBubbleView.setContentPaddingRight(AndroidUtils.dp2px(4));
@@ -59,10 +58,10 @@ public class MessagesPreviewAdapter extends RecyclerView.Adapter<MessagesPreview
} }
bubbleFluidLayout.setLayoutDirection(viewType); bubbleFluidLayout.setLayoutDirection(viewType);
final var msgTextView = inflater.inflate(R.layout.vkim_msg_part_text, viewGroup, false); var msgTextView = inflater.inflate(R.layout.vkim_msg_part_text, viewGroup, false);
msgTextView.setId(R.id.msg_text); msgTextView.setId(R.id.msg_text);
final var msgBubbleView = (MsgBubbleView) bubbleFluidLayout.findViewById(R.id.bubble); var msgBubbleView = (MsgBubbleView) bubbleFluidLayout.findViewById(R.id.bubble);
msgBubbleView.setContentView(msgTextView); msgBubbleView.setContentView(msgTextView);
return new MessagePreviewViewHolder(bubbleFluidLayout); return new MessagePreviewViewHolder(bubbleFluidLayout);
@@ -59,71 +59,7 @@ public class DockBarEditorManager {
: sInstance; : sInstance;
} }
private void init() { public static DockBarTab getTabByTag(String tag) {
if (vkme()) {
mSelectedTabs.add(getTabByTag("tab_settings"));
if (vkme_notifs()) {
if (milkshake()) {
mSelectedTabs.add(getTabByTag("tab_feedback"));
} else {
mSelectedTabs.add(getTabByTag("tab_friends"));
}
}
mSelectedTabs.add(getTabByTag("tab_messages"));
mSelectedTabs.add(getTabByTag("tab_profile"));
return;
}
checkOldConfig();
var selectedTabsTags = getPreferences()
.getString("dockbar_tabs",
"tab_news,tab_superapps,tab_messages,tab_friends,tab_profile")
.split(",");
parseSelectedTabs(selectedTabsTags);
}
private void checkOldConfig() {
File config = new File(getGlobalContext().getFilesDir(), "dockbar.json");
if (config.exists()) config.deleteOnExit();
}
private void parseSelectedTabs(String[] selectedTabsTags) {
var allTags = new ArrayList<>(ALL_TAGS);
for (String tag : selectedTabsTags) {
mSelectedTabs.add(getTabByTag(tag));
allTags.remove(tag);
}
for (String tag : allTags) {
mDisabledTabs.add(getTabByTag(tag));
}
}
public void save() {
var sb = new StringBuilder();
for (DockBarTab tab : mSelectedTabs)
sb.append(tab.tag).append(",");
getPreferences().edit().putString("dockbar_tabs", sb.toString()).commit();
}
public void reset() {
Preferences.getPreferences()
.edit()
.putString("dockbar_tabs", "tab_news,tab_superapps,tab_messages,tab_friends,tab_profile")
.commit();
}
public List<DockBarTab> getSelectedTabs() {
return mSelectedTabs;
}
public List<DockBarTab> getDisabledTabs() {
return mDisabledTabs;
}
private DockBarTab getTabByTag(String tag) {
return switch (tag) { return switch (tag) {
case "tab_news" -> DockBarTab.valuesOf( case "tab_news" -> DockBarTab.valuesOf(
"tab_news", "tab_news",
@@ -235,4 +171,68 @@ public class DockBarEditorManager {
useNewSettings()); useNewSettings());
}; };
} }
private void init() {
if (vkme()) {
mSelectedTabs.add(getTabByTag("tab_settings"));
if (vkme_notifs()) {
if (milkshake()) {
mSelectedTabs.add(getTabByTag("tab_feedback"));
} else {
mSelectedTabs.add(getTabByTag("tab_friends"));
}
}
mSelectedTabs.add(getTabByTag("tab_messages"));
mSelectedTabs.add(getTabByTag("tab_profile"));
return;
}
checkOldConfig();
var selectedTabsTags = getPreferences()
.getString("dockbar_tabs",
"tab_news,tab_superapps,tab_messages,tab_friends,tab_profile")
.split(",");
parseSelectedTabs(selectedTabsTags);
}
private void checkOldConfig() {
File config = new File(getGlobalContext().getFilesDir(), "dockbar.json");
if (config.exists()) config.deleteOnExit();
}
private void parseSelectedTabs(String[] selectedTabsTags) {
var allTags = new ArrayList<>(ALL_TAGS);
for (String tag : selectedTabsTags) {
mSelectedTabs.add(getTabByTag(tag));
allTags.remove(tag);
}
for (String tag : allTags) {
mDisabledTabs.add(getTabByTag(tag));
}
}
public void save() {
var sb = new StringBuilder();
for (DockBarTab tab : mSelectedTabs)
sb.append(tab.tag).append(",");
getPreferences().edit().putString("dockbar_tabs", sb.toString()).commit();
}
public void reset() {
Preferences.getPreferences()
.edit()
.putString("dockbar_tabs", "tab_news,tab_superapps,tab_messages,tab_friends,tab_profile")
.commit();
}
public List<DockBarTab> getSelectedTabs() {
return mSelectedTabs;
}
public List<DockBarTab> getDisabledTabs() {
return mDisabledTabs;
}
} }
@@ -17,8 +17,8 @@ public class DisableBattery {
public static void alert(Activity activity) { public static void alert(Activity activity) {
if (!(OEMDetector.isOEM() && Build.VERSION.SDK_INT >= 23 && Preferences.getBoolValue("showDoze", true))) if (!(OEMDetector.isOEM() && Build.VERSION.SDK_INT >= 23 && Preferences.getBoolValue("showDoze", true)))
return; return;
final String packName = activity.getPackageName(); String packName = activity.getPackageName();
final PowerManager manager = (PowerManager) activity.getSystemService(Context.POWER_SERVICE); PowerManager manager = (PowerManager) activity.getSystemService(Context.POWER_SERVICE);
if (manager.isIgnoringBatteryOptimizations(packName)) return; if (manager.isIgnoringBatteryOptimizations(packName)) return;
new VkAlertDialog.Builder(activity) new VkAlertDialog.Builder(activity)
.setTitle(R.string.batteryissuetitle) .setTitle(R.string.batteryissuetitle)
@@ -1,5 +1,6 @@
package ru.vtosters.lite.ui.dialogs; package ru.vtosters.lite.ui.dialogs;
import android.annotation.SuppressLint;
import android.app.Activity; import android.app.Activity;
import android.view.View; import android.view.View;
import android.widget.LinearLayout; import android.widget.LinearLayout;
@@ -41,6 +42,7 @@ public class OTADialog extends ModalBottomSheetWrapper<OTADialog> implements OTA
}); });
} }
@SuppressLint("SetTextI18n")
private View makeUpdateInfoView(String changelog) { private View makeUpdateInfoView(String changelog) {
LinearLayout container = new LinearLayout(mActivity); LinearLayout container = new LinearLayout(mActivity);
TextView changelogView = new TextView(mActivity); TextView changelogView = new TextView(mActivity);
@@ -168,12 +168,18 @@ public class DataSettingsFragment extends TrackedMaterialPreferenceToolbarFragme
var pref = Preferences.getPreferences().getString("autoclearcache", "Default"); var pref = Preferences.getPreferences().getString("autoclearcache", "Default");
switch (pref) { switch (pref) {
case "Default" -> findPreference("autoclearcache_btn").setSummary(requireContext().getString(com.vtosters.lite.R.string.cache_disabled)); case "Default" ->
case "100mb" -> findPreference("autoclearcache_btn").setSummary(requireContext().getString(com.vtosters.lite.R.string.cache_100mb)); findPreference("autoclearcache_btn").setSummary(requireContext().getString(com.vtosters.lite.R.string.cache_disabled));
case "500mb" -> findPreference("autoclearcache_btn").setSummary(requireContext().getString(com.vtosters.lite.R.string.cache_500mb)); case "100mb" ->
case "1gb" -> findPreference("autoclearcache_btn").setSummary(requireContext().getString(com.vtosters.lite.R.string.cache_1gb)); findPreference("autoclearcache_btn").setSummary(requireContext().getString(com.vtosters.lite.R.string.cache_100mb));
case "2gb" -> findPreference("autoclearcache_btn").setSummary(requireContext().getString(com.vtosters.lite.R.string.cache_2gb)); case "500mb" ->
case "5gb" -> findPreference("autoclearcache_btn").setSummary(requireContext().getString(com.vtosters.lite.R.string.cache_5gb)); findPreference("autoclearcache_btn").setSummary(requireContext().getString(com.vtosters.lite.R.string.cache_500mb));
case "1gb" ->
findPreference("autoclearcache_btn").setSummary(requireContext().getString(com.vtosters.lite.R.string.cache_1gb));
case "2gb" ->
findPreference("autoclearcache_btn").setSummary(requireContext().getString(com.vtosters.lite.R.string.cache_2gb));
case "5gb" ->
findPreference("autoclearcache_btn").setSummary(requireContext().getString(com.vtosters.lite.R.string.cache_5gb));
} }
PreferenceFragmentUtils.addPreferenceCategory(getPreferenceScreen(), AndroidUtils.getString("accounts")); PreferenceFragmentUtils.addPreferenceCategory(getPreferenceScreen(), AndroidUtils.getString("accounts"));
@@ -82,6 +82,9 @@ public class DockBarEditorFragment extends BaseToolbarFragment {
holder.bindMovingItem(tab.iconID, tab.titleID); holder.bindMovingItem(tab.iconID, tab.titleID);
}); });
adapter.setMinAndMaxCounts(DockBarEditorManager.MIN_SELECTED_TABS, DockBarEditorManager.MAX_SELECTED_TABS); adapter.setMinAndMaxCounts(DockBarEditorManager.MIN_SELECTED_TABS, DockBarEditorManager.MAX_SELECTED_TABS);
adapter.setExceptions(
DockBarEditorManager.getTabByTag("tab_profile"),
DockBarEditorManager.getTabByTag("")/*settings*/);
var recyclerView = new RecyclerView(requireContext()); var recyclerView = new RecyclerView(requireContext());
recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
@@ -1,35 +1,16 @@
package ru.vtosters.lite.ui.fragments; package ru.vtosters.lite.ui.fragments;
import android.annotation.SuppressLint;
import android.app.Activity; import android.app.Activity;
import android.content.*; import android.content.*;
import android.os.Bundle; import android.os.Bundle;
import android.util.TypedValue;
import android.webkit.WebView;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.Toast; import android.widget.Toast;
import androidx.appcompat.view.ContextThemeWrapper;
import b.h.g.m.FileUtils;
import com.vk.auth.api.VKAccount; import com.vk.auth.api.VKAccount;
import com.vk.core.dialogs.alert.VkAlertDialog;
import com.vk.core.util.ToastUtils; import com.vk.core.util.ToastUtils;
import com.vk.im.engine.ImEngine1;
import com.vk.im.engine.ImEngineExt;
import com.vk.im.ui.providers.audiomsg.ImAudioMsgPlayerProvider;
import com.vk.im.ui.providers.audiomsg.PlayerActionSources;
import com.vk.imageloader.VKImageLoader;
import com.vk.media.player.cache.AutoPlayCacheHolder;
import com.vk.mediastore.MediaStorage;
import com.vk.pushes.PushSubscriber; import com.vk.pushes.PushSubscriber;
import com.vk.stickers.Stickers;
import com.vtosters.lite.R; import com.vtosters.lite.R;
import com.vtosters.lite.auth.VKAccountManager; import com.vtosters.lite.auth.VKAccountManager;
import com.vtosters.lite.im.ImEngineProvider;
import ru.vtosters.hooks.GmsHook; import ru.vtosters.hooks.GmsHook;
import ru.vtosters.hooks.SwitchHook;
import ru.vtosters.hooks.other.Preferences; import ru.vtosters.hooks.other.Preferences;
import ru.vtosters.hooks.other.ThemesUtils;
import ru.vtosters.lite.deviceinfo.DeviceInfoCollector; import ru.vtosters.lite.deviceinfo.DeviceInfoCollector;
import ru.vtosters.lite.ssfs.UsersList; import ru.vtosters.lite.ssfs.UsersList;
import ru.vtosters.lite.ui.activities.VKAdminTokenActivity; import ru.vtosters.lite.ui.activities.VKAdminTokenActivity;
@@ -148,7 +129,6 @@ public class OtherFragment extends TrackedMaterialPreferenceToolbarFragment {
} }
private void copyText(String src) { private void copyText(String src) {
var manager = (ClipboardManager) requireContext().getSystemService(Context.CLIPBOARD_SERVICE); var manager = (ClipboardManager) requireContext().getSystemService(Context.CLIPBOARD_SERVICE);
manager.setPrimaryClip(ClipData.newPlainText("MBH-ST", src)); manager.setPrimaryClip(ClipData.newPlainText("MBH-ST", src));
@@ -43,15 +43,15 @@ public class ThemesFragment extends TrackedMaterialPreferenceToolbarFragment {
findPreference("systememoji").setSummary(AndroidUtils.getGlobalContext().getString(R.string.systememojisum) + " \uD83D\uDE00\uD83D\uDE01\uD83E\uDD11\uD83E\uDD75\uD83D\uDC4D"); findPreference("systememoji").setSummary(AndroidUtils.getGlobalContext().getString(R.string.systememojisum) + " \uD83D\uDE00\uD83D\uDE01\uD83E\uDD11\uD83E\uDD75\uD83D\uDC4D");
findPreference("useNewColorEngine").setVisible(Preferences.dev());
var invalidateThemeCache = findPreference("invalidate_theme_cache"); var invalidateThemeCache = findPreference("invalidate_theme_cache");
if (ThemesUtils.getReservedAccent() != Color.TRANSPARENT && Preferences.dev() && ThemesUtils.useNewColorEngine()) if (ThemesUtils.getReservedAccent() != Color.TRANSPARENT && Preferences.dev()) {
invalidateThemeCache.setOnPreferenceClickListener(preference -> { invalidateThemeCache.setOnPreferenceClickListener(preference -> {
setAccentColor(ThemesUtils.getReservedAccent()); setAccentColor(ThemesUtils.getReservedAccent());
return true; return true;
}); });
else invalidateThemeCache.setVisible(false); } else {
invalidateThemeCache.setVisible(false);
}
var navBarPreference = findPreference("navbar"); var navBarPreference = findPreference("navbar");
navBarPreference.setOnPreferenceClickListener(preference -> { navBarPreference.setOnPreferenceClickListener(preference -> {
@@ -156,12 +156,8 @@ public class ThemesFragment extends TrackedMaterialPreferenceToolbarFragment {
} }
}) })
.setNegativeButton(R.string.reset, (dialog, which) -> { .setNegativeButton(R.string.reset, (dialog, which) -> {
if (ThemesUtils.useNewColorEngine()) { ThemesManager.deleteModification();
ThemesManager.deleteModification(); ThemesUtils.reserveAccentColor(Color.TRANSPARENT, false);
ThemesUtils.reserveAccentColor(Color.TRANSPARENT, false);
} else {
ThemesUtils.setCustomAccentColor(0, false);
}
restart(); restart();
}) })
.setPositiveButton(R.string.cancel, null) .setPositiveButton(R.string.cancel, null)
@@ -207,35 +203,29 @@ public class ThemesFragment extends TrackedMaterialPreferenceToolbarFragment {
} }
void setAccentColor(int color) { void setAccentColor(int color) {
if (ThemesUtils.useNewColorEngine()) { final VKProgressDialog dialog = new VKProgressDialog(requireContext());
final VKProgressDialog dialog = new VKProgressDialog(requireContext()); dialog.setCancelable(false);
dialog.setCancelable(false); dialog.setMessage(AndroidUtils.getString("applying_accent") + "...");
dialog.setMessage(AndroidUtils.getString("applying_accent") + "..."); dialog.show();
dialog.show();
VTExecutors.getIoExecutor().execute(() -> { VTExecutors.getIoExecutor().execute(() -> {
try { try {
ThemesUtils.reserveAccentColor(color, true); ThemesUtils.reserveAccentColor(color, true);
ThemesManager.generateModApk(color); ThemesManager.generateModApk(color);
requireActivity().runOnUiThread(this::restart); requireActivity().runOnUiThread(this::restart);
} catch (Throwable e) { } catch (Throwable e) {
Log.e("ThemesFragment", e.getMessage()); Log.e("ThemesFragment", e.getMessage());
ThemesManager.deleteModification(); ThemesManager.deleteModification();
requireActivity().runOnUiThread(() -> { requireActivity().runOnUiThread(() -> {
dialog.dismiss(); dialog.dismiss();
new VkAlertDialog.Builder(requireContext()) new VkAlertDialog.Builder(requireContext())
.setTitle(AndroidUtils.getString("error")) .setTitle(AndroidUtils.getString("error"))
.setMessage(AndroidUtils.getString("error_applying_accent") + ":\n" + e) .setMessage(AndroidUtils.getString("error_applying_accent") + ":\n" + e)
.setPositiveButton("OK", null) .setPositiveButton("OK", null)
.show(); .show();
}); });
} }
}); });
} else {
ThemesUtils.setCustomAccentColor(color, false);
ThemesCore.setThemedColors(color);
restart();
}
} }
void restart() { void restart() {
@@ -31,4 +31,9 @@ public class DockBarTab {
Class<?> fragmentClass) { Class<?> fragmentClass) {
return new DockBarTab(tag, iconID, titleID, resID, fragmentClass); return new DockBarTab(tag, iconID, titleID, resID, fragmentClass);
} }
@Override
public boolean equals(Object arg) {
return this.id == ((DockBarTab) arg).id;
}
} }
@@ -13,4 +13,10 @@ public class SuperAppItem {
public static SuperAppItem valuesOf(String type, String title) { public static SuperAppItem valuesOf(String type, String title) {
return new SuperAppItem(type, title); return new SuperAppItem(type, title);
} }
@Override
public boolean equals(Object arg) {
var item = (SuperAppItem) arg;
return this.type.equals(item.type) && this.title.equals(item.title);
}
} }
@@ -37,16 +37,16 @@ public class AlphaView extends SliderViewBase implements ColorObserver {
@Override @Override
protected Bitmap makeBitmap(int w, int h) { protected Bitmap makeBitmap(int w, int h) {
final boolean isWide = w > h; boolean isWide = w > h;
final int n = Math.max(w, h); int n = Math.max(w, h);
int color = observableColor.getColor(); int color = observableColor.getColor();
int[] colors = new int[n]; int[] colors = new int[n];
for (int i = 0; i < n; ++i) { for (int i = 0; i < n; ++i) {
float alpha = isWide ? (float) i / n : 1 - (float) i / n; float alpha = isWide ? (float) i / n : 1 - (float) i / n;
colors[i] = color & 0xffffff | (int) (alpha * 0xff) << 24; colors[i] = color & 0xffffff | (int) (alpha * 0xff) << 24;
} }
final int bmpWidth = isWide ? w : 1; int bmpWidth = isWide ? w : 1;
final int bmpHeight = isWide ? 1 : h; int bmpHeight = isWide ? 1 : h;
return Bitmap.createBitmap(colors, bmpWidth, bmpHeight, Bitmap.Config.ARGB_8888); return Bitmap.createBitmap(colors, bmpWidth, bmpHeight, Bitmap.Config.ARGB_8888);
} }
@@ -18,13 +18,12 @@ class HexEdit {
new HexFilter() new HexFilter()
}; };
public static void setUpListeners(final EditText hexEdit, final ObservableColor observableColor) { public static void setUpListeners(EditText hexEdit, ObservableColor observableColor) {
class MultiObserver implements ColorObserver, TextWatcher { class MultiObserver implements ColorObserver, TextWatcher {
@Override @Override
public void updateColor(ObservableColor observableColor) { public void updateColor(ObservableColor observableColor) {
final String colorString = formatColor(observableColor.getColor()); String colorString = formatColor(observableColor.getColor());
// Prevent onTextChanged getting called when we update text programmatically // Prevent onTextChanged getting called when we update text programmatically
hexEdit.removeTextChangedListener(this); hexEdit.removeTextChangedListener(this);
hexEdit.setText(colorString); hexEdit.setText(colorString);
@@ -57,7 +56,7 @@ class HexEdit {
} }
} }
final MultiObserver multiObserver = new MultiObserver(); MultiObserver multiObserver = new MultiObserver();
hexEdit.addTextChangedListener(multiObserver); hexEdit.addTextChangedListener(multiObserver);
observableColor.addObserver(multiObserver); observableColor.addObserver(multiObserver);
setShowAlphaDigits(hexEdit, true); setShowAlphaDigits(hexEdit, true);
@@ -71,14 +70,13 @@ class HexEdit {
} }
} }
public static void setShowAlphaDigits(final EditText hexEdit, boolean showAlphaDigits) { public static void setShowAlphaDigits(EditText hexEdit, boolean showAlphaDigits) {
hexEdit.setFilters(showAlphaDigits ? withAlphaDigits : withoutAlphaDigits); hexEdit.setFilters(showAlphaDigits ? withAlphaDigits : withoutAlphaDigits);
hexEdit.setText(hexEdit.getText()); // trigger a reformat of text hexEdit.setText(hexEdit.getText()); // trigger a reformat of text
} }
private static class ColorPasteLengthFilter implements InputFilter { private static class ColorPasteLengthFilter implements InputFilter {
private static final int MAX_LENGTH = 6; private static final int MAX_LENGTH = 6;
private static final int PASTED_LEN = 8; private static final int PASTED_LEN = 8;
private final InputFilter sixDigitFilter = new InputFilter.LengthFilter(MAX_LENGTH); private final InputFilter sixDigitFilter = new InputFilter.LengthFilter(MAX_LENGTH);
@@ -86,8 +84,8 @@ class HexEdit {
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
// If 8 digits have been pasted, replacing all source, trim alpha digits. // If 8 digits have been pasted, replacing all source, trim alpha digits.
// Otherwise standard LengthFilter behavior. // Otherwise standard LengthFilter behavior.
final int srcLength = end - start; int srcLength = end - start;
final int dstSelLength = dend - dstart; int dstSelLength = dend - dstart;
if (srcLength == PASTED_LEN && dstSelLength == dest.length()) { if (srcLength == PASTED_LEN && dstSelLength == dest.length()) {
// Discard alpha digits: // Discard alpha digits:
return source.subSequence(PASTED_LEN - MAX_LENGTH, PASTED_LEN); return source.subSequence(PASTED_LEN - MAX_LENGTH, PASTED_LEN);
@@ -98,7 +96,6 @@ class HexEdit {
} }
private static class HexFilter implements InputFilter { private static class HexFilter implements InputFilter {
@Override @Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
boolean state = true; boolean state = true;
@@ -57,9 +57,9 @@ public class HueSatView extends SquareView implements ColorObserver {
float[] hsv = new float[]{0f, 0f, 1f}; float[] hsv = new float[]{0f, 0f, 1f};
for (int y = 0; y < radiusPx; ++y) { for (int y = 0; y < radiusPx; ++y) {
for (int x = 0; x < radiusPx; ++x) { for (int x = 0; x < radiusPx; ++x) {
final int i = x + y * radiusPx; int i = x + y * radiusPx;
final float sat = satForPos(x, y, radiusPx); float sat = satForPos(x, y, radiusPx);
final float arcBleed = 2f / radiusPx; // extend curved edge pixels just outside clip area. float arcBleed = 2f / radiusPx; // extend curved edge pixels just outside clip area.
if (sat <= 1 + arcBleed) { if (sat <= 1 + arcBleed) {
hsv[0] = hueForPos(x, y, radiusPx); hsv[0] = hueForPos(x, y, radiusPx);
hsv[1] = sat; hsv[1] = sat;
@@ -71,35 +71,35 @@ public class HueSatView extends SquareView implements ColorObserver {
} }
private static float hueForPos(float x, float y, float radiusPx) { private static float hueForPos(float x, float y, float radiusPx) {
final double r = radiusPx - 1; // gives values 0...1 inclusive double r = radiusPx - 1; // gives values 0...1 inclusive
final double dx = (r - x) / r; double dx = (r - x) / r;
final double dy = (r - y) / r; double dy = (r - y) / r;
final double angle = Math.atan2(dy, dx); double angle = Math.atan2(dy, dx);
final double hue = 360 * angle / (Math.PI / 2); double hue = 360 * angle / (Math.PI / 2);
return (float) hue; return (float) hue;
} }
private static float satForPos(float x, float y, float radiusPx) { private static float satForPos(float x, float y, float radiusPx) {
final double r = radiusPx - 1; // gives values 0...1 inclusive double r = radiusPx - 1; // gives values 0...1 inclusive
final double dx = (r - x) / r; double dx = (r - x) / r;
final double dy = (r - y) / r; double dy = (r - y) / r;
final double sat = dx * dx + dy * dy; // leave it squared -- exaggerates pale colors double sat = dx * dx + dy * dy; // leave it squared -- exaggerates pale colors
return (float) sat; return (float) sat;
} }
private static void setPointer(PointF pointer, float hue, float sat, float radiusPx) { private static void setPointer(PointF pointer, float hue, float sat, float radiusPx) {
final float r = radiusPx - 1; // for values 0...1 inclusive float r = radiusPx - 1; // for values 0...1 inclusive
final double distance = r * Math.sqrt(sat); double distance = r * Math.sqrt(sat);
final double angle = hue / 360 * Math.PI / 2; double angle = hue / 360 * Math.PI / 2;
final double dx = distance * Math.cos(angle); double dx = distance * Math.cos(angle);
final double dy = distance * Math.sin(angle); double dy = distance * Math.sin(angle);
pointer.set(r - (float) dx, r - (float) dy); pointer.set(r - (float) dx, r - (float) dy);
} }
private int optimalBitmapSize() { private int optimalBitmapSize() {
final int scale = 2; int scale = 2;
final int maxBitmapSize = 128; int maxBitmapSize = 128;
final DisplayMetrics dm = getResources().getDisplayMetrics(); DisplayMetrics dm = getResources().getDisplayMetrics();
return Math.min(maxBitmapSize, Math.min(dm.widthPixels, dm.heightPixels) / scale); return Math.min(maxBitmapSize, Math.min(dm.widthPixels, dm.heightPixels) / scale);
} }
@@ -159,9 +159,9 @@ public class HueSatView extends SquareView implements ColorObserver {
private boolean clamp(PointF pointer, float x, float y, boolean rejectOutside) { private boolean clamp(PointF pointer, float x, float y, boolean rejectOutside) {
x = Math.min(x, w); x = Math.min(x, w);
y = Math.min(y, h); y = Math.min(y, h);
final float dx = w - x; float dx = w - x;
final float dy = h - y; float dy = h - y;
final float r = (float) Math.sqrt(dx * dx + dy * dy); float r = (float) Math.sqrt(dx * dx + dy * dy);
boolean outside = r > w; boolean outside = r > w;
if (!outside || !rejectOutside) { if (!outside || !rejectOutside) {
if (outside) { if (outside) {
@@ -6,7 +6,6 @@ import android.view.MotionEvent;
import android.view.View; import android.view.View;
public abstract class SliderViewBase extends View { public abstract class SliderViewBase extends View {
private final Paint borderPaint; private final Paint borderPaint;
private final Paint checkerPaint; private final Paint checkerPaint;
private final Rect viewRect = new Rect(); private final Rect viewRect = new Rect();
@@ -18,10 +18,10 @@ class SquareView extends View {
@Override @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// Constrain to square // Constrain to square
final int w = MeasureSpec.getSize(widthMeasureSpec); int w = MeasureSpec.getSize(widthMeasureSpec);
final int h = MeasureSpec.getSize(heightMeasureSpec); int h = MeasureSpec.getSize(heightMeasureSpec);
final int modeW = MeasureSpec.getMode(widthMeasureSpec); int modeW = MeasureSpec.getMode(widthMeasureSpec);
final int modeH = MeasureSpec.getMode(heightMeasureSpec); int modeH = MeasureSpec.getMode(heightMeasureSpec);
int size = minSizePx; int size = minSizePx;
if (modeW == MeasureSpec.UNSPECIFIED) { if (modeW == MeasureSpec.UNSPECIFIED) {
size = h; size = h;
@@ -8,7 +8,6 @@ import android.graphics.RectF;
import ru.vtosters.lite.utils.AndroidUtils; import ru.vtosters.lite.utils.AndroidUtils;
public class SwatchView extends SquareView implements ColorObserver { public class SwatchView extends SquareView implements ColorObserver {
private final Paint borderPaint; private final Paint borderPaint;
private final Path borderPath; private final Path borderPath;
private final Paint checkerPaint; private final Paint checkerPaint;
@@ -46,14 +45,14 @@ public class SwatchView extends SquareView implements ColorObserver {
} }
private static void cornerArc(Path path, float cx, float cy, float r, float startAngle, float sweepAngle) { private static void cornerArc(Path path, float cx, float cy, float r, float startAngle, float sweepAngle) {
final RectF ovalRect = new RectF(-r, -r, r, r); RectF ovalRect = new RectF(-r, -r, r, r);
ovalRect.offset(cx, cy); ovalRect.offset(cx, cy);
path.arcTo(ovalRect, startAngle, sweepAngle); path.arcTo(ovalRect, startAngle, sweepAngle);
} }
private static void mainArc(Path path, float viewSize, float margin, float startAngle, float sweepAngle) { private static void mainArc(Path path, float viewSize, float margin, float startAngle, float sweepAngle) {
float r = viewSize + margin; float r = viewSize + margin;
final RectF ovalRect = new RectF(-r, -r, r, r); RectF ovalRect = new RectF(-r, -r, r, r);
ovalRect.offset(viewSize, viewSize); ovalRect.offset(viewSize, viewSize);
path.arcTo(ovalRect, startAngle, sweepAngle); path.arcTo(ovalRect, startAngle, sweepAngle);
} }
@@ -77,23 +76,23 @@ public class SwatchView extends SquareView implements ColorObserver {
protected void onSizeChanged(int w, int h, int oldw, int oldh) { protected void onSizeChanged(int w, int h, int oldw, int oldh) {
// We expect to be stacked behind a square HueSatView and fill the top left corner. // We expect to be stacked behind a square HueSatView and fill the top left corner.
final float inset = borderPaint.getStrokeWidth() / 2; float inset = borderPaint.getStrokeWidth() / 2;
final float r = Math.min(w, h); float r = Math.min(w, h);
// Trim the corners of the swatch is where it is radialMarginPx thick. // Trim the corners of the swatch is where it is radialMarginPx thick.
// find how long the outeredges are: // find how long the outeredges are:
final float margin = radialMarginPx; float margin = radialMarginPx;
final float diagonal = r + 2 * margin; float diagonal = r + 2 * margin;
final float opp = (float) Math.sqrt(diagonal * diagonal - r * r); float opp = (float) Math.sqrt(diagonal * diagonal - r * r);
final float edgeLen = r - opp; float edgeLen = r - opp;
// Arc angles for drawing CCW // Arc angles for drawing CCW
final float outerAngle = (float) Math.toDegrees(Math.atan2(opp, r)); float outerAngle = (float) Math.toDegrees(Math.atan2(opp, r));
final float startAngle = 270 - outerAngle; float startAngle = 270 - outerAngle;
// Sweep angle for each half of the swatch: // Sweep angle for each half of the swatch:
final float sweepAngle = outerAngle - 45; float sweepAngle = outerAngle - 45;
// Sweep angle for the smooth corners: // Sweep angle for the smooth corners:
final float cornerSweepAngle = 90 - outerAngle; float cornerSweepAngle = 90 - outerAngle;
// Outer border: // Outer border:
beginBorder(borderPath, inset, edgeLen, margin, cornerSweepAngle); beginBorder(borderPath, inset, edgeLen, margin, cornerSweepAngle);
@@ -5,7 +5,6 @@ import android.graphics.Bitmap;
import android.graphics.Color; import android.graphics.Color;
public class ValueView extends SliderViewBase implements ColorObserver { public class ValueView extends SliderViewBase implements ColorObserver {
private ObservableColor observableColor = new ObservableColor(0); private ObservableColor observableColor = new ObservableColor(0);
public ValueView(Context context) { public ValueView(Context context) {
@@ -37,8 +36,8 @@ public class ValueView extends SliderViewBase implements ColorObserver {
} }
protected Bitmap makeBitmap(int w, int h) { protected Bitmap makeBitmap(int w, int h) {
final boolean isWide = w > h; boolean isWide = w > h;
final int n = Math.max(w, h); int n = Math.max(w, h);
int[] colors = new int[n]; int[] colors = new int[n];
float[] hsv = new float[]{0, 0, 0}; float[] hsv = new float[]{0, 0, 0};
@@ -48,8 +47,8 @@ public class ValueView extends SliderViewBase implements ColorObserver {
hsv[2] = isWide ? (float) i / n : 1 - (float) i / n; hsv[2] = isWide ? (float) i / n : 1 - (float) i / n;
colors[i] = Color.HSVToColor(hsv); colors[i] = Color.HSVToColor(hsv);
} }
final int bmpWidth = isWide ? w : 1; int bmpWidth = isWide ? w : 1;
final int bmpHeight = isWide ? 1 : h; int bmpHeight = isWide ? 1 : h;
return Bitmap.createBitmap(colors, bmpWidth, bmpHeight, Bitmap.Config.ARGB_8888); return Bitmap.createBitmap(colors, bmpWidth, bmpHeight, Bitmap.Config.ARGB_8888);
} }
@@ -18,7 +18,6 @@ import ru.vtosters.hooks.other.Preferences;
import ru.vtosters.lite.foaf.FoafBase; import ru.vtosters.lite.foaf.FoafBase;
import ru.vtosters.lite.utils.AccountManagerUtils; import ru.vtosters.lite.utils.AccountManagerUtils;
import ru.vtosters.lite.utils.AndroidUtils; import ru.vtosters.lite.utils.AndroidUtils;
import ru.vtosters.lite.utils.RenameTool;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
@@ -5,12 +5,8 @@ import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.os.Build; import android.os.Build;
import android.view.View;
import android.widget.ImageView;
import com.vk.im.engine.h;
import com.vtosters.lite.R; import com.vtosters.lite.R;
import ru.vtosters.hooks.other.Preferences; import ru.vtosters.hooks.other.Preferences;
import ru.vtosters.hooks.other.ThemesUtils;
import ru.vtosters.lite.utils.AndroidUtils; import ru.vtosters.lite.utils.AndroidUtils;
import vigo.sdk.Log; import vigo.sdk.Log;
@@ -46,7 +46,7 @@ public class AndroidUtils {
@NonNull @NonNull
public static Context getGlobalContext() { public static Context getGlobalContext() {
try { try {
final Method getInitialApplicationMtd = ReflectionUtils.findMethod(Class.forName("android.app.AppGlobals"), "getInitialApplication"); Method getInitialApplicationMtd = ReflectionUtils.findMethod(Class.forName("android.app.AppGlobals"), "getInitialApplication");
return (Context) getInitialApplicationMtd.invoke(null); return (Context) getInitialApplicationMtd.invoke(null);
} catch (Exception e) { } catch (Exception e) {
Log.d("GlobalContext", "Error while fetching context via refl"); Log.d("GlobalContext", "Error while fetching context via refl");
@@ -186,8 +186,8 @@ public class AndroidUtils {
} }
private static String getRandomString(int sizeOfRandomString) { private static String getRandomString(int sizeOfRandomString) {
final Random random = new Random(); Random random = new Random();
final StringBuilder sb = new StringBuilder(sizeOfRandomString); StringBuilder sb = new StringBuilder(sizeOfRandomString);
for (int i = 0; i < sizeOfRandomString; ++i) for (int i = 0; i < sizeOfRandomString; ++i)
sb.append(ALLOWED_CHARACTERS.charAt(random.nextInt(ALLOWED_CHARACTERS.length()))); sb.append(ALLOWED_CHARACTERS.charAt(random.nextInt(ALLOWED_CHARACTERS.length())));
return sb.toString(); return sb.toString();
@@ -221,7 +221,6 @@ public class AndroidUtils {
long lastUpdateTime = context.getPackageManager().getPackageInfo(context.getPackageName(), 0).lastUpdateTime; long lastUpdateTime = context.getPackageManager().getPackageInfo(context.getPackageName(), 0).lastUpdateTime;
return firstInstallTime == lastUpdateTime; return firstInstallTime == lastUpdateTime;
} catch (PackageManager.NameNotFoundException e) { } catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
return true; return true;
} }
} }
@@ -26,7 +26,7 @@ public class CrashReporter {
} }
public static void init(Activity activity) { public static void init(Activity activity) {
final var defaultUncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler(); var defaultUncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler((thread, th) -> CrashReporter.start(defaultUncaughtExceptionHandler, thread, th, activity)); Thread.setDefaultUncaughtExceptionHandler((thread, th) -> CrashReporter.start(defaultUncaughtExceptionHandler, thread, th, activity));
} }
@@ -76,9 +76,8 @@ public class CrashReporter {
} }
private static boolean isFoxbinInstalled() { private static boolean isFoxbinInstalled() {
var pm = getGlobalContext().getPackageManager();
try { try {
pm.getPackageInfo("com.f0x1d.dogbin", 0); getGlobalContext().getPackageManager().getPackageInfo("com.f0x1d.dogbin", 0);
return true; return true;
} catch (Exception e) { } catch (Exception e) {
return false; return false;
@@ -16,7 +16,7 @@ import java.security.NoSuchAlgorithmException;
import java.util.Arrays; import java.util.Arrays;
public class IOUtils { public class IOUtils {
public static final int BUFFER_SIZE = 8192; public static int BUFFER_SIZE = 8192;
public static byte[] decodeStream(InputStream encIs, byte[] aesKey) public static byte[] decodeStream(InputStream encIs, byte[] aesKey)
throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, IOException { throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, IOException {
@@ -51,11 +51,11 @@ public class IOUtils {
return new String(readFully(is), StandardCharsets.UTF_8); return new String(readFully(is), StandardCharsets.UTF_8);
} }
public static byte[] readFully(final InputStream is) public static byte[] readFully(InputStream is)
throws IOException { throws IOException {
final var bos = new ByteArrayOutputStream(); var bos = new ByteArrayOutputStream();
try (bos) { try (bos) {
final byte[] buff = new byte[BUFFER_SIZE]; byte[] buff = new byte[BUFFER_SIZE];
int len; int len;
while ((len = is.read(buff)) > 0) while ((len = is.read(buff)) > 0)
bos.write(buff, 0, len); bos.write(buff, 0, len);
@@ -63,7 +63,7 @@ public class IOUtils {
} }
} }
public static byte[] readFully(final File in) public static byte[] readFully(File in)
throws IOException { throws IOException {
return readFully(new FileInputStream(in)); return readFully(new FileInputStream(in));
} }
@@ -80,25 +80,25 @@ public class IOUtils {
fos.close(); fos.close();
} }
public static void copy(final InputStream is, final OutputStream os) public static void copy(InputStream is, OutputStream os)
throws IOException { throws IOException {
final byte[] buff = new byte[BUFFER_SIZE]; byte[] buff = new byte[BUFFER_SIZE];
int len; int len;
while ((len = is.read(buff)) > 0) while ((len = is.read(buff)) > 0)
os.write(buff, 0, len); os.write(buff, 0, len);
} }
public static void copy(final byte[] buffer, final File out) public static void copy(byte[] buffer, File out)
throws IOException { throws IOException {
copy(new ByteArrayInputStream(buffer), new FileOutputStream(out)); copy(new ByteArrayInputStream(buffer), new FileOutputStream(out));
} }
public static void copy(final InputStream is, final File out) public static void copy(InputStream is, File out)
throws IOException { throws IOException {
copy(is, new FileOutputStream(out)); copy(is, new FileOutputStream(out));
} }
public static void copy(final File in, final File out) public static void copy(File in, File out)
throws IOException { throws IOException {
copy(new FileInputStream(in), new FileOutputStream(out)); copy(new FileInputStream(in), new FileOutputStream(out));
} }
@@ -119,7 +119,7 @@ public class IOUtils {
} }
public static long getDirSize(File dir) { public static long getDirSize(File dir) {
final var arr = dir.listFiles(); var arr = dir.listFiles();
if (arr == null || arr.length == 0) if (arr == null || arr.length == 0)
return 0; return 0;
@@ -242,13 +242,13 @@ public class NewsFeedFiltersUtils {
return false; return false;
} }
if (checkCopyright(post) && !isWhitelistedFilters(post)) { if (checkCopyright(post)) {
if (dev()) if (dev())
Log.d("NewsfeedAdBlockV2", "Removed post " + post.optInt("post_id") + " from discover, Reason: copyright filters"); Log.d("NewsfeedAdBlockV2", "Removed post " + post.optInt("post_id") + " from discover, Reason: copyright filters");
return false; return false;
} }
if (checkCaption(post) && !isWhitelistedFilters(post)) { if (checkCaption(post)) {
if (dev()) if (dev())
Log.d("NewsfeedAdBlockV2", "Removed post " + post.optInt("post_id") + " from discover, Reason: caption filters"); Log.d("NewsfeedAdBlockV2", "Removed post " + post.optInt("post_id") + " from discover, Reason: caption filters");
return false; return false;
@@ -448,13 +448,13 @@ public class NewsFeedFiltersUtils {
continue; continue;
} }
if (checkCopyright(list) && !isWhitelistedFilters(list)) { if (checkCopyright(list)) {
if (dev()) if (dev())
Log.d("NewsfeedAdBlockV2", "Removed post " + list.optInt("post_id") + " from feed, Reason: copyright filters"); Log.d("NewsfeedAdBlockV2", "Removed post " + list.optInt("post_id") + " from feed, Reason: copyright filters");
continue; continue;
} }
if (checkCaption(list) && !isWhitelistedFilters(list)) { if (checkCaption(list)) {
if (dev()) if (dev())
Log.d("NewsfeedAdBlockV2", "Removed post " + list.optInt("post_id") + " from feed, Reason: caption filters"); Log.d("NewsfeedAdBlockV2", "Removed post " + list.optInt("post_id") + " from feed, Reason: caption filters");
continue; continue;
@@ -17,6 +17,9 @@ import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.Locale; import java.util.Locale;
import static android.os.Environment.DIRECTORY_DOWNLOADS;
import static android.os.Environment.getExternalStoragePublicDirectory;
public class VKAccountDB { public class VKAccountDB {
private static SQLiteOpenHelper getDatabase() { private static SQLiteOpenHelper getDatabase() {
return new UsersDbHelper(AndroidUtils.getGlobalContext()); return new UsersDbHelper(AndroidUtils.getGlobalContext());
@@ -70,11 +73,11 @@ public class VKAccountDB {
var db = getDatabase().getReadableDatabase(); var db = getDatabase().getReadableDatabase();
var dateFormat = new SimpleDateFormat("yyyy-MM-dd.HH-mm-ss", Locale.getDefault()); var dateFormat = new SimpleDateFormat("yyyy-MM-dd.HH-mm-ss", Locale.getDefault());
var file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/VTLBackups/saved_accounts_" + dateFormat.format(new Date()) + ".vtl"); var dir = new File(getExternalStoragePublicDirectory(DIRECTORY_DOWNLOADS), "/VTLBackups/");
var file = new File(dir, "saved_accounts_" + dateFormat.format(new Date()) + ".vtl");
InputStream inputStream; try (InputStream inputStream = new FileInputStream(db.getPath())){
try { dir.mkdirs();
inputStream = new FileInputStream(db.getPath());
FileOutputStream outputStream = new FileOutputStream(file); FileOutputStream outputStream = new FileOutputStream(file);
byte[] buff = new byte[1024]; byte[] buff = new byte[1024];
@@ -86,7 +89,6 @@ public class VKAccountDB {
AndroidUtils.sendToast(AndroidUtils.getString("accounts_saved_by_path") + " " + file.getPath()); AndroidUtils.sendToast(AndroidUtils.getString("accounts_saved_by_path") + " " + file.getPath());
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace();
AndroidUtils.sendToast(AndroidUtils.getString("error_saving_file")); AndroidUtils.sendToast(AndroidUtils.getString("error_saving_file"));
} }
} }
+1 -1
View File
@@ -8,7 +8,7 @@ buildscript {
} }
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:8.0.2' classpath 'com.android.tools.build:gradle:7.4.2'
classpath 'org.mozilla.rust-android-gradle:plugin:0.9.3' classpath 'org.mozilla.rust-android-gradle:plugin:0.9.3'
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong
+1 -1
View File
@@ -1,6 +1,6 @@
#Tue Aug 16 21:49:57 MSK 2022 #Tue Aug 16 21:49:57 MSK 2022
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
-3
View File
@@ -22,9 +22,6 @@ if "%ERRORLEVEL%" == "0" (
echo %ESC%[31mFailed%ESC%[0m echo %ESC%[31mFailed%ESC%[0m
exit /B 1 exit /B 1
) )
del classes6.dex
del classes7.dex
del assets\version.properties
echo. echo.
echo %ESC%[1;4mSign apk...%ESC%[0m echo %ESC%[1;4mSign apk...%ESC%[0m
+1 -5
View File
@@ -33,8 +33,4 @@ cd ../scripts
./apksigner sign --ks debug.keystore --ks-key-alias androiddebugkey --ks-pass pass:android ../scripts/VTLite.apk ./apksigner sign --ks debug.keystore --ks-key-alias androiddebugkey --ks-pass pass:android ../scripts/VTLite.apk
check_result check_result
echo -e "${BOLD}VTosters Lite успешно собран! APK находится в папке scripts${NC}" echo -e "${BOLD}VTosters Lite успешно собран! APK находится в папке scripts${NC}"
cd ../smali
rm classes6.dex
rm classes7.dex
+3 -2
View File
@@ -57,6 +57,7 @@ cпocоб зaрaбoтать
В закрепленном комментарии В закрепленном комментарии
В Закрепленном комментарии В Закрепленном комментарии
В закрепленном Комментарии В закрепленном Комментарии
в комментариях
Успей подать заявку Успей подать заявку
Успей Подать Заявку Успей Подать Заявку
Успей подать Заявку Успей подать Заявку
@@ -94,6 +95,6 @@ cкорее подписывайся
Подписывайтесь👇 Подписывайтесь👇
Подписывайся👇 Подписывайся👇
ссылка в комментариях ссылка в комментариях
в комментариях👇
👉https:// 👉https://
👉http:// 👉http://
Ссылка удалится через часов
+1
View File
@@ -7012,6 +7012,7 @@
<string name="datasettings_title">Налады дадзеных прыкладання</string> <string name="datasettings_title">Налады дадзеных прыкладання</string>
<string name="invalidate_theme_cache_title">Інвалідацыя кэша тэмы</string> <string name="invalidate_theme_cache_title">Інвалідацыя кэша тэмы</string>
<string name="invalidate_theme_cache_each_update_title">Ачыстка кэша тэмы пасля абнаўлення для прадухілення праблем з акцэнтамі</string>
<string name="useCustomPrefsStyle_title">Выкарыстоўваць новыя тумблеры</string> <string name="useCustomPrefsStyle_title">Выкарыстоўваць новыя тумблеры</string>
<string name="useCustomPrefsStyle_summ">Больш сучасны і стыльны выгляд тумблераў у наладах</string> <string name="useCustomPrefsStyle_summ">Больш сучасны і стыльны выгляд тумблераў у наладах</string>
+1
View File
@@ -6394,6 +6394,7 @@
<string name="datasettings_title">Настройки данных приложения</string> <string name="datasettings_title">Настройки данных приложения</string>
<string name="invalidate_theme_cache_title">Инвалидация кэша темы</string> <string name="invalidate_theme_cache_title">Инвалидация кэша темы</string>
<string name="invalidate_theme_cache_each_update_title">Очистка кэша темы после обновления для предотвращения проблем с акцентами</string>
<string name="useCustomPrefsStyle_title">Использовать новые переключатели</string> <string name="useCustomPrefsStyle_title">Использовать новые переключатели</string>
<string name="useCustomPrefsStyle_summ">Более современный и стильный вид тумблеров в настройках</string> <string name="useCustomPrefsStyle_summ">Более современный и стильный вид тумблеров в настройках</string>
+1
View File
@@ -6319,6 +6319,7 @@
<string name="datasettings_title">Налаштування даних додатку</string> <string name="datasettings_title">Налаштування даних додатку</string>
<string name="invalidate_theme_cache_title">Інвалідація кешу теми</string> <string name="invalidate_theme_cache_title">Інвалідація кешу теми</string>
<string name="invalidate_theme_cache_each_update_title">Очищення кешу теми після оновлення для запобігання проблем з акцентами</string>
<string name="useCustomPrefsStyle_title">Використовувати нові перемикачі</string> <string name="useCustomPrefsStyle_title">Використовувати нові перемикачі</string>
<string name="useCustomPrefsStyle_summ">Більш сучасний і стильний вигляд тумблерів у налаштуваннях</string> <string name="useCustomPrefsStyle_summ">Більш сучасний і стильний вигляд тумблерів у налаштуваннях</string>
+96 -96
View File
@@ -527,9 +527,9 @@
<item name="action_sheet_action_foreground">@android:color/system_neutral1_100</item> <item name="action_sheet_action_foreground">@android:color/system_neutral1_100</item>
<item name="action_sheet_separator">@android:color/system_neutral1_100</item> <item name="action_sheet_separator">@android:color/system_neutral1_100</item>
<item name="activity_indicator_tint">@android:color/system_neutral1_600</item> <item name="activity_indicator_tint">@android:color/system_neutral1_600</item>
<item name="attach_picker_tab_active_background">@android:color/system_neutral1_100</item> <item name="attach_picker_tab_active_background">?accent</item>
<item name="attach_picker_tab_active_icon">@android:color/system_neutral1_900</item> <item name="attach_picker_tab_active_icon">@android:color/system_neutral1_1000</item>
<item name="attach_picker_tab_active_text">@android:color/system_neutral1_100</item> <item name="attach_picker_tab_active_text">?accent</item>
<item name="attach_picker_tab_inactive_background">@android:color/system_neutral1_800</item> <item name="attach_picker_tab_inactive_background">@android:color/system_neutral1_800</item>
<item name="attach_picker_tab_inactive_icon">@android:color/system_neutral1_100</item> <item name="attach_picker_tab_inactive_icon">@android:color/system_neutral1_100</item>
<item name="attach_picker_tab_inactive_text">@android:color/system_neutral1_500</item> <item name="attach_picker_tab_inactive_text">@android:color/system_neutral1_500</item>
@@ -547,27 +547,27 @@
<item name="button_commerce_foreground_disabled">#66ffffff</item> <item name="button_commerce_foreground_disabled">#66ffffff</item>
<item name="button_muted_background">@android:color/system_neutral1_800</item> <item name="button_muted_background">@android:color/system_neutral1_800</item>
<item name="button_muted_background_disabled">#662c2d2e</item> <item name="button_muted_background_disabled">#662c2d2e</item>
<item name="button_muted_foreground">@android:color/system_neutral1_100</item> <item name="button_muted_foreground">?accent</item>
<item name="button_muted_foreground_disabled">#66e1e3e6</item> <item name="button_muted_foreground_disabled">#66e1e3e6</item>
<item name="button_outline_border">?background_keyboard</item> <item name="button_outline_border">?accent</item>
<item name="button_outline_border_disabled">#66e1e3e6</item> <item name="button_outline_border_disabled">#66e1e3e6</item>
<item name="button_outline_foreground">@android:color/system_neutral1_100</item> <item name="button_outline_foreground">?accent</item>
<item name="button_outline_foreground_disabled">#66e1e3e6</item> <item name="button_outline_foreground_disabled">#66e1e3e6</item>
<item name="button_primary_background">@android:color/system_neutral1_100</item> <item name="button_primary_background">?accent</item>
<item name="button_primary_background_disabled">#66e1e3e6</item> <item name="button_primary_background_disabled">#66e1e3e6</item>
<item name="button_primary_foreground">@android:color/system_neutral1_900</item> <item name="button_primary_foreground">@android:color/system_neutral1_900</item>
<item name="button_primary_foreground_disabled">#6619191a</item> <item name="button_primary_foreground_disabled">#6619191a</item>
<item name="button_secondary_background">@android:color/system_neutral1_700</item> <item name="button_secondary_background">@android:color/system_neutral1_700</item>
<item name="button_secondary_background_disabled">#66454647</item> <item name="button_secondary_background_disabled">#66454647</item>
<item name="button_secondary_foreground">@android:color/system_neutral1_100</item> <item name="button_secondary_foreground">?accent</item>
<item name="button_secondary_foreground_disabled">#66e1e3e6</item> <item name="button_secondary_foreground_disabled">#66e1e3e6</item>
<item name="button_tertiary_background">@color/clear</item> <item name="button_tertiary_background">@color/clear</item>
<item name="button_tertiary_background_disabled">#00000000</item> <item name="button_tertiary_background_disabled">#00000000</item>
<item name="button_tertiary_foreground">@android:color/system_neutral1_100</item> <item name="button_tertiary_foreground">?accent</item>
<item name="button_tertiary_foreground_disabled">#66e1e3e6</item> <item name="button_tertiary_foreground_disabled">#66e1e3e6</item>
<item name="cell_button_foreground">@android:color/system_neutral1_100</item> <item name="cell_button_foreground">?accent</item>
<item name="cell_button_foreground_disabled">#66e1e3e6</item> <item name="cell_button_foreground_disabled">#66e1e3e6</item>
<item name="content_placeholder_icon">@android:color/system_neutral1_300</item> <item name="content_placeholder_icon">?accent</item>
<item name="content_placeholder_text">@android:color/system_neutral1_300</item> <item name="content_placeholder_text">@android:color/system_neutral1_300</item>
<item name="content_tint_background">@android:color/system_neutral1_900</item> <item name="content_tint_background">@android:color/system_neutral1_900</item>
<item name="content_tint_foreground">@android:color/system_neutral1_400</item> <item name="content_tint_foreground">@android:color/system_neutral1_400</item>
@@ -575,9 +575,9 @@
<item name="control_foreground">@android:color/system_neutral1_100</item> <item name="control_foreground">@android:color/system_neutral1_100</item>
<item name="control_tint">@android:color/system_neutral1_900</item> <item name="control_tint">@android:color/system_neutral1_900</item>
<item name="control_tint_muted">@android:color/system_neutral1_400</item> <item name="control_tint_muted">@android:color/system_neutral1_400</item>
<item name="counter_primary_background">?accent</item> <item name="counter_primary_background">@android:color/system_neutral1_100</item>
<item name="counter_primary_text">@android:color/system_neutral1_100</item> <item name="counter_primary_text">@android:color/system_neutral1_900</item>
<item name="counter_prominent_background">@android:color/system_accent1_500</item> <item name="counter_prominent_background">?accent</item>
<item name="counter_prominent_text">@android:color/system_neutral1_100</item> <item name="counter_prominent_text">@android:color/system_neutral1_100</item>
<item name="counter_secondary_background">@android:color/system_neutral1_500</item> <item name="counter_secondary_background">@android:color/system_neutral1_500</item>
<item name="counter_secondary_text">@android:color/system_neutral1_900</item> <item name="counter_secondary_text">@android:color/system_neutral1_900</item>
@@ -588,7 +588,7 @@
<item name="dynamic_orange">@color/orange</item> <item name="dynamic_orange">@color/orange</item>
<item name="dynamic_red">@color/red</item> <item name="dynamic_red">@color/red</item>
<item name="dynamic_violet">@color/violet_light</item> <item name="dynamic_violet">@color/violet_light</item>
<item name="feed_recommended_friend_promo_background">@android:color/system_neutral1_500</item> <item name="feed_recommended_friend_promo_background">@android:color/system_neutral1_100</item>
<item name="field_background">@android:color/system_neutral1_800</item> <item name="field_background">@android:color/system_neutral1_800</item>
<item name="field_border">?background_keyboard</item> <item name="field_border">?background_keyboard</item>
<item name="field_error_background">@color/red_dark</item> <item name="field_error_background">@color/red_dark</item>
@@ -599,37 +599,37 @@
<item name="float_button_background_disabled">#66454647</item> <item name="float_button_background_disabled">#66454647</item>
<item name="float_button_background_highlighted">@android:color/system_neutral1_600</item> <item name="float_button_background_highlighted">@android:color/system_neutral1_600</item>
<item name="float_button_background_highlighted_disabled">#665d5f61</item> <item name="float_button_background_highlighted_disabled">#665d5f61</item>
<item name="float_button_border">@android:color/system_neutral1_300</item> <item name="float_button_border">@color/black_alpha12</item>
<item name="float_button_border_disabled">@android:color/system_neutral1_300</item> <item name="float_button_border_disabled">#0c000000</item>
<item name="float_button_foreground">@android:color/system_neutral1_300</item> <item name="float_button_foreground">@android:color/system_neutral1_300</item>
<item name="float_button_foreground_disabled">#66aaaeb3</item> <item name="float_button_foreground_disabled">#66aaaeb3</item>
<item name="header_alternate_background">@android:color/system_neutral1_800</item> <item name="header_alternate_background">@android:color/system_neutral1_800</item>
<item name="header_alternate_tab_active_indicator">@android:color/system_neutral1_100</item> <item name="header_alternate_tab_active_indicator">@android:color/system_neutral1_100</item>
<item name="header_alternate_tab_active_text">@android:color/system_neutral1_100</item> <item name="header_alternate_tab_active_text">?accent</item>
<item name="header_alternate_tab_inactive_text">@android:color/system_neutral1_500</item> <item name="header_alternate_tab_inactive_text">@android:color/system_neutral1_500</item>
<item name="header_background">@android:color/system_neutral1_800</item> <item name="header_background">@android:color/system_neutral1_800</item>
<item name="header_background_before_blur">@color/gray_950</item> <item name="header_background_before_blur">@color/gray_A970</item>
<item name="header_background_before_blur_alternate">@color/gray_950</item> <item name="header_background_before_blur_alternate">@color/gray_A970</item>
<item name="header_search_field_background">@android:color/system_neutral1_800</item> <item name="header_search_field_background">@android:color/system_neutral1_800</item>
<item name="header_search_field_tint">@android:color/system_neutral1_300</item> <item name="header_search_field_tint">@android:color/system_neutral1_300</item>
<item name="header_tab_active_background">@android:color/system_neutral1_600</item> <item name="header_tab_active_background">@android:color/system_neutral1_600</item>
<item name="header_tab_active_indicator">@android:color/system_neutral1_100</item> <item name="header_tab_active_indicator">?accent</item>
<item name="header_tab_active_text">@android:color/system_neutral1_100</item> <item name="header_tab_active_text">?accent</item>
<item name="header_tab_inactive_text">@android:color/system_neutral1_500</item> <item name="header_tab_inactive_text">@android:color/system_neutral1_500</item>
<item name="header_text">@android:color/system_neutral1_100</item> <item name="header_text">?accent</item>
<item name="header_text_alternate">@android:color/system_neutral1_100</item> <item name="header_text_alternate">@android:color/system_neutral1_100</item>
<item name="header_text_secondary">@android:color/system_neutral1_100</item> <item name="header_text_secondary">@android:color/system_neutral1_100</item>
<item name="header_tint">@android:color/system_neutral1_100</item> <item name="header_tint">?accent</item>
<item name="header_tint_alternate">@android:color/system_neutral1_100</item> <item name="header_tint_alternate">@android:color/system_neutral1_100</item>
<item name="header_tint_disabled">#66e1e3e6</item> <item name="header_tint_disabled">#66e1e3e6</item>
<item name="icon_alpha_placeholder">@android:color/system_neutral1_100</item> <item name="icon_alpha_placeholder">@android:color/system_neutral1_100</item>
<item name="icon_medium">@android:color/system_neutral1_400</item> <item name="icon_medium">?accent</item>
<item name="icon_medium_disabled">#66909499</item> <item name="icon_medium_disabled">#66909499</item>
<item name="icon_name">@android:color/system_neutral1_300</item> <item name="icon_name">?accent</item>
<item name="icon_outline_medium">@android:color/system_neutral1_300</item> <item name="icon_outline_medium">?accent</item>
<item name="icon_outline_secondary">@android:color/system_neutral1_400</item> <item name="icon_outline_secondary">?accent</item>
<item name="icon_secondary">@android:color/system_neutral1_500</item> <item name="icon_secondary">?accent</item>
<item name="icon_tertiary">@android:color/system_neutral1_700</item> <item name="icon_tertiary">?accent</item>
<item name="im_attach_tint">?accent</item> <item name="im_attach_tint">?accent</item>
<item name="im_bubble_border_alternate">@color/clear</item> <item name="im_bubble_border_alternate">@color/clear</item>
<item name="im_bubble_border_alternate_highlighted">@color/clear</item> <item name="im_bubble_border_alternate_highlighted">@color/clear</item>
@@ -637,7 +637,7 @@
<item name="im_bubble_button_background_disabled">#10ffffff</item> <item name="im_bubble_button_background_disabled">#10ffffff</item>
<item name="im_bubble_button_background_highlighted">#3dffffff</item> <item name="im_bubble_button_background_highlighted">#3dffffff</item>
<item name="im_bubble_button_background_highlighted_disabled">#18ffffff</item> <item name="im_bubble_button_background_highlighted_disabled">#18ffffff</item>
<item name="im_bubble_button_foreground">@android:color/system_neutral1_100</item> <item name="im_bubble_button_foreground">@android:color/system_neutral1_900</item>
<item name="im_bubble_button_foreground_disabled">#66e1e3e6</item> <item name="im_bubble_button_foreground_disabled">#66e1e3e6</item>
<item name="im_bubble_expiring">@color/mint_400</item> <item name="im_bubble_expiring">@color/mint_400</item>
<item name="im_bubble_expiring_highlighted">@color/mint_500</item> <item name="im_bubble_expiring_highlighted">@color/mint_500</item>
@@ -657,54 +657,54 @@
<item name="im_bubble_wallpaper_button_background_disabled">#66454647</item> <item name="im_bubble_wallpaper_button_background_disabled">#66454647</item>
<item name="im_bubble_wallpaper_button_background_highlighted">@android:color/system_neutral1_500</item> <item name="im_bubble_wallpaper_button_background_highlighted">@android:color/system_neutral1_500</item>
<item name="im_bubble_wallpaper_button_background_highlighted_disabled">#6676787a</item> <item name="im_bubble_wallpaper_button_background_highlighted_disabled">#6676787a</item>
<item name="im_bubble_wallpaper_button_foreground">@android:color/system_neutral1_100</item> <item name="im_bubble_wallpaper_button_foreground">@android:color/system_neutral1_900</item>
<item name="im_bubble_wallpaper_button_foreground_disabled">#66e1e3e6</item> <item name="im_bubble_wallpaper_button_foreground_disabled">#66e1e3e6</item>
<item name="im_bubble_wallpaper_expiring_border">@color/mint_500</item> <item name="im_bubble_wallpaper_expiring_border">@color/mint_500</item>
<item name="im_bubble_wallpaper_incoming">@android:color/system_neutral1_800</item> <item name="im_bubble_wallpaper_incoming">@android:color/system_neutral1_800</item>
<item name="im_bubble_wallpaper_incoming_border">@android:color/system_neutral1_900</item> <item name="im_bubble_wallpaper_incoming_border">?accent</item>
<item name="im_bubble_wallpaper_incoming_highlighted">@android:color/system_neutral1_600</item> <item name="im_bubble_wallpaper_incoming_highlighted">@android:color/system_neutral1_600</item>
<item name="im_bubble_wallpaper_outgoing">@android:color/system_neutral1_700</item> <item name="im_bubble_wallpaper_outgoing">@android:color/system_neutral1_700</item>
<item name="im_bubble_wallpaper_outgoing_border">@android:color/system_neutral1_800</item> <item name="im_bubble_wallpaper_outgoing_border">?accent</item>
<item name="im_bubble_wallpaper_outgoing_highlighted">@android:color/system_neutral1_600</item> <item name="im_bubble_wallpaper_outgoing_highlighted">@android:color/system_neutral1_600</item>
<item name="im_forward_line_tint">@android:color/system_neutral1_100</item> <item name="im_forward_line_tint">?accent</item>
<item name="im_reply_separator">@android:color/system_neutral1_100</item> <item name="im_reply_separator">@android:color/system_neutral1_100</item>
<item name="im_service_message_text">@android:color/system_neutral1_400</item> <item name="im_service_message_text">@android:color/system_neutral1_500</item>
<item name="im_text_name">?accent</item> <item name="im_text_name">?accent</item>
<item name="im_toolbar_separator">@android:color/system_neutral1_300</item> <item name="im_toolbar_separator">@android:color/system_neutral1_300</item>
<item name="im_toolbar_voice_msg_background">@android:color/system_neutral1_700</item> <item name="im_toolbar_voice_msg_background">@android:color/system_neutral1_700</item>
<item name="image_border">?background_keyboard</item> <item name="image_border">?background_keyboard</item>
<item name="input_background">@android:color/system_neutral1_700</item> <item name="input_background">@android:color/system_neutral1_800</item>
<item name="input_border">@android:color/system_neutral1_700</item> <item name="input_border">@android:color/system_neutral1_800</item>
<item name="landing_background">@android:color/system_neutral1_900</item> <item name="landing_background">@android:color/system_neutral1_900</item>
<item name="landing_field_background">@android:color/system_neutral1_900</item> <item name="landing_field_background">@android:color/system_neutral1_900</item>
<item name="landing_field_border">?background_keyboard</item> <item name="landing_field_border">@color/clear</item>
<item name="landing_field_placeholder">@android:color/system_neutral1_300</item> <item name="landing_field_placeholder">@android:color/system_neutral1_300</item>
<item name="landing_login_button_background">@android:color/system_neutral1_100</item> <item name="landing_login_button_background">?accent</item>
<item name="landing_login_button_background_disabled">#66e1e3e6</item> <item name="landing_login_button_background_disabled">#66e1e3e6</item>
<item name="landing_login_button_foreground">@android:color/system_neutral1_900</item> <item name="landing_login_button_foreground">@android:color/system_neutral1_900</item>
<item name="landing_login_button_foreground_disabled">#6619191a</item> <item name="landing_login_button_foreground_disabled">#6619191a</item>
<item name="landing_primary_button_background">@android:color/system_neutral1_100</item> <item name="landing_primary_button_background">?accent</item>
<item name="landing_primary_button_background_disabled">#66e1e3e6</item> <item name="landing_primary_button_background_disabled">#66e1e3e6</item>
<item name="landing_primary_button_foreground">@android:color/system_neutral1_900</item> <item name="landing_primary_button_foreground">@android:color/system_neutral1_900</item>
<item name="landing_primary_button_foreground_disabled">#6619191a</item> <item name="landing_primary_button_foreground_disabled">#6619191a</item>
<item name="landing_secondary_button_background">@android:color/system_neutral1_100</item> <item name="landing_secondary_button_background">?accent</item>
<item name="landing_secondary_button_background_disabled">#0fffffff</item> <item name="landing_secondary_button_background_disabled">#0fffffff</item>
<item name="landing_secondary_button_foreground">@android:color/system_neutral1_900</item> <item name="landing_secondary_button_foreground">@android:color/system_neutral1_900</item>
<item name="landing_secondary_button_foreground_disabled">#66ffffff</item> <item name="landing_secondary_button_foreground_disabled">#66ffffff</item>
<item name="landing_snippet_border">@color/clear</item> <item name="landing_snippet_border">?background_keyboard</item>
<item name="landing_tertiary_button_background">@color/clear</item> <item name="landing_tertiary_button_background">@color/clear</item>
<item name="landing_tertiary_button_background_disabled">#00000000</item> <item name="landing_tertiary_button_background_disabled">#00000000</item>
<item name="landing_tertiary_button_foreground">@android:color/system_neutral1_500</item> <item name="landing_tertiary_button_foreground">?accent</item>
<item name="landing_tertiary_button_foreground_disabled">#6676787a</item> <item name="landing_tertiary_button_foreground_disabled">#66ffffff</item>
<item name="landing_text_primary">@android:color/system_neutral1_100</item> <item name="landing_text_primary">@android:color/system_neutral1_100</item>
<item name="landing_text_secondary">@android:color/system_neutral1_500</item> <item name="landing_text_secondary">@android:color/system_neutral1_500</item>
<item name="landing_text_title">@android:color/system_neutral1_100</item> <item name="landing_text_title">?accent</item>
<item name="like_text_tint">@color/red_light</item> <item name="like_text_tint">@color/red_light</item>
<item name="link_alternate">?accent</item> <item name="link_alternate">?accent</item>
<item name="loader_background">@android:color/system_neutral1_900</item> <item name="loader_background">@android:color/system_neutral1_900</item>
<item name="loader_tint">@android:color/system_neutral1_500</item> <item name="loader_tint">@android:color/system_neutral1_500</item>
<item name="loader_track_fill">@android:color/system_neutral1_700</item> <item name="loader_track_fill">@android:color/system_neutral1_700</item>
<item name="loader_track_value_fill">?accent</item> <item name="loader_track_value_fill">@android:color/system_neutral1_100</item>
<item name="media_overlay_button_background">@android:color/system_neutral1_100</item> <item name="media_overlay_button_background">@android:color/system_neutral1_100</item>
<item name="media_overlay_button_background_disabled">#66ffffff</item> <item name="media_overlay_button_background_disabled">#66ffffff</item>
<item name="media_overlay_button_foreground">@android:color/system_neutral1_800</item> <item name="media_overlay_button_foreground">@android:color/system_neutral1_800</item>
@@ -721,10 +721,10 @@
<item name="panel_tab_inactive_text">@android:color/system_neutral1_500</item> <item name="panel_tab_inactive_text">@android:color/system_neutral1_500</item>
<item name="placeholder_icon_background">@android:color/system_neutral1_800</item> <item name="placeholder_icon_background">@android:color/system_neutral1_800</item>
<item name="placeholder_icon_background_opaque">@android:color/system_neutral1_900</item> <item name="placeholder_icon_background_opaque">@android:color/system_neutral1_900</item>
<item name="placeholder_icon_foreground_primary">@android:color/system_neutral1_400</item> <item name="placeholder_icon_foreground_primary">?accent</item>
<item name="placeholder_icon_foreground_secondary">@android:color/system_neutral1_600</item> <item name="placeholder_icon_foreground_secondary">?accent</item>
<item name="placeholder_icon_tint">@android:color/system_neutral1_100</item> <item name="placeholder_icon_tint">?accent</item>
<item name="poll_option_background">@android:color/system_neutral1_100</item> <item name="poll_option_background">?accent</item>
<item name="search_bar_background">@android:color/system_neutral1_900</item> <item name="search_bar_background">@android:color/system_neutral1_900</item>
<item name="search_bar_field_background">@android:color/system_neutral1_700</item> <item name="search_bar_field_background">@android:color/system_neutral1_700</item>
<item name="search_bar_field_tint">@android:color/system_neutral1_300</item> <item name="search_bar_field_tint">@android:color/system_neutral1_300</item>
@@ -762,7 +762,7 @@
<item name="text_link">?accent</item> <item name="text_link">?accent</item>
<item name="text_link_hightlighted_background">?accent</item> <item name="text_link_hightlighted_background">?accent</item>
<item name="text_muted">@android:color/system_neutral1_200</item> <item name="text_muted">@android:color/system_neutral1_200</item>
<item name="text_name">@android:color/system_neutral1_100</item> <item name="text_name">?accent</item>
<item name="text_placeholder">@android:color/system_neutral1_300</item> <item name="text_placeholder">@android:color/system_neutral1_300</item>
<item name="text_primary">@android:color/system_neutral1_100</item> <item name="text_primary">@android:color/system_neutral1_100</item>
<item name="text_secondary">@android:color/system_neutral1_500</item> <item name="text_secondary">@android:color/system_neutral1_500</item>
@@ -1047,9 +1047,9 @@
<item name="action_sheet_action_foreground">@android:color/system_neutral1_100</item> <item name="action_sheet_action_foreground">@android:color/system_neutral1_100</item>
<item name="action_sheet_separator">@android:color/system_neutral1_100</item> <item name="action_sheet_separator">@android:color/system_neutral1_100</item>
<item name="activity_indicator_tint">@android:color/system_neutral1_600</item> <item name="activity_indicator_tint">@android:color/system_neutral1_600</item>
<item name="attach_picker_tab_active_background">@android:color/system_neutral1_100</item> <item name="attach_picker_tab_active_background">?accent</item>
<item name="attach_picker_tab_active_icon">@color/black</item> <item name="attach_picker_tab_active_icon">@color/black</item>
<item name="attach_picker_tab_active_text">@android:color/system_neutral1_100</item> <item name="attach_picker_tab_active_text">?accent</item>
<item name="attach_picker_tab_inactive_background">@color/black</item> <item name="attach_picker_tab_inactive_background">@color/black</item>
<item name="attach_picker_tab_inactive_icon">@android:color/system_neutral1_100</item> <item name="attach_picker_tab_inactive_icon">@android:color/system_neutral1_100</item>
<item name="attach_picker_tab_inactive_text">@android:color/system_neutral1_500</item> <item name="attach_picker_tab_inactive_text">@android:color/system_neutral1_500</item>
@@ -1067,27 +1067,27 @@
<item name="button_commerce_foreground_disabled">#66ffffff</item> <item name="button_commerce_foreground_disabled">#66ffffff</item>
<item name="button_muted_background">@color/black</item> <item name="button_muted_background">@color/black</item>
<item name="button_muted_background_disabled">#662c2d2e</item> <item name="button_muted_background_disabled">#662c2d2e</item>
<item name="button_muted_foreground">@android:color/system_neutral1_100</item> <item name="button_muted_foreground">?accent</item>
<item name="button_muted_foreground_disabled">#66e1e3e6</item> <item name="button_muted_foreground_disabled">#66e1e3e6</item>
<item name="button_outline_border">?background_keyboard</item> <item name="button_outline_border">?accent</item>
<item name="button_outline_border_disabled">#66e1e3e6</item> <item name="button_outline_border_disabled">#66e1e3e6</item>
<item name="button_outline_foreground">@android:color/system_neutral1_100</item> <item name="button_outline_foreground">?accent</item>
<item name="button_outline_foreground_disabled">#66e1e3e6</item> <item name="button_outline_foreground_disabled">#66e1e3e6</item>
<item name="button_primary_background">@android:color/system_neutral1_100</item> <item name="button_primary_background">?accent</item>
<item name="button_primary_background_disabled">#66e1e3e6</item> <item name="button_primary_background_disabled">#66e1e3e6</item>
<item name="button_primary_foreground">@color/black</item> <item name="button_primary_foreground">@color/black</item>
<item name="button_primary_foreground_disabled">#6619191a</item> <item name="button_primary_foreground_disabled">#6619191a</item>
<item name="button_secondary_background">@android:color/system_neutral1_700</item> <item name="button_secondary_background">@android:color/system_neutral1_700</item>
<item name="button_secondary_background_disabled">#66454647</item> <item name="button_secondary_background_disabled">#66454647</item>
<item name="button_secondary_foreground">@android:color/system_neutral1_100</item> <item name="button_secondary_foreground">?accent</item>
<item name="button_secondary_foreground_disabled">#66e1e3e6</item> <item name="button_secondary_foreground_disabled">#66e1e3e6</item>
<item name="button_tertiary_background">@color/clear</item> <item name="button_tertiary_background">@color/clear</item>
<item name="button_tertiary_background_disabled">#00000000</item> <item name="button_tertiary_background_disabled">#00000000</item>
<item name="button_tertiary_foreground">@android:color/system_neutral1_100</item> <item name="button_tertiary_foreground">?accent</item>
<item name="button_tertiary_foreground_disabled">#66e1e3e6</item> <item name="button_tertiary_foreground_disabled">#66e1e3e6</item>
<item name="cell_button_foreground">@android:color/system_neutral1_100</item> <item name="cell_button_foreground">?accent</item>
<item name="cell_button_foreground_disabled">#66e1e3e6</item> <item name="cell_button_foreground_disabled">#66e1e3e6</item>
<item name="content_placeholder_icon">@android:color/system_neutral1_300</item> <item name="content_placeholder_icon">?accent</item>
<item name="content_placeholder_text">@android:color/system_neutral1_300</item> <item name="content_placeholder_text">@android:color/system_neutral1_300</item>
<item name="content_tint_background">@color/black</item> <item name="content_tint_background">@color/black</item>
<item name="content_tint_foreground">@android:color/system_neutral1_400</item> <item name="content_tint_foreground">@android:color/system_neutral1_400</item>
@@ -1095,9 +1095,9 @@
<item name="control_foreground">@android:color/system_neutral1_100</item> <item name="control_foreground">@android:color/system_neutral1_100</item>
<item name="control_tint">@color/black</item> <item name="control_tint">@color/black</item>
<item name="control_tint_muted">@android:color/system_neutral1_400</item> <item name="control_tint_muted">@android:color/system_neutral1_400</item>
<item name="counter_primary_background">?accent</item> <item name="counter_primary_background">@android:color/system_neutral1_100</item>
<item name="counter_primary_text">@android:color/system_neutral1_100</item> <item name="counter_primary_text">@color/black</item>
<item name="counter_prominent_background">@android:color/system_accent1_500</item> <item name="counter_prominent_background">?accent</item>
<item name="counter_prominent_text">@android:color/system_neutral1_100</item> <item name="counter_prominent_text">@android:color/system_neutral1_100</item>
<item name="counter_secondary_background">@android:color/system_neutral1_500</item> <item name="counter_secondary_background">@android:color/system_neutral1_500</item>
<item name="counter_secondary_text">@color/black</item> <item name="counter_secondary_text">@color/black</item>
@@ -1125,31 +1125,31 @@
<item name="float_button_foreground_disabled">#66aaaeb3</item> <item name="float_button_foreground_disabled">#66aaaeb3</item>
<item name="header_alternate_background">@color/black</item> <item name="header_alternate_background">@color/black</item>
<item name="header_alternate_tab_active_indicator">@android:color/system_neutral1_100</item> <item name="header_alternate_tab_active_indicator">@android:color/system_neutral1_100</item>
<item name="header_alternate_tab_active_text">@android:color/system_neutral1_100</item> <item name="header_alternate_tab_active_text">?accent</item>
<item name="header_alternate_tab_inactive_text">@android:color/system_neutral1_500</item> <item name="header_alternate_tab_inactive_text">@android:color/system_neutral1_500</item>
<item name="header_background">@color/black</item> <item name="header_background">@color/black</item>
<item name="header_background_before_blur">@color/gray_950</item> <item name="header_background_before_blur">@color/gray_A970</item>
<item name="header_background_before_blur_alternate">@color/gray_950</item> <item name="header_background_before_blur_alternate">@color/gray_A970</item>
<item name="header_search_field_background">@android:color/system_neutral1_800</item> <item name="header_search_field_background">@android:color/system_neutral1_800</item>
<item name="header_search_field_tint">@android:color/system_neutral1_300</item> <item name="header_search_field_tint">@android:color/system_neutral1_300</item>
<item name="header_tab_active_background">@android:color/system_neutral1_600</item> <item name="header_tab_active_background">@android:color/system_neutral1_600</item>
<item name="header_tab_active_indicator">@android:color/system_neutral1_100</item> <item name="header_tab_active_indicator">?accent</item>
<item name="header_tab_active_text">@android:color/system_neutral1_100</item> <item name="header_tab_active_text">?accent</item>
<item name="header_tab_inactive_text">@android:color/system_neutral1_500</item> <item name="header_tab_inactive_text">@android:color/system_neutral1_500</item>
<item name="header_text">@android:color/system_neutral1_100</item> <item name="header_text">?accent</item>
<item name="header_text_alternate">@android:color/system_neutral1_100</item> <item name="header_text_alternate">@android:color/system_neutral1_100</item>
<item name="header_text_secondary">@android:color/system_neutral1_100</item> <item name="header_text_secondary">@android:color/system_neutral1_100</item>
<item name="header_tint">@android:color/system_neutral1_100</item> <item name="header_tint">?accent</item>
<item name="header_tint_alternate">@android:color/system_neutral1_100</item> <item name="header_tint_alternate">@android:color/system_neutral1_100</item>
<item name="header_tint_disabled">#66e1e3e6</item> <item name="header_tint_disabled">#66e1e3e6</item>
<item name="icon_alpha_placeholder">@android:color/system_neutral1_100</item> <item name="icon_alpha_placeholder">@android:color/system_neutral1_100</item>
<item name="icon_medium">@android:color/system_neutral1_400</item> <item name="icon_medium">?accent</item>
<item name="icon_medium_disabled">#66909499</item> <item name="icon_medium_disabled">#66909499</item>
<item name="icon_name">@android:color/system_neutral1_300</item> <item name="icon_name">?accent</item>
<item name="icon_outline_medium">@android:color/system_neutral1_300</item> <item name="icon_outline_medium">?accent</item>
<item name="icon_outline_secondary">@android:color/system_neutral1_400</item> <item name="icon_outline_secondary">?accent</item>
<item name="icon_secondary">@android:color/system_neutral1_500</item> <item name="icon_secondary">?accent</item>
<item name="icon_tertiary">@android:color/system_neutral1_700</item> <item name="icon_tertiary">?accent</item>
<item name="im_attach_tint">?accent</item> <item name="im_attach_tint">?accent</item>
<item name="im_bubble_border_alternate">@color/clear</item> <item name="im_bubble_border_alternate">@color/clear</item>
<item name="im_bubble_border_alternate_highlighted">@color/clear</item> <item name="im_bubble_border_alternate_highlighted">@color/clear</item>
@@ -1186,45 +1186,45 @@
<item name="im_bubble_wallpaper_outgoing">@android:color/system_neutral1_700</item> <item name="im_bubble_wallpaper_outgoing">@android:color/system_neutral1_700</item>
<item name="im_bubble_wallpaper_outgoing_border">@color/black</item> <item name="im_bubble_wallpaper_outgoing_border">@color/black</item>
<item name="im_bubble_wallpaper_outgoing_highlighted">@android:color/system_neutral1_600</item> <item name="im_bubble_wallpaper_outgoing_highlighted">@android:color/system_neutral1_600</item>
<item name="im_forward_line_tint">@android:color/system_neutral1_100</item> <item name="im_forward_line_tint">?accent</item>
<item name="im_reply_separator">@android:color/system_neutral1_100</item> <item name="im_reply_separator">@android:color/system_neutral1_100</item>
<item name="im_service_message_text">@android:color/system_neutral1_400</item> <item name="im_service_message_text">@android:color/system_neutral1_500</item>
<item name="im_text_name">?accent</item> <item name="im_text_name">?accent</item>
<item name="im_toolbar_separator">@android:color/system_neutral1_300</item> <item name="im_toolbar_separator">@android:color/system_neutral1_300</item>
<item name="im_toolbar_voice_msg_background">@android:color/system_neutral1_700</item> <item name="im_toolbar_voice_msg_background">@android:color/system_neutral1_700</item>
<item name="image_border">?background_keyboard</item> <item name="image_border">?background_keyboard</item>
<item name="input_background">@android:color/system_neutral1_700</item> <item name="input_background">@color/black</item>
<item name="input_border">@android:color/system_neutral1_700</item> <item name="input_border">@color/black</item>
<item name="landing_background">@color/black</item> <item name="landing_background">@color/black</item>
<item name="landing_field_background">@color/black</item> <item name="landing_field_background">@color/black</item>
<item name="landing_field_border">?background_keyboard</item> <item name="landing_field_border">@color/clear</item>
<item name="landing_field_placeholder">@android:color/system_neutral1_300</item> <item name="landing_field_placeholder">@android:color/system_neutral1_300</item>
<item name="landing_login_button_background">@android:color/system_neutral1_100</item> <item name="landing_login_button_background">?accent</item>
<item name="landing_login_button_background_disabled">#66e1e3e6</item> <item name="landing_login_button_background_disabled">#66e1e3e6</item>
<item name="landing_login_button_foreground">@color/black</item> <item name="landing_login_button_foreground">@color/black</item>
<item name="landing_login_button_foreground_disabled">#6619191a</item> <item name="landing_login_button_foreground_disabled">#6619191a</item>
<item name="landing_primary_button_background">@android:color/system_neutral1_100</item> <item name="landing_primary_button_background">?accent</item>
<item name="landing_primary_button_background_disabled">#66e1e3e6</item> <item name="landing_primary_button_background_disabled">#66e1e3e6</item>
<item name="landing_primary_button_foreground">@color/black</item> <item name="landing_primary_button_foreground">@color/black</item>
<item name="landing_primary_button_foreground_disabled">#6619191a</item> <item name="landing_primary_button_foreground_disabled">#6619191a</item>
<item name="landing_secondary_button_background">@android:color/system_neutral1_100</item> <item name="landing_secondary_button_background">?accent</item>
<item name="landing_secondary_button_background_disabled">#0fffffff</item> <item name="landing_secondary_button_background_disabled">#0fffffff</item>
<item name="landing_secondary_button_foreground">@color/black</item> <item name="landing_secondary_button_foreground">@color/black</item>
<item name="landing_secondary_button_foreground_disabled">#66ffffff</item> <item name="landing_secondary_button_foreground_disabled">#66ffffff</item>
<item name="landing_snippet_border">@color/clear</item> <item name="landing_snippet_border">?background_keyboard</item>
<item name="landing_tertiary_button_background">@color/clear</item> <item name="landing_tertiary_button_background">@color/clear</item>
<item name="landing_tertiary_button_background_disabled">#00000000</item> <item name="landing_tertiary_button_background_disabled">#00000000</item>
<item name="landing_tertiary_button_foreground">@android:color/system_neutral1_500</item> <item name="landing_tertiary_button_foreground">?accent</item>
<item name="landing_tertiary_button_foreground_disabled">#6676787a</item> <item name="landing_tertiary_button_foreground_disabled">#66ffffff</item>
<item name="landing_text_primary">@android:color/system_neutral1_100</item> <item name="landing_text_primary">@android:color/system_neutral1_100</item>
<item name="landing_text_secondary">@android:color/system_neutral1_500</item> <item name="landing_text_secondary">@android:color/system_neutral1_500</item>
<item name="landing_text_title">@android:color/system_neutral1_100</item> <item name="landing_text_title">?accent</item>
<item name="like_text_tint">@color/red_light</item> <item name="like_text_tint">@color/red_light</item>
<item name="link_alternate">?accent</item> <item name="link_alternate">?accent</item>
<item name="loader_background">@color/black</item> <item name="loader_background">@color/black</item>
<item name="loader_tint">@android:color/system_neutral1_500</item> <item name="loader_tint">@android:color/system_neutral1_500</item>
<item name="loader_track_fill">@android:color/system_neutral1_700</item> <item name="loader_track_fill">@android:color/system_neutral1_700</item>
<item name="loader_track_value_fill">?accent</item> <item name="loader_track_value_fill">@android:color/system_neutral1_100</item>
<item name="media_overlay_button_background">@android:color/system_neutral1_100</item> <item name="media_overlay_button_background">@android:color/system_neutral1_100</item>
<item name="media_overlay_button_background_disabled">#66ffffff</item> <item name="media_overlay_button_background_disabled">#66ffffff</item>
<item name="media_overlay_button_foreground">@color/black</item> <item name="media_overlay_button_foreground">@color/black</item>
@@ -1241,10 +1241,10 @@
<item name="panel_tab_inactive_text">@android:color/system_neutral1_500</item> <item name="panel_tab_inactive_text">@android:color/system_neutral1_500</item>
<item name="placeholder_icon_background">@android:color/system_neutral1_900</item> <item name="placeholder_icon_background">@android:color/system_neutral1_900</item>
<item name="placeholder_icon_background_opaque">@color/black</item> <item name="placeholder_icon_background_opaque">@color/black</item>
<item name="placeholder_icon_foreground_primary">@android:color/system_neutral1_400</item> <item name="placeholder_icon_foreground_primary">?accent</item>
<item name="placeholder_icon_foreground_secondary">@android:color/system_neutral1_600</item> <item name="placeholder_icon_foreground_secondary">?accent</item>
<item name="placeholder_icon_tint">@android:color/system_neutral1_100</item> <item name="placeholder_icon_tint">?accent</item>
<item name="poll_option_background">@android:color/system_neutral1_100</item> <item name="poll_option_background">?accent</item>
<item name="search_bar_background">@color/black</item> <item name="search_bar_background">@color/black</item>
<item name="search_bar_field_background">@android:color/system_neutral1_800</item> <item name="search_bar_field_background">@android:color/system_neutral1_800</item>
<item name="search_bar_field_tint">@android:color/system_neutral1_300</item> <item name="search_bar_field_tint">@android:color/system_neutral1_300</item>
@@ -1282,7 +1282,7 @@
<item name="text_link">?accent</item> <item name="text_link">?accent</item>
<item name="text_link_hightlighted_background">?accent</item> <item name="text_link_hightlighted_background">?accent</item>
<item name="text_muted">@android:color/system_neutral1_200</item> <item name="text_muted">@android:color/system_neutral1_200</item>
<item name="text_name">@android:color/system_neutral1_100</item> <item name="text_name">?accent</item>
<item name="text_placeholder">@android:color/system_neutral1_300</item> <item name="text_placeholder">@android:color/system_neutral1_300</item>
<item name="text_primary">@android:color/system_neutral1_100</item> <item name="text_primary">@android:color/system_neutral1_100</item>
<item name="text_secondary">@android:color/system_neutral1_500</item> <item name="text_secondary">@android:color/system_neutral1_500</item>
+1
View File
@@ -6532,6 +6532,7 @@ May look like a fake leaving the online"</string>
<string name="datasettings_title">Application data settings</string> <string name="datasettings_title">Application data settings</string>
<string name="invalidate_theme_cache_title">Invalidate theme cache</string> <string name="invalidate_theme_cache_title">Invalidate theme cache</string>
<string name="invalidate_theme_cache_each_update_title">Clear theme cache after update to prevent problems with accents</string>
<string name="useCustomPrefsStyle_title">Use new switches</string> <string name="useCustomPrefsStyle_title">Use new switches</string>
<string name="useCustomPrefsStyle_summ">More modern and stylish toggle switches in settings</string> <string name="useCustomPrefsStyle_summ">More modern and stylish toggle switches in settings</string>
+5 -5
View File
@@ -7,6 +7,11 @@
android:summary="@string/accent_color_summ" android:summary="@string/accent_color_summ"
android:icon="@drawable/bg_accent_circle" android:icon="@drawable/bg_accent_circle"
android:title="@string/accent_color_title"/> android:title="@string/accent_color_title"/>
<com.vtosters.lite.ui.MaterialSwitchPreference
android:defaultValue="true"
android:key="invalidate_theme_cache_each_update"
android:summary="@string/invalidate_theme_cache_each_update_title"
android:title="@string/invalidate_theme_cache_title"/>
<Preference <Preference
android:key="invalidate_theme_cache" android:key="invalidate_theme_cache"
android:title="@string/invalidate_theme_cache_title" /> android:title="@string/invalidate_theme_cache_title" />
@@ -84,10 +89,5 @@
android:key="VKUI_INJ" android:key="VKUI_INJ"
android:summary="@string/appearance_other_color_webview_summary" android:summary="@string/appearance_other_color_webview_summary"
android:title="@string/vkuiinj"/> android:title="@string/vkuiinj"/>
<com.vtosters.lite.ui.MaterialSwitchPreference
android:defaultValue="false"
android:key="useNewColorEngine"
android:summary="@string/useNewColorEngine_summ"
android:title="@string/useNewColorEngine_title"/>
</PreferenceCategory> </PreferenceCategory>
</PreferenceScreen> </PreferenceScreen>
@@ -157,7 +157,7 @@
.method public getResources()Landroid/content/res/Resources; .method public getResources()Landroid/content/res/Resources;
.registers 3 .registers 3
invoke-static {}, Lru/vtosters/hooks/other/ThemesUtils;->isCustomAccentEnabled()Z invoke-static {}, Lru/vtosters/hooks/other/ThemesUtils;->isMonetTheme()Z
move-result v1 move-result v1
@@ -222,41 +222,41 @@
.line 14 .line 14
:cond_0 :cond_0
new-instance v0, Lcom/vk/api/audio/AudioSendStartEvent; # new-instance v0, Lcom/vk/api/audio/AudioSendStartEvent;
invoke-virtual {p1}, Lcom/vk/dto/music/MusicTrack;->y1()Ljava/lang/String; # invoke-virtual {p1}, Lcom/vk/dto/music/MusicTrack;->y1()Ljava/lang/String;
move-result-object p1 # move-result-object p1
sget-object v2, Lcom/vk/api/base/ApiConfig;->d:Lcom/vk/api/base/ApiConfig$a; # sget-object v2, Lcom/vk/api/base/ApiConfig;->d:Lcom/vk/api/base/ApiConfig$a;
invoke-interface {v2}, Lcom/vk/api/base/ApiConfig$a;->O1()Ljava/lang/String; # invoke-interface {v2}, Lcom/vk/api/base/ApiConfig$a;->O1()Ljava/lang/String;
move-result-object v2 # move-result-object v2
invoke-direct {v0, p1, v2}, Lcom/vk/api/audio/AudioSendStartEvent;-><init>(Ljava/lang/String;Ljava/lang/String;)V # invoke-direct {v0, p1, v2}, Lcom/vk/api/audio/AudioSendStartEvent;-><init>(Ljava/lang/String;Ljava/lang/String;)V
const/4 p1, 0x0 # const/4 p1, 0x0
.line 15 # .line 15
invoke-static {v0, p1, v1, p1}, Lcom/vk/api/base/ApiRequest;->d(Lcom/vk/api/base/ApiRequest;Lcom/vk/api/base/ApiThreadHolder;ILjava/lang/Object;)Lio/reactivex/Observable; # invoke-static {v0, p1, v1, p1}, Lcom/vk/api/base/ApiRequest;->d(Lcom/vk/api/base/ApiRequest;Lcom/vk/api/base/ApiThreadHolder;ILjava/lang/Object;)Lio/reactivex/Observable;
move-result-object p1 # move-result-object p1
.line 16 # .line 16
new-instance v0, Lcom/vk/music/notifications/restriction/MusicRestrictionModelImpl$d; # new-instance v0, Lcom/vk/music/notifications/restriction/MusicRestrictionModelImpl$d;
invoke-direct {v0, p0}, Lcom/vk/music/notifications/restriction/MusicRestrictionModelImpl$d;-><init>(Lcom/vk/music/notifications/restriction/MusicRestrictionModelImpl;)V # invoke-direct {v0, p0}, Lcom/vk/music/notifications/restriction/MusicRestrictionModelImpl$d;-><init>(Lcom/vk/music/notifications/restriction/MusicRestrictionModelImpl;)V
.line 17 # .line 17
sget-object v1, Lcom/vk/music/notifications/restriction/MusicRestrictionModelImpl$e;->a:Lcom/vk/music/notifications/restriction/MusicRestrictionModelImpl$e; # sget-object v1, Lcom/vk/music/notifications/restriction/MusicRestrictionModelImpl$e;->a:Lcom/vk/music/notifications/restriction/MusicRestrictionModelImpl$e;
.line 18 # .line 18
invoke-virtual {p1, v0, v1}, Lio/reactivex/Observable;->a(Lio/reactivex/functions/Consumer;Lio/reactivex/functions/Consumer;)Lio/reactivex/disposables/Disposable; # invoke-virtual {p1, v0, v1}, Lio/reactivex/Observable;->a(Lio/reactivex/functions/Consumer;Lio/reactivex/functions/Consumer;)Lio/reactivex/disposables/Disposable;
move-result-object p1 # move-result-object p1
iput-object p1, p0, Lcom/vk/music/notifications/restriction/MusicRestrictionModelImpl;->a:Lio/reactivex/disposables/Disposable; # iput-object p1, p0, Lcom/vk/music/notifications/restriction/MusicRestrictionModelImpl;->a:Lio/reactivex/disposables/Disposable;
return-void return-void
.end method .end method